NativeAPI Äquivalente zu CreateService() und connect()
-
achso wie siehts eigentlich mit fenstern aus?
gibts was besseres als CreateWindowA/W?
-
da_kill05 schrieb:
ok das Loggen an sich klappt jetzt auch wunderbar.
Aber mit UPX oder FSG gepackte Programme holen sich ja beim Start des Programms per GetProcAddress() die Adressen der Funktionen. Somit können diese bisher noch dem Logging entgehen.Um da entgegenzuwirken, habe ich LdrGetProcedureAddress() gehookt und prüfe nun, von welchen Funktionen die Adressen gefordert werden. Wenn der Funktionsname "connect" ist, liefer ich halt einen Pointer auf meine gehookte Funktion zurück. Ich dachte von der Theorie müsste es so laufen, aber die Praxis zeigt was anderes: Bei einem Testprogramm gibt bereits WSAStartup() als Errorcode -2 zurück.
Das Logging ergab, dass die Adresse von "connect" nicht nur einmal, sondern gleich ca. 10mal angefordert wurde.Ich bin total verblüfft und hab leider keine Ahnung, an was das jetzt liegen könnte?!?
Also bei gepackten Programme wirst du ein Problem bekommen, da manche EXE Packer die Adressen per Hand ermitteln und nicht mit einer Funktion von Windows.
Das connect kann wird wohl öfters, wegen der ganzen forwarding exports aufgerufen und da auch DLLs z.B. diese Funktion importieren (z.B. wsock32.connect -> ws2_32.connect = wsock32.connect wird also auf die Adresse von wsock32.connect gesetzt, und zwar bei jeder DLL und EXE die geladen wird und das importiert)
-
hm wie meinst du, die Packer ermitteln die Adressen "per Hand"?
Normalerweise importiert jeder Packer, den ich kenne, mittels GetProcAddress() alle Adressen und überschreibt dann den IAT.
Somit sollte, wenn ich GetProcAddress() hooke, auch kein Problem mit gepackten Programmen auftreten.Achso und wegen den Mehrmals-Aufrufen: Nur die Funktionen, die ich im IAT verändert habe, werden von LdrGetProcedureAddress() mehrmals geladen (ca 10mal), alle anderen Funktionen nach wie vor 1mal (oder halt 1mal pro Modul, dass diesen Import verwendet).
Wenn ich den Hook von connect() entferne, wird LdrGetProcedureAddress("connect") nur einmal aufgerufen!Ich weiß jetzt überhaupt nicht woran das liegen könnte und spekulier wild herum, dass es sogar eine Schutzfunktion von Windows sein könnte oder so (wenn eine Adresse außerhalb des Modulspeichers liegt zB...)
naja ich probier sonst noch ein wenig rum, später sollte das Programm jedenfalls schon mit gepackten/gecrypteten Dateien umgehen können.
-
ui hab erstmal einen ziemlich dämlichen fehler in meiner hook-funktion gefunden...die aufrufe von GetProcAddress() kamen von mir selbst oO.
trotzdem bleibt weiterhin der fehler, dass die ws2_32.dll in WSAStartup() einen selbstschutz durchführt!
sie ruft nämlich in der tat GetProcAddress() auf alle ihre funktionen auf, und wenn dieser nicht dem Original entspricht (frag mich nicht wie der das rauskriegt (obwohl, vielleicht muss ich noch einen EAT hook anwenden?)), bricht der sofort ab.für hilfe immer noch dankbar, da_kill05

