CS起源pointermap找基址+工具函数测试
這是我的愛好,但我不會用這些技術做越界的事情,希望您也是。
這是我的愛好,但我不會用這些技術做越界的事情,希望您也是。
這是我的愛好,但我不會用這些技術做越界的事情,希望您也是。
一、MemHackLib庫
參考casuallibrary項目,整了個閹割版,刪掉了我不會的C++語法,只保留了vector和模板函數,這兩個工具還是很實用的。這個庫剛開始整,只有外部讀寫內存的功能,以后慢慢加。
主函數
這里演示了庫的基本功能,獲取玩家基址,然后鎖血1000.其實庫的功能差不多就這些了,后期會加入AOB掃描的功能,然后適配一下64位,也沒什么別的了。
MemHackLib.hpp
#pragma once/* * 參考項目:https://github.com/CasualCoder91/CasualLibrary * 日期:2021年8月21日 * 作者:hambaga * * 我編寫這個庫時會兼容多字節字符集和Unicode字符集;也嘗試兼容64位,但沒有測試過,以后用這個庫開發64位外掛時會完善的。 * */#include <Windows.h> #include <iostream> #include <stdio.h> #include <TlHelp32.h> #include <tchar.h> #include <vector>// ---------------------------------------------------------------------------------------------------------------- // External hack, just use this api in a external program... // ----------------------------------------------------------------------------------------------------------------// Open process and return pid BOOL OpenProcessWithName(const TCHAR* ProcessName, HANDLE* Process, DWORD* Pid) {HANDLE hSnapshot;hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (INVALID_HANDLE_VALUE == hSnapshot){std::cerr << "CreateToolhelp32Snapshot failed, error code: " << GetLastError() << "\n";return FALSE;}PROCESSENTRY32 process;process.dwSize = sizeof(PROCESSENTRY32);BOOL first = Process32First(hSnapshot, &process);while (first){if (!_tcscmp(ProcessName, process.szExeFile)){*Process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID);if (*Process != NULL){*Pid = process.th32ProcessID;return TRUE;}}first = Process32Next(hSnapshot, &process);}CloseHandle(hSnapshot);return FALSE; }// Get a dll address or main exe address. HMODULE GetModuleBase(const TCHAR* ModuleName, DWORD Pid) {HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, Pid);MODULEENTRY32 ModuleEntry;ModuleEntry.dwSize = sizeof(ModuleEntry);do{if (!_tcscmp(ModuleName, ModuleEntry.szModule)){CloseHandle(hSnapshot);return ModuleEntry.hModule;}} while (Module32Next(hSnapshot, &ModuleEntry));return NULL; }// Get an object address by specify some offsets. uintptr_t GetObjectAddress(HANDLE ProcessHandle, uintptr_t Address, const std::vector<uintptr_t>& Offsets) {for (size_t i = 0; i < Offsets.size(); i++){if (!ReadProcessMemory(ProcessHandle, (BYTE*)Address, &Address, sizeof(Address), NULL)){std::cerr << "ReadProcessMemory failed at reading " << std::hex << Address << "\n";}Address += Offsets[i];}return Address; }template <typename T> BOOL ExternalRead(HANDLE ProcessHandle, const uintptr_t& Address, BOOL ReadableCheck, T *ReadData) {if (ReadableCheck){MEMORY_BASIC_INFORMATION mbi;VirtualQueryEx(ProcessHandle, (LPCVOID)Address, &mbi, sizeof(mbi));if (!(mbi.State & MEM_COMMIT)){return FALSE;}} ReadProcessMemory(ProcessHandle, (LPBYTE)Address, ReadData, sizeof(T), NULL);return TRUE; }template <typename T> BOOL ExternalWrite(HANDLE ProcessHandle, const uintptr_t& Address, BOOL WritableCheck, T WriteData) {if (WritableCheck){MEMORY_BASIC_INFORMATION mbi;VirtualQueryEx(ProcessHandle, (LPCVOID)Address, &mbi, sizeof(mbi));if (!(mbi.State & MEM_COMMIT)){return FALSE;}if (mbi.Protect & (PAGE_GUARD | PAGE_NOCACHE | PAGE_NOACCESS | PAGE_READONLY)){if (!VirtualProtectEx(ProcessHandle, mbi.BaseAddress, mbi.RegionSize, PAGE_READWRITE, &mbi.Protect)) {return FALSE;}WriteProcessMemory(ProcessHandle, (LPBYTE*)Address, &WriteData, sizeof(T), NULL);DWORD dwOldProtect;VirtualProtectEx(ProcessHandle, mbi.BaseAddress, mbi.RegionSize, mbi.Protect, &dwOldProtect);return TRUE;}}WriteProcessMemory(ProcessHandle, (LPBYTE)Address, &WriteData, sizeof(T), NULL);return TRUE; }// ---------------------------------------------------------------------------------------------------------------- // Internal hack, just use this api in a dll, and use some other tool to inject this dll into the game... // ----------------------------------------------------------------------------------------------------------------二、如何使用 pointermap 找玩家基址
如果您不知道什么是 指針掃描 ,建議您先看一下CE教程,把CE內置的教程過一遍。pointermap我的理解是把多個指針掃描的結果放在一起比較,原理不清楚,反正效果就是篩選過程比普通指針掃描更快,搜出來的結果更少。下面演示一下CS起源怎么找基址,我這里用的是steam的CS起源,估計和破解版也沒什么區別。
2-1 找血量
只要找到血量,看看誰訪問/修改了血量,根據指令的偏移,就能找到玩家基址。開一局游戲吧:
找到十幾個地址,其中只有一個是真正的血量:
全部拉下來,用二分法修改+鎖定:
我這里將下半區這幾個鎖定成1000,如果我無敵了,說明真正的血量就是這里邊其中一個,那么上半區的就可以刪掉了;否則,真正的血量就在上半區,那么把下半區刪掉。重復這個步驟,可以快速找到真正的血量地址:
2-2 查偏移
看看誰訪問了血量:
如果你附加進程CE崩潰了,只需設置一下使用VEH調試器即可:
現在我們知道血量的偏移是E4,那么玩家地址就是-E4,但是先不急,我們要找基址。待會再用這個E4。
2-3 生成 pointermap
找到血量后,右鍵生成pointermap:
生成pointermap1后,指針掃描:
選擇 use pointer map,使用剛才生成的pointermap1:
指定一下最后一個偏移 E4
選擇PTR文件保存路徑后,開始掃描
第一次掃描結束,重啟游戲,CE不關。
第二次啟動游戲,用二分法找到血量。
生成pointermap :
第二次指針掃描,有幾個地方要設置,首先要使用剛才生成的pointermap2,然后勾選compare result,與上次游戲的pointermap1對比,設置地址為上次游戲的血量地址,然后開始掃描:
得到了18000個結果,第一次是16萬個:
再來一次,重啟游戲,找到血量:
生成pointermap3:
指針掃描,使用pointermap3,和前兩個pointermap對比:
開始掃描:
得到了13000個結果:
似乎再重復也沒什么大變化了,找幾個偏移少的試試:
只要找到一個可以用的就行了,結果越少越準確。
總結
以上是生活随笔為你收集整理的CS起源pointermap找基址+工具函数测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bat脚本+vs2019编译openss
- 下一篇: 使用 rsync / scp 命令下载l