2009-04-20 4 views
4

Wir möchten Aufrufe an LoadLibrary haken, um Assemblys herunterzuladen, die nicht gefunden werden. Wir haben einen Handler für ResolveAssembly, der die verwalteten Assemblys behandelt, aber wir müssen auch nicht verwaltete Assemblys behandeln.Hook-LoadLibrary-Aufruf von verwaltetem Code

Wir haben versucht, LoadLibrary-Aufrufe durch erneutes Schreiben der Importtabelle über die in "Programmieren von Anwendungen für Microsoft Windows" angegebenen Techniken zu haken, aber wenn WriteProcessMemory() aufgerufen wird, erhalten wir einen Fehler (998). (Ja, wir laufen mit erhöhten Rechten)

Hat es jemand geschafft, die Import-Tabelle neu zu schreiben, während die CLR geladen ist? Kann mir jemand in die richtige Richtung zeigen?

Update: Wir behoben das Problem verweigert, aber jetzt, wenn wir die Imports-Tabelle einer gemischten Assembly iterieren (verwaltet + nicht verwaltet), der einzige Eintrag, den wir finden, ist mscoree.dll. Weiß jemand, wie man die einheimischen Importe findet? (wir arbeiten in C++/CLI).

Antwort

10

Ich habe erfolgreich aus verwaltetem Code gehakt. Ich habe es jedoch getan, indem ich eine nicht verwaltete DLL in den Remote-Prozess injiziert habe und die Import-Tabelle in DllMain neu schreiben ließ. Vielleicht möchten Sie diese Methode in Betracht ziehen.

Hier ist meine Hakenfunktion:

//structure of a function to hook 
struct HookedFunction { 
public: 
    LPTSTR moduleName; 
    LPTSTR functionName; 
    LPVOID newfunc; 
    LPVOID* oldfunc; 
}; 

BOOL Hook(HMODULE Module, struct HookedFunction Function) { 
    //parse dos header 
    IMAGE_DOS_HEADER* dos_header = (IMAGE_DOS_HEADER*)Module; 
    if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) return 0; //not a dos program 

    //parse nt header 
    IMAGE_NT_HEADERS* nt_header = (IMAGE_NT_HEADERS*)(dos_header->e_lfanew + (SIZE_T)Module); 
    if (nt_header->Signature != IMAGE_NT_SIGNATURE) return 0; //not a windows program 

    //optional header (pretty much not optional) 
    IMAGE_OPTIONAL_HEADER optional_header = nt_header->OptionalHeader; 
    if (optional_header.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) return 0; //no optional header 

    IMAGE_IMPORT_DESCRIPTOR* idt_address = (IMAGE_IMPORT_DESCRIPTOR*)(optional_header.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + (SIZE_T)Module); 
    if (!optional_header.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size) return 0; //no import table 

    //enumerate the import dlls 
    BOOL hooked = false; 
    for(IMAGE_IMPORT_DESCRIPTOR* i = idt_address; i->Name != NULL; i++) 
     //check the import filename 
     if (!_stricmp(Function.moduleName, (char*)(i->Name + (SIZE_T)Module))) 
      //enumerate imported functions for this dll 
      for (int j = 0; *(j + (LPVOID*)(i->FirstThunk + (SIZE_T)Module)) != NULL; j++) 
       //check if the function matches the function we are looking for 
       if (!_stricmp(Function.functionName, (char*)(*(j + (SIZE_T*)(i->OriginalFirstThunk + (SIZE_T)Module)) + (SIZE_T)Module + 2))) { 
        //replace the function 
        LPVOID* memloc = j + (LPVOID*)(i->FirstThunk + (SIZE_T)Module); 
        if (*memloc != Function.newfunc) { //not already hooked 
         DWORD oldrights; 
         DWORD newrights = PAGE_READWRITE; 
         VirtualProtect(memloc, sizeof(LPVOID), newrights, &oldrights); 
         if (Function.oldfunc && !*Function.oldfunc) 
          *Function.oldfunc = *memloc; 
         *memloc = Function.newfunc; 
         VirtualProtect(memloc, sizeof(LPVOID), oldrights, &newrights); 
        } 
        hooked = true; 
       } 

    return hooked; 
} 
7

Sollte funktionieren, aber versuchen Sie stattdessen detours (oder die kostenlose N-CodeHook).
Umwege ist fast die de-facto-Art der Instrumentierung Win32-Binärdateien.

+1

... oder Sie könnten eine Open-Source-lib wie N-CodeHook (http://newgre.net/ncodehook), die auch 64-Bit verwenden Unterstützung hat (Sie haben um X64 zu bezahlen, wenn man Umwege benutzt) – newgre

+0

@jn: selbst fördernd :) Ich werde ncodehook versuchen das nächste Mal muss ich mit Code-Injektion beschäftigen, obwohl ich zugeben muss, dass Umwege für mich recht gut funktioniert hat. Haben Sie darüber nachgedacht, die API zu spiegeln? damit bestehende Umwege Apps problemlos migriert werden können? –

+0

Bekam mich ;-) Eigentlich nein, daran habe ich nicht gedacht. Wird es auf meine Todo-Liste setzen. thx – newgre

0

Der beste Weg wäre, LoadLibrary/LoadLibraryEx zu haken, den Download bei Bedarf durchzuführen und die heruntergeladene Datei in der Kette weiterzuleiten. Ich wäre jedoch besorgt über das Blockieren der GUI während dieses Downloads.

2

Wir beschlossen die angegebene Ausgabe über einen Aufruf VirtualProtect() vor dem Aufruf von Write() und es dann später wieder aufrufen, die Schutzstufen wieder herzustellen. Dadurch wird vorübergehend der schreibgeschützte Schutz für den Speicher entfernt, in dem sich der IAT befindet. Das funktioniert gut für uns und behebt das Problem, wenn LoadLibrary() aufgerufen wird.

Nun, wenn ich nur herausfinden können, warum Loadlibrary() nicht aufgerufen wird, wenn eine nicht verwaltete Baugruppe Links gegen eine lib (kein statisches lib) ...

By the way, Detour und N-Code Hook beide schauen wie nette Produkte und sind wahrscheinlich die Art, wie ich gehen sollte, aber ich möchte vermeiden, eine 3rd-Party-Assembly wenn möglich hinzuzufügen.

+0

Das ist einfach. Sie haben nicht alle vier Varianten angehängt (LoadLibraryA, LoadLibraryW, LoadLibraryExA, LoadLibraryExW). – Joshua

Verwandte Themen