-- 声明全局变量 EditOutput -- Declare global variable EditOutput local EditOutput -- 调试打印函数 -- Function to print debug messages to Memo or console local function debugPrint(message) if EditOutput then EditOutput.Lines.add("" .. message) else print("" .. message) end end -- 初始化全局变量 -- Initialize global variables local ppsspp_WindowClass = "PPSSPPWnd" -- PPSSPP window class name local ppsspp_ProcessHwnd = 0 -- Handle for PPSSPP process window local ppsspp_ProcessID = 0 -- ID of the PPSSPP process local ppsspp_Is64BitProcess = false -- Flag to check if the process is 64-bit local psp_MemoryBaseAddress = 0 -- PSP memory base address local psp_MemoryBasePointer = 0 -- PSP memory base pointer local ppsspp_ProcessBaseAddress = 0 -- Base address of the PPSSPP process local ppsspp_BaseOffset = 0 -- Offset between memory base pointer and process base address local WM_USER_GET_BASE_POINTER = 0xB118 -- Custom message to get base pointers (WM_APP + 0x3118) -- 检查是否为目标进程 -- Check if the current process is the target PPSSPP process local function isTargetProcess(processid) local hwnd = findWindow(ppsspp_WindowClass) return hwnd ~= nil and getWindowProcessID(hwnd) == processid end -- 获取进程相关信息 -- Retrieve process variables such as handle, ID, and bitness local function getProcessVars() ppsspp_ProcessHwnd = findWindow(ppsspp_WindowClass) if not ppsspp_ProcessHwnd then debugPrint("PPSSPP window not found") return false end ppsspp_ProcessID = getWindowProcessID(ppsspp_ProcessHwnd) debugPrint("Process ID: " .. ppsspp_ProcessID) debugPrint("Process hWnd: " .. string.format("0x%X", ppsspp_ProcessHwnd)) ppsspp_Is64BitProcess = targetIs64Bit() debugPrint(ppsspp_Is64BitProcess and "64-bit process detected" or "32-bit process detected") return true end -- 发送消息获取指针地址 -- Send custom WM_APP messages to get base pointers local function sendWMs(lParam) local result = sendMessage(ppsspp_ProcessHwnd, WM_USER_GET_BASE_POINTER, 0, lParam) if type(result) == "number" and result >= 0 then debugPrint("sendMessage succeeded for lParam: " .. lParam) return result else debugPrint("sendMessage failed for lParam: " .. lParam .. " ErrorLevel: " .. tostring(result)) return 0 -- Return 0 on failure to avoid errors end end -- 合并低位和高位值为64位指针 -- Combine lower and upper 32-bit values into a 64-bit pointer local function combinePointer(lower, upper) return (upper * 0x100000000) + lower end -- 检索内存基址及其高低位 -- Retrieve the PSP memory base address and pointer using custom messages local function getAddresses() local replies = {sendWMs(0), sendWMs(1), sendWMs(2), sendWMs(3)} replies[1], replies[2] = replies[1] or 0, replies[2] or 0 -- PSP Memory Base Address low and high replies[3], replies[4] = replies[3] or 0, replies[4] or 0 -- PSP Memory Base Pointer low and high psp_MemoryBaseAddress = combinePointer(replies[1], ppsspp_Is64BitProcess and replies[2] or 0) psp_MemoryBasePointer = combinePointer(replies[3], ppsspp_Is64BitProcess and replies[4] or 0) debugPrint("PSP Memory Base Address: " .. string.format("0x%X", psp_MemoryBaseAddress)) debugPrint("PSP Memory Base Pointer: " .. string.format("0x%X", psp_MemoryBasePointer)) -- 匹配 PPSSPP 的模块 -- Match module names to identify the base address of PPSSPP for _, module in ipairs(enumModules()) do if string.match(module.Name, "^PPSSPP.*%.exe$") then ppsspp_ProcessBaseAddress = module.Address debugPrint("Matched module: " .. module.Name) break end end debugPrint("Process Base Address: " .. string.format("0x%X", ppsspp_ProcessBaseAddress or 0)) -- 计算基址偏移量 -- Calculate the offset between the memory base pointer and process base address if psp_MemoryBasePointer > 0 and ppsspp_ProcessBaseAddress > 0 then ppsspp_BaseOffset = psp_MemoryBasePointer - ppsspp_ProcessBaseAddress debugPrint("Base Offset: " .. string.format("0x%X", ppsspp_BaseOffset)) else debugPrint("Failed to calculate Base Offset") end end -- 执行脚本逻辑 -- Main script logic to execute the retrieval of process and memory information local function executeScript() local processid = getOpenedProcessID() if processid == 0 then debugPrint("No process currently opened.") return end if isTargetProcess(processid) and getProcessVars() then getAddresses() else debugPrint("Non-target process detected, skipping script execution.") end end -- GUI部分 -- GUI Section: Create the form and its components local form = createForm(false) form.Caption = "PPSSPP Memory Retrieval" form.Width = 620 form.Height = 400 -- 创建Memo框用于显示调试信息 -- Create Memo box for displaying debug information EditOutput = createMemo(form) EditOutput.Left = 10 EditOutput.Top = 10 EditOutput.Width = 620 EditOutput.Height = 355 EditOutput.ReadOnly = true EditOutput.ScrollBars = ssVertical EditOutput.WordWrap = true -- 创建刷新按钮 -- Create a refresh button to re-execute the script local ButtonRefresh = createButton(form) ButtonRefresh.Caption = "Refresh" ButtonRefresh.Height = 28 ButtonRefresh.Left = 10 ButtonRefresh.Top = 370 ButtonRefresh.Width = 600 -- 按下刷新按钮后执行脚本 -- Refresh button click event to clear output and execute the script ButtonRefresh.OnClick = function() EditOutput.Clear() executeScript() end -- 启动时检测目标进程 -- Initial execution to detect target process on startup executeScript() -- 显示 GUI 窗口 -- Show the GUI window form.Show()