CheatMaker 论坛

注册

 

发新话题 回复该主题

PPSSPP Cheat Engine 获取基址 [复制链接]

1#



最近找了一下PPSSPP 的基址,发现在日志里就提到了
找到源码 https://github.com/hrydgard/ppss ... emMap.cpp#L281-L304
  1. bool Init() {
  2.         // On some 32 bit platforms (like Android, iOS, etc.), you can only map < 32 megs at a time.
  3.         const static int MAX_MMAP_SIZE = 31 * 1024 * 1024;
  4.         _dbg_assert_msg_(g_MemorySize <= MAX_MMAP_SIZE * 3, "ACK - too much memory for three mmap views.");
  5.         for (size_t i = 0; i < ARRAY_SIZE(views); i++) {
  6.                 if (views[i].flags & MV_IS_PRIMARY_RAM)
  7.                         views[i].size = std::min((int)g_MemorySize, MAX_MMAP_SIZE);
  8.                 if (views[i].flags & MV_IS_EXTRA1_RAM)
  9.                         views[i].size = std::min(std::max((int)g_MemorySize - MAX_MMAP_SIZE, 0), MAX_MMAP_SIZE);
  10.                 if (views[i].flags & MV_IS_EXTRA2_RAM)
  11.                         views[i].size = std::min(std::max((int)g_MemorySize - MAX_MMAP_SIZE * 2, 0), MAX_MMAP_SIZE);
  12.         }

  13.         int flags = 0;
  14.         if (!MemoryMap_Setup(flags)) {
  15.                 return false;
  16.         }

  17.         INFO_LOG(MEMMAP, "Memory system initialized. Base at %p (RAM at @ %p, uncached @ %p)",
  18.                 base, m_pPhysicalRAM, m_pUncachedRAM);

  19.         MemFault_Init();
  20.         return true;
  21. }
复制代码
这里的 base 就是申请到的内存地址,而且是全局变量,所以找这个就可以了,在 MemoryMap_Setup 里赋值
我本来是想在内存申请的函数里注入获取的,比如这里:

  1. 申请内存的函数

  2. PPSSPPWindows64.exe+8866B0 - 40 53                 - push rbx
  3. PPSSPPWindows64.exe+8866B2 - 48 83 EC 20           - sub rsp,20 { 32 }
  4. PPSSPPWindows64.exe+8866B6 - 33 C9                 - xor ecx,ecx
  5. PPSSPPWindows64.exe+8866B8 - BA 000000E1           - mov edx,E1000000 { -520093696 }
  6. PPSSPPWindows64.exe+8866BD - 41 B8 00200000        - mov r8d,00002000 { 8192 }
  7. PPSSPPWindows64.exe+8866C3 - 44 8D 49 04           - lea r9d,[rcx+04]
  8. PPSSPPWindows64.exe+8866C7 - FF 15 9B801F00        - call qword ptr [PPSSPPWindows64.exe+A7E768] { ->KERNEL32.VirtualAlloc }
  9. PPSSPPWindows64.exe+8866CD - 48 8B D8              - mov rbx,rax
  10. PPSSPPWindows64.exe+8866D0 - 48 85 C0              - test rax,rax
  11. PPSSPPWindows64.exe+8866D3 - 74 14                 - je PPSSPPWindows64.exe+8866E9
  12. PPSSPPWindows64.exe+8866D5 - 33 D2                 - xor edx,edx
  13. PPSSPPWindows64.exe+8866D7 - 41 B8 00800000        - mov r8d,00008000 { 32768 }
  14. PPSSPPWindows64.exe+8866DD - 48 8B C8              - mov rcx,rax
  15. PPSSPPWindows64.exe+8866E0 - FF 15 5A801F00        - call qword ptr [PPSSPPWindows64.exe+A7E740] { ->KERNEL32.VirtualFree }
  16. PPSSPPWindows64.exe+8866E6 - 48 8B C3              - mov rax,rbx
  17. PPSSPPWindows64.exe+8866E9 - 48 83 C4 20           - add rsp,20 { 32 }
  18. PPSSPPWindows64.exe+8866ED - 5B                    - pop rbx
  19. PPSSPPWindows64.exe+8866EE - C3                    - ret