-
was euch bestimmt helfen könnte ist das hier: http://research.microsoft.com/sn/detours/
...und natürlich die windows-quelltexte
(erhältlich im p2p-netz eures vertrauens)
-
hi,
danke für den link, guck ich mir mal an.
Ansonsten: stimmt windows-quelltext erspart mir das debuggen von ws2_32.dll (von der es zum glück von ms ne pdb gibt!). Darin hab ich übrigens schon gefunden, dass es tatsächlich innerhalb der Dll ne Funktion "CheckForHookersAndChainers" oder so gibt...
naja ich guck da nochmal n bisschen, scheint ja mal wieder komplexer zu sein als man vermutet hat
-
da_kill05 schrieb:
hm wie meinst du, die Packer ermitteln die Adressen "per Hand"?
Normalerweise importiert jeder Packer, den ich kenne, mittels GetProcAddress() alle Adressen und überschreibt dann den IAT.
Somit sollte, wenn ich GetProcAddress() hooke, auch kein Problem mit gepackten Programmen auftreten.Achso und wegen den Mehrmals-Aufrufen: Nur die Funktionen, die ich im IAT verändert habe, werden von LdrGetProcedureAddress() mehrmals geladen (ca 10mal), alle anderen Funktionen nach wie vor 1mal (oder halt 1mal pro Modul, dass diesen Import verwendet).
Wenn ich den Hook von connect() entferne, wird LdrGetProcedureAddress("connect") nur einmal aufgerufen!Ich weiß jetzt überhaupt nicht woran das liegen könnte und spekulier wild herum, dass es sogar eine Schutzfunktion von Windows sein könnte oder so (wenn eine Adresse außerhalb des Modulspeichers liegt zB...)
naja ich probier sonst noch ein wenig rum, später sollte das Programm jedenfalls schon mit gepackten/gecrypteten Dateien umgehen können.
Mit per Hande mein ich das was GetProcAddres macht selbst zu machen. Also die Export Table, des Moduls selber duchzugehn und die Address hohlen. Ich hab sowas z.B. schon mal geschrieben um hooks zu verhindern in meiner Anwendung
void* GetModuleProcAddr( void* lpBaseAddr, unsigned short nOridinal, const char* lpszName ) { if( !lpBaseAddr ) return NULL; // get headers IMAGE_DOS_HEADER* lpDOSHeader = (IMAGE_DOS_HEADER*)lpBaseAddr; if( !lpDOSHeader->e_lfanew ) return NULL; IMAGE_NT_HEADERS* lpNTHeaders = (IMAGE_NT_HEADERS*)( (char*)lpBaseAddr + lpDOSHeader->e_lfanew ); if( !lpNTHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ].Size ) return NULL; // no exports IMAGE_EXPORT_DIRECTORY* lpExportDir = (IMAGE_EXPORT_DIRECTORY*)( (char*)lpBaseAddr + lpNTHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ].VirtualAddress ); if( lpszName ) { // get string array bool bFound = false; char** lplpszNames = (char**)( (char*)lpBaseAddr + lpExportDir->AddressOfNames ); unsigned short* lpnNameOrdinals = (unsigned short*)( (char*)lpBaseAddr + lpExportDir->AddressOfNameOrdinals ); for( unsigned long n = 0; n < lpExportDir->NumberOfNames; n++ ) { // check if name machtes char* a = (unsigned long)lpBaseAddr + lplpszNames[ n ]; if( !stricmp( a, lpszName ) ) { nOridinal = lpnNameOrdinals[ n ]; bFound = true; break; } } // found? if( !bFound ) return false; } else { // lower than ordinal base? if( nOridinal < lpExportDir->Base ) return NULL; // substract base nOridinal -= (unsigned short)lpExportDir->Base; } // out of range? if( nOridinal >= lpExportDir->NumberOfFunctions ) return NULL; // get function unsigned long* lpnFunctions = (unsigned long*)( (char*)lpBaseAddr + lpExportDir->AddressOfFunctions ); // is forwarded? if( lpnFunctions[ nOridinal ] >= lpNTHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ].VirtualAddress && lpnFunctions[ nOridinal ] <= lpNTHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ].VirtualAddress + lpNTHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ].Size ) { // Dll.EntryPoint char* lpszForward = ( (char*)lpBaseAddr + lpnFunctions[ nOridinal ] ); // load module // - split module name part char szBuffer[ MAX_PATH ]; wchar_t wszBuffer[ MAX_PATH ]; strncpy( szBuffer, lpszForward, sizeof( szBuffer ) ); strtok( szBuffer, "." ); strncat( szBuffer, ".DLL", sizeof( szBuffer ) ); mbstowcs( wszBuffer, szBuffer, sizeof( wszBuffer ) / sizeof( wchar_t ) ); // - get module base void* lpForwardBaseAddr = GetModuleBaseAddr( wszBuffer ); if( !lpForwardBaseAddr || lpForwardBaseAddr == lpBaseAddr ) return NULL; // get function // - split function name part (dll.function) strncpy( szBuffer, lpszForward, sizeof( szBuffer ) ); strtok( szBuffer, "." ); strncpy( szBuffer, &szBuffer[ strlen( szBuffer ) + 1 ], sizeof( szBuffer ) ); // - get entry point return GetModuleProcAddr( lpForwardBaseAddr, 0, szBuffer ); } // return function return ( (char*)lpBaseAddr + lpnFunctions[ nOridinal ] ); }
-
ich bins nochmal

dein code ist interessant, aber auch machtlos wenn man zusätzlich einen EAT-hook auf die DLLs macht.wollte nur noch sagen das bei mir jetzt alles so läuft wie es soll, habe das problem mit der ws2_32.dll durch einen memory patch beseitigt (ok, nicht gerade ne saubere lösung und sehr versionsabhängig, aber eine andere ist mir nicht eingefallen).
bei interesse release ich das resultat ma
da_kill05
-
da_kill05 schrieb:
ich bins nochmal

dein code ist interessant, aber auch machtlos wenn man zusätzlich einen EAT-hook auf die DLLs macht.wollte nur noch sagen das bei mir jetzt alles so läuft wie es soll, habe das problem mit der ws2_32.dll durch einen memory patch beseitigt (ok, nicht gerade ne saubere lösung und sehr versionsabhängig, aber eine andere ist mir nicht eingefallen).
bei interesse release ich das resultat ma
da_kill05
wenn du damit meinst, die EAT zu manipulieren, hast du solange recht, solange ich die Daten nicht etwa aus der Datei direkt auslese oder diese nochmal selbst mappe, was im restlichen Code ist - das war nur ein kleiner Teil als Beispiel

Kannst gerne mal dein Resultat zeigen, würde mich schon einmal intressieren
-
so, wird noch etwas verbessert werden die nächsten tage, aber so in etwa wirds aussehen:
http://neonew.ne.funpic.de/files/neoLogger.execiao, neonew
-
da_kill05 schrieb:
so, wird noch etwas verbessert werden die nächsten tage, aber so in etwa wirds aussehen:
http://neonew.ne.funpic.de/files/neoLogger.execiao, neonew
hmm, gibt's nicht
-
jo sry musst rechtsklick->ziel speichern unter machen.
wenns immer noch nicht geht, link in die zwischenablage kopieren, neues IE fenster aufmachen und link manuell reinkopieren.hab aber leider grad keinen anderen webspace.
-
hmm, ich glaube die Seite benötigt Cookies, erst wenn ich das erlaube bekomm ich keine JPEG-Meldung mehr, "Externes Linken ist nicht erlaubt"...
Könntest du evtl. noch die Runtime DLLs dazupacken? Ich hab keine MSVCP71.dll auf meinem System
-
gibts zwar auch über google, aber ich hab sie mal hochgeladen:
(geht es so besser mit nem neuen verzeichnis?)http://neonew.ne.funpic.de/files/neoLogger/
ciao, neonew
-
Also jetzt kann das Programm starten, aber wenn ich was damit startet crasht die Anwendung gleich. Liegt wohl daran, dass ich andere DLLs habe.
-
oh.
hm du brauchst natürlich ein NT-based system.
und stürzt der logger ab oder die anwendung, die du starten möchtest?der logger reserviert an der stelle 0x13330000 speicher und kopiert sich dort in die andere anwendung, vielleicht kommt es da ja zu einem fehler ?!?
wird denn eine .nlg-datei erstellt?
ciao, neonew
-
Also, die Anwendung die ich starten will stürzt ab und eine .nlg wird erstellt
Mein System ist ein Windows 2000 SP4 mit einige zusätzlichen Patchtes
Die Anweisung in "0x7c36a9bb" verweist auf den Speicher in "0x7c36a9bb". Der Vorgang "read" konnte nicht [...]
an der Stelle ist keien DLL im Speicher geladen - zumindest keine die sichtbar ist
.nlg
* creating process 'C:\WINNT\regedit.exe'...+ successful created, injecting into 0x66C...6 Inject: trying to allocate 0x29000 bytes at 0x13330000* Inject: allocated memory in target process$ CreateRemoteThread in target process
-
achso, ich glaube es liegt daran, dass die DLL msvcr71.dll auch in regedit reingeladen werden muss!
somit nehme ich mal an, dass du die datei nur in den ordner vom logger extrahiert hast, sie muss aber ins system32-verzeichnis, damit alles korrekt geht!vielen dank auf jeden fall für das testen, solche tester braucht das land!
hab gleich ne abfrage eingebaut, ob die dlls erfolgreich geladen werden konnten
wär cool wenn du sagen könntest, ob es daran gelegen hat. ich hab auch die neue version hochgeladen (gleiche adresse).
ciao, neonew
-
jetzt stürzt die Anwendung nicht mehr direkt ab, aber wird gleich nach dem Start wieder beendet
-
kannste die log nochma posten?