读取指定进程,指定地址的整型数据
HWND hWnd = ::FindWindowW(NULL, L"窗口标题");
if (NULL == hWnd)
{
MessageBoxW(L"未找到");
return;
}
//
DWORD dwProcessId = 0;
// 通过窗口句柄,获取进程id
GetWindowThreadProcessId(hWnd, &dwProcessId);
//参数1所有权限,通过进程id获取进程句柄handle
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, dwProcessId);
int val = 0;
//通过进程句柄,读取基地址数据,由于预先知道基地址的值为整型,且占用空间是4个字节
ReadProcessMemory(hProcess, (LPCVOID)0x1005194, (LPVOID)&val, 4, NULL);
写入整型数据
int sunshine = 9999;
WriteProcessMemory(hProcess, (LPVOID)address, &sunshine, 4, NULL);
改写目标程序在内存中汇编(代码)
004B2FE8 | . / 74 1D je short 004B3007
004B2FEA | . | FF47 24 inc dword ptr ds : [edi + 24]
004B2FED | . | 8B47 24 mov eax, dword ptr ds : [edi + 24]
004B2FF0 | . | 3B47 28 cmp eax, dword ptr ds : [edi + 28]
004B2FF3 | 7E 12 jle short 004B3007
004B2FF5 | . | 8BC7 mov eax, edi
如上诉程序在内存中的反汇编,如果不在地址004B2FF3处进行<=跳转判断,可以直接在内存中写入汇编 nop 两个,因为要保持原来的代码短数据不被打乱,7E 12占用两个字节,所以要两个nop,同时改写了 7E 12 为nop nop,nop对应十六进制是0x90。
buffer[0] = 0x90;
buffer[1] = 0x90;
WriteProcessMemory(hProcess, (LPVOID)0x004B2FF3, (LPVOID)buffer, 2, NULL);
向目标程序内部写入汇编(函数)代码(代码注入)
①、在目标程序内开辟空间。
②、把函数代码写入到在目标程序开辟的空间内。
③、CreateRemoteThread执行目标进程函数代码
LPVOID virtualAddress = VirtualAllocEx(hProcess,
NULL,
4096,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
VirtualAllocEx function (memoryapi.h) - Win32 apps | Microsoft Docs 详细介绍
①
需要注意:
第四个参数MEM_COMMIT
第五个参数PAGE_EXECUTE_READWRITE
因为向目标程序写入的是函数代码,所以第五个参数是PAGE_EXECUTE_READWRITE。
若是向目标程序内写入的是数据或是参数,则第五个参数是PAGE_READWRITE
②
现成函数声明
DWORD WINAPI ThreadProc(
_In_ LPVOID lpParameter
);
DWORD __stdcall PutPlant(LPVOID lpParamter)
{
__asm
{
pushad
mov eax, 0
mov ecx, -1
mov edx, 2
mov ebx, 8
mov edi, ds: [0x007794F8]
mov edi, ds: [edi + 0x868]
push ecx
push edx
push ebx
push edi
mov esi, 0x00422610
call esi
popad
}
return 0;
}
把函数写入到目标进程中
注意、注意、注意。不要再debug模式下运行写入,要使用release模式,因为debug模式下含有int3,代码写入到目标程序后,目标程序极易崩溃。
DWORD dwWrite = 0;
bool bWrite = WriteProcessMemory(hProcess, virtualAddress, PutPlant, 4096, &dwWrite);
③
HANDLE hThread = CreateRemoteThread(hProcess,
NULL,
NULL,
(LPTHREAD_START_ROUTINE)virtualAdd,
NULL,
NULL,
NULL);
启动远程线程执行目标进程中刚写入的代码。
④释放资源
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
若是目标进程中刚写入的代码区域,以后决用不到,也可以用 VirtualFreeEx VirtualFreeEx function (memoryapi.h) - Win32 apps | Microsoft Docs
释放掉。
CreateRemoteThread第五个参数目前给的是null,表示我没有给参数,那么如何给参数呢?
在目标进程中申请参数空间
//在目标进程中申请参数空间
LPVOID virtualParameterAddress = VirtualAllocEx(hProcess,
NULL,
4096,
MEM_COMMIT,
PAGE_READWRITE);
把参数数据写入到目标进程
DWORD dwWrite = 0;
bool bWrite = WriteProcessMemory(hProcess,
virtualParameterAddress,
参数地址,
4096,
&dwWrite);
创建远程线程且带有参数(virtualParameterAddress)地址
HANDLE hThread = CreateRemoteThread(hProcess,
NULL,
NULL,
(LPTHREAD_START_ROUTINE)virtualAdd,
virtualParameterAddress,
NULL,
NULL);