--this script adds "Copy Selection Address relative Offset Value to clipboard" --http://forum.cheatengine.org/viewtopic.php?t=606762 local mv = getMemoryViewForm() -- Check and destroy previous menu item if (miCopyRelativeAddress ~= nil) then miCopyRelativeAddress.destroy() miCopyRelativeAddress = nil end -- Create new menu item miCopyRelativeAddress = createMenuItem(mv.memorypopup) miCopyRelativeAddress.Name = "miCopyRelativeAddress" miCopyRelativeAddress.Caption = "Copy relative offset to clipboard" miCopyRelativeAddress.ShortCut = textToShortCut("Ctrl+]") -- Menu item click event miCopyRelativeAddress.OnClick = function() local hv = mv.HexadecimalView if hv.UseRelativeBase then local s -- Calculate relative offset if hv.SelectionStart >= hv.RelativeBase then s = string.format("+%x", hv.SelectionStart - hv.RelativeBase) else s = string.format("-%x", hv.RelativeBase - hv.SelectionStart) end -- If there is a selection range, calculate the offset of the end position if hv.SelectionStop ~= hv.SelectionStart then if hv.SelectionStop >= hv.RelativeBase then s = string.format("%s to +%x", s, hv.SelectionStop - hv.RelativeBase) else s = string.format("%s to -%x", s, hv.RelativeBase - hv.SelectionStop) end end -- Write the result to clipboard writeToClipboard(s) end end -- Find the index of "Add this address to the list" and insert the new menu item after it local addAddressIndex = -1 for i = 0, mv.memorypopup.Items.Count - 1 do if mv.memorypopup.Items[i].Name == "Addthisaddresstothelist1" then addAddressIndex = i break end end if addAddressIndex ~= -1 then mv.memorypopup.Items.Insert(addAddressIndex + 1, miCopyRelativeAddress) -- Insert new menu item after it end -- Save the old OnPopup function local oldmemorypopuponpopup = mv.memorypopup.OnPopup -- Control the visibility of the menu item -- TDisassemblerview.UseRelativeBase : false mv.memorypopup.OnPopup = function(s) miCopyRelativeAddress.Visible = mv.HexadecimalView.UseRelativeBase return oldmemorypopuponpopup(s) end -- Define target processes and their address ranges local TARGET_PROCESSES = { ["pcsx2"] = function() local baseAddress = readQword("EEmem") if baseAddress then return string.format("%016X", baseAddress), string.format("%016X", baseAddress + 0x20000000) else return end end, ["cemu"] = function() local baseAddress = executeCode(getAddress("Cemu.memory_getBase"), 0, 2000) if baseAddress then return string.format("%016X", baseAddress), string.format("%016X", baseAddress + 0x20000000) else return end end, ["rpcs3"] = function() return string.format("%016X", 0x300000000), string.format("%016X", 0x300000000 + 0x1FFFFFF) end, ["epsxe"] = function() local aobPattern = "81E1FFFF1F0081C1" local foundAddress = AOBScan(aobPattern) if foundAddress then local address = tonumber(foundAddress[0], 16) + 8 registerSymbol("ePSXe_x32", address) local value = readInteger(address) foundAddress = nil return string.format("%016X", value), string.format("%016X", value + 0x200000) else return end end } -- Process opened event handler MainForm.OnProcessOpened = function(pid, handle, caption) local moduleList = enumModules() local processName for _, module in ipairs(moduleList) do local name = module.Name:lower() if name:match("%.exe$") then processName = name:match("([^/]+)%.exe$") break end end local processType = processName and (processName:match("^pcsx2") and "pcsx2" or processName:match("^cemu") and "cemu" or processName:match("^rpcs3") and "rpcs3" or processName:match("^epsxe") and "epsxe") local mv = getMemoryViewForm() local mvhv = mv.HexadecimalView if processType then local fromAddress, toAddress = TARGET_PROCESSES[processType]() MainForm.FromAddress.Text = fromAddress MainForm.ToAddress.Text = toAddress if fromAddress then mvhv.UseRelativeBase = true mvhv.RelativeBase = tonumber(fromAddress, 16) mvhv.Address = mvhv.RelativeBase mv.show() -- If you need to hide the memory viewer, change this to mv.hide() end if processType ~= "epsxe" then disableScript() end else MainForm.FromAddress.Text = "0000000000000000" MainForm.ToAddress.Text = "7fffffffffffffff" -- Set UseRelativeBase to false for non-target processes mvhv.UseRelativeBase = false -- Uncomment here if you need to automatically disable "show relative address CTRL + Enter" after opening a non-target process. end end -- Function to disable the ePSXe script function disableScript() unregisterSymbol("ePSXe_x32") end