WinApi hooken?
-
und falls es herausfindet, dass es die Funktion nicht ok ist(gehookt ist) wie kann ich das bypassen?
-
oh man denk doch mal nach!
Wenn die ersten 5 Bytes überschrieben wurden,
dann führe diese manuell aus und springe dann zu dem Funktion Offset + 5 Bytes.
Du öffnest also Olly und suchst nach der WinApi Funktion in den DLLs.
Nimm die ersten 5 Bytes kopiere sie in dein Programm (Inline Asm) und mach nen jump hin zu der Funktion +5 bytes.
-
ich verstehe nur bahnhof
-
helferlein schrieb:
das ganze klappt nicht bei jedem prozess und als nicht-admin bei nochweniger.
schützen kannst du dich in dem du jede! funktion der api vor dem aufruf
auf einen sprung überprüfst, der ja mit dem opcode 0xE9 anfängt.template <class T> bool isFuncOk(T funcptr) { char *addr = reinterpret_cast<char *>(funcptr); return *addr != 0xE9; }gibt aber bestimmt noch andere sprünge außer far-call die das selbe ermöglichen
das ist doch quartsch es gibt jawoll viele möglichleiten api hooking zu betrieben stichwort IAT und viele andere
-
ganz einfach:
die ersten 5 byte der funktion wurde überschrieben und durch einen farcall
ersetzt, also dem opcode für den sprung an deine eigene funktion.sämtliche funktionen der winapi nutzen die stdcall aufrufkonvention. diese
funktionen beginnen aufgrund der konvention immer mit den selben 5 bytes.push ebp
mov ebp, esp
sub esp, xx(xx steht für die größe aller lokalen variablen)
diese wurden überschrieben. um die funktion dennoch aufrufen zu können,
muss man diese selber ausführen, z.b. mit inline-assembler__declspec(naked) DWORD callfunc(void * func) // verhindert dass der kompiler den funktionsprolog hinzufügt { char *addr = reinterpret_cast<char *>(func) + 5; // 5 bytes weiter __asm { mov ebx, addr // hier speichern wir die addresse push ebp mov ebp, esp sub esp, xx // !! jmp ebx } }hier haben wir allerdings ein problem, denn wir wissen nicht wieviele variablen
die funktion auf den stack legt.wenn wir zuwenig nehmen überschreiben wir die rücksprungaddresse und den framepointer.
wenn wir zuviel nehmen, kann es sein dass das selbe problem auftrifft,
es kann aber auch sein, dass der wert von ebp genommen wird statt die selbe
größe wieder auf den esp zu addieren. hier weiß ich nicht genau wie die
winapi das macht, ich befürchte beide versionen gibt es.lässt sich bestimmt auch lösen, aber dazu müsste man die funktion
disassemblieren und ....aber ich weiß nicht ob dir das viel bringt, da du die grundlagen verstanden
haben musst. was dein letzer post nur bestätigt.guck dir mal die links an und versuch alles zu verstehen.
edit:
klempfner schrieb:
es gibt jawoll viele möglichleiten api hooking zu betrieben stichwort IAT und viele andere
es war nur ein beispiel. natürlich gibt es noch viele andere möglichkeiten

-
helferlein schrieb:
sämtliche funktionen der winapi nutzen die stdcall aufrufkonvention. diese
funktionen beginnen aufgrund der konvention immer mit den selben 5 bytes.push ebp
mov ebp, esp
sub esp, xx(xx steht für die größe aller lokalen variablen)
Aber dann hät ich da mal ne Frage:
Warum hat dann z.B. FindNextFileW diese ersten 12Bytes:
6A 2C PUSH 2C 68 C8F0807C PUSH kernel32.7C80F0C8 E8 0035FFFF CALL kernel32.7C8024D6Zumindestens laut Olly?
Gruß Pingu
-
weil's nur'n stub is

