【C++】從零開始的CS:GO逆向分析3——寫出一個透視( 三 )



獲得屏幕大小儲存在全局變量、創建透明窗口

循環遍歷敵人對象,通過地址讀取到人物的視角矩陣、敵人的位置

在循環中將敵人的位置結合矩陣,轉換成2D坐標

再循環中在透明窗口上把算出來的坐標畫出來
再寫一段偽代碼出來幫助理解,代碼貼在后面
int main{獲取視角矩陣地址、獲取本地人物地址、獲取敵人對象地址獲取屏幕分辨率根據屏幕分辨率創建窗口while(1)消息循環{清除畫的線獲得視角矩陣 , 因為會變,所以需要不停的獲取for(int i=0;i<64;i++)因為游戲人數最大為64{獲得自己的陣營獲取當前敵人對象根據對象獲取人物血量、陣營、生存狀態、敵人是否有效如果敵人血量<=0 或者 敵人陣營=自己陣營 或者 無效 或者 敵人對象為空 或者 敵人生存狀態則遍歷下一個對象獲得敵人的位置將敵人的坐標轉換為2D坐標畫線}}}代碼部分GetImformation.h
#pragma oncestruct Vec2{public:float x, y;};struct Vec3{public:float x, y, z;};bool is_error();void error(const char*text);class module_information{public:HANDLE module_handle;char module_name[1024];char *module_data;UINT_PTR module_address;int module_size;void alloc(int size){module_size = size;module_data = https://www.huyubaike.com/biancheng/(char *)VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);if (is_error())error("申請內存失敗");}void release(){if (module_data)VirtualFree(module_data, 0, MEM_RELEASE);module_data = https://www.huyubaike.com/biancheng/nullptr;}};void init_address(const char*process_name);DWORD get_process_id(const char*process_name);HANDLE get_process_handle(DWORD process_id);void ConvertToRange(Vec2 &Point);bool WorldToScreen(const Vec3& VecOrgin, Vec2& VecScreen, float* Matrix);void get_moduel_info(DWORD process_id, const char *name, OUT module_information&info);DWORD read_memory(HANDLE process, DWORD address, void *recv, int size);templateT ReadMem(HANDLE ProcessHandle, UINT_PTR Address, int size){T Reader;ReadProcessMemory(ProcessHandle, (LPVOID)Address, &Reader, size, NULL);return Reader;}GetImformation.cpp
#include<Windows.h>#include<TlHelp32.h>#include"GetIMformation.h"DWORD g_process_id = NULL;HANDLE g_process_handle = NULL;UINT_PTR g_local_player = NULL;UINT_PTR g_player_list_address = NULL;UINT_PTR g_matrix_address = NULL;UINT_PTR g_angle_address = NULL;HWND g_game_hwnd = NULL;module_information engine_module;module_information client_module;module_information server_module;float g_client_width;float g_client_height;#define dwViewMatrix 0x4DCF254#define dwLocalPlayer 0xDC14CC#define dwClientState 0x58CFDC#define dwEntityList 0x4DDD93C#define dwClientState_ViewAngles 0x4D90#define m_vecOrigin 0x138#define m_bDormant 0xED#define m_lifeState 0x25F#define m_iHealth 0x100#define m_iTeamNum 0xF4//獲取模塊信息void get_moduel_info(DWORD process_id, const char *name, OUT module_information&info){HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, process_id);if (is_error())error("創建快照錯誤");MODULEENTRY32 module_info;ZeroMemory(&module_info, sizeof(module_info));module_info.dwSize = sizeof(module_info);char target[1024];ZeroMemory(target, 1024);strncpy(target, name, strlen(name));_strupr(target);bool status = Module32First(snap, &module_info);while (status){if (strncmp(_strupr(module_info.szModule), target, sizeof(target)) == 0){info.module_address = (UINT_PTR)module_info.modBaseAddr;info.module_handle = module_info.hModule;info.alloc(module_info.modBaseSize);//DWORD size = read_memory(g_process_handle, info.module_address);//TODODWORD size = read_memory(g_process_handle, info.module_address, info.module_data, info.module_size);//TODOCloseHandle(snap);return;}status = Module32Next(snap, &module_info);}error("未找到模塊");return;}void error(const char*text){MessageBoxA(nullptr, text, nullptr, MB_OK);exit(-1);}bool is_error(){return GetLastError() != 0;}DWORD read_memory(HANDLE process, DWORD address, void *recv, int size){DWORD readsize;ReadProcessMemory(process, (LPVOID)address, recv, size, &readsize);return readsize;if (is_error())error("讀取內存失敗");}HANDLE get_process_handle(DWORD process_id){HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_id);if (is_error())error("get_process_handle失敗");std::cout << "進程句柄為:" << std::hex << process_handle << std::endl;return process_handle;}DWORD get_process_id(const char*process_name){HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (is_error()) error("CreateToolhelp32Snapshot失敗");PROCESSENTRY32 process_info;ZeroMemory(&process_info, sizeof(process_info));process_info.dwSize = sizeof(process_info);char target[1024];ZeroMemory(target, 1024);strncpy_s(target, process_name, strlen(process_name));_strupr(target);bool state = Process32First(snap, &process_info);while (state){if (strncmp(_strupr(process_info.szExeFile), target, strlen(target)) == 0){CloseHandle(snap);return process_info.th32ProcessID;}state = Process32Next(snap, &process_info);}CloseHandle(snap);MessageBoxA(NULL, "查找進程id失敗", "提示", MB_OK);return 0;}void GetWindowSize(){HDC hdc = GetDC(nullptr);g_client_width = GetDeviceCaps(hdc, DESKTOPHORZRES);g_client_height = GetDeviceCaps(hdc, DESKTOPVERTRES);ReleaseDC(nullptr, hdc);}void init_address(const char*process_name){std::cout << "請先啟動游戲"<< std::endl;DWORD process_id = get_process_id(process_name);HANDLE process_handle = get_process_handle(process_id);g_process_id = process_id;//獲取模塊信息g_process_handle = process_handle;get_moduel_info(process_id, "engine.dll", engine_module);get_moduel_info(process_id, "client.dll", client_module);get_moduel_info(process_id, "server.dll", server_module);//TODO 要寫一個特征碼尋址,獲取視角矩陣信息UINT_PTR temp_address;float Matrix[16];UINT_PTR matrix_address = client_module.module_address + dwViewMatrix;g_matrix_address = matrix_address;//獲取 人物視角地址ReadProcessMemory(g_process_handle, (LPVOID)(engine_module.module_address + 0x58CFDC), &temp_address, 4, NULL);//[engine.dll + 58CFDC]+00004D90g_angle_address = temp_address + 0x00004D90;//獲取本地人物地址 [client.dll+0xDC04CC]+100 = 生命值ReadProcessMemory(g_process_handle, (LPVOID)(client_module.module_address + dwLocalPlayer), &temp_address, 4, NULL);g_local_player = temp_address; //[g_local_player+100] = 生命值temp_address = 0;//獲得ENtitylist地址[client.dll+0x4DDC90C + i *0x10]+100 = 敵人生命值g_player_list_address = client_module.module_address + dwEntityList;}bool WorldToScreen(const Vec3& VecOrgin, Vec2& VecScreen, float* Matrix){VecScreen.x = VecOrgin.x *Matrix[0] + VecOrgin.y*Matrix[1] + VecOrgin.z*Matrix[2] + Matrix[3];VecScreen.y = VecOrgin.x *Matrix[4] + VecOrgin.y*Matrix[5] + VecOrgin.z*Matrix[6] + Matrix[7];float w = VecOrgin.x*Matrix[12] + VecOrgin.y*Matrix[13] + VecOrgin.z*Matrix[14] + Matrix[15];if (w < 0.01f){return false;}Vec2 NDC;NDC.x = VecScreen.x / w;NDC.y = VecScreen.y / w;VecScreen.x = (g_client_width / 2 * NDC.x) + (NDC.x + g_client_width / 2);VecScreen.y = (g_client_height / 2 * NDC.y) + (NDC.y + g_client_height / 2);ConvertToRange(VecScreen);return true;}void ConvertToRange(Vec2 &Point){Point.x /= g_client_width;Point.x *= 2.0f;Point.x -= 1.0f;Point.y /= g_client_height;Point.y *= 2.0f;Point.y -= 1.0f;}

推薦閱讀