Strukturen und die Pointer auf die Pointer :)



  • Hallo zusammen,

    Ich habe eine Frage im Umgang mit den Strukturen und Pointern.
    Was ich machen möchte ist, alle IP's meines PC'S auslesen und anzeigen lassen.

    Das ganze wie folgt:

    hostent STRUCT
      h_name      DWORD      ?
      h_alias     DWORD      ?
      h_addr      WORD       ?
      h_len       WORD       ?
      h_list      DWORD      ?
    hostent ENDS
    
    .DATA
    
    hos hostent <>
    dnsname db "meinpc",0
    
    .Code
    
    invoke gethostbyname, addr dnsname
         mov esi, eax			;Pointer der HOSTENT Struc nach ESI
    	mov edi, offset hos		;EDI zeigt auf unsere HOSTENT Struc
    	xor ecx, ecx
    	mov ecx, sizeof hos
    	rep movsb                  ;Struktur mit Daten füllen
    
           xor eax, eax
    		mov eax, hos.h_list
    		mov eax, [eax]
    		mov eax, [eax]
    
            call ip_to_ascii
    
    		invoke MessageBox, NULL, eax, addr szCaption, MB_OK
    

    Die Funktion ip_to_ascii habe ich selbst erstellt, da ich die Funktion inet_ntoa (Netzwerk IP to ASCIIZ) nicht zum laufen bewegen kann.

    Jedenfalls tut meine Funktion auch ihren Dienst und meine IP (sowie diverser Inet-Seiten) wird korrekt angezeigt.

    Nun kommen wir endlich zu meinen Fragen.
    Folgendes steht über HOSTENT in der MSDN

    typedef struct hostent {
       char FAR      *h_name;
       char FAR FAR **h_aliases;
       short         h_addrtype;
       short         h_length;
       char FAR FAR **h_addr_list;
     } HOSTENT, *PHOSTENT, FAR *LPHOSTENT;
    
    **h_addr_list = A NULL -terminated list of addresses for the host
    

    h_name ist ein FAR Pointer, den ich aber direkt der MessageBox() übergeben kann.
    h_aliases ist ein FAR FAR Pointer genau wie h_addr_list.

    Wie man in Zeile 25 und 26 erkennen kann, muss ich zweimal die Speicherstelle auf die EAX zeigt nach EAX laden um an die IP zu kommen. 😕
    Da h_addr_list aber eine NULL terminierte Liste sein soll, wie komme ich an die
    anderen Einträge ran und wie sehe ich das Ende der Liste?
    Null-terminiert heißt das irgendwann EAX = 0 ist, aber den Weg dahin?

    Kann mir jemand erklären wie das "verkettet" ist und wie ich an eine (falls
    vorhanden) zweite IP käme?

    Was ich mir denke ist folgendes:
    Einen Pointer kann ich direkt übergeben, während ein FAR Pointer einmal

    mov eax, [eax]
    

    und FAR FAR Pointer zweimal

    mov eax, [eax]
    mov eax, [eax]
    

    muss???

    h_aliases = A NULL -terminated array of alternate names
    Liegen hier mehrere DWORD's hintereinander im Speicher die jeweils auf einen String
    zeigen und das letzte hat den Wert NULL?

    Hoffentlich weiß jemand was ich meine und kann mir das erklären 💡

    Danke und Gruß, Nicky



  • Das sind Pointer-Arrays, bei denen, wie du schon erkannt hast, der letzte Eintrag ein Null-Pointer ist. Wie immer führen sehr viele Wege nach Rom:

    esi = h_list
    ;1.
    xor ecx,ecx
    .while PVOID ptr [esi+ecx*4]
        mov edx,PVOID ptr [esi+ecx*4]
        ; edx = *pp = Zeiger aus Array
        ; ...
        add ecx,1
    .endw
    
    ;2.
    @1: mov edx,PVOID ptr [esi]
        test edx,edx
        jz @2:
        ; edx = *pp
        ;...
        add esi,4
        jmp @1
    
    3. ...
    

    BTE: Das "FAR" hat keine Bedeutung mehr – es steht nur aus historische Gründen da.



  • Hallo masm,

    mov esi, hos.h_list

    speichert also die Nummer der Speicherstelle an der das Array beginnt?

    Dann kann ich immer mit (esi + 4) (esi + 😎 usw. auf die Elemente
    des Arrays zugreifen? Das versuche ich dann mal. (Hab am Handy keine eckigen Klammern)

    Kannst du mir nochwas zu Zeile 25 und 26 sagen, wieso ich
    zweimal machen musste mit den Speicherstellen?

    Gruss und Danke, Nicky 👍



  • Du solltest dir dringen ein C-Tutorial durcharbeiten damit du:
    1. Pointer und arrays verstehst!
    2. danach Funktionsdeklaration, insbesondere der WinAPI verstehst (ich ahne warum du "Netzwerk IP to ASCIIZ" nicht zum Laufen gebracht hast)

    Danach sollte es dann auch mit Assembler klappen.

    masm



  • Schau mal dir mal hier den Post an:

    http://www.tutorials.de/c-c/142672-c-gethostbyname-ip-ausgeben.html#post1184996

    Demnach ist h_addr_list ein Pointer auf ein Array von Pointern. Diese Pointer zeigen auf die Bytes der jeweiligen IP-Adresse. Sagen wir mal hier 4 Byte wegen IPv4.

    Ein Zugriff dürfte demnach so aussehen (ungetestet, bin anner Arbeit):

    Test proc pArray: Dword
        LOCAL ipAddr: Dword ;Die IP-Adresse des aktuellen Eintrages
        push eax ;Enthält den Pointer auf den aktuellen Listeneintrag
        push ebx ;Enthält den Pointer des aktuellen Listeneintrages auf die IP-Adr
    
        mov eax, pArray ;Kopiere Start-Adresse auf das Pointer-Array nach EAX
    fl:
        mov ebx, dword ptr[eax] ;Kopiere aktuellen Listeneintrag (Ptr) nach EBX
        cmp ebx, 0 ;Check ob Ende der Liste erreicht (NULL-Pointer)
        je fle ;Wenn EBX 0 dann den weiteren Schleifencode überspringen
        mov ipAddr, dword ptr[ebx] ;Kopiere die 4 Byte auf die EBX zeigt nach lokale Stackvariable
        ... ;Mache irgendwas
        add eax, 4 ;Addiere 4 auf EAX um zum nächsten Pointer-Eintrag zu zeigen
        jmp fl ;Springe zum Anfang der Schleife und mache mit nächstem Eintrag weiter
    fle:
        pop ebx //EBX wiederherstellen
        pop eax //EAX wiederherstellen
    
        ret ;4 //Rücksprungadresse wiederherstellen und DWORD argument freigeben
    Test endp
    

    Ich hoffe, dass ich helfen konnte. ^^



  • wazzup schrieb:

    Schau mal dir mal hier den Post an:

    http://www.tutorials.de/c-c/142672-c-gethostbyname-ip-ausgeben.html#post1184996

    Demnach ist h_addr_list ein Pointer auf ein Array von Pointern. Diese Pointer zeigen auf die Bytes der jeweiligen IP-Adresse. Sagen wir mal hier 4 Byte wegen IPv4.

    Ein Zugriff dürfte demnach so aussehen (ungetestet, bin anner Arbeit):

    Test proc pArray: Dword
        LOCAL ipAddr: Dword ;Die IP-Adresse des aktuellen Eintrages
        push eax ;Enthält den Pointer auf den aktuellen Listeneintrag
        push ebx ;Enthält den Pointer des aktuellen Listeneintrages auf die IP-Adr
    
        mov eax, pArray ;Kopiere Start-Adresse auf das Pointer-Array nach EAX
    fl:
        mov ebx, dword ptr[eax] ;Kopiere aktuellen Listeneintrag (Ptr) nach EBX
        cmp ebx, 0 ;Check ob Ende der Liste erreicht (NULL-Pointer)
        je fle ;Wenn EBX 0 dann den weiteren Schleifencode überspringen
        mov ipAddr, dword ptr[ebx] ;Kopiere die 4 Byte auf die EBX zeigt nach lokale Stackvariable
        ... ;Mache irgendwas
        add eax, 4 ;Addiere 4 auf EAX um zum nächsten Pointer-Eintrag zu zeigen
        jmp fl ;Springe zum Anfang der Schleife und mache mit nächstem Eintrag weiter
    fle:
        pop ebx //EBX wiederherstellen
        pop eax //EAX wiederherstellen
    
        ret ;4 //Rücksprungadresse wiederherstellen und DWORD argument freigeben
    Test endp
    

    Ich hoffe, dass ich helfen konnte. ^^

    Hallo,

    habe es hinbekommen...

    😉


Anmelden zum Antworten