![]() |
|
Basic Hooking tutorial - Printable Version +- LCKB (https://lckb.dev/forum) +-- Forum: ** OLD LCKB DATABASE ** (https://lckb.dev/forum/forumdisplay.php?fid=109) +--- Forum: Programmers Gateway (https://lckb.dev/forum/forumdisplay.php?fid=196) +---- Forum: Coders Talk (https://lckb.dev/forum/forumdisplay.php?fid=192) +---- Thread: Basic Hooking tutorial (/showthread.php?tid=1081) |
- someone - 09-03-2012 This tutorial will show you how to hook a dll into your application. First thing you need to do is to create a DLL: Now Some Dll Tutorial: You would need a main.cpp - A file that contains the entry point for your dll Hook.def - module definition file used to make functions much visible Hook.h - used to define your Common stuff And your c++ files: main.cpp 2 #include <windows.h> /* *hinstDLL - Dll instances you want *fdwReason - attaching reason BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){ switch (fdwReason){ case DLL_PROCESS_ATTACH:{ printf("Hook.dll has been attached\n"); break; } case DLL_PROCESS_DETACH:{ printf("Hook.dll has been detached\n"); break; } } return TRUE; } Hook.h //to make your objects/methods visible (exported) #ifndef HOOK_API #define HOOK_API __declspec(dllexport) #else #define HOOK_API __declspec(dllimport) #endif Your cpp/h files: #include "Hook.h" #include <stdio.h> void HOOK_API MyFunction(){ printf("myFunction\n"); } Hook.def 2 It is used to make visible the functions to GetProcAddress, that will be used to retrieve functions from dll. LIBRARY "Hook" DESCRIPTION Simple Hook Dll EXPORTS MyFunction Attaching the DLL Second thing is to attach the DLL to your application: 1)Open the executable with a OllyDbg 2)Search some free space on the executable and write the Dll File name(Select a zone to edit, right click->Binary->edit->write "MyHook.dll" with out quotes), and copy the offset (lets call it offset1). 007EE120 4D DEC EBP ; ASCII "MyHook.dll",0 007EE121 79 48 JNS SHORT GameServ.007EE16B 007EE123 6F OUTS DX,DWORD PTR ES:[EDI] 007EE124 6F OUTS DX,DWORD PTR ES:[EDI] 007EE125 6B2E 64 IMUL EBP,DWORD PTR DS:[ESI],64 007EE128 6C INS BYTE PTR ES:[EDI],DX 007EE129 6C INS BYTE PTR ES:[EDI],DX 3)Search for another free space on the executable and write the code to load your dll(write "push offset1" without quotes, and copy to a file the offset of this instruction). 007EE142 68 20E17E00 PUSH GameServ.007EE120 ; ASCII "MyHook.dll" 4)now to load the dll, press CTRL+N and search for LoadLibraryA, and press enter, nother window will appear. Follow 1 of the call DWORD instructions there, copy that command and to the next line of your instruction(or much simple you could write call KERNEL32.LoadLibraryA, but this will give error). 007EE142 68 20E17E00 PUSH GameServ.007EE120 ; ASCII "MyHook.dll" 007EE147 FF15 4C816200 CALL DWORD PTR DS:[<&KERNEL32.LoadLibraryA>] ; kernel32.LoadLibraryA 007EE14D 90 NOP ; ignore this line, ^this instruction is copied from CTRL+N 5)Go to your Entry point(or somewhere at the beginning of the program) and jump to your dll loading code (add "jmp offset2" with out qotes). 6)Save EAX somewhere in memory. 7)Complete entry point code(or the missing code from the first jump) and jump back 007EE142 68 20E17E00 PUSH GameServ.007EE120 ; ASCII "MyHook.dll" 007EE147 FF15 4C816200 CALL DWORD PTR DS:[<&KERNEL32.LoadLibraryA>] ; kernel32.LoadLibraryA 007EE14D 90 NOP ; ignore this line, ^this instruction is copied from CTRL+N 007EE14E A3 30CC7E00 MOV DWORD PTR DS:[7ECC30],EAX ; Save eax in memory->dll handle 007EE153 55 PUSH EBP ; -complete code 007EE154 8BEC MOV EBP,ESP ; | 007EE156 6A FF PUSH -1 ; | 007EE158 -E9 C8C9E0FF JMP GameServ.005FAB25 ; jumps back to the program And lastly using the functions from the DLL in your application: Now using the functions from the Executable: I made a code to not write the same thing all over again(this code return the function address). 007EE19A 55 PUSH EBP ; Save base stack pointer 007EE19B 8BEC MOV EBP,ESP ; the stack pointer becomes the new base stack 007EE19D FF75 08 PUSH DWORD PTR SS:[EBP+8] ; get last parameter, ASCII "MyFinction",0 007EE1A0 FF35 30CC7E00 PUSH DWORD PTR DS:[7ECC30] ; MyHook.73120000 007EE1A6 FF15 C4806200 CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; kernel32.GetProcAddress 007EE1AC A3 34CC7E00 MOV DWORD PTR DS:[7ECC34],EAX ; save the function address address for later use 007EE1B1 8BE5 MOV ESP,EBP ; return to the previous stack pointer 007EE1B3 5D POP EBP ; return to the previous base pointer 007EE1B4 C2 0400 RETN 4 ; retun and remove a Dword value from stack And to use it: 007EE18A 68 DAE07E00 PUSH GameServ.007EE0DA ; ASCII "MyFunction" 007EE18F E8 06000000 CALL GameServ.007EE19A 007EE194 FFD0 CALL EAX ; MyHook.MyFunction Hooking without knowing ASM For this you will need to know About this Windows API: - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 What you need to do first: The First thing you need is to get the process ID, you can get the process ID either by getting it from task manager, starting a process thru 2+ 2, or searching the memory to find the Process Id thru 2 + 2, or thru 2 After you got the process ID you can simply open the Process with OpenProcess, to get the process Handle, if you already have the process handle, you dont need to open the process(if you use ShellExecuteEx, or create Process, to open it with All Access). //open the processm 1234 is the process ID HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 1234); if (hProcess == NULL){ //error could not open process } Now you need to allocate some Memory in the process(create a new data section), for your data: //your file that you need to hook char myFile[] = "C:\myHook.dll"; //this usully does not matter if you put 1 byte or 1000 but you allways allocates 1000 bytes in hex int iAllocSize = strlen(myFile)+1; HANDLE addr = VirtualAllocEx( hProcess, NULL, iAllocSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); if( addr == NULL ) { //Error could not allocate memory } Now you need to copy your data to the Process, for the process to find it(the process will look in its memory not in some other process memory) //Write your Hook File Location to the Process bool bWrite = WriteProcessMemory( hProcess, addr, myFile, strlen(myFile), NULL ); if(bWrite){ //error could not write to process } Now The Hooking Part: Hooking with LoadLibrary and and CreateRemoteThread, it starts the Loadlibrary function in a Thread separate thread, Usually is rewuired to suspend the process first before you create the thread. //geting the handle of LoadLibrary functrion HANDLE hLoadLibrary = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"); if (hLoadLibrary == NULL){ // return failed } //Creating the Thread to run Loadlibrary, with the parameter the String that i made HANDLE hThread = CreateRemoteThread( x, NULL, 0,(LPTHREAD_START_ROUTINE)hLoadLibrary, addr, 0, NULL ); // Wait till the thread finishes int Result = WaitForSingleObject(hThread, INFINITE); if(Result != 0){ //error thread failed } //close the thread CloseHandle(hThread); //delete the data section created earlier VirtualFreeEx(hProcess, addr, iAllocSize, MEM_RELEASE); //close the process CloseHandle(hProcess); More documentation(start with C then continue with c++): C/C++ C: 2 C++: 2 Tools Win32:Notepad++, CodeBlocks , Visual C++, Borland C++, Turbo C Tools Linux:Geany, CodeBlocks, Kwrite, gedit, emacs To learn Assembly I suggestThis Book: Read this 16bit Edition: 2 On linux AT&T sintax: 2 - Nikolee - 09-03-2012 Very nice Tutorial thank yoouuuu ) - TheEvilAnt - 09-04-2012 Thankyou - someone - 09-04-2012 I suggest using 2 tutorials for learning assembly as they are the best detailed. Also always jump to your code cave and push the library onto the stack as soon as possible. Especially for important library's like anticheat. 2 is an example for loading a library with the client. By the way there it doesnt push the library into the stack it pushes all the registry into the stack, for later use(if you know the registrys that will change will not be necessary, you can do it without pushing the registry inyo the stack). but why did you make the Application to crash, if it does not load the dll. 00407B52 >/$ 55 PUSH EBP ;//save the base pointer 00407B53 |. 8BEC MOV EBP,ESP ;//make esp as the new base pointer 00407B55 |. 6A FF PUSH -1 ;// -1 00408550 60 PUSHAD ;save registry onto the stack 00408551 68 71854000 PUSH Nksp.00408571 ; ASCII "hook.dll" 00408556 FF15 30C74000 CALL DWORD PTR DS:[<&KERNEL32.LoadLibraryA>] ; kernel32.LoadLibraryA 0040855C 83F8 00 CMP EAX,0 ;if it didn't load the DLL 0040855F 0F84 9B7ABFFF JE 00000000 ; crash the application 00408565 61 POPAD ;Load the regystry back from the stack 00408566 55 PUSH EBP ;why would you need to save EBP again into the stack 00408567 8BEC MOV EBP,ESP ; new base pointer (I think your starting a new function here) 00408569 6A FF PUSH -1 ;save -1 into the stack 0040856B ^E9 E7F5FFFF JMP Nksp.00407B57 ; jump somewhere There are so many problems here, first is that your starting a new function(like CALL XXXX) but at the end it shows its just a JMP, second problem you made the application crash where you could just save the handle somewhere and continue with the program(checked later if it loaded or not), third problem it it was a CALL XXXX instead of starting a new function you could just simply ended the function and instead of JMP you could use RETN. Or simply use JMP code section, then save Registry, Load DLL, Save Handle, recover Registry, continue with the program. - someone - 09-04-2012 I got it from the link that you posted. and the code cave looked like a CALL then a JMP, I can ensure you that code is not proper, it will crash the application. Look whose talking about brushing ASM. - someone - 09-04-2012 Now you changed It but what you posted, first time was that code and deleted your Pastebin, I can see a liar here. - Rosario - 05-03-2013 Thank You ^_^ - spadge88 - 07-30-2013 Very nice guide its very helpfull thanks - someone - 07-30-2013 you can hookn much easier using CreateRemoteThread and LoadLibrary 2 Updated The main thread |