fix 31-4302

This commit is contained in:
RiceCake
2024-08-03 10:39:25 +08:00
committed by GitHub
parent 849d75cbd1
commit 8c036c5a0a

View File

@@ -29,13 +29,13 @@ const std::vector<DWORD> PrioityClass = {
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, 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,
@@ -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
@@ -89,10 +91,11 @@ const BYTE _shellcode_genshin_Const[] =
0xEB, 0xF1, //jmp set
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
@@ -105,26 +108,27 @@ const BYTE _shellcode_genshin_Const[] =
//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,
'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
};
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 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<HMODULE> 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;
}
// ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ID
// 通过进程名搜索进程ID
DWORD GetPID(std::string ProcessName)
{
DWORD pid = 0;
@@ -292,43 +264,6 @@ 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"))//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷhook<6F><6B>λ//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"))//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷhook<6F><6B>λ//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);
@@ -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("<EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n<EFBFBD>벻Ҫ<EFBFBD>رմ˽<EFBFBD><EFBFBD><EFBFBD> - Ȼ<><C8BB><EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ\n<EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD> - <20><><EFBFBD>ڻ<EFBFBD>ȡ<EFBFBD><C8A1>Ϸ·<CFB7><C2B7>\n");
printf("\n<EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>...\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));
// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD>̾<EFBFBD><EFBFBD><EFBFBD> - <20><>Ȩ<EFBFBD>޺ܵ͵<DCB5><CDB5><EFBFBD> - <20><>Ӧ<EFBFBD>û<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
// 获取进程句柄 - 这权限很低的了 - 不应该获取不了
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("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ·<EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><EFBFBD><EFBFBD> - <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n");
printf("配置里的游戏路经改变了 - 开始重新配置\n");
DeleteFileA("config.ini");
LoadConfig();
}
}
// <EFBFBD>ȼ<EFBFBD><EFBFBD>߳<EFBFBD>
// 热键线程
DWORD __stdcall Thread1(LPVOID p)
{
if (!p)
@@ -513,7 +436,7 @@ int main(int argc, char** argv)
CommandLine += argv[i] + std::string(" ");
}
// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 读取配置
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<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>õĻ<C3B5><C4BB><EFBFBD><EFBFBD><EFBFBD>star<61><72>\n");
printf("https://github.com/xiaonian233/genshin-fps-unlock \n4.7<EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD>лwinTEuser<EFBFBD>ϸ<EFBFBD>֧<EFBFBD><EFBFBD> \n");
printf("<EFBFBD><EFBFBD>Ϸ·<EFBFBD><EFBFBD>: %s\n\n", ProcessPath.c_str());
printf("FPS解锁 好用的话点个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("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>\n");
printf("<EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ<EFBFBD><EFBFBD><EFBFBD>ʧЧ<EFBFBD><EFBFBD>\n");
printf("<EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD>Ϸ - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϸ\n");
printf("检测到游戏已在运行!\n");
printf("手动启动游戏会导致失效的\n");
printf("请手动关闭游戏 - 解锁器会自动启动游戏\n");
return 0;
}
@@ -551,13 +474,13 @@ int main(int argc, char** argv)
Sleep(200);
StartPriority = PrioityClass[1];
SetPriorityClass(pi.hProcess, StartPriority);
// <EFBFBD>ȴ<EFBFBD>UnityPlayer.dll<EFBFBD><EFBFBD><EFBFBD>غͻ<EFBFBD>ȡDLL<EFBFBD><EFBFBD>Ϣ
// 等待UnityPlayer.dll加载和获取DLL信息
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;//<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD>ڶβ<EFBFBD><EFBFBD><EFBFBD>
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:
// <EFBFBD>ڱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD>С<EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 在本进程内申请代码段大小的内存 - 用于特征搜索
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;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 把整个模块读出来
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;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ե<EFBFBD>ַ (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("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ctrl + <EFBFBD><EFBFBD>ͷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:\n");
printf(" <EFBFBD><EFBFBD>ctrl + <EFBFBD><EFBFBD>: +20\n");
printf(" <EFBFBD><EFBFBD>ctrl + <EFBFBD><EFBFBD>: -20\n");
printf(" <EFBFBD><EFBFBD>ctrl + <EFBFBD><EFBFBD>: -2\n");
printf(" <EFBFBD><EFBFBD>ctrl + <EFBFBD><EFBFBD>: +2\n\n");
printf("用右ctrl + 箭头键更改限制:\n");
printf(" ctrl + : +20\n");
printf(" ctrl + : -20\n");
printf(" ctrl + : -2\n");
printf(" ctrl + : +2\n\n");
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><EFBFBD>߳<EFBFBD>
// 创建热键线程
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);
// ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>
// 每两秒检查一次
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);
}
}