Implementing functions under Windows Piling: Blocking API moderecently, because of the work needs, began to study the method of function piling. The idea of using Google Gmock was abandoned because he didn't want to make too many changes to the project. But it's been bothering me. Another day and night. After the struggle, finally some gains. Talk less and start to see what you have to do.
first, the basic preparation1.
function Call principle : Through the function name ( the function's entry address ) to access the function, if we can change the memory of the first address point of the word, so that it jumps to another function to execute, then you can implement the function of piling. 2.
method : The first address of the function is written in an assembly language jmp xxx (where xxx is the relative address to jump). 3. The original function is Oldfun, and the new function is Newfun, then the relative address of the function jump when piling is offset = newfun-oldfun-(the size of this instruction we set), here is the length of the absolute jump instruction = 5. jmp xxx altogether 6 bytes.
function:
1.VirtualQuery
Winbaseapisize_twinapivirtualquery ( __in_opt lpcvoid lpaddress, //memory address __out_bcount_part (dwLength, return) pmemory_basic_information lpbuffer, //Save buffer __in size_t dwlength //Information length of memory area );
This function is used to queryThe memory information of a section of memory, fact VirtualQueryEx can also be used. 2. VirtualProtect
Winbaseapiboolwinapivirtualprotect ( __in lpvoid lpaddress, __in size_t dwsize, __in DWORD Flnewprotect, __out pdword lpfloldprotect );
This function is used to modify the protected mode of dwsize bytes in the specified memory area.
3. Virtualprotectex
Winbaseapiboolwinapivirtualprotectex ( __in HANDLE hprocess, //Process handle __in lpvoid lpaddress, //need to modify the first address of memory __in size_t dwsize, //Modified bytes __in DWORD flnewprotect, //New Protection properties __out Pdword lpfloldprotect //Old protection attribute );
Virtualprotectex is used to change the protected mode of the specified process memory segment by default, the memory space of the function is not writable, which is why the function to change the protection property.
4. ReadProcessMemory
Winbaseapiboolwinapireadprocessmemory ( __in HANDLE hprocess, __in lpcvoid lpbaseaddress, __ Out_bcount_part (NSize, *lpnumberofbytesread) lpvoid lpbuffer, __in size_t nSize, __out_opt size_t * Lpnumberofbytesread );
Reads the process memory, Lpprocess is the first address, and lpbuffer is used to hold the read data, Nsize is the number of bytes that need to be read out.
5. WriteProcessMemory
Winbaseapiboolwinapiwriteprocessmemory ( __in HANDLE hprocess, __in lpvoid lpbaseaddress, __in_bcount (nSize) lpcvoid lpbuffer, __in size_t nSize, __out_opt size_t * Lpnumberofbyteswritten );
This function is used to write the memory space of the process, and can inject the data you want to inject into the process memory, such as functions.
6. GetCurrentProcess
Winbaseapi__outhandlewinapigetcurrentprocess ( VOID );
The function returns a pseudo-process handle of 0xFFFFFFFF, which can be used by any memory that requires a process handle.
second, to the library of the API piling
programme One:
Piling:
#define FLATJMPCODE_LENGTH 5//x86 flat memory mode, absolute jump instruction length # define FLATJMPCMD_LENGTH 1//Mechanical code 0XE9 length # define F Latjmpcmd 0xe9//correspond to the compiled JMP instructions//record the contents of the piling function in order to restore the byte g_apibackup[flatjmpcode_length+flatjmpcmd_length]; BOOL Setstub (LPVOID apifun,lpvoid hookfun) {bool issuccess = FALSE; DWORD Tempprotectvar; Temporary protection attribute variable memory_basic_information meminfo; Memory Paging Property Information VirtualQuery (Apifun,&meminfo,sizeof (memory_basic_information)); if (VirtualProtect (Meminfo.baseaddress,meminfo.regionsize, Page_readwrite,&meminfo.protect)) The modified page is writable {memcpy (void*) g_apibackup, (const void*) apifun, sizeof (g_apibackup)); * (byte*) apifun = Flatjmpcmd; Intercept API, inject jmp XXX * (dword*) ((byte*) Apifun + flatjmpcmd_length) = (DWORD) Hookfun-(DWORD) Apifun in front of the function code snippet -Flatjmpcode_length; VirtualProtect (Meminfo.baseaddress,meminfo.regionsize, Meminfo.protect,&tempprotectvar); Change back to original attribute issuccess = TRUE; } return issuccess;}
Pile Clearance:
BOOL Clearstub (LPVOID apifun) { bool issuccess = FALSE; DWORD Tempprotectvar; Temporary protection attribute variable memory_basic_information meminfo; Memory Paging Property Information virtualquery (apifun,&meminfo,sizeof (memory_basic_information)); if (VirtualProtect (meminfo.baseaddress,meminfo.regionsize, page_readwrite,&meminfo.protect)) // The modified page is writable { memcpy (void*) Apifun, (const void*) g_apibackup, sizeof (G_apibackup)); Recovery Code Snippet virtualprotect (meminfo.baseaddress,meminfo.regionsize, meminfo.protect,&tempprotectvar); Change back to original property issuccess = TRUE; } return issuccess;}
Scenario Two:
Piling:
BOOL Setstub (LPVOID apifun,lpvoid hookfun) {HANDLE File_handler = getcurrentprocess (); Get process pseudo handle DWORD Oldprotect,tempprotectvar;char newcode[6]; Used to read function original memory information int SIZE = flatjmpcode_length+flatjmpcmd_length; Need to modify the memory size if (! Virtualprotectex (file_handler,apifun,size,page_readwrite,&oldprotect)) //Modify memory to read/write {return false;} if (! ReadProcessMemory (file_handler,apifun,newcode,size,null)) //Read memory {return false;} memcpy ((void*) g_apibackup, (const void*) newcode, sizeof (G_apibackup)); Save the Piling function information * (byte*) apifun = Flatjmpcmd; * (dword*) ((byte*) Apifun + flatjmpcmd_length) = (DWORD) Hookfun-(DWORD) apifun-flatjmpcode_length; Pile function Injection virtualprotectex (file_handler,apifun,size,oldprotect,&tempprotectvar); Restore Protection Properties}
Pile Clearance:
BOOL Clearstub (LPVOID apifun) { bool issuccess = FALSE; HANDLE File_handler = GetCurrentProcess (); DWORD Oldprotect,tempprotectvar; int SIZE = flatjmpcode_length+flatjmpcmd_length;if (Virtualprotectex (file_handler,apifun,size,page_readwrite,& Oldprotect)) { memcpy ((void*) Apifun, (const void*) g_apibackup, sizeof (G_apibackup)); Recover the piling function memory Virtualprotectex (File_handler,apifun,size,oldprotect,&tempprotectvar); issuccess = TRUE; } return issuccess;}
Programme III:
Piling:
BOOL Setstub (LPVOID apifun,lpvoid hookfun) {HANDLE File_handler = getcurrentprocess ();D word Oldprotect,tempprotectvar; char Newcode[6];int SIZE = flatjmpcode_length+flatjmpcmd_length;if (! ReadProcessMemory (File_handler,apifun,newcode,size,null)) {return false;} memcpy ((void*) g_apibackup, (const void*) newcode, sizeof (g_apibackup)); * (byte*) Newcode = Flatjmpcmd; * (dword*) ((byte*) Newcode + flatjmpcmd_length) = (DWORD) Hookfun-(DWORD) apifun-flatjmpcode_length; if (! WriteProcessMemory (File_handler,apifun,newcode,flatjmpcode_length,null)) {return false;}}
Strange to say, this program does not change the Read permission, incredibly can, here the way to write is to use writeprocessmemory to achieve, and directly with pointers. Clear Pile Ibid. However, if you write directly with the pointer, you will get an error and don't know the reason for the moment.
At this point we have implemented the function of piling, but there is a small problem, if only this, the function of the member of the function of piling a little problem, the pointer cannot be converted, because the class member function pointer is not just a normal pointer, he also includes other information. All these need to solve this problem, found on the Internet two methods:
1. Common function member address translation for classes
LPVOID getclassfnaddress (...) { lpvoid fnaddress; __asm { lea eax,fnaddress mov edx,[ebp+8] //EBP+8 is the address of the first parameter, Ebp+c is the address of the second parameter, and so on mov [eax],edx } return fnaddress;}
2. Virtual member function address translation for classes
LPVOID getclassvirtualfnaddress (LPVOID pthis,int Index)//add 2010.8.6{lpvoid fnaddress ; * (int*) &fnaddress = * (int*) pthis; Lpvtable * (int*) &fnaddress = * (int*) ((int*) fnaddress + Index); return fnaddress;}
This concludes the introduction of the function piling.
Implementing functions under Windows Piling: Blocking API mode