diff --git a/unlockfps/main.cpp b/unlockfps/main.cpp index ac70773..fbad9d9 100644 --- a/unlockfps/main.cpp +++ b/unlockfps/main.cpp @@ -28,20 +28,20 @@ const std::vector PrioityClass = { //credit by winTEuser const BYTE _shellcode_genshin_Const[] = { - 0x00, 0x00, 0x00, 0x00, //uint32_t unlocker_pid _shellcode_genshin[0] - 0x00, 0x00, 0x00, 0x00, //FREE _shellcode_genshin[4] - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //DWORD64 unlocker_FpsValue_addr _shellcode_genshin[8] - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //DWORD64 API_OpenProcess _shellcode_genshin[16] - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //DWORD64 API_ReadProcessmem _shellcode_genshin[24] - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //DWORD64 API_Sleep _shellcode_genshin[32] - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //DWORD64 API_MessageBoxA _shellcode_genshin[40] - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //DWORD64 API_CloseHandle _shellcode_genshin[48] - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //FREE _shellcode_genshin[56] + 0x00, 0x00, 0x00, 0x00, //uint32_t unlocker_pid _shellcode_genshin[0] + 0x00, 0xC0, 0x9C, 0x66, //uint32_t shellcode_timestamp _shellcode_genshin[4] //2024-07-21 16:00:00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //uint64_t unlocker_FpsValue_addr _shellcode_genshin[8] + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //uint64_t API_OpenProcess _shellcode_genshin[16] + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //uint64_t API_ReadProcessmem _shellcode_genshin[24] + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //uint64_t API_Sleep _shellcode_genshin[32] + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //uint64_t API_MessageBoxA _shellcode_genshin[40] + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //uint64_t API_CloseHandle _shellcode_genshin[48] + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //FREE _shellcode_genshin[56] //int3 - 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, - 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, //int3 - 0x48, 0x83, 0xEC, 0x38, //sub rsp,0x38 _shellcode_genshin[80] _sync_thread + 0x48, 0x83, 0xEC, 0x38, //sub rsp,0x38 _shellcode_genshin[80] _sync_thread 0x8B, 0x05, 0xA6, 0xFF, 0xFF, 0xFF, //mov eax,dword[unlocker_pid] 0x85, 0xC0, //test eax, eax 0x74, 0x5C, //jz return @@ -56,7 +56,7 @@ const BYTE _shellcode_genshin_Const[] = 0x0F, 0x1F, 0x44, 0x00, 0x00, //nop 0x89, 0xF1, //mov ecx, esi //Read_tar_fps 0x48, 0x89, 0xFA, //mov rdx, rdi - 0x4C, 0x8D, 0x05, 0xF8, 0x00, 0x00, 0x00,//lea r8, qword:[Readmem_buffer] + 0x4C, 0x8D, 0x05, 0x08, 0x01, 0x00, 0x00,//lea r8, qword:[Readmem_buffer] 0x41, 0xB9, 0x04, 0x00, 0x00, 0x00, //mov r9d, 4 0x31, 0xC0, //xor eax, eax 0x48, 0x89, 0x44, 0x24, 0x20, //mov qword ptr ss:[rsp+20],rax @@ -65,21 +65,23 @@ const BYTE _shellcode_genshin_Const[] = 0x74, 0x12, //jz Show msg and closehandle 0xB9, 0xF4, 0x01, 0x00, 0x00, //mov ecx,0x1F4 (500ms) 0xFF, 0x15, 0x72, 0xFF, 0xFF, 0xFF, //call [API_Sleep] - 0xE8, 0x4D, 0x00, 0x00, 0x00, //call Sync_auto + 0xE8, 0x5D, 0x00, 0x00, 0x00, //call Sync_auto 0xEB, 0xCB, //jmp Read_tar_fps - 0xE8, 0x66, 0x00, 0x00, 0x00, //call Show Errormsg and CloseHandle + 0xE8, 0x76, 0x00, 0x00, 0x00, //call Show Errormsg and CloseHandle 0x48, 0x83, 0xC4, 0x38, //add rsp,0x38 0xC3, //return - 0xCC, //int3 - 0x89, 0x0D, 0xBA, 0x00, 0x00, 0x00, //mov [Game_Current_set], ecx //hook_fps_set _shellcode_genshin[192] + 0xCC, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, + //int3 + 0x89, 0x0D, 0xBA, 0x00, 0x00, 0x00, //mov [Game_Current_set], ecx //hook_fps_set _shellcode_genshin[0xD0] 0x31, 0xC0, //xor eax, eax 0x83, 0xF9, 0x1E, //cmp ecx, 0x1E 0x74, 0x0E, //je set 60 0x83, 0xF9, 0x2D, //cmp ecx, 0x2D 0x74, 0x15, //je Sync_buffer - 0x90, //nop - 0xB9, 0xE8, 0x03, 0x00, 0x00, //mov ecx, 0x3E8 + 0x2E, 0xB9, 0xE8, 0x03, 0x00, 0x00, //mov ecx, 0x3E8 0xEB, 0x06, //jmp set 0xCC, //int3 0xB9, 0x3C, 0x00, 0x00, 0x00, //mov ecx, 0x3C @@ -87,12 +89,13 @@ const BYTE _shellcode_genshin_Const[] = 0xC3, //ret 0x8B, 0x0D, 0x97, 0x00, 0x00, 0x00, //mov ecx, dword[Readmem_buffer] //Sync_buffer 0xEB, 0xF1, //jmp set - 0xCC, + 0xCC, //int3 - 0xB8, 0x78, 0x00, 0x00, 0x00, //mov eax,0x78 //hook_fps_get _shellcode_genshin[240] + 0xB8, 0x78, 0x00, 0x00, 0x00, //mov eax,0x78 //hook_fps_get _shellcode_genshin[0xF0] 0xC3, //ret //int3 - 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, + 0xCC, 0xCC, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, //int3 0x8B, 0x05, 0x7A, 0x00, 0x00, 0x00, //mov eax, dword[Game_Current_set] //Sync_auto 0x83, 0xF8, 0x2D, //cmp eax, 0x2D @@ -101,30 +104,31 @@ const BYTE _shellcode_genshin_Const[] = 0x89, 0x05, 0xDA, 0xFF, 0xFF, 0xFF, //mov dword[hook_fps_get + 1], eax 0xC3, //ret //int3 - 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, //int3 0x48, 0x83, 0xEC, 0x28, //sub rsp, 0x28 //Show Errormsg and closehandle 0x31, 0xC9, //xor ecx, ecx - 0x48, 0x8D, 0x15, 0x23, 0x00, 0x00, 0x00,//lea rdx, qword:["Sync failed!"] - 0x4C, 0x8D, 0x05, 0x2C, 0x00, 0x00, 0x00,//lea r8, qword:["Error"] + 0x48, 0x8D, 0x15, 0x33, 0x00, 0x00, 0x00,//lea rdx, qword:["Sync failed!"] + 0x4C, 0x8D, 0x05, 0x3C, 0x00, 0x00, 0x00,//lea r8, qword:["Error"] 0x41, 0xB9, 0x10, 0x00, 0x00, 0x00, //mov r9d, 0x10 - 0xFF, 0x15, 0xE8, 0xFE, 0xFF, 0xFF, //call [API_MessageBoxA] + 0xFF, 0x15, 0xD8, 0xFE, 0xFF, 0xFF, //call [API_MessageBoxA] 0x89, 0xF1, //mov ecx, esi - 0xFF, 0x15, 0xE8, 0xFE, 0xFF, 0xFF, //call [API_CloseHandle] + 0xFF, 0x15, 0xD8, 0xFE, 0xFF, 0xFF, //call [API_CloseHandle] 0x48, 0x83, 0xC4, 0x28, //add rsp, 0x28 0xC3, //ret //int3 - 0xCC, 0xCC, 0xCC, + 0xCC, 0xCC, 0xCC, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 'S','y','n','c',' ','f','a','i','l','e','d','!', 0x00, 0x00, 0x00, 0x00, 'E','r','r','o','r', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00, //uint32_t Game_Current_set 0x00, 0x00, 0x00, 0x00, //uint32_t Readmem_buffer 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -// 特征搜索 winTEuser +// 鐗瑰緛鎼滅储 winTEuser static uintptr_t PatternScan_Region(uintptr_t startAddress, size_t regionSize, const char* signature) { auto pattern_to_byte = [](const char* pattern) @@ -176,38 +180,6 @@ std::string GetLastErrorAsString(DWORD code) return ret; } -bool GetModule2(HANDLE GameHandle, std::string ModuleName, PMODULEENTRY32 pEntry) -{ - if (!pEntry) - return false; - - std::vector modules(1024); - ZeroMemory(modules.data(), modules.size() * sizeof(HMODULE)); - DWORD cbNeeded = 0; - - if (!EnumProcessModules(GameHandle, modules.data(), modules.size() * sizeof(HMODULE), &cbNeeded)) - return false; - - modules.resize(cbNeeded / sizeof(HMODULE)); - for (auto& it : modules) - { - char szModuleName[MAX_PATH]{}; - if (!GetModuleBaseNameA(GameHandle, it, szModuleName, MAX_PATH)) - continue; - if (ModuleName != szModuleName) - continue; - MODULEINFO modInfo{}; - if (!GetModuleInformation(GameHandle, it, &modInfo, sizeof(MODULEINFO))) - continue; - - pEntry->modBaseAddr = (BYTE*)modInfo.lpBaseOfDll; - pEntry->modBaseSize = modInfo.SizeOfImage; - return true; - } - - - return false; -} static bool GetModule(DWORD pid, std::string ModuleName, PMODULEENTRY32 pEntry) { if (!pEntry) @@ -238,7 +210,7 @@ static bool GetModule(DWORD pid, std::string ModuleName, PMODULEENTRY32 pEntry) CloseHandle(snap); return 0; } -// 通过进程名搜索进程ID +// 閫氳繃杩涚▼鍚嶆悳绱㈣繘绋婭D DWORD GetPID(std::string ProcessName) { DWORD pid = 0; @@ -292,44 +264,7 @@ static DWORD64 inject_patch(LPVOID text_buffer, DWORD text_size, DWORD64 _text_b DWORD64 Hook_addr_tar_fpsSet = 0; DWORD64 _addr_tar_fpsget_TarFun = 0; DWORD64 _addr_tar_fpsSet_TarFun = 0; - while (address = PatternScan_Region(Module_TarSec_RVA, text_size, "CC 8B 05 ?? ?? ?? ?? C3 CC"))//搜索正确hook点位//get_fps - { - uintptr_t rip = address; - rip += 3; - rip += *(int32_t*)(rip)+4; - if ((rip - (uintptr_t)Module_TarSec_RVA + (uintptr_t)_text_baseaddr) == _ptr_fps) - { - Hook_addr_fpsget = address + 1; - Hook_addr_tar_fpsget = Hook_addr_fpsget - (uintptr_t)Module_TarSec_RVA + (uintptr_t)_text_baseaddr; - goto __Get_fpsGet_addr; - } - else - { - *(uint64_t*)(address + 1) = 0xCCCCCCCCCCCCCCCC; - } - } - printf_s("Get get_fps pattern Fail! \n"); - return 0; - -__Get_fpsGet_addr: - while (address = PatternScan_Region(Module_TarSec_RVA, text_size, "CC 89 0D ?? ?? ?? ?? C3 CC"))//搜索正确hook点位//set_fps - { - uintptr_t rip = address; - rip += 3; - rip += *(int32_t*)(rip)+4; - if ((rip - (uintptr_t)Module_TarSec_RVA + (uintptr_t)_text_baseaddr) == _ptr_fps) - { - Hook_addr_fpsSet = address + 1; - Hook_addr_tar_fpsSet = Hook_addr_fpsSet - (uintptr_t)Module_TarSec_RVA + (uintptr_t)_text_baseaddr; - goto __Get_fpsSet_addr; - } - else - { - *(uint64_t*)(address + 1) = 0xCCCCCCCCCCCCCCCC; - } - } - printf_s("Get set_fps pattern Fail! \n"); - + __Get_fpsSet_addr: uint64_t _shellcode_buffer = (uint64_t)VirtualAlloc(0, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (_shellcode_buffer == 0) @@ -351,34 +286,22 @@ __Get_fpsSet_addr: *(uint64_t*)(_shellcode_buffer + 32) = _Addr_Sleep; *(uint64_t*)(_shellcode_buffer + 40) = _Addr_MessageBoxA; *(uint64_t*)(_shellcode_buffer + 48) = _Addr_CloseHandle; - *(uint32_t*)(_shellcode_buffer + 0xD4) = 1000; - *(uint32_t*)(_shellcode_buffer + 0xDC) = 60; + *(uint32_t*)(_shellcode_buffer + 0xE4) = 1000; + *(uint32_t*)(_shellcode_buffer + 0xEC) = 60; + + *(uint64_t*)(_shellcode_buffer + 0x110) = 0xB848; //mov rax, game_pfps + *(uint64_t*)(_shellcode_buffer + 0x118) = 0x741D8B0000; //mov ebx, dword[Readmem_buffer] + *(uint64_t*)(_shellcode_buffer + 0x120) = 0xCCCCCCCCCCC31889; //mov [rax], ebx + *(uint64_t*)(_shellcode_buffer + 0x112) = _ptr_fps; //ret + *(uint64_t*)(_shellcode_buffer + 0x15C) = 0x5C76617E8834858; //keep thread + *(uint64_t*)(_shellcode_buffer + 0x164) = 0xE0FF21EBFFFFFF16; + LPVOID __Tar_proc_buffer = VirtualAllocEx(Tar_handle, 0, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (__Tar_proc_buffer) { if (WriteProcessMemory(Tar_handle, __Tar_proc_buffer, (void*)_shellcode_buffer, sizeof(_shellcode_genshin_Const), 0)) { VirtualFree((void*)_shellcode_buffer, 0, MEM_RELEASE); - _addr_tar_fpsSet_TarFun = (uint64_t)__Tar_proc_buffer + 0xC0; - _addr_tar_fpsget_TarFun = (uint64_t)__Tar_proc_buffer + 0xF0; - *(uint64_t*)Hook_addr_fpsget = 0xB848; //hook mov rax,[jmp addr] - *(uint64_t*)(Hook_addr_fpsget + 2) = _addr_tar_fpsget_TarFun; - *(uint16_t*)(Hook_addr_fpsget + 10) = 0xE0FF; // jmp rax - *(uint64_t*)Hook_addr_fpsSet = 0xB848; - *(uint64_t*)(Hook_addr_fpsSet + 2) = _addr_tar_fpsSet_TarFun; - *(uint16_t*)(Hook_addr_fpsSet + 10) = 0xE0FF; - if (WriteProcessMemory(Tar_handle, (LPVOID)Hook_addr_tar_fpsget, (LPVOID)Hook_addr_fpsget, 0x10, 0) == 0) - { - DWORD ERR_code = GetLastError(); - printf_s("\nHook Get_fps Fail! ( 0x%X ) - %s\n", ERR_code, GetLastErrorAsString(ERR_code).c_str()); - return 0; - } - if (WriteProcessMemory(Tar_handle, (LPVOID)Hook_addr_tar_fpsSet, (LPVOID)Hook_addr_fpsSet, 0x10, 0) == 0) - { - DWORD ERR_code = GetLastError(); - printf_s("\nHook Set_fps Fail! ( 0x%X ) - %s\n", ERR_code, GetLastErrorAsString(ERR_code).c_str()); - return 0; - } HANDLE temp = CreateRemoteThread(Tar_handle, 0, 0, (LPTHREAD_START_ROUTINE)((uint64_t)__Tar_proc_buffer + 0x50), 0, 0, 0); if (temp) { @@ -389,7 +312,7 @@ __Get_fpsSet_addr: printf_s("Create InGame SyncThread Fail! "); return 0; } - return ((uint64_t)__Tar_proc_buffer + 0xF1); + return ((uint64_t)__Tar_proc_buffer + 0x194); } printf_s("Inject shellcode Fail! "); VirtualFree((void*)_shellcode_buffer, 0, MEM_RELEASE); @@ -410,14 +333,14 @@ void LoadConfig() INIReader reader("fps_config.ini"); if (reader.ParseError() != 0) { - printf("配置不存在\n请不要关闭此进程 - 然后手动开启游戏\n这只需要进行一次 - 用于获取游戏路经\n"); - printf("\n等待游戏启动...\n"); + printf("閰嶇疆涓嶅瓨鍦╘n璇蜂笉瑕佸叧闂杩涚▼ - 鐒跺悗鎵嬪姩寮鍚父鎴廫n杩欏彧闇瑕佽繘琛屼竴娆 - 鐢ㄤ簬鑾峰彇娓告垙璺粡\n"); + printf("\n绛夊緟娓告垙鍚姩...\n"); DWORD pid = 0; while (!(pid = GetPID("YuanShen.exe")) && !(pid = GetPID("GenshinImpact.exe"))) std::this_thread::sleep_for(std::chrono::milliseconds(200)); - // 获取进程句柄 - 这权限很低的了 - 不应该获取不了 + // 鑾峰彇杩涚▼鍙ユ焺 - 杩欐潈闄愬緢浣庣殑浜 - 涓嶅簲璇ヨ幏鍙栦笉浜 HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE | PROCESS_TERMINATE, FALSE, pid); if (!hProcess) { @@ -458,13 +381,13 @@ void LoadConfig() if (GetFileAttributesA(GamePath.c_str()) == INVALID_FILE_ATTRIBUTES) { - printf("配置里的游戏路经改变了 - 开始重新配置\n"); + printf("閰嶇疆閲岀殑娓告垙璺粡鏀瑰彉浜 - 寮濮嬮噸鏂伴厤缃甛n"); DeleteFileA("config.ini"); LoadConfig(); } } -// 热键线程 +// 鐑敭绾跨▼ DWORD __stdcall Thread1(LPVOID p) { if (!p) @@ -513,7 +436,7 @@ int main(int argc, char** argv) CommandLine += argv[i] + std::string(" "); } - // 读取配置 + // 璇诲彇閰嶇疆 LoadConfig(); int TargetFPS = FpsValue; std::string ProcessPath = GamePath; @@ -522,18 +445,18 @@ int main(int argc, char** argv) if (ProcessPath.length() < 8) return 0; - printf("FPS解锁 好用的话点个star吧\n"); - printf("https://github.com/xiaonian233/genshin-fps-unlock \n4.7版本特别感谢winTEuser老哥支持 \n"); - printf("游戏路经: %s\n\n", ProcessPath.c_str()); + printf("FPS瑙i攣 濂界敤鐨勮瘽鐐逛釜star鍚 4.8\n"); + printf("https://github.com/xiaonian233/genshin-fps-unlock \n鐗瑰埆鎰熻阿winTEuser鑰佸摜 \n"); + printf("娓告垙璺粡: %s\n\n", ProcessPath.c_str()); ProcessDir = ProcessPath.substr(0, ProcessPath.find_last_of("\\")); std::string procname = ProcessPath.substr(ProcessPath.find_last_of("\\") + 1); DWORD pid = GetPID(procname); if (pid) { - printf("检测到游戏已在运行!\n"); - printf("手动启动游戏会导致失效的\n"); - printf("请手动关闭游戏 - 解锁器会自动启动游戏\n"); + printf("妫娴嬪埌娓告垙宸插湪杩愯锛乗n"); + printf("鎵嬪姩鍚姩娓告垙浼氬鑷村け鏁堢殑\n"); + printf("璇锋墜鍔ㄥ叧闂父鎴 - 瑙i攣鍣ㄤ細鑷姩鍚姩娓告垙\n"); return 0; } @@ -551,13 +474,13 @@ int main(int argc, char** argv) Sleep(200); StartPriority = PrioityClass[1]; SetPriorityClass(pi.hProcess, StartPriority); - // 等待UnityPlayer.dll加载和获取DLL信息 + // 绛夊緟UnityPlayer.dll鍔犺浇鍜岃幏鍙朌LL淇℃伅 MODULEENTRY32 hUnityPlayer{}; { DWORD times = 1000; while (times != 0) { - if (GetModule2(pi.hProcess, procname, &hUnityPlayer)) + if (GetModule(pi.dwProcessId, procname, &hUnityPlayer)) { goto __get_procbase_ok; } @@ -570,11 +493,11 @@ int main(int argc, char** argv) } { DWORD times = 1000; - while (!GetModule2(pi.hProcess, "UnityPlayer.dll", &hUnityPlayer)) + while (!GetModule(pi.dwProcessId, "UnityPlayer.dll", &hUnityPlayer)) { Sleep(50); times -= 5; - if (GetModule2(pi.hProcess, "unityplayer.dll", &hUnityPlayer)) + if (GetModule(pi.dwProcessId, "unityplayer.dll", &hUnityPlayer)) { goto __get_procbase_ok; } @@ -587,7 +510,7 @@ int main(int argc, char** argv) } } printf("UnityPlayer: %X%X\n", (uintptr_t)hUnityPlayer.modBaseAddr >> 32 & -1, hUnityPlayer.modBaseAddr); - __get_procbase_ok: +__get_procbase_ok: LPVOID _mbase_PE_buffer = VirtualAlloc(NULL, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (_mbase_PE_buffer == 0) { @@ -614,7 +537,7 @@ int main(int argc, char** argv) uint32_t Text_Vsize; if (_FilePE_Nt_header.Signature == 0x00004550) { - DWORD sec_num = _FilePE_Nt_header.FileHeader.NumberOfSections;//获得指定节段参数 + DWORD sec_num = _FilePE_Nt_header.FileHeader.NumberOfSections;//鑾峰緱鎸囧畾鑺傛鍙傛暟 DWORD num = sec_num; DWORD target_sec_VA_start = 0; while (num) @@ -641,7 +564,7 @@ int main(int argc, char** argv) return (int)-1; } __Get_target_sec: - // 在本进程内申请代码段大小的内存 - 用于特征搜索 + // 鍦ㄦ湰杩涚▼鍐呯敵璇蜂唬鐮佹澶у皬鐨勫唴瀛 - 鐢ㄤ簬鐗瑰緛鎼滅储 LPVOID Copy_Text_VA = VirtualAlloc(0, Text_Vsize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (Copy_Text_VA == NULL) { @@ -649,7 +572,7 @@ __Get_target_sec: CloseHandle(pi.hProcess); return (int)-1; } - // 把整个模块读出来 + // 鎶婃暣涓ā鍧楄鍑烘潵 if (ReadProcessMemory(pi.hProcess, (void*)Text_Remote_RVA, Copy_Text_VA, Text_Vsize, 0) == 0) { printf("Readmem Fail ! (text)"); @@ -668,7 +591,7 @@ __Get_target_sec: return 0; } - // 计算相对地址 (FPS) + // 璁$畻鐩稿鍦板潃 (FPS) uintptr_t pfps = 0; { uintptr_t rip = address; @@ -677,7 +600,9 @@ __Get_target_sec: rip += *(int32_t*)(rip)+4; pfps = rip - (uintptr_t)Copy_Text_VA + Text_Remote_RVA; printf("FPS Offset: %X\n", pfps); + goto __offset_ok; } +__offset_ok: uintptr_t Patch_ptr = 0; { Patch_ptr = inject_patch(Copy_Text_VA, Text_Vsize, Text_Remote_RVA, pfps, pi.hProcess);//patch inject @@ -690,30 +615,36 @@ __Get_target_sec: VirtualFree(_mbase_PE_buffer, 0, MEM_RELEASE); VirtualFree(Copy_Text_VA, 0, MEM_RELEASE); printf("Done\n\n"); - printf("用右ctrl + 箭头键更改限制:\n"); - printf(" 右ctrl + 上: +20\n"); - printf(" 右ctrl + 下: -20\n"); - printf(" 右ctrl + 左: -2\n"); - printf(" 右ctrl + 右: +2\n\n"); + printf("鐢ㄥ彸ctrl + 绠ご閿洿鏀归檺鍒:\n"); + printf(" 鍙砪trl + 涓: +20\n"); + printf(" 鍙砪trl + 涓: -20\n"); + printf(" 鍙砪trl + 宸: -2\n"); + printf(" 鍙砪trl + 鍙: +2\n\n"); - // 创建热键线程 + // 鍒涘缓鐑敭绾跨▼ HANDLE hThread = CreateThread(nullptr, 0, Thread1, &TargetFPS, 0, nullptr); if (hThread) CloseHandle(hThread); DWORD dwExitCode = STILL_ACTIVE; + uint32_t fps = 0; while (dwExitCode == STILL_ACTIVE) { GetExitCodeProcess(pi.hProcess, &dwExitCode); - // 每两秒检查一次 + // 姣忎袱绉掓鏌ヤ竴娆 std::this_thread::sleep_for(std::chrono::seconds(2)); int fps = 0; ReadProcessMemory(pi.hProcess, (LPVOID)pfps, &fps, sizeof(fps), nullptr); if (fps == -1) continue; if (fps != TargetFPS) + { WriteProcessMemory(pi.hProcess, (LPVOID)pfps, &TargetFPS, sizeof(TargetFPS), nullptr); + //鐑慨琛ュ惊鐜 + WriteProcessMemory(pi.hProcess, (LPVOID)Patch_ptr, &TargetFPS, 4, nullptr); + } + }