Hooking der send Funktion verursacht eine "Acess violation"

Guten Tag erstmal.
Ich versuche gerade einen Winsock-Hook, welcher in jedem programm, solange es geügend Rechte hat, laufen soll. (So ähnlich wie ein Winsock Packet Editor)
Zum Ausprobieren benutze ich momentan Firefox 3.6.11.
Das Problem:
->nachdem ich die Dll injected habe, wird die Bypass-Funktion aufgerufen, welche eine messagebox zeigt und anschließend die orginale sendfunktion aufruft.
Das funktioniert soweit auch noch ganz gut, aber sobald die send-Funktion beendet ist, wird folgender Befehl ausgeführt:
CMP DWORD PRT[ECX+4]. ECX ist zu diesem Zeitpunkt 0x34333231, weshalb der Befehl auf eine nicht verfügbare Adresse zugreift.
Wenn der Hook nicht installiert ist, ist ECX meistens 0x8386A0.
Anscheinend manipuliert meine Funktion in irgendeiner Weise den ECX.
Meine Vermutung liegt in darin, dass meine Funktion beim Rücksprung einen falschen Wert in den ECX schreibt.
Allerdings funktioniert die Dll in anderen Programmen. Nur Firefox will nicht.

Die Dll ist mit dem MinGW kompilliert.
PHP:
#include <windows.h>
#include <stdio.h>


int (*new_send)(SOCKET, char*, int , int);
int (*new_sendto)();


unsigned int sprungoffset(unsigned int absprung, unsigned int ziel)
{
    return ziel - absprung;
}
int bypass_send(SOCKET s, char *buf, int len, int flags)
{
    int retval;
    MessageBoxA(0, "gehookt", "yeah", 0);
    retval = new_send(s, buf, len, flags);
    return retval;
}

bool SetDebugPrivileges(){
  bool b = FALSE;
  TOKEN_PRIVILEGES tp;
  HANDLE hToken;
  if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid)){
     if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)){
        if (hToken != INVALID_HANDLE_VALUE){
           tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
           tp.PrivilegeCount = 1;
           if (AdjustTokenPrivileges(hToken, FALSE, &tp, 0, 0, 0))
              b = TRUE;
           CloseHandle(hToken);
        }
     }
  }
  return b;
}

unsigned int GetProc(char *sDll, char *sFunc)
{
    return (unsigned int) GetProcAddress(GetModuleHandle(sDll), sFunc);
}

void DumpInt(unsigned int a, char *sTitle, int zahlensystem)
{
    char buffer[20];
    itoa(a, buffer, zahlensystem);
    MessageBox(0, buffer, sTitle, 0);
}



unsigned int hook_function(unsigned int old_address, unsigned int bypass_address, unsigned int bytes_to_save)
{
    unsigned int sprungweg = sprungoffset(old_address+5, bypass_address), sprungweg_back;
    unsigned char op_byte; DWORD dw; unsigned int *new_address = 0; unsigned int temp_help_var = 0;
    //~printf("[DEBUG]good ist at 0x%x\nsprungoffset: 0x%x\n", bypass_address, sprungweg);
    ///===============>Vorige Sicherungsbyte speichern
    new_address = (unsigned int*) malloc(bytes_to_save+5); //Den Speicher für das NOPArray anfordern (die 5 bytes din für den humpbefehl)
    VirtualProtect((LPVOID)new_address, bytes_to_save+5, PAGE_EXECUTE_READWRITE, &dw);
    printf("new address is at 0x%x\n", new_address);
    memset(new_address, 0x90, bytes_to_save+5); //alle bytes des array als NOP speichern
    //~printf("[DEBUG]new_address contains 0x%x\n", new_address); //DEBUG
    memcpy(new_address, (void*)old_address, bytes_to_save); //alle sicherungsbytes kopieren
    memset((LPVOID)new_address+bytes_to_save, 0xE9, 1); //sprungop schreiben
    sprungweg_back = sprungoffset((unsigned int)new_address+bytes_to_save+5, old_address+bytes_to_save);
    memcpy((void*)new_address+bytes_to_save+1, &sprungweg_back, sizeof(sprungweg_back)); //sprungoffset schreiben
    //jetzt fehlt noch der Sprung zurück
    ///=======================>
    VirtualProtect((LPVOID)old_address, 5, PAGE_EXECUTE_READWRITE, &dw); //die Sicherung des Speichers aufheben
    memset((LPVOID)old_address++, 0xE9, 1); //den opcode schreiben und old_address um 1 Byte erhöhen
    memcpy((void*)old_address, &sprungweg, sizeof(sprungweg)); //sprungoffset schreiben
    //=================================>Fertig
    return (unsigned int) new_address;
}

void startupDllMsg()
{
    MessageBoxA(0, "Gestartet...", "Die Dll wurde geladen", 0);
}

extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    unsigned int send_address;
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
        SetDebugPrivileges();
            send_address = GetProc("ws2_32.dll", "send");
            new_send = (int (*) (SOCKET, char*, int , int)) hook_function(send_address, (unsigned int)bypass_send, 5);
            DumpInt(send_address, "Adresse von Send", 16);
            DumpInt((unsigned int)new_send, "Adresse von new_send", 16);
            break;

        case DLL_PROCESS_DETACH:
            // detach from process
            break;

        case DLL_THREAD_ATTACH:
            // attach to thread
            break;

        case DLL_THREAD_DETACH:
            // detach from thread
            break;
    }
    return TRUE; // succesful
}
Desweitern möchte ich nicht gerne, dass die sendFunktion(wie bei Detours) direkt nach der bypass-Funktion aufgerufen wird, da ich die Daten bei der recv-Funktion gerne abfangen würde...
lg
 
Zuletzt bearbeitet:
Zurück
Oben