Kisy
- 注册会员
- 26
- 0
- 31
- 0
- 260 元
- 2014-08-12
|
1#
t
T
发表于 2021-10-07 20:26
|只看楼主
最近找了一下PPSSPP 的基址,发现在日志里就提到了找到源码 https://github.com/hrydgard/ppss ... emMap.cpp#L281-L304- bool Init() {
- // On some 32 bit platforms (like Android, iOS, etc.), you can only map < 32 megs at a time.
- const static int MAX_MMAP_SIZE = 31 * 1024 * 1024;
- _dbg_assert_msg_(g_MemorySize <= MAX_MMAP_SIZE * 3, "ACK - too much memory for three mmap views.");
- for (size_t i = 0; i < ARRAY_SIZE(views); i++) {
- if (views[i].flags & MV_IS_PRIMARY_RAM)
- views[i].size = std::min((int)g_MemorySize, MAX_MMAP_SIZE);
- if (views[i].flags & MV_IS_EXTRA1_RAM)
- views[i].size = std::min(std::max((int)g_MemorySize - MAX_MMAP_SIZE, 0), MAX_MMAP_SIZE);
- if (views[i].flags & MV_IS_EXTRA2_RAM)
- views[i].size = std::min(std::max((int)g_MemorySize - MAX_MMAP_SIZE * 2, 0), MAX_MMAP_SIZE);
- }
- int flags = 0;
- if (!MemoryMap_Setup(flags)) {
- return false;
- }
- INFO_LOG(MEMMAP, "Memory system initialized. Base at %p (RAM at @ %p, uncached @ %p)",
- base, m_pPhysicalRAM, m_pUncachedRAM);
- MemFault_Init();
- return true;
- }
复制代码 这里的 base 就是申请到的内存地址,而且是全局变量,所以找这个就可以了,在 MemoryMap_Setup 里赋值 我本来是想在内存申请的函数里注入获取的,比如这里:- 申请内存的函数
- PPSSPPWindows64.exe+8866B0 - 40 53 - push rbx
- PPSSPPWindows64.exe+8866B2 - 48 83 EC 20 - sub rsp,20 { 32 }
- PPSSPPWindows64.exe+8866B6 - 33 C9 - xor ecx,ecx
- PPSSPPWindows64.exe+8866B8 - BA 000000E1 - mov edx,E1000000 { -520093696 }
- PPSSPPWindows64.exe+8866BD - 41 B8 00200000 - mov r8d,00002000 { 8192 }
- PPSSPPWindows64.exe+8866C3 - 44 8D 49 04 - lea r9d,[rcx+04]
- PPSSPPWindows64.exe+8866C7 - FF 15 9B801F00 - call qword ptr [PPSSPPWindows64.exe+A7E768] { ->KERNEL32.VirtualAlloc }
- PPSSPPWindows64.exe+8866CD - 48 8B D8 - mov rbx,rax
- PPSSPPWindows64.exe+8866D0 - 48 85 C0 - test rax,rax
- PPSSPPWindows64.exe+8866D3 - 74 14 - je PPSSPPWindows64.exe+8866E9
- PPSSPPWindows64.exe+8866D5 - 33 D2 - xor edx,edx
- PPSSPPWindows64.exe+8866D7 - 41 B8 00800000 - mov r8d,00008000 { 32768 }
- PPSSPPWindows64.exe+8866DD - 48 8B C8 - mov rcx,rax
- PPSSPPWindows64.exe+8866E0 - FF 15 5A801F00 - call qword ptr [PPSSPPWindows64.exe+A7E740] { ->KERNEL32.VirtualFree }
- PPSSPPWindows64.exe+8866E6 - 48 8B C3 - mov rax,rbx
- PPSSPPWindows64.exe+8866E9 - 48 83 C4 20 - add rsp,20 { 32 }
- PPSSPPWindows64.exe+8866ED - 5B - pop rbx
- PPSSPPWindows64.exe+8866EE - C3 - ret
复制代码 只要在 call qword ptr [PPSSPPWindows64.exe+A7E768] { ->KERNEL32.VirtualAlloc } 后获取 rax 的值就行,可以注入,但是有个问题,就是这里只有在加载游戏时才会执行,所以不是随时都能获取到数据
所以就得找把申请到的内存地址赋值的地方,比如这里- PPSSPPWindows64.exe+2AC3DF - 32 C0 - xor al,al
- PPSSPPWindows64.exe+2AC3E1 - 48 8B 5C 24 50 - mov rbx,[rsp+50]
- PPSSPPWindows64.exe+2AC3E6 - 48 8B 74 24 58 - mov rsi,[rsp+58]
- PPSSPPWindows64.exe+2AC3EB - 48 83 C4 40 - add rsp,40 { 64 }
- PPSSPPWindows64.exe+2AC3EF - 5F - pop rdi
- PPSSPPWindows64.exe+2AC3F0 - C3 - ret
- PPSSPPWindows64.exe+2AC3F1 - 48 8D 0D A881B300 - lea rcx,[PPSSPPWindows64.exe+DE45A0] { (2708) }
- PPSSPPWindows64.exe+2AC3F8 - E8 B3A25D00 - call PPSSPPWindows64.exe+8866B0 { 这里就是 call 上面的内存申请函数 }
- PPSSPPWindows64.exe+2AC3FD - 33 C9 - xor ecx,ecx
- PPSSPPWindows64.exe+2AC3FF - 48 89 05 8282B300 - mov [PPSSPPWindows64.exe+DE4688],rax { 把申请到的内存地址赋值给全局变量, 这个地址可以当作基址 }
- PPSSPPWindows64.exe+2AC406 - E8 75000000 - call PPSSPPWindows64.exe+2AC480
- PPSSPPWindows64.exe+2AC40B - 84 C0 - test al,al
- PPSSPPWindows64.exe+2AC40D - 74 D0 - je PPSSPPWindows64.exe+2AC3DF
复制代码 我这里写成了 lua 的脚本,可以 ctrl+alt+L 写在 lua 脚本框里,这样打开 CT 表,就自动设置 CE 的查找起始地址和结束地址了 也是参考的银行漫步大佬的脚本,在这里感谢一下- local result = AOBScanModuleUnique(process, "E8xxxxxxxx33C948xxxxxxxxxxxxE8xxxxxxxx84xx74xx")
- if result == nil then
- return
- end
- result = result + 7
- -- print(getNameFromAddress(result, true, false))
- local _, opcode, bytes = splitDisassembledString(disassemble(result))
- local pos_s, pos_e = string.find(opcode, "%[.*%]")
- if pos_s == nil then
- return
- end
- local offset = tonumber('0x'..string.sub(opcode, pos_s+1,pos_e-1))
- local BaseAddress = readPointer(offset) + 0x8800000
- registerSymbol("BaseAddress", BaseAddress,true)
- MainForm.FromAddress.Text = string.format("%X",BaseAddress)
- MainForm.ToAddress.Text = string.format("%X",BaseAddress+0x1800000)
- print(string.format("base address: %X",BaseAddress))
复制代码 这个脚本其实就是在找 mov [PPSSPPWindows64.exe+DE4688],rax 这条语句方括号里的地址,然后取出来,再加上 0x8800000,这样才是真正的数据地址 这里也注册了BaseAddress 全局变量,可以在其他地方使用
这个适用 PPSSPP 64 位版本,我试了一下,最近几个版本都是可以的,一般来说内存部分的代码不改就没问题,希望能用的长久一些吧,但是 32 位下的PPSSPP代码是跟这个完全不一样的,需要重新查找。
|