句柄 进程 内存
窗口句柄
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
HWND FindWindow(
LPCTSTR IpClassName, //窗口的类名
LPCTSTR IpWindowName //窗口的标题
); //返回窗口句柄
HWND FindWindowW(//使用Unicode字符集
LPCTSTR IpClassName,
LPCTSTR IpWindowName //IpWindowName前要加L,如L”魔兽世界“
);
HWND FindWindowA(//使用多字节字符集
LPCTSTR IpClassName,
LPCTSTR IpWindowName
);
HWND FindWindowEx( //获得一个窗口的句柄,该窗口的类名和窗口名与给定的字符串相匹配
HWND hwndParent, //要查找子窗口的父窗口句柄 可为NULL
HWND hwndChildAfter, //子窗口句柄 可为NULL
LPCTSTR lpszClass, //窗口的类名 可为NULL
LPCTSTR lpszWindow //窗口的标题 可为NULL
);
//如果hwndParent为NULL,则函数以桌面窗口为父窗口,查找桌面窗口的所有子窗口。
//如果hwndParent为HWND_MESSAGE,函数仅查找所有消息窗口。
//子窗口必须为hwndPareRt窗口的直接子窗口而非后代窗口。
//如果hwndChildAfter为NULL,查找从hwndParent的第一个子窗口开始。
//如果hwndParent 和 hwndChildAfter同时为NULL,则函数查找所有的顶层窗口及消息窗口。
HWND FindWindowExA( //使用多字节字符集
HWND hwndParent,
HWND hwndChildAfter,
LPCTSTR lpszClass,
LPCTSTR lpszWindow
);
|
通过类名或窗口名查找,返回窗口句
进程ID和线程ID
1
2
3
4
|
DWORD GetWindowThreadProcessId(
HWND hWnd, //被查找窗口的句柄.
LPDWORD lpdwProcessId //进程号的存放地址
); //返回线程号
|
得到窗口句柄后通过GetWindowThreadProcessId这个函数来获得窗口所属进程ID和线程ID
进程句柄
1
|
HANDLE OpenProcess(DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwProcessId);
|
打开一个已存在的进程对象,并返回进程的句柄
写入内存
三种方式:
- 函数WriteProcessMemory(远程跨进程)
1
2
3
4
5
6
7
|
BOOL WriteProcessMemory(
HANDLE hProcess, //进程句柄
LPVOID lpBaseAddress, //内存首地址
LPVOID lpBuffer, //指向要写的数据的指针
DWORD nSize, //字节数
LPDWORD lpNumberOfBytesWritten //这个是返回实际写入的字节
);
|
能写入某一进程的内存区域。入口区必须可以访问,否则操作将失败
读取内存
1
2
3
4
5
6
7
|
BOOL ReadProcessMemory(
HANDLE hProcess, //目标进程句柄
LPCVOID lpBaseAddress, //要读取的起始地址
LPVOID lpBuffer, //存放读取数据的地址
DWORD nSize, //要读取的字节数
LPDWORD lpNumberOfBytesRead //存放实际读取字节大小
); //返回值 成功非0,失败0
|
根据进程句柄读入该进程的某个内存空间lpBaseAddress的nSize字节,并写入缓冲区lpBuffer,多次计算基址和偏移即可
加载模块
GetModuleHandleA 获得应用程序或动指定模块的模块句柄
1
2
3
4
5
6
7
|
HMODULE GetModuleHandleA(
[in, optional] LPCSTR lpModuleName //加载模块的名称(.dll或.exe文件)
);//返回值是指定模块的句柄。
//如果函数失败,返回值为NULL
//实例
DWORD B =(DWORD)GetModuleHandleA("ELEMENTCLIENT.EXE");
|
遍历模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
int 遍历进程模块(DWORD 进程PID)
{
HMODULE hMods[1024]; //20*sizeof(HMODULE)
HANDLE 进程句柄;
DWORD cbNeeded;
unsigned int i;
//Print the proess identifier.
printf("\nprocess ID: %u\n",进程PID);
//Get a handle to the process.
进程句柄=OpenProcess(PROCESS_ALL_ACCESS,FALSE,进程PID);
if (NULL == 进程句柄)
return 1;
//Get a list of all the modules in this process.
BOOL br = EnumProcessModules(进程句柄,hMods,sizeof(hMods),&cbNeeded);
if (br)
{
UINT32 模块数量=cbNeeded/sizeof(HMODULE);
for ( i = 0; i < 模块数量; i++)
{
TCHAR szModName[MAX_PATH];
//Get the full path to the module file.
if(GetModuleFileNameEx(进程句柄,hMods[i],szModName,
sizeof(szModName)/sizeof(TCHAR)))
{
//Print the module name and handle value.
//_tprintf(TEXT("模块名[%d]=%s 地址=%08X\n"),i,szModName,hModes[i]);
printf("模块名[%d]=%s 地址=%p\n",i,szModName,hMods[i]);
}
}
}
//Release the handle to the process.
//
CloseHandle(进程句柄);
return 0;
}
|
获取窗口句柄
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
HWND CFINDCODE::GetGameHwnd(void)
{
HWND hNext = FindWindowExA(HWND_DESKTOP,0,0,0);
HWND h2 = FindWindowExA(HWND_DESKTOP,hNext,0,0);
int i =0;
while(h2)
{
char buf[256]={0};
GetWindowTextA(h2,buf,256);
if (strstr(buf,szGameSubCaption))
{
break;
}
h2 = FindWindowExA(HWND_DESKTOP,h2,0,0);
}
return h2;
}
|
获取进程ID
1
2
3
4
5
6
7
8
|
DWORD CFINDCODE::GetPID()
{
HWND h=GetGameHwnd();
DWORD dwpid=0;
GetWindowThreadProcessId(h,&dwpid);
return dwpid;
}
|
获取进程句柄
1
2
3
4
5
6
7
|
HANDLE CFINDCODE::GetGameHp()
{
DWORD dwPid = GetPID();
HANDLE hp = OpenProcess(PROCESS_ALL_ACCESS,0,dwPid);
// printf("hp=%hp, pid=%d\r\n",hp,dwPid);
return hp;
}
|
获取EXE模块起始地址
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
UINT_PTR CFINDCODE::GetExeBase()
{
UINT_PTR exeBase64=NULL;
HMODULE hMods[1024]; //20*sizeof(HMODULE)
DWORD cbNeeded;
unsigned int i;
HANDLE 进程句柄=GetGameHp();
//Get a list of all the modules in this process.
BOOL br = EnumProcessModules(进程句柄,hMods,sizeof(hMods),&cbNeeded);
if (br)
{
UINT32 模块数量=cbNeeded/sizeof(HMODULE);
for ( i = 0; i < 模块数量; i++)
{
TCHAR szModName[MAX_PATH];
//Get the full path to the module file.
if(GetModuleFileNameEx(进程句柄,hMods[i],szModName,
sizeof(szModName)/sizeof(TCHAR)))
{
//如果是“*.exe”的模块,直接返回基址
if (strstr(szModName,".exe"))
{
exeBase64 = (UINT_PTR)hMods[i];
}
//Print the module name and handle value.
//_tprintf(TEXT("模块名[%d]=%s 地址=%08X\n"),i,szModName,hModes[i]);
// printf("模块名[%d]=%s 地址=%p\n",i,szModName,hMods[i]);
}
}
}
//Release the handle to the process.
//
CloseHandle(进程句柄);
return exeBase64;
}
|
获取EXE结束地址
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
UINT_PTR CFINDCODE::GetExeEnd()
{
// HANDLE 进程句柄=GetGameHp();
// UINT_PTR 模块基址 = GetExeBegin();
// MEMORY_BASIC_INFORMATION meminfo;
// //nSize函数写入lpBuffer的字节数,如果不等于sizeof(MEMORY_BASIC_INFORMATION)表示失败
// SIZE_T nSize /*返回buf大小 */ = VirtualQueryEx(进程句柄,(LPCVOID)模块基址,&meminfo,sizeof(meminfo));
// UINT_PTR 结束地址=(UINT_PTR)meminfo.AllocationBase+meminfo.RegionSize;
// printf("GetExeEnd: AllocationBase=%llx,RegionSize=%X 结束地址=%llx \r\n",meminfo.AllocationBase,meminfo.RegionSize,结束地址);
// return 结束地址;
return GetExeBase()+GetExeSize();
}
|
获取EXE模块大小
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
SIZE_T CFINDCODE::GetExeSize();
{
static SIZE_T nSize=0;
if (nSize)
{
/* code */
return nSize;
}
HANDLE 进程句柄=GetGameHp();
UINT_PTR 模块基址 = GetExeBase();
MEMORY_BASIC_INFORMATION meminfo;
//nSize函数写入lpBuffer的字节数,如果不等于sizeof(MEMORY_BASIC_INFORMATION)表示失败
SIZE_T nSize /*返回buf大小 */ = VirtualQueryEx(进程句柄,(LPCVOID)模块基址,&meminfo,sizeof(meminfo));
nSize = meminfo.RegionSize;
CloseHandle(进程句柄);
return nSize;
}
|