我已无力接住你,再也不能抗风雨
这里主要用到的函数是EnumProcessModulesEx
:
BOOL EnumProcessModulesEx(
HANDLE hProcess,
HMODULE *lphModule,
DWORD cb,
LPDWORD lpcbNeeded,
DWORD dwFilterFlag
);
hProcess
表示处理的句柄;
lphModule
表示接收模块句柄列表的数组;
cb
表示lphModule数组的大小,以字节为单位;
lpcbNeeded
表示在lphModule数组中存储所有模块句柄所需的字节数;
dwFilterFlag
表示过滤条件,下列值之一:
值 | 含义 |
---|---|
LIST_MODULES_32BIT 0x01 |
列出32位模块 |
LLIST_MODULES_64BIT 0x02 |
列出64位模块 |
LIST_MODULES_ALL 0x03 |
列出所有模块 |
LIST_MODULES_DEFAULT 0x00 |
使用默认行为 |
所以我们在用这个函数时需要先利用函数FindWindow()
找到程序的窗口句柄,然后利用函数GetWindowThreadProcessId()
找到程序的进程ID,最后调用函数OpenProcess()
找到程序进程的打开句柄,最后可以调用EnumProcessModulesEx()
函数获取模块的基地址;
这里直接以获取植物大战僵尸的基地址来演示:
#include
#include
#include
int main(){
HWND hWnd = FindWindow(NULL,"植物大战僵尸中文版");
if (hWnd == NULL){ //如果无法获取句柄则报错
printf("无法获取窗口句柄,请检查进程是否存在!\n");
system("pause");
return -1;
}
DWORD pro_id;
GetWindowThreadProcessId(hWnd, &pro_id); //获取进程ID
if(pro_id == 0){
printf("无法获取进程ID\n");
system("pause");
return 0;
}
printf("进程id: %d\n",pro_id);
//打开进程对象,并获取进程句柄
HANDLE hpro = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pro_id);
if (hpro == 0){
printf("无法获取进程句柄");
}
printf("进程句柄id: %d\n",hpro);
// 获取每一个模块加载基址
DWORD pro_base = NULL;
HMODULE hModule[100] = {0};
DWORD dwRet = 0;
int num = 0;
int bRet = EnumProcessModulesEx(hpro, (HMODULE *)(hModule), sizeof(hModule),&dwRet,NULL);
if (bRet == 0){
printf("EnumProcessModules");
}
// 总模块个数
num = dwRet/sizeof(HMODULE);
printf("总模块个数: %d\n",num);
// 打印每一个模块加载基址
char lpBaseName[100];
for(int i = 0;i<num;i++){
GetModuleBaseNameA(hpro,hModule[i],lpBaseName,sizeof(lpBaseName));
printf("%-2d %-25s基址: 0x%p\n",i,lpBaseName,hModule[i]);
}
pro_base = (DWORD)hModule[0];
printf("程序基址: 0x%p\n",pro_base);
DWORD sun_addr = pro_base + 0x002A9EC0;
printf("阳光基址: 0x%p\n",sun_addr);
DWORD sun_value;
DWORD new_sun_value = 2000;
DWORD kill_1 = pro_base + 0x0013130F; //0x0053130F
DWORD code_1 = 0x9090ff29; //0x20247c2b
DWORD kill_2 = pro_base + 0x00131044; //0x00531044
WORD code_2 = 0xC929; //0xc82b
// 0x0048728C
ReadProcessMemory(hpro,(PVOID)sun_addr,&sun_addr,4,0);
sun_addr = sun_addr + 0x768;
ReadProcessMemory(hpro,(PVOID)sun_addr,&sun_addr,4,0);
sun_addr = sun_addr + 0x5560;
ReadProcessMemory(hpro,(PVOID)sun_addr,&sun_value,4,0);
printf("阳光地址: %p\n当前阳光值: %d\n",sun_addr,sun_value);
printf("修改的阳光值: 2000\n");
//scanf("%d",&new_sun_value);
WriteProcessMemory(hpro, (LPVOID)sun_addr, &new_sun_value, 4, 0); //修改阳光
WriteProcessMemory(hpro, (LPVOID)kill_1, (LPVOID)&code_1, 4, 0); //普通僵尸秒杀
WriteProcessMemory(hpro, (LPVOID)kill_2, (LPVOID)&code_2, 2, 0); //帽子僵尸秒杀
system("pause");
return 0;
}