最强C++x86x64驱动级读写开发库(导师开发)2121
发表时间:2020-07-05 21:09 //***************调用静态变量static***************需要修改下 X64常用内存读写库 DWORD GetModuleSizeX64(DWORD Pid, const TCHAR* ModuleName)//获取模块大小,只能搞64位=64位,32位无法对64位操作 {/*初始化DLL列表*/ HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, Pid); if (hProcess == INVALID_HANDLE_VALUE || !hProcess)return NULL; DWORD dwBuffSize = 0; BOOL bRet = EnumProcessModulesEx(hProcess, NULL, 0, &dwBuffSize, LIST_MODULES_ALL); HMODULE * pModuleHandlerArr = (HMODULE*) new char[dwBuffSize]; bRet = EnumProcessModulesEx(hProcess, pModuleHandlerArr, dwBuffSize, &dwBuffSize, LIST_MODULES_ALL); // 模块名称 TCHAR szModuleName[MAX_PATH] = { 0 }; TCHAR szBaseName[MAX_PATH];//新建 // 保存模块信息 MODULEINFO stcModuleInfo = { 0 }; // 遍历模块列表 int nCount = dwBuffSize / sizeof(HMODULE); for (int i = 0; i < nCount; ++i) { // 根据进程句柄和模块句柄,获取模块信息 GetModuleInformation(hProcess, pModuleHandlerArr[i], &stcModuleInfo, sizeof(stcModuleInfo)); GetModuleBaseNameA(hProcess, pModuleHandlerArr[i], szBaseName, MAX_PATH); //printf("\n%x\n", (DWORD)stcModuleInfo.SizeOfImage); //模块内存大小 if (strcmp(szBaseName, ModuleName) == 0) { delete[] pModuleHandlerArr;// 释放数组 pModuleHandlerArr = nullptr; return stcModuleInfo.SizeOfImage; } } return NULL; } HMODULE GetModuleBaseX64(DWORD Pid, const TCHAR* ModuleName) {/*初始化DLL列表*/ // 这个程序不能删除,基础功能 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, Pid); if (hProcess == INVALID_HANDLE_VALUE || !hProcess)return NULL; DWORD dwBuffSize = 0; BOOL bRet = EnumProcessModulesEx(hProcess, NULL, 0, &dwBuffSize, LIST_MODULES_ALL); HMODULE * pModuleHandlerArr = (HMODULE*) new char[dwBuffSize]; bRet = EnumProcessModulesEx(hProcess, pModuleHandlerArr, dwBuffSize, &dwBuffSize, LIST_MODULES_ALL); // 模块名称 TCHAR szModuleName[MAX_PATH] = { 0 }; TCHAR szBaseName[MAX_PATH];//新建 // 保存模块信息 MODULEINFO stcModuleInfo = { 0 }; // 遍历模块列表 int nCount = dwBuffSize / sizeof(HMODULE); for (int i = 0; i < nCount; ++i) { // 根据进程句柄和模块句柄,获取模块信息 GetModuleInformation(hProcess, pModuleHandlerArr[i], &stcModuleInfo, sizeof(stcModuleInfo)); // 根据进程句柄和模块句柄,获取模块的路径(包括模块名) //GetModuleFileNameEx(hProcess, pModuleHandlerArr[i], szModuleName, MAX_PATH); //获取模块的路径 GetModuleBaseNameA(hProcess, pModuleHandlerArr[i], szBaseName, MAX_PATH); printf("\n%llx\n", (UINT64)stcModuleInfo.lpBaseOfDll); //获取模块基地址 printf("\n%llx\n", (UINT64)stcModuleInfo.EntryPoint); //获取模块入口地址 printf("\n%llx\n", (UINT64)stcModuleInfo.SizeOfImage); //模块内存大小 if (strcmp(szBaseName, ModuleName) == 0) { printf("基地址是:%s\n\n", szBaseName); printf("基地址是:%llX\n\n", (UINT64)stcModuleInfo.lpBaseOfDll); delete[] pModuleHandlerArr;// 释放数组 pModuleHandlerArr = nullptr; return (HMODULE)stcModuleInfo.lpBaseOfDll; } // 基址 //CString szTemp; //szTemp.Format(L"%08X", stcModuleInfo.lpBaseOfDll); //// 入口点 //szTemp.Format(L"%08X", stcModuleInfo.EntryPoint); //// 内存大小 //szTemp.Format(L"%d", stcModuleInfo.SizeOfImage); //// 模块路径 //szModuleName; } return NULL; } HMODULE GetModuleBaseAddr(DWORD Pid, CONST TCHAR* moduleName)//获取进程模块入口地址 1.进程pid 2.模块的名称 xxx.exe 或者xxx.dll { MODULEENTRY32 moduleEntry; //模块信息的结构体 HANDLE handle = NULL; handle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, Pid); // 获取进程快照中包含在th32ProcessID中指定的进程的所有的模块 //printf("handle %llX \n", (DWORD)handle); if (!handle) { //handle 类似指针,指向进程模块信息 CloseHandle(handle); return NULL; } ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32)); //清空 moduleEntry.dwSize = sizeof(MODULEENTRY32); if (!Module32First(handle, &moduleEntry)) { //结果传到 结构体指针moduleEntry CloseHandle(handle); return NULL; } do { if (strcmp(moduleEntry.szModule, moduleName) == 0) { //wcscmp宽字节比较 moduleEntry.szModule模块名字 //printf("基地址是 %X \n", (DWORD)moduleEntry.hModule); return moduleEntry.hModule; //返回模块入口地址 } } while (Module32Next(handle, &moduleEntry)); CloseHandle(handle); return 0; } BOOL EnableSeDebugPrivilege(IN const CHAR* PriviledgeName, BOOL IsEnable) { // 打开权限令牌 HANDLE ProcessHandle = GetCurrentProcess(); HANDLE TokenHandle = NULL; TOKEN_PRIVILEGES TokenPrivileges = { 0 }; if (!OpenProcessToken(ProcessHandle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle)) { return FALSE; } LUID v1; if (!LookupPrivilegeValue(NULL, PriviledgeName, &v1))// 通过权限名称查找uID { CloseHandle(TokenHandle); TokenHandle = NULL; return FALSE; } TokenPrivileges.PrivilegeCount = 1;// 要提升的权限个数 TokenPrivileges.Privileges[0].Attributes = IsEnable == TRUE ? SE_PRIVILEGE_ENABLED : 0; // 动态数组,数组大小根据Count的数目 TokenPrivileges.Privileges[0].Luid = v1; if (!AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { CloseHandle(TokenHandle); TokenHandle = NULL; return FALSE; } CloseHandle(TokenHandle); TokenHandle = NULL; return TRUE; } //==============================================x86x64内存读写wow64函数指针获取===================================================== LPFN_NTWOW64READVIRTUALMEMORY64 __NtWow64ReadVirtualMemory64; LPFN_NTWOW64WRITEVIRTUALMEMORY64 __NtWow64WriteVirtualMemory64; BOOL GetNTWOW64MemoryProcAddress() { HMODULE NtdllModuleBase = NULL; NtdllModuleBase = GetModuleHandle("Ntdll.dll"); if (NtdllModuleBase == NULL) { return FALSE; } __NtWow64ReadVirtualMemory64 = (LPFN_NTWOW64READVIRTUALMEMORY64)GetProcAddress(NtdllModuleBase, "NtWow64ReadVirtualMemory64"); printf("__NtWow64ReadVirtualMemory64 %llx\n", (UINT64)__NtWow64ReadVirtualMemory64); __NtWow64WriteVirtualMemory64 = (LPFN_NTWOW64WRITEVIRTUALMEMORY64)GetProcAddress(NtdllModuleBase, "NtWow64WriteVirtualMemory64"); return TRUE; } char* UTF8ToUnicode(char* szUTF8)//编码转换,已经修复delet释放bug { DWORD wcscLen = MultiByteToWideChar(CP_UTF8, NULL, szUTF8, (int)strlen(szUTF8), NULL, 0);//得到所需空间的大小 wchar_t wszcString[1024] = { 0 };//这个大小的转换我这里是为了写辅助的。溢出数据自己修改 MultiByteToWideChar(CP_UTF8, NULL, szUTF8, (int)strlen(szUTF8), wszcString, wcscLen); //转换 wszcString[wcscLen] = '\0'; DWORD len = WideCharToMultiByte(CP_ACP, 0, wszcString, (int)wcslen(wszcString), NULL, 0, NULL, NULL); static char m_char[1024] = { 0 };//这个大小的转换我这里是为了写辅助的。 WideCharToMultiByte(CP_ACP, 0, wszcString, (int)wcslen(wszcString), m_char, len, NULL, NULL); m_char[len] = '\0'; return m_char; } char* UnicodeToUTF8(wchar_t* wszcString)//编码转换,已经修复 注意内存delet释放bug { DWORD utf8Len = ::WideCharToMultiByte(CP_UTF8, NULL, wszcString, (int)wcslen(wszcString), NULL, 0, NULL, NULL); //得到所需空间的大小 static char szUTF8[1024] = { 0 };//这个大小的转换我这里是为了写辅助的。 WideCharToMultiByte(CP_UTF8, NULL, wszcString, (int)wcslen(wszcString), szUTF8, utf8Len, NULL, NULL); //转换 szUTF8[utf8Len] = '\0'; return szUTF8; } int Wow64ReadInt(ULONG ProcessID, ULONG64 BaseAddress) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; int BufferData = NULL;//=====================ULONG64 BufferData = NULL ULONG64 ReturnLen = 4;//默认 ULONG64 BufferLen = 4;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { NTSTATUS Status = __NtWow64ReadVirtualMemory64(ProcessHandle, BaseAddress, &BufferData, BufferLen, &ReturnLen); printf("4字节数据是:%ld\r\n", BufferData); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常\r\n"); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return BufferData; } char * Wow64ReadAscii(ULONG ProcessID, ULONG64 BaseAddress, DWORD Len) //写入ASCII 参数三是长度 { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; static char BufferData[4096] = { 0 };//===================== ULONG64 ReturnLen = 4;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { NTSTATUS Status = __NtWow64ReadVirtualMemory64(ProcessHandle, BaseAddress, &BufferData, Len, &ReturnLen); printf("字符串是:%s \n", BufferData); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常\r\n"); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return BufferData; } wchar_t * Wow64ReadUnicode(ULONG ProcessID, ULONG64 BaseAddress, DWORD Len) //写入ASCII 参数三是长度 { setlocale(LC_ALL, "chs"); // unicode 必加 只有添加这一句下面的打印1,2与调试打印成功 BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; static wchar_t BufferData[4096] = { 0 };//===================== ULONG64 ReturnLen = 4;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { NTSTATUS Status = __NtWow64ReadVirtualMemory64(ProcessHandle, BaseAddress, &BufferData, Len * 5, &ReturnLen); //unicode编码要乘以2 //printf("字符串是:%s \n", BufferData); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常\r\n"); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return BufferData; } float Wow64ReadFloat(ULONG ProcessID, ULONG64 BaseAddress) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; FLOAT BufferData = NULL;//===================== ULONG64 ReturnLen = 4;//默认 ULONG64 BufferLen = 4;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDeb if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { NTSTATUS Status = __NtWow64ReadVirtualMemory64(ProcessHandle, BaseAddress, &BufferData, BufferLen, &ReturnLen); printf("单精度数据是:%f \n", BufferData); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常\r\n"); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return BufferData; } double Wow64ReadDouble(ULONG ProcessID, ULONG64 BaseAddress) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; DOUBLE BufferData = NULL;//===================== ULONG64 ReturnLen = 8;//默认 ULONG64 BufferLen = 8;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { NTSTATUS Status = __NtWow64ReadVirtualMemory64(ProcessHandle, BaseAddress, &BufferData, BufferLen, &ReturnLen); printf("浮点数数据是:%lf \n", BufferData); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常\r\n"); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return BufferData; } LONG64 Wow64ReadInt64(ULONG ProcessID, ULONG64 BaseAddress) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; ULONG64 BufferData = NULL;//===================== ULONG64 ReturnLen = 8;//默认 ULONG64 BufferLen = 8;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { NTSTATUS Status = __NtWow64ReadVirtualMemory64(ProcessHandle, BaseAddress, &BufferData, BufferLen, &ReturnLen); printf("8字节数据是:%lld\r\n", BufferData); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常\r\n"); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return BufferData; } BOOL Wow64WriteInt(ULONG ProcessID, ULONG64 BaseAddress, INT Value) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; ULONG64 ReturnLen = 4;//默认 ULONG64 BufferLen = 4;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常\r\n"); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return TRUE; } BOOL Wow64WriteFloat(ULONG ProcessID, ULONG64 BaseAddress, FLOAT Value) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; ULONG64 ReturnLen = 4;//默认 ULONG64 BufferLen = 4;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { __NtWow64WriteVirtualMemory64(ProcessHandle, BaseAddress, &Value, BufferLen, &ReturnLen); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常\r\n"); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return TRUE; } BOOL Wow64WriteDouble(ULONG ProcessID, ULONG64 BaseAddress, DOUBLE Value) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; ULONG64 ReturnLen = 8;//默认 ULONG64 BufferLen = 8;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { __NtWow64WriteVirtualMemory64(ProcessHandle, BaseAddress, &Value, BufferLen, &ReturnLen); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常\r\n"); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return TRUE; } BOOL Wow64WriteInt64(ULONG ProcessID, ULONG64 BaseAddress, INT64 Value) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; ULONG64 ReturnLen = 8;//默认 ULONG64 BufferLen = 8;//默认 if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { __NtWow64WriteVirtualMemory64(ProcessHandle, BaseAddress, &Value, BufferLen, &ReturnLen); } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常\r\n"); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return TRUE; } BOOL Wow64WriteAscii(ULONG ProcessID, ULONG64 BaseAddress, const char* Value) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; ULONG64 ReturnLen = NULL;//默认 ULONG64 BufferLen = strlen(Value);//获取字符串长度 //printf("BufferLen %d\n", BufferLen); if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { __NtWow64WriteVirtualMemory64(ProcessHandle, BaseAddress, (PVOID64)Value, BufferLen, &ReturnLen);//32位和64位区别 } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常\r\n"); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return TRUE; } BOOL Wow64WriteUTF8(ULONG ProcessID, UINT64 BaseAddress, const wchar_t * GBK_Str)//为了兼容,写入的是unicode,函数内部会进行转换操作的。 { BOOL IsWow64 = FALSE; //64位程序备用 HANDLE ProcessHandle = NULL; ULONG64 ReturnLen = NULL;//默认 char strUTF8[4096] = { 0 }; char *unGunG = UnicodeToUTF8((wchar_t*)GBK_Str); size_t BufferLen = strlen(unGunG);//获取字符串长度 宽字符用 wcslen RtlMoveMemory(strUTF8, unGunG, BufferLen); //printf("BufferLen %lld\n", BufferLen); if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { __NtWow64WriteVirtualMemory64(ProcessHandle, BaseAddress, &strUTF8, BufferLen, &ReturnLen);//32位和64位区别 } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常\r\n"); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return TRUE; } BOOL Wow64WriteUnicode(ULONG ProcessID, UINT64 BaseAddress, const wchar_t * Value) { BOOL IsWow64 = FALSE; HANDLE ProcessHandle = NULL; UINT64 ReturnLen = NULL;//默认 UINT64 BufferLen = wcslen(Value) * 2;//获取字符串长度 宽字符用 wcslen printf("BufferLen %lld\n", BufferLen); if (BaseAddress == NULL) { return FALSE; } if (EnableSeDebugPrivilege("SeDebugPrivilege", TRUE) == FALSE) { return FALSE; } ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, ProcessID); if (ProcessHandle == NULL) { return FALSE; } if (__NtWow64ReadVirtualMemory64 == NULL || __NtWow64WriteVirtualMemory64 == NULL) { goto Exit; } __try { __NtWow64WriteVirtualMemory64(ProcessHandle, BaseAddress, (PVOID64)Value, BufferLen, &ReturnLen);//32位和64位区别 } __except (EXCEPTION_EXECUTE_HANDLER) { printf("异常\r\n"); goto Exit; } Exit: if (ProcessHandle != NULL) { CloseHandle(ProcessHandle); ProcessHandle = NULL; } EnableSeDebugPrivilege("SeDebugPrivilege", FALSE); return TRUE; } //===============================x86 r3层普通API 内存读写================================================= BOOL WriteInt64(DWORD ProcessID, UINT64 Addr, __int64 Value) { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败\n"); } else { printf("获取进程句柄成功\n"); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &Value, 8, NULL); CloseHandle(Process_handle); return ret; } BOOL WriteInt(DWORD ProcessID, UINT64 Addr, int Value) { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败\n"); } else { printf("获取进程句柄成功\n"); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &Value, 4, NULL); CloseHandle(Process_handle); return ret; } BOOL WriteShort(DWORD ProcessID, UINT64 Addr, short Value) //2字节整数 { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败\n"); } else { //printf("获取进程句柄成功\n"); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &Value, 2, NULL); CloseHandle(Process_handle); return ret; } bool WriteData(DWORD ProcessID, UINT64 Addr, byte byteArr[]) //写入字节集 "1d 80 66 a2" { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败\n"); } else { printf("获取进程句柄成功\n"); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, byteArr, sizeof(byteArr), NULL);//strlen字符长度 CloseHandle(Process_handle); return ret; } BOOL WriteByte(DWORD ProcessID, UINT64 Addr, byte Value) { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败\n"); } else { //printf("获取进程句柄成功\n"); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &Value, 2, NULL); CloseHandle(Process_handle); return ret; } // BOOL WriteFloat(DWORD ProcessID, UINT64 Addr, float Value) { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败\n"); } else { //printf("获取进程句柄成功\n"); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &Value, 4, NULL); CloseHandle(Process_handle); return ret; } BOOL WriteDouble(DWORD ProcessID, UINT64 Addr, double Value) { //printf("打印输出进程pid :%x \n", game_pid); HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败\n"); } else { printf("获取进程句柄成功\n"); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &Value, 8, NULL); CloseHandle(Process_handle); return ret; } BOOL WriteAcsii(DWORD ProcessID, UINT64 Addr, const char * str) { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败\n"); } else { printf("获取进程句柄成功\n"); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, (LPVOID)str, strlen(str), NULL);//strlen字符长度 CloseHandle(Process_handle); return ret; } BOOL WriteUnicode(DWORD ProcessID, UINT64 Addr, const wchar_t * str) { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败\n"); } else { printf("获取进程句柄成功\n"); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, (LPVOID)str, wcslen(str) * 2 + 2, NULL);//wcslen宽字符长度+2 CloseHandle(Process_handle); return ret; } BOOL WriteUnicode(DWORD ProcessID, UINT64 Addr, wchar_t * str) { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) { printf("获取进程句柄失败\n"); } else { printf("获取进程句柄成功\n"); } BOOL ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, (LPVOID)str, wcslen(str) * 2 + 2, NULL);//wcslen宽字符长度+2 //printf("iiiiiiiiiii %d\n", sizeof(str)); CloseHandle(Process_handle); return ret; } DWORD GetPidByHwnd(HWND hwnd) { DWORD Pid = NULL; GetWindowThreadProcessId(hwnd, &Pid); //lpdword指针类型 return Pid; } DWORD FloatToDword(float value)//单浮点数转整数 { DWORD val = NULL; memcpy(&val, &value, 4); return val; } UINT64 DoubleToDword(double value)//双浮点数转整数 { UINT64 val = NULL; memcpy(&val, &value, 8); return val; } int Int64To32(__int64 value)//部分接口 { DWORD val = NULL; memcpy(&val, &value, 4); return val; } int DwordToInt(DWORD value)//无符号转有符号 { int val = NULL; memcpy(&val, &value, 4); return val; } DWORD IntToDword(int value)//无符号转有符号 { DWORD val = NULL; memcpy(&val, &value, 4); return val; } BOOL WriteIntEx(DWORD ProcessID, UINT64 Addr, __int64 Value, int NumByte) { HANDLE Process_handle = OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcessID); //1.渴望得到的访问权限(标志),全局 if (Process_handle == NULL) printf("获取进程句柄失败\n"); else printf("获取进程句柄成功\n"); BOOL ret = NULL; if (NumByte == 4) { int real_val = (int)Value; ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &real_val, 4, NULL); } else if (NumByte == 2) { short real_val = (short)Value; ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &real_val, 2, NULL); } else if (NumByte == 1) { short real_val = (short)Value; ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &real_val, 1, NULL); } else if (NumByte == 8) { ret = WriteProcessMemory(Process_handle, (LPVOID)Addr, &Value, 8, NULL); } CloseHandle(Process_handle); return ret; } byte* ReadByteArray(DWORD ProcessID, UINT64 addr, DWORD size) //写入4字节整数 { byte *Value = NULL; HANDLE Hprocess = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess == 0) printf("打开进程失败!\n"); else { printf("打开进程成功!\n"); ReadProcessMemory(Hprocess, (LPVOID)(addr), Value, size, NULL);//注意参数 4字节 } CloseHandle(Hprocess);//关闭进程句柄 return Value; } byte ReadByte(DWORD ProcessID, UINT64 addr) //写入4字节整数 { byte Value = NULL; HANDLE Hprocess = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess == 0) printf("打开进程失败!\n"); else { printf("打开进程成功!\n"); ReadProcessMemory(Hprocess, (LPVOID)(addr), &Value, 1, NULL);//注意参数 4字节 } CloseHandle(Hprocess);//关闭进程句柄 return Value; } short ReadShort(DWORD ProcessID, UINT64 addr) //写入4字节整数 { short Value = NULL; HANDLE Hprocess = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess == 0) printf("打开进程失败!\n"); else { printf("打开进程成功!\n"); ReadProcessMemory(Hprocess, (LPVOID)(addr), &Value, 2, NULL);//注意参数 4字节 } CloseHandle(Hprocess);//关闭进程句柄 return Value; } int ReadInt(DWORD ProcessID, UINT64 addr) //写入4字节整数 { int Value = NULL; HANDLE Hprocess = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess == 0) printf("打开进程失败!\n"); else { printf("打开进程成功!\n"); ReadProcessMemory(Hprocess, (LPVOID)(addr), &Value, 4, NULL);//注意参数 4字节 } CloseHandle(Hprocess);//关闭进程句柄 return Value; } DWORD ReadDword(DWORD ProcessID, UINT64 addr) //写入4字节整数 { DWORD Value = NULL; HANDLE Hprocess = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess == 0) printf("打开进程失败!\n"); else { printf("打开进程成功!\n"); ReadProcessMemory(Hprocess, (LPVOID)(addr), &Value, 4, NULL);//注意参数 4字节 } CloseHandle(Hprocess);//关闭进程句柄 return Value; } __int64 ReadInt64(DWORD ProcessID, UINT64 addr) //写入8字节整数,地址还是4字节 { __int64 Value = NULL; HANDLE Hprocess = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess == 0) printf("打开进程失败!\n"); else { printf("打开进程成功!\n"); ReadProcessMemory(Hprocess, (LPVOID)(addr), &Value, 8, NULL);//注意参数 4字节 } CloseHandle(Hprocess);//关闭进程句柄 return Value; } UINT64 MemoryVirtualAllocEx(DWORD ProcessID, DWORD Len) //远程申请内存空间 { HANDLE Hprocess = NULL; LPVOID Addr = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 Addr = VirtualAllocEx(Hprocess, NULL, Len, MEM_COMMIT, PAGE_READWRITE); CloseHandle(Hprocess);//关闭进程句柄 return (UINT64)Addr; } void * ReadAscii(DWORD ProcessID, UINT64 addr, DWORD Len) //写入8字节整数,地址还是4字节 { static char Value[1024] = { 0 }; char ByteBuffer = NULL; HANDLE Hprocess = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess == 0) printf("打开进程失败!\n"); else { printf("打开进程成功!\n"); for (size_t i = 0; i < 1024; i++)//遍历长度,上限1024 { ReadProcessMemory(Hprocess, (LPCVOID)(addr + i), &ByteBuffer, 1, NULL);//注意参数 4字节 //printf("遍历I数值! %d \n", i); if (ByteBuffer == 0) { if (Len == 0)//如果是0自动长度 { ReadProcessMemory(Hprocess, (LPCVOID)(addr), &Value, i + 1, NULL); // 字节\0 break; } else { ReadProcessMemory(Hprocess, (LPCVOID)(addr), &Value, Len, NULL); // 字节\0 break; } } } } CloseHandle(Hprocess);//关闭进程句柄 return Value; } wchar_t * ReadUnicode(DWORD ProcessID, UINT64 addr, DWORD Len) //控制台程序不支持unicode打印输出 { static wchar_t StrValue[1024] = { 0 }; wchar_t ShortBuffer = NULL; HANDLE Hprocess = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess == 0) printf("打开进程失败!\n"); else { printf("打开进程成功!\n"); for (size_t i = 0; i < 1024; i = i + 2)//遍历长度,上限1024 { ReadProcessMemory(Hprocess, (LPCVOID)(addr + i), &ShortBuffer, 2, NULL);//注意参数 4字节 if (ShortBuffer == '\0') { if (Len == 0)//如果是0自动长度 { ReadProcessMemory(Hprocess, (LPCVOID)(addr), &StrValue, i + 2, NULL); // 字节\0 printf("打印 %ls \n", StrValue); //printf("打印i : %d \n", i); break; } else { ReadProcessMemory(Hprocess, (LPCVOID)(addr), &StrValue, Len, NULL); // 字节\0 break; } } } } CloseHandle(Hprocess);//关闭进程句柄 return StrValue; } int ReadIntEx(DWORD ProcessID, UINT64 BaseAddr, UINT64 OffsetArray[], DWORD Num) //第二个是基地址 第三个参数是偏移数组 第四个偏移数量 { int Value = NULL; HANDLE Hprocess = NULL; DWORD nBuffer = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess != 0) { ReadProcessMemory(Hprocess, (LPVOID)(BaseAddr), &Value, 4, NULL);//注意参数 4字节 for (size_t i = 0; i < Num; i++)//word占2字节 { ReadProcessMemory(Hprocess, (LPVOID)(Value + OffsetArray[i]), &Value, 4, NULL);//注意参数 4字节 } } else printf("打开进程失败!\n"); CloseHandle(Hprocess);//关闭进程句柄 return Value; } float ReadFloatEx(DWORD ProcessID, UINT64 BaseAddr, UINT64 OffsetArray[], DWORD Num) //第二个是基地址 第三个参数是偏移数组 第四个偏移数量 { UINT64 Value = NULL; HANDLE Hprocess = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess != 0) { ReadProcessMemory(Hprocess, (LPVOID)(BaseAddr), &Value, 4, NULL);//注意参数 4字节 for (size_t i = 0; i < Num; i++)//word占2字节 { //printf("str %lld\n", Value); ReadProcessMemory(Hprocess, (LPVOID)(Value + OffsetArray[i]), &Value, 4, NULL);//注意参数 4字节 } } else printf("打开进程失败!\n"); CloseHandle(Hprocess);//关闭进程句柄 return (float)Value; } double ReadDoubleEx(DWORD ProcessID, UINT64 BaseAddr, UINT64 OffsetArray[], DWORD Num) //第二个是基地址 第三个参数是偏移数组 第四个偏移数量 { double ValueDouble = NULL; HANDLE Hprocess = NULL; UINT64 nBuffer = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess != 0) { ReadProcessMemory(Hprocess, (LPVOID)(BaseAddr), &nBuffer, 4, NULL);//注意参数 4字节 DWORD i = NULL; for (i = 0; i < Num - 1; i++)//word占2字节 { ReadProcessMemory(Hprocess, (LPVOID)(nBuffer + OffsetArray[i]), &nBuffer, 4, NULL);//注意参数 4字节 /*printf("double %x\n", OffsetArray[i]);*/ } ReadProcessMemory(Hprocess, (LPVOID)(nBuffer + OffsetArray[i]), &ValueDouble, 8, NULL);//Value64最终结果 } else printf("打开进程失败!\n"); CloseHandle(Hprocess);//关闭进程句柄 return ValueDouble; } __int64 ReadIntEx64(DWORD ProcessID, UINT64 BaseAddr, DWORD OffsetArray[], DWORD Num) //第二个是基地址 第三个参数是偏移数组 第四个偏移数量 { __int64 value64 = NULL; HANDLE Hprocess = NULL; UINT64 nBuffer = NULL; Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 if (Hprocess != 0) { ReadProcessMemory(Hprocess, (LPVOID)(BaseAddr), &nBuffer, 4, NULL);//注意参数 4字节 DWORD i = NULL; for (i = 0; i < Num - 1; i++)//word占2字节 { ReadProcessMemory(Hprocess, (LPVOID)(nBuffer + OffsetArray[i]), &nBuffer, 4, NULL);//注意参数 4字节 /*printf("double %x\n", OffsetArray[i]);*/ } ReadProcessMemory(Hprocess, (LPVOID)(nBuffer + OffsetArray[i]), &value64, 8, NULL);//Value64最终结果 } else printf("打开进程失败!\n"); CloseHandle(Hprocess);//关闭进程句柄 return value64; } int EnableDebugPriv(const char *name) { HANDLE hToken; //进程令牌句柄 TOKEN_PRIVILEGES tp; //TOKEN_PRIVILEGES结构体,其中包含一个【类型+操作】的权限数组 LUID luid; //上述结构体中的类型值 //打开进程令牌环 //GetCurrentProcess()获取当前进程的伪句柄,只会指向当前进程或者线程句柄,随时变化 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { fprintf(stderr, "OpenProcessToken error\n"); return -1; } //获得本地进程name所代表的权限类型的局部唯一ID if (!LookupPrivilegeValue(NULL, name, &luid)) { fprintf(stderr, "LookupPrivilegeValue error\n"); } tp.PrivilegeCount = 1; //权限数组中只有一个“元素” tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //权限操作 tp.Privileges[0].Luid = luid; //权限类型 //调整进程权限 if (!AdjustTokenPrivileges(hToken, 0, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { fprintf(stderr, "AdjustTokenPrivileges error!\n"); return -1; } return 0; } DWORD GetPidByName(const char * ProcessName) //根据进程名字获取进程ID { HANDLE ProcessAll = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); PROCESSENTRY32 processInfo = { 0 }; processInfo.dwSize = sizeof(PROCESSENTRY32); do { if (strcmp(ProcessName, processInfo.szExeFile) == 0) { return processInfo.th32ProcessID; } } while (Process32Next(ProcessAll, &processInfo)); return NULL; } //======================================注入========================== VOID InjectDll(const CHAR pathStr[0x1000], const CHAR ProcessName[256]) { //CHAR pathStr[0x1000] = { "K:\\我的文档\\visual studio 2012\\Projects\\InjectChat\\Debug\\WeChatDll.dll" }; DWORD PID = GetPidByName((CHAR*)ProcessName); if (PID == 0) { MessageBox(NULL, "没有找到微信进程或者微信没有启动", "错误", 0); return; } HANDLE hProcsee = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID); if (hProcsee == NULL) { MessageBox(NULL, "没有找到微信进程", "错误", 0); return; } LPVOID dllAdd = VirtualAllocEx(hProcsee, NULL, strlen(pathStr), MEM_COMMIT, PAGE_READWRITE); if (dllAdd == NULL) { MessageBox(NULL, "内存写入", "错误", 0); } if (WriteProcessMemory(hProcsee, dllAdd, pathStr, strlen(pathStr), NULL) == 0) { MessageBox(NULL, "内存写入", "错误", 0); return; } HMODULE K32 = GetModuleHandle("Kernel32.dll"); LPVOID LoadAdd = GetProcAddress(K32, "LoadLibraryA"); HANDLE exec = CreateRemoteThread(hProcsee, NULL, 0, (LPTHREAD_START_ROUTINE)LoadAdd, dllAdd, 0, NULL); if (NULL == exec) { MessageBox(NULL, "远程注入失败", "错误", 0); return; } WaitForSingleObject(exec, INFINITE); CloseHandle(hProcsee); } VOID InjectSellCode(DWORD processid, BYTE SellCode[]) //注入硬编码 shellcode { EnableDebugPriv(SE_DEBUG_NAME); //提高进程权限 if (processid == 0) { MessageBox(NULL, "没有找到微信进程或者微信没有启动", "错误", 0); return; } HANDLE hProcsee = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processid); //打开目的程序,获取游戏权限 PROCESS_ALL_ACCESS获取所有权限 if (hProcsee == NULL) { MessageBox(NULL, "没有找到微信进程", "错误", 0); return; } LPVOID dllAdd = VirtualAllocEx(hProcsee, NULL, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);//向游戏申请内存空间 if (dllAdd == NULL) { MessageBox(NULL, "内存申请失败", "0", 0); } if (WriteProcessMemory(hProcsee, dllAdd, SellCode, 1023, NULL) == 0) { //讲shellcode内存写入到游戏里面 MessageBox(NULL, "内存写入", "错误", 0); return; } TRACE("申请的内存空间是 %x\n", dllAdd); HANDLE ThreadHandle = CreateRemoteThread(hProcsee, NULL, 0, (LPTHREAD_START_ROUTINE)dllAdd, NULL, 0, NULL); //远程 创建线程 返回值是线程句柄 if (NULL == ThreadHandle) { MessageBox(NULL, "远程注入失败", "错误", 0); return; } WaitForSingleObject(ThreadHandle, INFINITE); //等到我线程代码执行完成之后,再返回,否则一直在等待 1秒=1000毫秒。 大量代码注入的 CloseHandle(ThreadHandle); ///释放线程句柄 CloseHandle(hProcsee); //关闭临时进程句柄 临时的指针 } BOOL UnloadDll(DWORD dwPid, CHAR strDllName[256]) { //获取宿主进程的句柄,注意那几个参数,不然会出错 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid); if (hProcess == NULL) { ::MessageBox(NULL, "无法获取进程句柄", "错误", MB_OK | MB_ICONERROR); return FALSE; } DWORD dwSize = 0; ULONG64 dwWritten = 0; DWORD dwHandle = 0; dwSize = sizeof(strDllName) + 1;//dll的全路径名的长度,待会分配内存要用到的 //向宿主进程分配内存,返回一个指针 LPVOID lpBuf = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); //如果在宿主进程空间写失败就直接报错闪人 if (!WriteProcessMemory(hProcess, lpBuf, strDllName, dwSize, (SIZE_T*)&dwWritten)) { VirtualFreeEx(hProcess, lpBuf, dwSize, MEM_DECOMMIT); CloseHandle(hProcess); MessageBox(NULL, "在目标进程中写入失败", "错误", MB_OK | MB_ICONERROR); return FALSE; } //获取GetModuleHandleA函数地址 LPVOID pFun = GetProcAddress(GetModuleHandle("Kernel32"), "GetModuleHandleA"); //在宿主进程中创建一个远程线程,线程函数为上面导出的GetModuleHandleA,参数为lpBuf指针,还 //记得我们获取的dll全路径不 HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFun, lpBuf, 0, NULL); //如果创建线程失败,直接报错闪人 if (hThread == NULL) { CloseHandle(hProcess); ::MessageBox(NULL, "在目标进程创建远程线程失败", "错误", MB_OK | MB_ICONERROR); return FALSE; } // 等待GetModuleHandle运行完毕 WaitForSingleObject(hThread, INFINITE); // 获得GetModuleHandle的返回值 GetExitCodeThread(hThread, &dwHandle); // 释放目标进程中申请的空间 VirtualFreeEx(hProcess, lpBuf, dwSize, MEM_DECOMMIT); CloseHandle(hThread); // 使目标进程调用FreeLibraryAndExit,卸载DLL,实际也可以用FreeLibrary,但是我发现前者好一点 pFun = GetProcAddress(GetModuleHandle("Kernel32"), "FreeLibraryAndExitThread"); hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFun, (LPVOID)dwHandle, 0, NULL); // 等待FreeLibraryAndExitThread执行完毕 WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); CloseHandle(hProcess); return TRUE; //操作成功 } //提升进程访问权限 bool enableDebugPriv() { HANDLE hToken; LUID sedebugnameValue; TOKEN_PRIVILEGES tkp; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) ) { return false; } if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) { CloseHandle(hToken); return false; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Luid = sedebugnameValue; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) { CloseHandle(hToken); return false; } return true; } //======================================结尾部分 HANDLE GetModule() { HANDLE hProcess; //进程句柄 HANDLE hModule; //模块句柄 BOOL bProcess = FALSE; //获取进程信息的函数返回值 BOOL bModule = FALSE; //获取模块信息的函数返回值 PROCESSENTRY32 pe32; //保存进程信息 MODULEENTRY32 me32; //保存模块信息 int i = 0; int j = 0; //获取进程调试权限,如果失败,则提示获取权限失败,失败的话,有的进程信息就会获取不到 if (EnableDebugPriv(SE_DEBUG_NAME)) { fprintf(stderr, "Add Privilege error\n"); } hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//获取进程快照 if (hProcess == INVALID_HANDLE_VALUE) { printf("获取进程快照失败\n"); exit(1); } bProcess = Process32First(hProcess, &pe32); //获取第一个进程信息 while (bProcess) //循环获取其余进程信息 { printf("%d :\t Father's PID(%d)\tPID(%d)\t%s\n", i, pe32.th32ParentProcessID, pe32.th32ProcessID, pe32.szExeFile); i++; j = 0; if (0 != pe32.th32ParentProcessID) //获取进程PID不为0的模块信息 { hModule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe32.th32ProcessID); //获取模块快照 if (hModule != INVALID_HANDLE_VALUE) { bModule = Module32First(hModule, &me32); //获取第一个模块信息,即进程相应可执行文件的信息 while (bModule) { printf("模块:\n%d\t%s\n", j, me32.szExePath); j++; bModule = Module32Next(hModule, &me32); //获取其他模块信息 } CloseHandle(hModule); } } bProcess = Process32Next(hProcess, &pe32); //继续获取其他进程信息 printf("\n\n"); getchar(); } CloseHandle(hProcess); return 0; } PVOID GetRemoteProcAddress32(HANDLE hProc, HMODULE hModule, LPCSTR lpProcName)//这个函数只支持32位的 { PVOID pAddress = NULL; SIZE_T OptSize; IMAGE_DOS_HEADER DosHeader; SIZE_T ProcNameLength = lstrlenA(lpProcName) + sizeof(CHAR);//'\0' //读DOS头 if (ReadProcessMemory(hProc, hModule, &DosHeader, sizeof(DosHeader), &OptSize)) { IMAGE_NT_HEADERS NtHeader; //读NT头 if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + DosHeader.e_lfanew), &NtHeader, sizeof(NtHeader), &OptSize)) { IMAGE_EXPORT_DIRECTORY ExpDir; SIZE_T ExportVirtualAddress = NtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; //读输出表 if (ExportVirtualAddress && ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + ExportVirtualAddress), &ExpDir, sizeof(ExpDir), &OptSize)) { if (ExpDir.NumberOfFunctions) { //x64待定:地址数组存放RVA的数据类型是4字节还是8字节??? SIZE_T *pProcAddressTable = (SIZE_T *)GlobalAlloc(GPTR, ExpDir.NumberOfFunctions * sizeof(SIZE_T)); //读函数地址表 if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + ExpDir.AddressOfFunctions), pProcAddressTable, ExpDir.NumberOfFunctions * sizeof(PVOID), &OptSize)) { //x64待定:名称数组存放RVA的数据类型是4字节还是8字节??? SIZE_T *pProcNamesTable = (SIZE_T *)GlobalAlloc(GPTR, ExpDir.NumberOfNames * sizeof(SIZE_T)); //读函数名称表 if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + ExpDir.AddressOfNames), pProcNamesTable, ExpDir.NumberOfNames * sizeof(PVOID), &OptSize)) { CHAR *pProcName = (CHAR *)GlobalAlloc(GPTR, ProcNameLength); //遍历函数名称 for (DWORD i = 0; i < ExpDir.NumberOfNames; i++) { if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + pProcNamesTable[i]), pProcName, ProcNameLength, &OptSize)) { if (RtlEqualMemory(lpProcName, pProcName, ProcNameLength)) { //x64待定:函数在地址数组索引的数据类型是2字节还是??? WORD NameOrdinal; //获取函数在地址表的索引 if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + ExpDir.AddressOfNameOrdinals + sizeof(NameOrdinal) * i), &NameOrdinal, sizeof(NameOrdinal), &OptSize)) { pAddress = (PVOID)((SIZE_T)hModule + pProcAddressTable[NameOrdinal]); } break;//for } } } GlobalFree(pProcName); } GlobalFree(pProcNamesTable); } GlobalFree(pProcAddressTable); } } } } return pAddress; } //=========================内存搜索支持x86x64位游戏=================================== //查找内存地址 INT64 X64ScanAddr(DWORD ProcessID, char *markCode, const wchar_t * ModuleName, DWORD offset) { DWORD size = 8; //==== 返回大小 DWORD ordinal = 1;//====返回次数 UINT64 beginAddr = GetX86X64Module(ProcessID, ModuleName); UINT64 endAddr = beginAddr + GetX86X64ModuleSize(ProcessID, ModuleName); return X64ScanOpcode(ProcessID, markCode, offset, size, ordinal, beginAddr, endAddr); } INT64 X64ScanBase(DWORD ProcessID, const char *markCode, const wchar_t * ModuleName, DWORD offset, DWORD size)//==== 返回大小) { DWORD ordinal = 1;//====返回次数 INT64 BufferData = NULL; // //ULONG64 Len = size; UINT64 beginAddr = GetX86X64Module(ProcessID, ModuleName); UINT64 endAddr = beginAddr + GetX86X64ModuleSize(ProcessID, ModuleName); INT64 Addr_Ret = X64ScanOpcode(ProcessID, markCode, offset, size, ordinal, beginAddr, endAddr); HANDLE Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 __NtWow64ReadVirtualMemory64(Hprocess, Addr_Ret, &BufferData, size, 0);//注意返回值大小问题,size就是字节大小 CloseHandle(Hprocess); return BufferData; } INT64 X64ScanCall(DWORD ProcessID, const char *markCode, const wchar_t * ModuleName, DWORD offset)//==== 返回大小) { DWORD ordinal = 1;//====返回次数 DWORD size = 4;//x64的call只能是4字节的,不能8字节,否走要mov rax 0x1121212121 jmp rax INT64 BufferData = NULL; ULONG64 Len = size; UINT64 beginAddr = GetX86X64Module(ProcessID, ModuleName); UINT64 endAddr = beginAddr + GetX86X64ModuleSize(ProcessID, ModuleName); INT64 Addr_Ret = X64ScanOpcode(ProcessID, markCode, offset, size, ordinal, beginAddr, endAddr); HANDLE Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 __NtWow64ReadVirtualMemory64(Hprocess, Addr_Ret, &BufferData, size, &Len);//注意返回值大小问题,size就是字节大小 CloseHandle(Hprocess); return Addr_Ret - 1 + 5 + BufferData;; } /************************************************************************/ /* 函数说明:查找特征码 /* process: 要查找的进程 /* markCode: 特征码字符串,不能有空格 /* distinct:特征码首地址离目标地址的距离 负数在特征码在上 /* offset: 返回目标地址 /* size: 设置返回数据为几个BYTE 1 2 3 4 /* ordinal: 特征码出现的次数 /* beginAddr: 开始搜索地址 /* endAddr: 结束地址 /* ret:返回目标地址的内容 /************************************************************************/ INT64 X64ScanOpcode(DWORD ProcessID, const char *markCode, ///核心算法 DWORD offset, DWORD size, // size: 设置返回数据为几个BYTE 1 2 3 4 DWORD ordinal, //ordinal: 特征码出现的次数 UINT64 beginAddr, UINT64 endAddr) { HANDLE Hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);//打开进程 GetNTWOW64MemoryProcAddress(); //加进去的 //每次读取游戏内存数目的大小 const DWORD pageSize = 4096; ////////////////////////处理特征码///////////////////// //特征码长度不能为单数 if (strlen(markCode) % 2 != 0) return 0; //特征码长度 size_t len = strlen(markCode) / 2; //将特征码转换成byte型 BYTE *m_code = new BYTE[len]; for (int i = 0; i < len; i++) { char c[] = { markCode[i * 2], markCode[i * 2 + 1], '\0' }; m_code[i] = (BYTE)::strtol(c, NULL, 16); } /////////////////////////查找特征码///////////////////// BOOL _break = FALSE; //用来保存在第几页中的第几个找到的特征码 int curPage = 0; int curIndex = 0; //每页读取4096个字节 BYTE *page = new BYTE[pageSize + len - 1]; UINT64 tmpAddr = beginAddr; DWORD ord = 0; ULONG64 BufferLen = 4096; while (tmpAddr <= endAddr - len) { //printf("Status打印输出: %llx\n", tmpAddr); NTSTATUS Status = __NtWow64ReadVirtualMemory64(Hprocess, tmpAddr, page, pageSize + len - 1, &BufferLen); //在该页中查找特征码 for (int i = 0; i < pageSize; i++) { for (int j = 0; j < len; j++) { //只要有一个与特征码对应不上则退出循环 if (m_code[j] != page[i + j])break; //找到退出所有循环 if (j == len - 1) { ord++; if (ord != ordinal) break; _break = TRUE; curIndex = i; // 特征码的首地址偏移 break; } } if (_break) break; } if (_break) break; curPage++; tmpAddr += pageSize; } // 一个也没找到 //__NtWow64ReadVirtualMemory64(ProcessHandle, BaseAddress, &BufferData, BufferLen, &ReturnLen); delete m_code; delete page; CloseHandle(Hprocess); //printf("base :%llx\n", offsetaddr); return offsetaddr; } UINT64 GetX86X64Module(DWORD ProcessID, const wchar_t* DllName) { DWORD dwPid = ProcessID; HANDLE m_ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid); BOOL bTarget = FALSE; BOOL bSource = FALSE; IsWow64Process(GetCurrentProcess(), &bSource); IsWow64Process(m_ProcessHandle, &bTarget); SYSTEM_INFO si; GetSystemInfo(&si); if (bTarget == FALSE && bSource == TRUE) { HMODULE NtdllModule = GetModuleHandle("ntdll.dll"); pfnNtWow64QueryInformationProcess64 NtWow64QueryInformationProcess64 = (pfnNtWow64QueryInformationProcess64)GetProcAddress(NtdllModule, "NtWow64QueryInformationProcess64"); pfnNtWow64ReadVirtualMemory64 NtWow64ReadVirtualMemory64 = (pfnNtWow64ReadVirtualMemory64)GetProcAddress(NtdllModule, "NtWow64ReadVirtualMemory64"); PROCESS_BASIC_INFORMATION64 pbi64 = { 0 }; if (NT_SUCCESS(NtWow64QueryInformationProcess64(m_ProcessHandle, ProcessBasicInformation, &pbi64, sizeof(pbi64), NULL))) { DWORD64 Ldr64 = 0; LIST_ENTRY64 ListEntry64 = { 0 }; LDR_DATA_TABLE_ENTRY64 LDTE64 = { 0 }; wchar_t ProPath64[256]; if (NT_SUCCESS(NtWow64ReadVirtualMemory64(m_ProcessHandle, (PVOID64)(pbi64.PebBaseAddress + offsetof(PEB64, Ldr)), &Ldr64, sizeof(Ldr64), NULL))) { if (NT_SUCCESS(NtWow64ReadVirtualMemory64(m_ProcessHandle, (PVOID64)(Ldr64 + offsetof(PEB_LDR_DATA64, InLoadOrderModuleList)), &ListEntry64, sizeof(LIST_ENTRY64), NULL))) { if (NT_SUCCESS(NtWow64ReadVirtualMemory64(m_ProcessHandle, (PVOID64)(ListEntry64.Flink), &LDTE64, sizeof(_LDR_DATA_TABLE_ENTRY64), NULL))) { while (1) { if (LDTE64.InLoadOrderLinks.Flink == ListEntry64.Flink) break; /*if (NT_SUCCESS(NtWow64ReadVirtualMemory64(m_ProcessHandle, (PVOID64)LDTE64.FullDllName.Buffer, ProPath64, sizeof(ProPath64), NULL)))*/ if (NT_SUCCESS(NtWow64ReadVirtualMemory64(m_ProcessHandle, (PVOID64)LDTE64.BaseDllName.Buffer, ProPath64, sizeof(ProPath64), NULL)))//修改 { //printf("模块基址:0x%llX 模块大小:0x%X 模块路径:%ls\n", LDTE64.DllBase, LDTE64.SizeOfImage, ProPath64); //printf("BaseDllName :%ls\n", ProPath64); if (wcscmp(ProPath64, DllName) == 0) { //printf("BaseDllName :%ls\n", ProPath64); return (UINT64)LDTE64.DllBase; } } if (!NT_SUCCESS(NtWow64ReadVirtualMemory64(m_ProcessHandle, (PVOID64)LDTE64.InLoadOrderLinks.Flink, &LDTE64, sizeof(_LDR_DATA_TABLE_ENTRY64), NULL))) break; } } } } } } else if (bTarget == TRUE && bSource == TRUE || si.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_AMD64 || si.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_IA64) { HMODULE NtdllModule = GetModuleHandle("ntdll.dll"); pfnNtQueryInformationProcess NtQueryInformationProcess = (pfnNtQueryInformationProcess)GetProcAddress(NtdllModule, "NtQueryInformationProcess"); PROCESS_BASIC_INFORMATION32 pbi32 = { 0 }; if (NT_SUCCESS(NtQueryInformationProcess(m_ProcessHandle, ProcessBasicInformation, &pbi32, sizeof(pbi32), NULL))) { DWORD Ldr32 = 0; LIST_ENTRY32 ListEntry32 = { 0 }; LDR_DATA_TABLE_ENTRY32 LDTE32 = { 0 }; wchar_t ProPath32[256]; if (ReadProcessMemory(m_ProcessHandle, (PVOID)(pbi32.PebBaseAddress + offsetof(PEB32, Ldr)), &Ldr32, sizeof(Ldr32), NULL)) { if (ReadProcessMemory(m_ProcessHandle, (PVOID)(Ldr32 + offsetof(PEB_LDR_DATA32, InLoadOrderModuleList)), &ListEntry32, sizeof(LIST_ENTRY32), NULL)) { if (ReadProcessMemory(m_ProcessHandle, (PVOID)(ListEntry32.Flink), &LDTE32, sizeof(_LDR_DATA_TABLE_ENTRY32), NULL)) { while (1) { if (LDTE32.InLoadOrderLinks.Flink == ListEntry32.Flink) break; if (ReadProcessMemory(m_ProcessHandle, (PVOID)LDTE32.BaseDllName.Buffer, ProPath32, sizeof(ProPath32), NULL))//修改PVOID)LDTE32.BaseDllName.Buffer { //printf("模块基址:0x%X\n模块大小:0x%X\n模块路径:%ls\n", LDTE32.DllBase, LDTE32.SizeOfImage, ProPath32); //printf("模块基址:0x%X 模块大小:0x%X 模块路径:%ls\n", LDTE32.DllBase, LDTE32.SizeOfImage, ProPath32); //printf("%d\n", LDTE32.BaseDllName); if (wcscmp(ProPath32, DllName) == 0) { //printf("BaseDllName :%ls\n", ProPath32); return (UINT64)LDTE32.DllBase; //============32位这里最好改成DWORD } } if (!ReadProcessMemory(m_ProcessHandle, (PVOID)LDTE32.InLoadOrderLinks.Flink, &LDTE32, sizeof(_LDR_DATA_TABLE_ENTRY32), NULL)) break; } } } } } } return FALSE; CloseHandle(m_ProcessHandle); } UINT64 GetX86X64ModuleSize(DWORD ProcessID, const wchar_t* DllName) { DWORD dwPid = ProcessID; HANDLE m_ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid); BOOL bTarget = FALSE; BOOL bSource = FALSE; IsWow64Process(GetCurrentProcess(), &bSource); IsWow64Process(m_ProcessHandle, &bTarget); SYSTEM_INFO si; GetSystemInfo(&si); if (bTarget == FALSE && bSource == TRUE) { HMODULE NtdllModule = GetModuleHandle("ntdll.dll"); pfnNtWow64QueryInformationProcess64 NtWow64QueryInformationProcess64 = (pfnNtWow64QueryInformationProcess64)GetProcAddress(NtdllModule, "NtWow64QueryInformationProcess64"); pfnNtWow64ReadVirtualMemory64 NtWow64ReadVirtualMemory64 = (pfnNtWow64ReadVirtualMemory64)GetProcAddress(NtdllModule, "NtWow64ReadVirtualMemory64"); PROCESS_BASIC_INFORMATION64 pbi64 = { 0 }; if (NT_SUCCESS(NtWow64QueryInformationProcess64(m_ProcessHandle, ProcessBasicInformation, &pbi64, sizeof(pbi64), NULL))) { DWORD64 Ldr64 = 0; LIST_ENTRY64 ListEntry64 = { 0 }; LDR_DATA_TABLE_ENTRY64 LDTE64 = { 0 }; wchar_t ProPath64[256]; if (NT_SUCCESS(NtWow64ReadVirtualMemory64(m_ProcessHandle, (PVOID64)(pbi64.PebBaseAddress + offsetof(PEB64, Ldr)), &Ldr64, sizeof(Ldr64), NULL))) { if (NT_SUCCESS(NtWow64ReadVirtualMemory64(m_ProcessHandle, (PVOID64)(Ldr64 + offsetof(PEB_LDR_DATA64, InLoadOrderModuleList)), &ListEntry64, sizeof(LIST_ENTRY64), NULL))) { if (NT_SUCCESS(NtWow64ReadVirtualMemory64(m_ProcessHandle, (PVOID64)(ListEntry64.Flink), &LDTE64, sizeof(_LDR_DATA_TABLE_ENTRY64), NULL))) { while (1) { if (LDTE64.InLoadOrderLinks.Flink == ListEntry64.Flink) break; /*if (NT_SUCCESS(NtWow64ReadVirtualMemory64(m_ProcessHandle, (PVOID64)LDTE64.FullDllName.Buffer, ProPath64, sizeof(ProPath64), NULL)))*/ if (NT_SUCCESS(NtWow64ReadVirtualMemory64(m_ProcessHandle, (PVOID64)LDTE64.BaseDllName.Buffer, ProPath64, sizeof(ProPath64), NULL)))//修改 { //printf("模块基址:0x%llX 模块大小:0x%X 模块路径:%ls\n", LDTE64.DllBase, LDTE64.SizeOfImage, ProPath64); //printf("BaseDllName :%ls\n", ProPath64); if (wcscmp(ProPath64, DllName) == 0) { //printf("BaseDllName :%ls\n", ProPath64); return (UINT64)LDTE64.SizeOfImage; } } if (!NT_SUCCESS(NtWow64ReadVirtualMemory64(m_ProcessHandle, (PVOID64)LDTE64.InLoadOrderLinks.Flink, &LDTE64, sizeof(_LDR_DATA_TABLE_ENTRY64), NULL))) break; } } } } } } else if (bTarget == TRUE && bSource == TRUE || si.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_AMD64 || si.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_IA64) { HMODULE NtdllModule = GetModuleHandle("ntdll.dll"); pfnNtQueryInformationProcess NtQueryInformationProcess = (pfnNtQueryInformationProcess)GetProcAddress(NtdllModule, "NtQueryInformationProcess"); PROCESS_BASIC_INFORMATION32 pbi32 = { 0 }; if (NT_SUCCESS(NtQueryInformationProcess(m_ProcessHandle, ProcessBasicInformation, &pbi32, sizeof(pbi32), NULL))) { DWORD Ldr32 = 0; LIST_ENTRY32 ListEntry32 = { 0 }; LDR_DATA_TABLE_ENTRY32 LDTE32 = { 0 }; wchar_t ProPath32[256]; if (ReadProcessMemory(m_ProcessHandle, (PVOID)(pbi32.PebBaseAddress + offsetof(PEB32, Ldr)), &Ldr32, sizeof(Ldr32), NULL)) { if (ReadProcessMemory(m_ProcessHandle, (PVOID)(Ldr32 + offsetof(PEB_LDR_DATA32, InLoadOrderModuleList)), &ListEntry32, sizeof(LIST_ENTRY32), NULL)) { if (ReadProcessMemory(m_ProcessHandle, (PVOID)(ListEntry32.Flink), &LDTE32, sizeof(_LDR_DATA_TABLE_ENTRY32), NULL)) { while (1) { if (LDTE32.InLoadOrderLinks.Flink == ListEntry32.Flink) break; if (ReadProcessMemory(m_ProcessHandle, (PVOID)LDTE32.BaseDllName.Buffer, ProPath32, sizeof(ProPath32), NULL))//修改PVOID)LDTE32.BaseDllName.Buffer { //printf("模块基址:0x%X\n模块大小:0x%X\n模块路径:%ls\n", LDTE32.DllBase, LDTE32.SizeOfImage, ProPath32); //printf("模块基址:0x%X 模块大小:0x%X 模块路径:%ls\n", LDTE32.DllBase, LDTE32.SizeOfImage, ProPath32); //printf("%d\n", LDTE32.BaseDllName); if (wcscmp(ProPath32, DllName) == 0) { //printf("BaseDllName :%ls\n", ProPath32); return (UINT64)LDTE32.SizeOfImage; //============32位这里最好改成DWORD } } if (!ReadProcessMemory(m_ProcessHandle, (PVOID)LDTE32.InLoadOrderLinks.Flink, &LDTE32, sizeof(_LDR_DATA_TABLE_ENTRY32), NULL)) break; } } } } } } return FALSE; CloseHandle(m_ProcessHandle); } |