赞
踩
本文章函数介绍部分大量引用寻梦&之璐的一篇文章
FindWindow
GetWindowThreadProcessId
OpenProcess
ReadProcessMemory
WriteProcessMemory
具体代码实现
函数检索处理顶级窗口的类名和窗口名称匹配指定的字符串,这个函数不搜索子窗口。
第一个是要找的窗口的类,第二个是要找的窗口的标题。
FindWindowW(
_In_opt_ LPCWSTR lpClassName,
_In_opt_ LPCWSTR lpWindowName
);
在搜索的时候不一定两者都知道,但至少要知道其中的一个。
lpClassName,输入参数,指向一个以null结尾的、用来指定类名的字符串或一个可以确定类名字符串的原子。如果这个参数是一个原子,那么它必须是一个在调用此函数前已经通过GlobalAddAtom函数创建好的全局原子。这个原子(一个16bit的值),必须被放置在lpClassName的低位字节中,lpClassName的高位字节置零。
如果该参数为null时,将会寻找任何与lpWindowName参数匹配的窗口。
如果函数执行成功,则返回值是拥有指定窗口类名或窗口名的窗口的句柄。
如果函数执行失败,则返回值为NULL。可以通过调用GetLastError函数获得更加详细的错误信息。
该函数返回创建指定窗口线程的标识和创建窗口的进程的标识符,后一项是可选的。得到窗口句柄后我们可以通过GetWindowsTreadProcessId来获得窗口所属进程ID和线程ID,从而判断创建窗口的进程和线程。
GetWindowThreadProcessId(
_In_ HWND hWnd,
_Out_opt_ LPDWORD lpdwProcessId
);
输入参数,hWnd,窗口句柄。
输出参数,lpdwProcessld,接收进程标识的32位值的地址。如果这个参数不为NULL,GetWindwThreadProcessld将进程标识拷贝到这个32位值中,否则不拷贝,输出参数是进程ID地址。
返回值为运行窗口的线程标识,返回的是窗口所属线程ID
根据进程ID打开对应进程,并返回进程的句柄。
输入参数,dwDesiredAccess 想拥有的该进程访问权限。
PROCESS_ALL_ACCESS //所有能获得的权限
PROCESS_CREATE_PROCESS //需要创建一个进程
PROCESS_CREATE_THREAD //需要创建一个线程
PROCESS_DUP_HANDLE //重复使用DuplicateHandle句柄
PROCESS_QUERY_INFORMATION //获得进程信息的权限,如它的退出代码、优先级
PROCESS_QUERY_LIMITED_INFORMATION /获得某些信息的权限,如果获得
PROCESS_QUERY_INFORMATION,也拥有PROCESS_QUERY_LIMITED_INFORMATION权限/
PROCESS_SET_INFORMATION //设置某些信息的权限,如进程优先级
PROCESS_SET_QUOTA //设置内存限制的权限,使用SetProcessWorkingSetSize
PROCESS_SUSPEND_RESUME //暂停或恢复进程的权限
PROCESS_TERMINATE //终止一个进程的权限,使用TerminateProcess
PROCESS_VM_OPERATION //操作进程内存空间的权限(可用VirtualProtectEx和WriteProcessMemory)
PROCESS_VM_READ //读取进程内存空间的权限,可使用ReadProcessMemory
PROCESS_VM_WRITE//读取进程内存空间的权限,可使用WriteProcessMemory
SYNCHRONIZE //等待进程终止
输入参数,bInheritHandle表示所得到的进程句柄是否可以被继承
输入参数,dwProcessId被打开进程的PID
如果函数调用成功将返回一个进程句柄值,否则将返回NULL
注意:在使用完所获得的进程句柄后一定要调用==CloseHandle(handle)==来关闭进程的句柄。
读取进程内存
第二个参数就是基址,第三个参数用来存放基址的值,因为基值是固定的,但基址的值是不固定的,用这个值加上偏移就是一级偏移地址。
hProcess
目标进程的句柄,该句柄必须对目标进程具有PROCESS_VM_READ 的访问权限。
lpBaseAddress
从目标进程中读取数据的起始地址。 在读取数据前,系统将先检验该地址的数据是否可读,如果不可读,函数将调用失败。
lpBuffer
用来接收数据的缓存区地址。
nSize
从目标进程读取数据的字节数。
lpNumberOfBytesRead
实际被读取数据大小的存放地址。如果被指定为NULL,那么将忽略此参数。
返回值
如果函数执行成功,返回值非零。
如果函数执行失败,返回值为零。
该函数与readProcessMemory的参数基本相同,只不过第三个参数lpBuffer为要写入进程的内容。
#include<stdio.h> #include<windows.h> #include<stdbool.h> int main(void) { HWND hwnd=FindWindow(NULL, L"植物大战僵尸中文版");//获取窗口句柄 if (hwnd == NULL) { printf_s("获取窗口句柄失败"); } printf_s("窗口句柄=%d ",(int)hwnd); HWND ProcessID = NULL; GetWindowThreadProcessId(hwnd, &ProcessID);//获取进程ID,系统内进程唯一标识 if (ProcessID == NULL) { printf_s("获取进程ID失败"); } printf_s("ProcessID=%d ", (int)ProcessID); HWND HProcess = OpenProcess(PROCESS_ALL_ACCESS, false, ProcessID);//根据进程ID获取进程访问权限和句柄 if (HProcess == NULL) { printf_s("获取进程句柄失败"); } int jizi = 0X006AA00C;//基址 int jiziNuber = 0;//基址值 int dwSize = 0;//保存实际读取字节大小 ReadProcessMemory(HProcess, jizi, &jiziNuber, sizeof(int), dwSize);//读取基址,dwSize可以用NULL替代 int firstSize = 0X768;//一级偏移 int firstSizeNuber = 0;//一级偏移值 ReadProcessMemory(HProcess, jiziNuber + firstSize, &firstSizeNuber, sizeof(int), dwSize);//一级偏移,dwSize可以用NULL替代 int cecondSize = 0X5560;//二级偏移 int cecondSizeNuber = 0;//二级偏移值 ReadProcessMemory(HProcess, firstSizeNuber + cecondSize, &cecondSizeNuber, sizeof(int), dwSize);//二级偏移,dwSize可以用NULL替代 printf("%d", cecondSizeNuber); int sunNuber;//保存新阳光值 printf("输入新的阳光值\n"); scanf_s("%d", &sunNuber); WriteProcessMemory(HProcess, (LPVOID)(firstSizeNuber + cecondSize), &sunNuber, sizeof(int), dwSize);//写入数值 CloseHandle(HProcess); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。