connect IP prüfen [Detours]



  • Hallo,

    Ich verwende Detours 1.5 und versuche damit die "connect" abzuändern.
    Ich möchte lediglich die IP Adresse auslesen die mit der sockaddr Struktur übergeben wird und dann ggf austauschen.

    Mein bisheriger Code:

    #include <Winsock2.h>
    #include <Windows.h>
    #include <detours.h>
    
    #pragma comment(lib, "detours.lib")
    #pragma comment(lib, "Ws2_32.lib")
    
    typedef int (*connectType)(SOCKET s, const struct sockaddr *name, int namelen);
    connectType connect_orig = NULL;
    
    int connectDetour(SOCKET s, const struct sockaddr *name, int namelen)
    {
    	//Hier auslesen, aber wie?
    	MessageBoxW(NULL, L"Test", L"Test", MB_OK);
    	return connect_orig(s, name, namelen);
    }
    
    bool APIENTRY DllMain(HANDLE _HDllHandle, DWORD _Reason, LPVOID _Reserved)
    {
    	switch(_Reason)
    	{
    	case DLL_PROCESS_ATTACH:
    		connect_orig = (connectType)DetourFunction((PBYTE)connect, (PBYTE)connectDetour);
    		break;
    
    	case DLL_PROCESS_DETACH:
    		break;
    	}
    
    	return TRUE;
    }
    

    Der Detour klappt schonmal, jedoch popt die MessageBox immer wieder auf. Also vermute ich das mit den neuen Parametern nicht zur Uhrsprünglichen Funktion gejumpt wird. Warum auch immer.
    Die IP Adresse wird der Struktur doch so: sin_addr.s_addr = inet_addr("127.0.0.1"); zugewiesen, doch wie komm ich wieder an die IP ran und kann sie dann ggf. ändern in der Struktur?

    Habe es mal im WinAPI bereich gepostet, da der Detour ja klappt bis auf die Wiederholung der MessageBox. Ich hoffe ich finde hier Hilfe, denn ich probier es schon den ganzen Tag. 😕

    MfG



  • Vieleicht wird das connect mehrmals aufgerufen!? Wie kommst Du darauf, dass es nur einmal aufgerufen wird?



  • oh 🙄
    connect wurde in der Tat öfters aufgerufen, habe es heute Morgen noch einmal an einem Beispiel von mir getestet. Nach dem connect aber aufgerufen wird, crasht das Programm.
    Liegt das vllt an dem Cast zu SOCKADDR bei connect?

    connect(ConnectSocket, (SOCKADDR*)&clientService, sizeof(clientService));
    

    So das ich es vllt hiermit:

    return connect_orig(s, name, namelen);
    

    falsch der Zielfunktion übergebe?

    Und ich hab immer noch keine Idee wie ich an die IP komme... 😕



  • Wenn Du im connect etwas castest, dann ist dort das Problem... sowas sollte nie nötig sein...



  • Okay, danke. Habe mich daran an dem Beispiel von der MSDN orientiert.

    Doch wie komm ich jetzt an die IP durch die sockaddr Struktur?

    struct sockaddr {
            ushort  sa_family;
            char    sa_data[14];
    };
    


  • Ev. hilft sockaddr_in - da sollte die IP drin sein.



  • Soll ich dann von sockaddr zu sockaddr_in casten? 😕
    Die IP wird ja mit inet_addr() übergeben.
    "The inet_addr function converts a string containing an IPv4 dotted-decimal address into a proper address for the IN_ADDR structure."

    Dann muss noch die IP, die dann im unsigned long Format ist, wieder zum String bekommen? Ist das wirklich so aufwendig oder vertuh ich mich hier grade? 😃
    Ich versuch mein Glück nochmal, aber mit so einem Aufwand habe ich nicht gerechnet.



  • Kopiere den Inhalt von sockaddr nach sockaddr_in, danch benutze inet_ntoa(..) mit dem Member sin_addr:
    sockaddr, sockaddr_in:http://msdn.microsoft.com/en-us/library/windows/desktop/ms740496.aspx
    inet_ntoa(..):http://msdn.microsoft.com/en-us/library/windows/desktop/ms738564.aspx

    Edit: Links angepasst.



  • Danke theta. Grade ist mir aufgefallen das es dafür sogar eine Funktion gibt, doch auch die bereitet mir Probleme.

    WSAAddressToString
    The WSAAddressToString function converts all components of a sockaddr structure into a human-readable string representation of the address.

    So kann ich mir zumindest das kopieren der Struktur sparen. Mein Versuch:

    int connectDetour(SOCKET s, const struct sockaddr *name, int namelen)
    {
    	char buf[MAX_PATH];
    	if(WSAAddressToString(const_cast<LPSOCKADDR>(name), sizeof(name), NULL, buf, NULL) == SOCKET_ERROR)
    	{
    		MessageBox(NULL, GetLastErrorString(WSAGetLastError()).c_str(), "Error", MB_OK);
    	}
    
    	MessageBox(NULL, buf, "IP Adresse", MB_OK);
    	return connect_orig(s, name, namelen);
    }
    

    Fehler der mir zurück gegeben wird: Ein ungültiges Argument wurde angegeben.
    Weiß jemand was ich jetzt falsch mache?



  • Verwende keinen const_cast... kopiere die Struktur falls nötig.
    Zu deinem Fehler: Wie gross ist sizeof(name), wie gross ist sizeof(*name)?
    Und der letzte Parameter? Darf der NULL sein? 🕶
    http://msdn.microsoft.com/en-us/library/windows/desktop/ms741516(v=vs.85).aspx



  • Okay, habs jetzt ohne die Kovertierung versucht. Jetzt crasht mein Programm und vorher bekomme ich diesen Fehler ausgegeben:
    Bei dem Versuch das Zeigerargument eines Aufrufs zu verwenden, wurde eine ungültige Zeigeradresse gefunden.

    Mein Code sieht jetzt so aus:

    int connectDetour(SOCKET s, const struct sockaddr *name, int namelen)
    {
    	char buf[MAX_PATH];
    	DWORD bufsize = 0;
    	struct sockaddr *cpyname = new sockaddr[sizeof(*name)];
    	*cpyname = *name;
    
    	if(WSAAddressToString(cpyname, sizeof(*name), NULL, buf, &bufsize) == SOCKET_ERROR)
    	{
    		MessageBox(NULL, GetLastErrorString(WSAGetLastError()).c_str(), "Error", MB_OK);
    	}
    
    	MessageBox(NULL, buf, "IP Adresse", MB_OK);
    	return connect_orig(s, name, namelen);
    }
    


  • Okay, habs jetzt ohne die Kovertierung versucht. Jetzt crasht mein Programm und vorher bekomme ich diesen Fehler ausgegeben:
    Bei dem Versuch das Zeigerargument eines Aufrufs zu verwenden, wurde eine ungültige Zeigeradresse gefunden.

    Ja, und welcher der Parameter könnte den das Problem verursachen?
    Lies die Doku genau und sieh in deinem Code nach ob da was nicht stimmt... 🙄

    Edit: und zum Code allgemein: 😞
    Edit2: Ist nicht mehr zum ertragen... hier Bsp. Code:
    Ohne WSA... aber ich denke, er macht das was du möchtest, oder?

    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    #include <winsock2.h>
    
    #pragma comment (lib, "ws2_32.lib")
    
    #include <iostream>
    
    int connect_orig(SOCKET /*s*/, const struct sockaddr* /*name*/, int /*namelen*/) { return SOCKET_ERROR; }
    
    int connectDetour(SOCKET s, const struct sockaddr* name, int namelen) 
    {
        const sockaddr_in* internetName = reinterpret_cast<const sockaddr_in*>(name);
        const char* ipAddress = inet_ntoa(internetName->sin_addr);
        std::cout << "IP Address: " << ipAddress << std::endl;
    
        return connect_orig(s, name, namelen);
    }
    
    int main()
    {
        SOCKET sock = INVALID_SOCKET;
    
        sockaddr_in name = {};
        name.sin_port = htons(1234);
        name.sin_addr.S_un.S_addr = inet_addr("10.1.44.120");
    
        connectDetour(sock, reinterpret_cast<const sockaddr*>(&name), sizeof(name));
    }
    


  • Danke theta, hätte ich mal von Anfang an auf deinen Tipp gehört einfach inet_ntoa zu verwenden. Das Programm crasht allerdings jetzt, aber sobald ich die zwei Zeilen rausnehme und die Parameter ohne irgendwelche Aktionen mit connect_orig zurückgebe, funktioniert es. 😮



  • Wenns crasht würde ich debuggen... Gibt es Restriktionen bei ge-detourten Funktionen? z.B. kein std::cout? Ich weiss es leider nicht.

    Ev. musst Du noch den protocol familiy testen - so etwa:

    #define WIN32_LEAN_AND_MEAN 
    #include <windows.h> 
    #include <winsock2.h> 
    
    #pragma comment (lib, "ws2_32.lib") 
    
    #include <iostream> 
    
    int connect_orig(SOCKET /*s*/, const struct sockaddr* /*name*/, int /*namelen*/) { return SOCKET_ERROR; }
    
    int connectDetour(SOCKET s, const struct sockaddr* name, int namelen) 
    { 
        if (name->sa_family == AF_INET)
        {
            const sockaddr_in* internetName = reinterpret_cast<const sockaddr_in*>(name);
            const char* ipAddress = inet_ntoa(internetName->sin_addr); 
            std::cout << "IP Address: " << ipAddress << std::endl; 
        }
        else
        {
            std::cout << "name not of type sockadd_in" << std::endl;
        }
    
        return connect_orig(s, name, namelen); 
    } 
    
    int main() 
    { 
        SOCKET sock = INVALID_SOCKET; 
    
        sockaddr_in name = {}; 
        name.sin_family = AF_INET;
        name.sin_port = htons(1234); 
        name.sin_addr.S_un.S_addr = inet_addr("10.1.44.120"); 
    
        connectDetour(sock, reinterpret_cast<const sockaddr*>(&name), sizeof(name));
    }
    


  • Okay, ich werde mir das heute Abend mal im Debugger anschauen und morgen dann ggf. Detours 3.0 ausprobieren. Zurzeit verwende ich ja die Version 1.5, welche vielleicht recht veraltet scheint.



  • Habe nun selber ein Beispiel Programm geschrieben welches die connect Funktion verwendet und habe dort die dll injiziert. Der debugger spuckt ständig den selben Fehler aus, hier ein Beispiel von Firefox.
    Unbehandelte Ausnahme bei 0x00000010 in firefox.exe: 0xC0000005: Access violation.

    Ich weiß nicht ob ich mir die Mühe machen soll und das ganze mit Detours 3.0 zu testen, den "Access violation" hört sich nicht nach einem Problem von Detours selbst an, oder?

    Die Funktion connect wird ja gefunden und auch mit meiner ersetzt, auch das auslesen der IP funktioniert einwandfrei, doch sobald die Parameter an die Original Funktion weiter gegeben werden, bricht das Programm ab mit "Access violation".

    Langsam verzweifel ich, vorallem weil ich zu Detours 1.5 nicht einmal eine gescheite Doku finde.



  • So, fehler behoben. Für alle die es noch wissen wollen: Man muss __stdcall als calling convention nehmen. 🙂


Log in to reply