不知为何叫inlink hook 叫hot patch 更适合一点,说的是什么事呢,大概是这个意思
int ccc(int a, int b) { a++; b++; return a + b; } int main() { getchar(); char k[] = "xxxx"; //写这一行,在OD上容易找到位置,要不还得麻烦! int c = ccc(1, 2); cout << c << endl; system("pause"); return 0; }
现在我想在跟一个第三方程序时,想获取ccc方法中a的值,或者说想修改参数a的值,那么就肯定要改ccc这个函数的一些东西 ,最后变成这样的
int ccc(int a, int b) { goto newaddress(); backaddress: a++; b++; return a + b; } int newaddress()() { do sth.... goto backaddress; }
当然在c++里是不能这样写的,但在内存里执行指令的时候可以,当然也有区别,内存的指令是不可以插队的,但可以换个办法把某个指令换掉,后面再执行回来
比如
在内存里,调用ccc方法(call C2.012B10EB)之前,有两个指令push ,分别把1和2这个参数传给它了,就在这里下手
一般情况下,为什么要用call来下手呢,因为刚好我们要用jmp xxxxxx 等5个字节替换它,长度一致,省得出问题,就直接替换成jmp xxxxxxxx
跳过去弄完自己的事,然后把这个call C2.012B10EB 执行一下,然后跳回012B6C11这个地址继续执行,即可达到自己的目的 ,这个哥们虽然没有完整代码,但写的较好理解
https://www.cnblogs.com/luoyesiqiu/p/12306336.html
exe代码就上面那些,啥都没有,空壳,dll代码如下:
//#include "stdafx.h"; #include <iostream>; using namespace std; #include <windows.h>; #include <tlhelp32.h>; #include <tchar.h>; #include<stdio.h>; DWORD WINAPI MyThreadProc2( LPVOID pParam ); DWORD WINAPI MyThreadProc1(LPVOID pParam); int StartHooks(DWORD hookAddr, BYTE backCode[5], void(*FuncBeCall)()); BYTE backCode[5] = { 0 }; DWORD baseaddr; DWORD calloriaddr; DWORD jmbback; BOOL isrun=TRUE; DWORD EXesp; char addInt[1] = {5}; char testkk[1024] = { 0 }; int Unhooks(DWORD hookAddr, BYTE backCode[5]); void Wchar_tToString(std::string& szDst, wchar_t* wchar); HANDLE hProcessForWrite; int StartHooks(DWORD hookAddr, BYTE backCode[5], void(*FuncBeCall)()) { DWORD jmpAddr = (DWORD)FuncBeCall - (hookAddr + 5); BYTE jmpCode[5]; *(jmpCode + 0) = 0xE9; *(DWORD*)(jmpCode + 1) = jmpAddr; HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, GetCurrentProcessId()); if (ReadProcessMemory(hProcess, (LPVOID)hookAddr, backCode, 5, NULL) == 0) { return -1; } if (WriteProcessMemory(hProcess, (LPVOID)hookAddr, jmpCode, 5, NULL) == 0) { return -1; } return 0; } int Unhooks(DWORD hookAddr, BYTE backCode[5]) { HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, GetCurrentProcessId()); if (WriteProcessMemory(hProcess, (LPVOID)hookAddr, backCode, 5, NULL) == 0) { return -1; } return 0; } _declspec(naked) void OnCall() { calloriaddr = baseaddr + 0x110EB; jmbback= baseaddr + 0x16C11; __asm { mov EXesp, esp //跟了一下,第一个参数传回的值在esp里,所以取了esp的值 pushad } //修改传入的第一个参数的值 hProcessForWrite = OpenProcess(PROCESS_ALL_ACCESS, NULL, GetCurrentProcessId()); if (WriteProcessMemory(hProcessForWrite, (LPVOID)EXesp,addInt, sizeof(addInt), NULL) == 0) { MessageBox(NULL, "faild", "indll", NULL); } else { MessageBox(NULL, "success", "indll", NULL); } __asm { popad call calloriaddr jmp jmbback } isrun = FALSE; } DWORD WINAPI MyThreadProc1(LPVOID pParam) { while (isrun) { Sleep(100); } DWORD hkaddr = baseaddr + 0x16C0C; Unhooks(hkaddr, backCode); return 0; } DWORD WINAPI MyThreadProc2( LPVOID pParam ) { isrun = TRUE; HMODULE hModule = GetModuleHandle(NULL); baseaddr = (DWORD) hModule; DWORD hkaddr = baseaddr+ 0x16C0C; char kk[1024] = { 0 }; sprintf_s(kk, "%x", hkaddr); MessageBox(NULL, kk, "test", NULL); StartHooks(hkaddr, backCode,&OnCall); return 0; } BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { isrun = TRUE; MessageBox(NULL, "DLL已进入目标进程。", "信息", MB_ICONINFORMATION); DWORD dwThreadId; HANDLE myThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThreadProc2, NULL, 0, &dwThreadId); HANDLE myThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThreadProc1, NULL, 0, &dwThreadId); break; } case DLL_PROCESS_DETACH: { MessageBox(NULL, "DLL已从目标进程卸载。", "信息", MB_ICONINFORMATION); break; } } return TRUE; }
原文:https://www.cnblogs.com/szyicol/p/13031161.html