local configPath="/sdcard/Download/conf.txy" local configExists= false local libPath="" local updateMode=1 local customOffset=0 local callHistory={} local Index function huifu() gg.processPause() local file=io.open("/sdcard/sj.txt", "r") if not file then gg.alert("没有找到恢复文件") return end for line in file:lines() do local addr, value=line:match("^(%x+) ([-]?%d+)$") if addr and value then addr=tonumber(addr, 16) value=tonumber(value) if addr and value then gg.setValues({{address=addr, flags=gg.TYPE_DWORD, value=value}}) else gg.alert("地址或值格式不正确: "..line) end else gg.alert("无法解析行: "..line) end end file:close() gg.processResume() end local function checkConfig() local file=io.open(configPath, "r") if file then configExists= true libPath=file:read("*l") or "" local modeLine=file:read("*l") or "1" if modeLine:find("2%(") then updateMode=2 customOffset=tonumber(modeLine:match("%((%d+)%)")) or 0 else updateMode=tonumber(modeLine) or 1 end local indexLine=file:read("*l") or "2" Index=tonumber(indexLine) or 2 offsets={} for line in file:lines() do local name, offset=line:match("(.+)=(0x%x+)") if name and offset then offsets[name]=tonumber(offset, 16) end end file:close() end end function so(l) g=gg.getValues s=gg.setValues f=string.format O={"System V", "HP-UX", "NetBSD", "Linux", "GNU Hurd", "Solaris", "AIX", "IRIX", "FreeBSD", "Tru64", "Novell Modesto", "OpenBSD", "OpenVMS", "NonStop Kernel", "AROS", "Fenix OS", "CloudABI"} T={["0"]="ET_NONE", ["1"]="ET_REL", ["2"]="ET_EXEC", ["3"]="ET_DYN", ["4"]="ET_CORE", ["65024"]="ET_LOOS", ["65279"]="ET_HIOS", ["65280"]="ET_LOPROC", ["65535"]="ET_HIPROC"} M={["0"]="No Specific Instruction Set !", ["2"]="SPARC", ["3"]="x86", ["8"]="MIPS", ["20"]="PowerPC", ["22"]="S390", ["40"]="ARM", ["42"]="SuperH", ["50"]="IA-64", ["62"]="x86-64", ["183"]="AArch64", ["243"]="RISC-V"} P={"PT_NULL", "PT_LOAD", "PT_DYNAMIC", "PT_INTERP", "PT_NOTE", "PT_SHLIB", "PT_PHDR"} D={"DT_NULL", "DT_NEEDED", "DT_PLTRELSZ", "DT_PLTGOT", "DT_HASH", "DT_STRTAB", "DT_SYMTAB", "DT_RELA", "DT_RELASZ", "DT_RELAENT", "DT_STRSZ", "DT_SYMENT", "DT_INIT", "DT_FINI", "DT_SONAME", "DT_RPATH", "DT_SYMBOLIC", "DT_REL", "DT_RELSZ", "DT_RELENT", "DT_PLTREL", "DT_DEBUG", "DT_TEXTREL", "DT_JMPREL"} S={"STT_NOTYPE", "STT_OBJECT", "STT_FUNC", "STT_SECTION", "STT_FILE", "STT_COMMON", "STT_TLS"} function r(a, b) _={} if type(b)=="数字" then _="" for _=1, b do _[_]={address=(a-1)+_, flags=gg.TYPE_BYTE} end for v, __ in ipairs(g(_)) do _=_..f("%02X", __.value&0xFF) end return _ end B={} b:gsub("..", function (x) B[#B+1]=x _[#B]={address=(a-1)+#B, flags=gg.TYPE_BYTE, value=x.."h"} end ) s(_) end function d(a, b) if b== nil or type(b)~="数字" then b=128 end local t="" for _ in r(a, b):gmatch("..") do if _=="00" then break end t=t..string.char(tonumber(_, 16)) end return t end function b(l) local function a(l) local p= nil for _, __ in pairs(gg.getRangesList(l)) do if __["state"]=="Xs" then return p, __["start"], __["end"] end p=__["start"] end return nil end local function c(l) for _, __ in pairs(gg.getRangesList(l)) do if __["state"]=="Xa" or __["state"]=="Xs" then return __["start"], __["end"] end end return nil end local s, e=a(l) if not s then s, e=c(l) end return s, e end function i(l) local B=b(l) if B~= nil then _=g({{address=B, flags=gg.TYPE_DWORD}, {address=B+0x4, flags=gg.TYPE_BYTE}, {address=B+0x5, flags=gg.TYPE_BYTE}, {address=B+0x6, flags=gg.TYPE_BYTE}, {address=B+0x7, flags=gg.TYPE_BYTE}, {address=B+0x8, flags=gg.TYPE_BYTE}, {address=B+0x10, flags=gg.TYPE_WORD}, {address=B+0x12, flags=gg.TYPE_WORD}, {address=B+0x14, flags=gg.TYPE_DWORD}, {address=B+0x18, flags=gg.TYPE_DWORD}, {address=B+0x1C, flags=gg.TYPE_DWORD}, {address=B+0x20, flags=gg.TYPE_DWORD}, {address=B+0x24, flags=gg.TYPE_DWORD}, {address=B+0x28, flags=gg.TYPE_WORD}, {address=B+0x2A, flags=gg.TYPE_WORD}, {address=B+0x2C, flags=gg.TYPE_WORD}, {address=B+0x2E, flags=gg.TYPE_WORD}, {address=B+0x30, flags=gg.TYPE_WORD}, {address=B+0x32, flags=gg.TYPE_WORD}, }) local E={Magic=_[1].value, Class=_[2].value, Data=_[3].value, Version=_[4].value, OSABI=_[5].value, ABIVer=_[6].value, Type=_[7].value, Machine=_[8].value, Version2=_[9].value, EntryPoint=_[10].value, PHOffset=_[11].value, SHOffset=_[12].value, Flags=_[13].value, HeaderSize=_[14].value, PHSize=_[15].value, PHNum=_[16].value, SHSize=_[17].value, SHNum=_[18].value, SHStrIndex=_[19].value, pHdr={}, Dyn={}, Sym={}} for _=1, E.PHNum do local p=B+E.PHOffset+(_*E.PHSize) local h=g({{address=p, flags=gg.TYPE_DWORD}, {address=p+4, flags=gg.TYPE_DWORD}, {address=p+8, flags=gg.TYPE_DWORD}, {address=p+0xC, flags=gg.TYPE_DWORD}, {address=p+0x10, flags=gg.TYPE_DWORD}, {address=p+0x14, flags=gg.TYPE_DWORD}, {address=p+0x18, flags=gg.TYPE_DWORD}, {address=p+0x1C, flags=gg.TYPE_DWORD}, }) E.pHdr[_]={p_type=h[1].value, p_offset=h[2].value, p_vaddr=h[3].value, p_paddr=h[4].value, p_filesz=h[5].value, p_memsz=h[6].value, p_flags=h[7].value, p_align=h[8].value} end for _=1, E.PHNum do if P[E.pHdr[_].p_type+1]=="PT_DYNAMIC" then local C=0 while true do local y=g({{address=B+E.pHdr[_].p_vaddr+(C*8), flags=gg.TYPE_DWORD}, {address=B+E.pHdr[_].p_vaddr+4+(C*8), flags=gg.TYPE_DWORD}}) if y[1].value==0 and y[2].value==0 then break end C=C+1 E.Dyn[C]={d_tag=y[1].value, d_val=y[2].value, d_ptr=y[2].value} end end end for _=1, #E.Dyn do if D[tonumber(E.Dyn[_].d_tag)+1]=="DT_HASH" then n=g({{address=(E.Dyn[_].d_ptr+4)+B, flags=gg.TYPE_DWORD}})[1].value end if D[tonumber(E.Dyn[_].d_tag)+1]=="DT_STRTAB" then t=E.Dyn[_].d_ptr+B end if D[tonumber(E.Dyn[_].d_tag)+1]=="DT_SYMTAB" then m=E.Dyn[_].d_ptr+B end end if n~= nil then for _=1, n do local y=m+(_*0x10) __=g({{address=y, flags=gg.TYPE_DWORD}, {address=y+0x4, flags=gg.TYPE_DWORD}, {address=y+0x8, flags=gg.TYPE_DWORD}, {address=y+0xC, flags=gg.TYPE_DWORD}}) E.Sym[_]={name=d(t+__[1].value), st_name=__[1].value, st_value=__[2].value, st_size=__[3].value, st_info=__[4].value} end end return E end return nil end B=b(l) return B end function libcjx(so, s) local a=so local b=io.open(a, "rb") if not b then return end b:seek("set", 0) local c=b:read(4) if c~="\x7fELF" then b:close() return end b:seek("set", 4) local d=b:read(1) local e=(d=="\x02") if not e then b:close() return end b:seek("set", 0x28) local f=b:read(8) f=string.unpack("0 then gg.setValues(paramValues) end gg.processResume() gg.setValues({{address=fkndl+0x67C, flags=4, value=2}}) local retValue=0 while retValue==0 do retValue=gg.getValues({{address=fkndl+0x798, flags=4}})[1].value end huifu() type=fkndl+0x778 gg.addListItems({{address=type, flags=4, name="返回值int"}, {address=type+0x8, flags=16, name="返回值float"}}) end function call() local selected=gg.getSelectedListItems() if #selected==0 then gg.alert("请先选择要调用的函数地址") return end local address_list={} for i, v in ipairs(selected) do table.insert(address_list, string.format("0x%X", v.address)) end local choice=gg.choice(address_list, nil , "选择要调用的函数地址") if not choice then return end local inputs=gg.prompt({"参数x0", "参数x1", "参数x2", "参数x3", "参数x4", "参数x5", "参数x6", "参数x7", "参数s0", "参数s1", "参数s2", "调用名称"}, {"nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", "nop", ""}, {"text", "text", "text", "text", "text", "text", "text", "text", "text", "text", "text", "text"}) if not inputs then return end local args={} local types={4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 16} for i=1, 11 do if inputs[i]=="nop" then args[i]="nop" else args[i]=tonumber(inputs[i]) or 0 if args[i]~=0 then local typePrompt="选择参数" local regName if i<=8 then regName="x"..(i-1) typePrompt=typePrompt..regName local t=gg.choice({"DWORD (4)", "QWORD (32)"}, nil , typePrompt) types[i]=t==2 and 32 or 4 else regName="s"..(i-9) typePrompt=typePrompt..regName local t=gg.choice({"FLOAT (16)", "DOUBLE (32)"}, nil , typePrompt) types[i]=t==2 and 32 or 16 end end end end returnz=diaoyhs(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11], types[1], types[2], types[3], types[4], types[5], types[6], types[7], types[8], types[9], types[10], types[11], selected[choice].address) table.insert(callHistory, {address=selected[choice].address, name=inputs[12] or "未命名调用", args=args, types=types}) gg.toast(string.format("调用成功")) end function calllis() if #callHistory==0 then gg.alert("没有历史调用记录") return end local historyList={} for i, v in ipairs(callHistory) do table.insert(historyList, string.format("%s (地址:0x%X)", v.name, v.address)) end local choice=gg.choice(historyList, nil , "选择历史调用") if not choice then return end local selected=callHistory[choice] returnz=diaoyhs(selected.args[1], selected.args[2], selected.args[3], selected.args[4], selected.args[5], selected.args[6], selected.args[7], selected.args[8], selected.args[9], selected.args[10], selected.args[11], selected.types[1], selected.types[2], selected.types[3], selected.types[4], selected.types[5], selected.types[6], selected.types[7], selected.types[8], selected.types[9], selected.types[10], selected.types[11], selected.address) gg.toast(string.format("调用成功")) end function chongzhi() local configPath="/sdcard/Download/conf.txy" local file=io.open(configPath, "r") file:close() os.remove(configPath) os.exit() end while true do gg.showUiButton() if gg.isClickedUiButton( false ) then gg.hideUiButton() callhans() end end