NativeAPI Äquivalente zu CreateService() und connect()
-
da_kill05 schrieb:
Kennt jemand die Funktionen, die immer aufgerufen werden, wenn ein Service oder eine neue Socketverbindung erstellt wird?
vielleicht hilft dir das hier: http://www.ndis.com/papers/winpktfilter.htm
-
hallo,
@ScriptGod: danke, das habe ich befürchtet. Das Problem bei ZwDeviceIoControlFile() ist wohl, dass zwischen zwei Aufrufen von meinem Programm das fremde Programm schon eine Verbindung hergestellt, Daten verändert und die Verbindung wieder geschlossen hat. So kann ich evtl Verbindungen verpassen!
@net: danke, das sieht interessant aus.Wie würdet ihr jetzt vorgehen? connect() aus ws2_32.dll, mswsock.dll etc einzeln hooken? Da wäre ja das Problem, dass wenn ein Programm eine eigene, modifizierte ws2_32.dll im Arbeitsverzeichnis hätte, die genau gleich wie das Original ist, lediglich die Funktion connect() in cXnnect() oder so umbenannt wurde, dann würde ich das wieder nicht mitkriegen.
Wie machen Firewalls das? Sind die alle auf Treiberebene?
-
da_kill05 schrieb:
Wie machen Firewalls das? Sind die alle auf Treiberebene?
wenn man wirklich jedes paket erwischen will, wird man wohl nicht drum herum kommen
-
da_kill05 schrieb:
hallo,
@ScriptGod: danke, das habe ich befürchtet. Das Problem bei ZwDeviceIoControlFile() ist wohl, dass zwischen zwei Aufrufen von meinem Programm das fremde Programm schon eine Verbindung hergestellt, Daten verändert und die Verbindung wieder geschlossen hat. So kann ich evtl Verbindungen verpassen!
@net: danke, das sieht interessant aus.Wie würdet ihr jetzt vorgehen? connect() aus ws2_32.dll, mswsock.dll etc einzeln hooken? Da wäre ja das Problem, dass wenn ein Programm eine eigene, modifizierte ws2_32.dll im Arbeitsverzeichnis hätte, die genau gleich wie das Original ist, lediglich die Funktion connect() in cXnnect() oder so umbenannt wurde, dann würde ich das wieder nicht mitkriegen.
Wie machen Firewalls das? Sind die alle auf Treiberebene?
Wenn du eine DLL hooks reicht dabei ws2_32.dll da alle andere DLLs momentan diese wiederum aufrufen. Aber wenn die wirklich alle Packete hooken willst kommst du über einen Treiber nicht herum. Da auch das Programm mittels Treiber Packete verschicken könnten, die du nicht sehen würdest.
-
hallo,
ok danke, dann werde ich wohl die hooks auf connect()/listen() aus ws2_32.dll und CreateServiceA()/CreateServiceW() aus der advapi32.dll setzen.ciao, da_kill05
-
achso: es muss sowieso kein perfekter Hook werden, es gibt immer Wege Client Hooks zu umgehen.
Alleine um NtCreateFile() zu umgehen kann man das theoretisch gleich als Interrupt aufrufen und ich kann nichts dagegen tun
-
da_kill05 schrieb:
Alleine um NtCreateFile() zu umgehen kann man das theoretisch gleich als Interrupt aufrufen und ich kann nichts dagegen tun

doch. musste 'ntdll.dll' hooken

sorry, quatsch, so geht's nicht
-
da_kill05 schrieb:
achso: es muss sowieso kein perfekter Hook werden, es gibt immer Wege Client Hooks zu umgehen.
Alleine um NtCreateFile() zu umgehen kann man das theoretisch gleich als Interrupt aufrufen und ich kann nichts dagegen tun
Ein direkter interrupt oder syscall Aufruf ist nicht hookbar mit DLLs (im user mode). Das kannst nur im Kernel aber selbst da gibt es Wege das zu umgehn. Die Techniken die gegen Hooks oder zum entdecken der Hooks eingesetzt werden sind momentan weiterentwickelt.
Aber wenn du das nur zum Protokolieren oder sowas willst ist das eher egal.
-
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?!?
-
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