复制代码

只要在 call qword ptr [PPSSPPWindows64.exe+A7E768] { ->KERNEL32.VirtualAlloc } 后获取 rax 的值就行,可以注入,但是有个问题,就是这里只有在加载游戏时才会执行,所以不是随时都能获取到数据

所以就得找把申请到的内存地址赋值的地方,比如这里
  1. PPSSPPWindows64.exe+2AC3DF - 32 C0                 - xor al,al
  2. PPSSPPWindows64.exe+2AC3E1 - 48 8B 5C 24 50        - mov rbx,[rsp+50]
  3. PPSSPPWindows64.exe+2AC3E6 - 48 8B 74 24 58        - mov rsi,[rsp+58]
  4. PPSSPPWindows64.exe+2AC3EB - 48 83 C4 40           - add rsp,40 { 64 }
  5. PPSSPPWindows64.exe+2AC3EF - 5F                    - pop rdi
  6. PPSSPPWindows64.exe+2AC3F0 - C3                    - ret
  7. PPSSPPWindows64.exe+2AC3F1 - 48 8D 0D A881B300     - lea rcx,[PPSSPPWindows64.exe+DE45A0] { (2708) }
  8. PPSSPPWindows64.exe+2AC3F8 - E8 B3A25D00           - call PPSSPPWindows64.exe+8866B0 { 这里就是 call 上面的内存申请函数 }
  9. PPSSPPWindows64.exe+2AC3FD - 33 C9                 - xor ecx,ecx
  10. PPSSPPWindows64.exe+2AC3FF - 48 89 05 8282B300     - mov [PPSSPPWindows64.exe+DE4688],rax { 把申请到的内存地址赋值给全局变量, 这个地址可以当作基址 }
  11. PPSSPPWindows64.exe+2AC406 - E8 75000000           - call PPSSPPWindows64.exe+2AC480
  12. PPSSPPWindows64.exe+2AC40B - 84 C0                 - test al,al
  13. PPSSPPWindows64.exe+2AC40D - 74 D0                 - je PPSSPPWindows64.exe+2AC3DF
复制代码
我这里写成了 lua 的脚本,可以 ctrl+alt+L 写在 lua 脚本框里,这样打开 CT 表,就自动设置 CE 的查找起始地址和结束地址了
也是参考的银行漫步大佬的脚本,在这里感谢一下
  1. local result = AOBScanModuleUnique(process, "E8xxxxxxxx33C948xxxxxxxxxxxxE8xxxxxxxx84xx74xx")
  2. if result == nil then
  3.     return
  4. end

  5. result = result + 7
  6. -- print(getNameFromAddress(result, true, false))
  7. local _, opcode, bytes = splitDisassembledString(disassemble(result))
  8. local pos_s, pos_e = string.find(opcode, "%[.*%]")
  9. if pos_s == nil then
  10.     return
  11. end

  12. local offset = tonumber('0x'..string.sub(opcode, pos_s+1,pos_e-1))

  13. local BaseAddress = readPointer(offset) + 0x8800000
  14. registerSymbol("BaseAddress", BaseAddress,true)
  15. MainForm.FromAddress.Text = string.format("%X",BaseAddress)
  16. MainForm.ToAddress.Text = string.format("%X",BaseAddress+0x1800000)

  17. print(string.format("base address: %X",BaseAddress))
复制代码
这个脚本其实就是在找 mov [PPSSPPWindows64.exe+DE4688],rax 这条语句方括号里的地址,然后取出来,再加上 0x8800000,这样才是真正的数据地址
这里也注册了BaseAddress 全局变量,可以在其他地方使用

这个适用 PPSSPP 64 位版本,我试了一下,最近几个版本都是可以的,一般来说内存部分的代码不改就没问题,希望能用的长久一些吧,但是 32 位下的PPSSPP代码是跟这个完全不一样的,需要重新查找。
最后编辑Kisy 最后编辑于 2021-10-07 20:37:46
分享 转发
TOP
2#

32位的我已经提供了
TOP
发新话题 回复该主题