-
nehmen wir mal an es handelt sich um SetCurserPos
#include <windows.h> #include <iostream> using namespace std; BOOL WINAPI __stdcall SetCursorPosA(int x, int y); DWORD DLLFunc; int main() { Sleep(2000); HINSTANCE hInst = LoadLibrary(TEXT("user32.dll")); DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos") + 5; bool somebool = SetCursorPosA(0, 0); return 0; } BOOL WINAPI __stdcall SetCursorPosA(int x, int y) { __asm { mov edi, edi push ebp mov ebp, esp jmp [DLLFunc] } }Warum crashed das programm?
-
tester312 schrieb:
BOOL WINAPI __stdcall SetCursorPosA(int x, int y) { __asm { mov edi, edi push ebp mov ebp, esp jmp [DLLFunc] } }Warum crashed das programm?
Hi,
ich würd behaupten das, dass Problem is das du bei jmp ein Offset angeben musst und nicht die Adresse die du z.B. von GetProcAddress() bekommts.
Und das Offset wäre: Ziel-Absprung.
Desweiteren wird doch ,wenn du das so machst, der Prolog deiner Funktion + der Prolog von SetCursorPos aufgerufen. Das sollte au nicht so gut sein.
Schreib lieber statt:BOOL WINAPI __stdcall SetCursorPosA(int x, int y)was zumal sowieso komisch is da ja WINAPI nur ein #define für __stdcall ist,
BOOL __declspec(naked) SetCursorPosA(int x, int y)Somit haste kein Prolog und es sollte funktionieren.
Gruß Pingu
-
'SetCursorPosA': 'naked' kann nur auf nicht-Memberfunktionsdefinitionen angewendet werden
-
#include <windows.h> #include <iostream> using namespace std; DWORD DLLFunc; BOOL __declspec(naked) SetCursorPosA(int x, int y) { __asm { mov edi, edi push ebp mov ebp, esp jmp [DLLFunc] } } int main() { Sleep(2000); HINSTANCE hInst = LoadLibrary(TEXT("user32.dll")); DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos") + 5; SetCursorPosA(0, 0); return 0; }Es funktioniert jetzt, die Funktion wird ausgeführt, aber danach Crashed das Programm noch
-
Pingu-Group schrieb:
ich würd behaupten das, dass Problem is das du bei jmp ein Offset angeben musst und nicht die Adresse die du z.B. von GetProcAddress() bekommts.
Und das Offset wäre: Ziel-Absprung.!!
-
was meinst du mit Ziel- Absprung? Ich verstehe nicht ganz was gemeint ist
-
tester312 schrieb:
was meinst du mit Ziel- Absprung? Ich verstehe nicht ganz was gemeint ist
00411113 /E9 D8060000 JMP muh.mainCRTStartup //dieser Jump springt von 0x00411113 nach 0x004117F0 und nicht nach D8060000 .... 004117F0 \8BFF MOV EDI,EDISprich:
Offset = Ziel - AbsprungAlso musst du das Offset angeben das im "Little-Endian-Format" angegeben ist, was ich auch erst vor ein paar Tagen erfahren hab ;).
Gruß Pingu
-
danke, ich verstehe wo das Problem liegt aber
Offset = Ziel - Absprung
Ziel = DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos") + 5;
Absprung = DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos");
Offset = DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos") + 5; - DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos");
ich denke nicht, dass das so gemeint war?
-
tester312 schrieb:
danke, ich verstehe wo das Problem liegt aber
Offset = Ziel - Absprung
Ziel = DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos") + 5;
Absprung = DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos");
Offset = DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos") + 5; - DLLFunc = (DWORD)GetProcAddress(hInst, "SetCursorPos");
ich denke nicht, dass das so gemeint war?Noe nicht ganz.
Also Ziel ist korrekt, aber Absprung ist ja:
SetCursorPosA + länge der Opcodes bist jmp [DLLFunc] + 5 für die länge des Opcodes jmpDeswegen is bei meinem Bspl.
Ziel: 004117F0
Absprung: 00411118Offset: D8060000 //Little Endian
Wenn nicht klar dann schau mal den Thread hier an:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-230718.htmlGruß Pingu
-
SetCursorPosA + länge der Opcodes bist jmp [DLLFunc] + 5 für die länge des Opcodes jmp
Absprung = (DWORD)GetProcAddress(hInst, "SetCursorPosA") + opcodes + 5
was sind die länge der Opcodes?
-
Also entweder kannste ned lesen oder du verstehst due Grundlagen nicht!?
In beiden Fällen rate ich dir lass es einfach!
-
also als erstes, ein einfachs +5 tuts nicht. das verschiebt den offset um
5 * sizeof(funcptr) = 20 bytes. zuerst nach char castender offset wird vom folgenden befehl aus gerechnet
quelle = newfunc + 5 + 5
ziel = func + 5ziel - quelle = func - newfunc - 5
edianprobleme hatte ich auf meinem intel x86 nicht

hab aber auch das ganze DWORD reinkopiert also nicht byteweisemusste aber n bissel ruumprobierenbis das aufs byte genau passt, ober von
obriger formel sollte man ausgehen. (disassembly im debugmodus > all)morgen guck ich nochmal den genauen wert nach
-
helferlein schrieb:
edianprobleme hatte ich auf meinem intel x86 nicht

hab aber auch das ganze DWORD reinkopiert also nicht byteweiseAlso beim schreiben in Inline Assembly war des bei mir au keine Problem, aber beim auslesen eines jmp + Offset eines Prozesses, siehe verheriger Link, wusste ich nicht wo der hinspringt wegen dem Little-Endian-Format und kommte somit meine Funktion nicht patchen.
Gruß Pingu