windows - Win32, How can i hook functions in compiled programs with C++? -


take instance function (viewed in ollydbg debugger) enter image description here

the first push ebp instruction start void* f(int32_t n) (idk returns, guessing void*), know input parameter n @ stack, , ebp+8 pointer variable, guess int* n=(int*)(uint32_t(ebp)+0x08); /*assuming ebp void* , sizeof(ebp)==sizeof(uint32_t)==sizeof(void*) , +8 math same in c++ uint32_t , x86 assembly..*/

i want make hook, check if n above 7, or below 0, , if is, change 1. ollydbg, writing assembly code directly, can do: patch first mov ebp,esp instruction jmp short int3 instructions behind (i'll need 7 bytes), change (unused) int3's mov ebp,esp jmp long 0068bccd 0068bccd unused 0x000000000000's @ end of file enter image description here

, @ 0068bccd , can write assembly codes check int pointed @ ebp+8 , , modify if necessary:

pushad cmp dword ptr ss:[ebp+8],7 ja short error cmp dword ptr ss:[ebp+8],0 jl short error jmp short finished error: pushad push offset thestring call onlink-x86.app::output add esp,4 popad mov dword ptr ss:[ebp+8],1 finished: popad jmp long 00447493 thestring: "warning: label assertion failed, (pretending 1 and) trying ignore.."+0x00 

enter image description here

which (if didn't mess up) equivalent of

void filterintatebp_8(){ int i=*(int*)(uint32_t(ebp)+8); if(i>7 || i<0){ output("warning: label assertion failed, (pretending 1 and) trying ignore.."); *(int*)(uint32_t(ebp)+8)=1; } return; } 

finally, here question: how can make hook, not ollydbg, c++ ? (i saw source code way back, mmorpg cheat program, hooking client, this, code lost me )

first, want inject dll in target process. so, can use code:

injector.h

#ifndef injector_h_included #define injector_h_included  #include <windows.h> #include <string>  class injector { public:     /**      * loads dll remote process      * @return true on sucess, false on failure     */     bool injectdll(dword processid, std::string dllpath); private: };  #endif // injector_h_included 

injector.cpp

#include "injector.h"  bool injector::injectdll(dword processid, std::string dllpath) {     handle hthread, hprocess;     void*  plibremote = 0;  // address (in remote process) szlibpath copied to;      hmodule hkernel32 = getmodulehandle("kernel32");     hinstance hinst = getmodulehandle(null);      char dllfullpathname[_max_path];     getfullpathname(dllpath.c_str(), _max_path, dllfullpathname, null);      // process handle     hprocess = openprocess(process_all_access, false, processid);      // copy file path in szlibpath     char szlibpath[_max_path];     strcpy_s(szlibpath, dllfullpathname);      // 1. allocate memory in remote process szlibpath     plibremote = virtualallocex( hprocess, null, sizeof(szlibpath), mem_commit, page_readwrite );      if (plibremote == null)     {         // because don't have administrator's right         return false;     }      // 2. write szlibpath allocated memory     writeprocessmemory(hprocess, plibremote, (void*)szlibpath, sizeof(szlibpath), null);      // 3. force remote process load dll     hthread = createremotethread(hprocess, null, 0, (lpthread_start_routine) getprocaddress(hkernel32,"loadlibrarya"), plibremote, 0, null);      if (hthread == null)     {         return false;     }      return true; } 

main.cpp

#include "injector.h" int main() {     injector injector;     dword processid = 1653; // change process id here.       if (injector.injectdll(processid, "injected.dll"))     {         printf("good job, injected dll\n");     }     else     {         printf("something wrong happened\n");     }      while (true); } 

then have make dll. gets little more complicated. first includes:

injected.dll

#include <windows.h> #include <stdio.h> 

then need make function detour right location:

void detouraddress(void* funcptr, void* hook, byte* mem) {     byte cmd[5] = { 0xe9, 0x00, 0x00, 0x00, 0x00 }; // jump place holder     void* rvaaddr = (void*)((dword)funcptr + (dword)getmodulehandle(null)); // base + relative address      // make memory readable/writable     dword dwprotect;     virtualprotect(rvaaddr, 5, page_execute_readwrite, &dwprotect);      // read memory     readprocessmemory(getcurrentprocess(), (lpvoid)rvaaddr, &mem[2], 5, null);      // write jmp in cmd     dword offset = ((dword)hook - (dword)rvaaddr - 5);  // (dest address) - (source address) - (jmp size)     memcpy(&cmd[1], &offset, 4); // write address jmp     writeprocessmemory(getcurrentprocess(), (lpvoid)rvaaddr, cmd, 5, 0); // write jmp      // write mem     virtualprotect(mem, 13, page_execute_readwrite, &dwprotect);      void* returnadress = (void*)((dword)rvaaddr + 5);     memcpy(&mem[8], &returnadress, 4); // write return address mem      // reprotect     virtualprotect(rvaaddr, 5, dwprotect, null); } 

if need remove dll @ point, need restore code:

void patchaddress(void* funcptr, byte* mem) {     void* rvaaddr = (void*)((dword)funcptr + (dword)getmodulehandle(null)); // base + relative address      // make memory readable/writable     dword dwprotect;     virtualprotect(funcptr, 5, page_execute_readwrite, &dwprotect);      writeprocessmemory(getcurrentprocess(), (lpvoid)rvaaddr, &mem[2], 5, null); // write jmp      virtualprotect(rvaaddr, 5, dwprotect, null); } 

next, need make function out of detoured bytes in order program execute them, isn't affected our detour. add in global space:

// memory (0x5e = pop esi, 0x68 = push dword, 0xc3 = retn) byte detourmem[13] = { 0x5e, 0x5e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0x00, 0x00, 0x00, 0x00, 0xc3 };  // convert bytes array function typedef void ( * pfunc)(); pfunc funcmem = (pfunc) &detourmem;  // added variable example of can it. dword var = 0; 

after that, need detouring function:

_declspec(naked) void detourfunction() {     // need push flag , registers on stack don't modify them accident     __asm     {         pushfd         pushad          // can "whatever" want here in assembly code         // ex, put eax value var:         mov var, eax     }      printf("this code executed everytime detoured function called\n");     // whatever want in c++ here     if (var < 7)     {         // eax smaller 7     }      // pop every flags , registers first pushed program continue supposed     __asm     {         // set normal         popad         popfd         push esi          // call our funcmem         mov edx, funcmem;         call edx     } } 

finaly, here how dllmain like:

bool apientry dllmain( hmodule hmodule, dword  ul_reason_for_call, lpvoid lpreserved  ) {     dword detouredaddress = 0x689b; // add relative address of location want detour     file *stream;     switch (ul_reason_for_call)     {     case dll_process_attach:         // add if want console appears when inject dll (don't forget freeconsole when remove dll)         allocconsole();         freopen_s(&stream, "conout$", "w", stdout);          // if need know base address of process injected:            printf("base address: 0x%x\n", (dword)getmodulehandle(null));          // our detour function         detouraddress((void*)detouredaddress, (void*)&detourfunction, detourmem);         break;     case dll_process_detach:         // restore process have before injected         patchaddress((void*)detouredaddress, detourmem);          freeconsole();         break;     }      return true; } 

i understand lot @ once, if have questions don't hesitate!


Comments

Popular posts from this blog

node.js - Mongoose: Cast to ObjectId failed for value on newly created object after setting the value -

gradle error "Cannot convert the provided notation to a File or URI" -

python - NameError: name 'subprocess' is not defined -