function Search_the_base_addressC() local pathdjxh = "/sdcard/Android/[C]配置数据对接信号" local pathdjpz = "/sdcard/Android/[C]链表数据DATA.txt" local pathCprint ="/sdcard/Android/[C]运算完Printf数据.txt" local depth, maxOffset, iii local ti = gg.getTargetInfo() getSelectedAdd() if gg.getResultsCount() == 1 then else gg.alert("搜索列表为空\n".. "或者大于1条数据,请更正后再开启" ) return end function getRanges() local ranges = {} local archs = {[0x3] = 'x86', [0x28] = 'ARM', [0x3E] = 'x86-64', [0xB7] = 'AArch64'} -------区分处理器架构 local t = gg.getRangesList('^/data/*lib*.so*$') -- local t = gg.getRangesList('^/data/*lib*.so:bss$') local arch = 'unknown' for i, v in ipairs(t) do if v.type:sub(2, 2) == '-' then local t = gg.getValues({ {address = v.start, flags = gg.TYPE_DWORD}, {address = v.start + 0x12, flags = gg.TYPE_WORD} }) if t[1].value == 0x464C457F then arch = archs[t[2].value] if arch == nil then arch = 'unknown' end end end if v.type:sub(2, 2) == 'w' then v.arch = arch v["页面数量"]=(v["end"]-v["start"])/4096 if v["页面数量"]>=8 then table.insert(ranges, v) end end end return ranges end function getRangesPro() local lb,t_name,path={},{},{} local list = gg.getRangesList('^/data/*lib*so*$') if #list==0 then return lb,t_name end local x64=list[#list]['end']>0xffffffff local flags=(x64 and 32 or 4) for i, v in ipairs(list) do list[i]["模块名称"]=v.internalName:gsub('^.*/', '') list[i]["flags"]=flags list[i]["x64"]=x64 list[i]["目录名称"]=(string.sub(v.internalName,7,-1):match("(%a+)")) list[i]["页面数量"]=(v["end"]-v["start"])/4096 if not path[list[i]["模块名称"]] then path[list[i]["模块名称"]]={} path[list[i]["模块名称"]]["序号"]=1 else path[list[i]["模块名称"]]["序号"]=path[list[i]["模块名称"]]["序号"]+1 end list[i]["模块序号"]=path[list[i]["模块名称"]]["序号"] if path[list[i]["模块名称"]..":bss"] then list[i]["模块序号"]=path[list[i]["模块名称"]]["序号"]+path[list[i]["模块名称"]..":bss"]["序号"] end list[i]["模块特征字符串"]=string.format("%s[%s][%s]%s" , list[i]["模块名称"],list[i]["模块序号"],list[i]["x64"],list[i].state) if list[i].type:sub(2, 2) == 'w' then if list[i]["页面数量"]>=8 then table.insert(lb, list[i]) end end end for i, v in ipairs(lb) do t_name[v["模块特征字符串"]]=v end return lb,t_name end local cfg_file = gg.EXT_FILES_DIR.."/"..'基址扫描C.cfg' local chunk = loadfile(cfg_file) local cfg = nil if chunk ~= nil then cfg = chunk() end if cfg == nil then cfg = {} end local pkg = gg.getTargetPackage() if pkg == nil then pkg = 'none' end local def = cfg[pkg] if def == nil then def = {6, 0x400} end local p = gg.prompt({ '深度: →》', '最大偏移量: ', }, def, { "number", "number", }) if p == nil then return end local old = gg.getResults(1) local Nc=gg.getValuesRange(old)[1] local PNc=gg.REGION_C_BSS | gg.REGION_C_DATA | gg.REGION_STACK | gg.REGION_C_HEAP | gg.REGION_C_ALLOC | gg.REGION_C_ALLOC | gg.REGION_ANONYMOUS | gg.REGION_OTHER gg.setRanges(PNc) gg.loadResults(gg.getResults(100000)) cfg[pkg] = p gg.saveVariable(cfg, cfg_file) depth, maxOffset = tonumber(p[1]), tonumber(p[2]) MKTZZFC=true local script = GetNewPath("[文本基址].txt") os.remove(pathdjxh, "e") os.remove(pathdjpz, "e") local x = os.clock() gg.setVisible(false) gg.toast("加载模块信息中...") local ranges = {} if MKTZZFC then ranges=getRangesPro() else ranges=getRanges() end local Basenumber , Pointernumber = "", "" --输出配置结构 local PDCa while true do for lvl = 0, depth do if lvl<=depth-2 then --if lvl==1 or lvl==2 or lvl==3 then if gg.isPointer then if gg.getResultsCount() <= 99999 then local TP={} local RT=gg.getResults(100000) for i, v in ipairs(RT) do if gg.isPointer(v.address) then table.insert( TP, v) end end if #TP~=0 then gg.loadResults(TP) end end end end --end if lvl > 0 then local bl_1, bl_2, bl_3 = 400000, 0, 0 if (gg.ExclusiveoutputG ~= nil) then bl_3 = gg.ExclusiveoutputG(pathdjpz) else local fileLE = io.open(pathdjpz, 'a') while true do local datak = gg.getResults(bl_1, bl_2) if (#datak ~= 0) then bl_2 = bl_2 + bl_1 for i, PointerData in ipairs(datak) do bl_3 = bl_3 + 1 fileLE:write( string.format('Pointer|%d|%d\n', PointerData.address, PointerData.value) ) end else break end end fileLE:close() end Pointernumber = string.format('%s2000|%d|%d|\n', Pointernumber, lvl, bl_3) if (lvl == depth) then gg.setRanges(gg.REGION_C_DATA | gg.REGION_C_BSS) end gg.toast(lvl..' ﹥_﹥ '..depth) if lvl==1 then gg.searchPointer(maxOffset) elseif maxOffset>256 then gg.searchPointer(256) else gg.searchPointer(maxOffset) end end iii = 0 local fileLE = io.open(pathdjpz, 'a') if MKTZZFC then for m, r in ipairs(ranges) do local p = gg.getResults(800000, 0, r.start, r['end']) if #p > 0 then for j, u in pairs(p) do iii = iii + 1 fileLE:write( string.format('Base|%d|%s+0x%X\n', u.value, r["模块特征字符串"], (u.address - r.start)) ) end gg.removeResults(p) end end else for m, r in ipairs(ranges) do local p = gg.getResults(800000, 0, r.start, r['end']) if #p > 0 then for j, u in pairs(p) do iii = iii + 1 fileLE:write( string.format('Base|%d|%s+0x%X\n', u.value, r.internalName:gsub('^.*/', ''), (u.address - r.start)) ) end gg.removeResults(p) end end end fileLE:close() if lvl >= 1 then Basenumber = string.format('%s3500|%d|%d|\n', Basenumber, lvl, iii) end if gg.getResultsCount() == 0 then print("凉透了 没有数据符合") break end end gg.loadResults(old) if iii ~= 0 then -- print("C语言 运算\n 运算出的路径为 : "..p[3]) end break end io.open(pathdjxh, "w+"):write( string.format('%d<>%d<>%d<>%s\n%s%s', depth, (ti.x64 and 1 or 0), maxOffset, script, Basenumber, Pointernumber ) ):close() local path = gg.FILES_DIR.."/" local c_name = "基址C运算.c" if (io.open(path .. c_name)) then os.remove(path .. c_name) end gg.getRaw(path .. c_name, "chunk_cpp3") local printf = gg.command( "su -p -M" .. "\n cd " .. path .. "\n chmod 777 " .. c_name .. "\n " .. "'" .. "./" .. c_name .. "'" .. " " .. "'" .. pathCprint .. "'" .. " " .. "'" .. "交互验证" .. "'" .. "\n rm -f " .. c_name ) printf=printf.."\n"..rfile(pathCprint) printf=string.match(printf,"(基址.-秒)") printf=printf.."\n"..script if rfile(script)=="" then dfile(script) end print(printf) gg.alert(printf) gg.setVisible(true) --↑↑↑↑-- end function The_text_contrasts() local script1 = GetNewPath("[文本基址].txt",true) local script2 = GetNewPath("[文本基址].txt",true,true) local script = GetNewPath("[文本基址].txt") local route = gg.prompt({ '请选择要[对比]的文本:A', '请选择要[对比]的文本:B', '请选择要[输出]的路径:🎆', }, { script1, script2, script, }, { 'file', 'file', 'file', }) if route == nil or route[3] == "" then return end local path = gg.FILES_DIR.."/" local c_name = "文本对比.c" local txt_name = "文本对比.txt" io.open(path .. txt_name, 'w+'):write( route[1].."\n".. route[2].."\n".. route[3].."\n" ):close( ) if (io.open(path .. c_name)) then os.remove(path .. c_name) end gg.getRaw(path .. c_name, "chunk_cpp0") local printf = gg.command( "su -p -M" .. "\n cd " .. path .. "\n chmod 777 ".. c_name .. "\n ./" .. c_name.. "\n rm -f " .. c_name.. "\n rm -f " .. txt_name , true ) printf=printf:match("(文件.-秒)") if rfile(route[3])~="" then printf=printf.."\n"..route[3] else dfile(route[3]) end print(printf) gg.alert(printf) gg.setVisible(true) --↑↑↑↑-- end local function GLPointer() local function getRangesPro() local lb,t_name,path={},{},{} local list = gg.getRangesList('^/data/*lib*so*$') if #list==0 then return lb,t_name end local x64=list[#list]['end']>0xffffffff local flags=(x64 and 32 or 4) for i, v in ipairs(list) do list[i]["模块名称"]=v.internalName:gsub('^.*/', '') list[i]["flags"]=flags list[i]["x64"]=x64 list[i]["目录名称"]=(string.sub(v.internalName,7,-1):match("(%a+)")) if not path[list[i]["模块名称"]] then path[list[i]["模块名称"]]={} path[list[i]["模块名称"]]["序号"]=1 else path[list[i]["模块名称"]]["序号"]=path[list[i]["模块名称"]]["序号"]+1 end list[i]["模块序号"]=path[list[i]["模块名称"]]["序号"] if path[list[i]["模块名称"]..":bss"] then list[i]["模块序号"]=path[list[i]["模块名称"]]["序号"]+path[list[i]["模块名称"]..":bss"]["序号"] end list[i]["模块特征字符串"]=string.format("%s[%s][%s]%s" , list[i]["模块名称"],list[i]["模块序号"],list[i]["x64"],list[i].state) table.insert(lb, list[i]) end for i, v in ipairs(lb) do t_name[v["模块特征字符串"]]=v end return lb,t_name end local ranges,nameS = getRangesPro() local function ReadPointerPro(name, offset) if nameS[name] then if gg.readPointer then return gg.readPointer(nameS[name].start,offset) end local addr=nameS[name].start+offset[1] if nameS[name].x64 then for i = 2,#offset do addr = gg.getValues({{address=addr,flags=nameS[name].flags}}) addr = addr[1].value addr = addr + offset[i] end else for i = 2,#offset do addr = gg.getValues({{address=addr,flags=nameS[name].flags}}) addr = addr[1].value & 0xFFFFFFFF addr = addr + offset[i] end end if addr==offset[#offset] then return 0 end return addr end print("链条非pro格式") os.exit() return 0 end local function readPointer(name, offset) if nameS[name] then return gg.readPointer(nameS[name].start,offset) end return 0 end local function get_offset(sp_str) local offset={} local inputstr=tostring(sp_str) local spe="+" local n=inputstr:find(spe) if n then inputstr=inputstr:sub(n+1) else spe="," inputstr=tostring(sp_str):match("{(.-)}") if not inputstr then inputstr=tostring(sp_str) end end for t,c in tostring(inputstr):gmatch("([^"..spe.."]*)("..spe.."?)") do if t=="0x0" then table.insert(offset, 0) else table.insert(offset, tonumber(t)) end end return offset end local function get_name(sp_str) return string.match(sp_str,"(.-)%+") end local t=gg.getResults(100) local addrstr if #t==1 then addrstr=string.format("%X" , t[1].address) else addrstr="" end local script = GetNewPath("[文本基址].txt",true) local fp=gg.prompt({ "选择过滤文件" , "过滤地址Hex" , "过滤文本", "是否过滤文本", }, {script, addrstr, },{ "file" , "text" , "text" , "checkbox" , }) if not fp then return end if fp[4] then local s=fp[3] local list={} local addr local lb={} list=BLTQ(s,"(.-)\n") if #list==0 then table.insert( list, s) end for i, sp_str in ipairs(list) do addr=ReadPointerPro(get_name(sp_str), get_offset(sp_str)) if addr~=0 then table.insert( lb, {address=addr,flags=4}) end end if #lb~=0 then lb=gg.getValues(lb) gg.loadResults(lb) gg.addListItems(lb) gg.alert("读取成功 总数"..#list.." 识别数"..#lb) else gg.alert("读取失败") end return end local x=time() local x64=gg.getTargetInfo().x64==true local data2,data3 local num,allnum=0,0 local address0,address1,address2 local smlx="盲扫" if XtoD(fp[2])~=0 then address0=XtoD(fp[2]) smlx="精扫" end if x64 then address1=XtoD("1000000000") else address1=XtoD("10000000") end txt_file1=fp[1] --txt_file2=txt_file1:gsub("[^%/]+$","")..'["过滤"]'..txt_file1:match("[^%/]+$") local txt_file2 = GetNewPath("[文本基址].txt") local f1 = io.open(txt_file1) local SM if f1 ~= nil then data2=f1:read("*l") f1:close() data3=string.gsub(data2,"%[","") if data2==data3 then SM="普通格式" else SM="Pro格式" end end local f1 = io.open(txt_file1,"r") local f2 = io.open(txt_file2,"a+") wfile(txt_file2,"") local taddr_num={} if SM=="Pro格式" then if address0 then for sp_str in f1:lines() do address2=ReadPointerPro(get_name(sp_str), get_offset(sp_str)) if address0==address2 then f2:write(sp_str.."\n") num=num+1 end allnum=allnum+1 if allnum%10000==0 then f2:close() f2 = io.open(txt_file2,"a+") end end else for sp_str in f1:lines() do address2=ReadPointerPro(get_name(sp_str), get_offset(sp_str)) if address1= 60.0 then fs = xx // 60.0 ms = xx - (fs * 60.0) ms=tostring(ms):sub(1,5) fm = fs .. " 分 " .. ms .." 秒" else ms=tostring(xx):sub(1,5) fm = ms .. " 秒" end return fm end function GetNewPath(Path,isTrue,isTrue2) local function get_path() local path=string.char(47,115,100,99,97,114,100,47) local f=gg.getFile() if tostring(f):sub(1,1)=="/" then path=f:gsub("[^/]+$", "") end return path end local s=Path local ti=gg.getTargetInfo() local name="name" local sd=get_path() if ti~=nil then name=ti['label'] end local Type={"%p","%s","%c","%z"} for i, v in ipairs(Type) do name=string.gsub(name,v,"_") end if s=="" or s==nil then s=sd..name..".lua" end if s:gsub("[^/]+$", "")=="" then s=sd..name..s end if s:gsub("[^.]+$", ""):sub(1,-2)=="" then s=s..".lua" end local t={} t[#t+1]=s t[#t+1]=s:gsub("[^.]+$", ""):sub(1,-2) t[#t+1]=s:gsub("[^/]+$", "") t[#t+1]=t[2]:gsub(t[3],"") t[#t+1]=name t[#t+1]=t[4]:gsub(name,"") if nil then t[2]=t[3]..t[5].."[" t[#t+1]="]"..t[6].."."..s:match('[^.]+$') else t[#t+1]="]."..s:match('[^.]+$') t[2]=t[3]..t[5]..t[6].."[" end local pn=t[1] local script=t[2] if not isTrue then for i = 1, 500 do local f = io.open(script..i..t[#t]) if f == nil then script = script..i..t[#t] pn=script break end if f then f:close() end end end local isTrue2pd=isTrue2 if isTrue then for k = 500, 1, -1 do pn=script..k..t[#t] local f = io.open(script..k..t[#t]) if f then f:close() pn = script..k..t[#t] if not isTrue2pd then break end isTrue2pd=nil end end end return pn end function getSelectedAdd() local function toX(text) local s=string.lower(tostring(text)) if s:find("x") then return s end return string.format("0x%X",text) end local function toD(text,num) if type(text)=="number" then return text elseif type(text)=="string" then if text=="" then return 0 end local s=string.lower(text) if s:find("0x") then s=string.match(s,"0x(%w+)") return tonumber(s,16) end end return tonumber(text,num) end local lb={} lb["选中搜索"]={} local t={} local List=gg.getSelectedResults() local state=gg.getValuesRange(List) for i, v in pairs(List) do table.insert(t,List[i]) end local state=gg.getValuesRange(t) for i, v in pairs(t) do lb["选中搜索"][i]=v lb["选中搜索"][i].state=state[i] end lb["搜索"]={} local maxCount=gg.getResultCount() if maxCount>100 then maxCount=100 end local t={} local List=gg.getResults(maxCount) for i, v in pairs(List) do table.insert(t,List[i]) end local state=gg.getValuesRange(t) for i, v in pairs(t) do lb["搜索"][i]=v lb["搜索"][i].state=state[i] end lb["保存"]={} local t={} local List=gg.getListItems() for i, v in pairs(List) do table.insert(t,List[i]) end local state=gg.getValuesRange(t) for i, v in pairs(t) do lb["保存"][i]=v lb["保存"][i].state=state[i] end lb["选中保存"]={} local t={} local List=gg.getSelectedListItems() for i, v in pairs(List) do table.insert(t,List[i]) end local state=gg.getValuesRange(t) for i, v in pairs(t) do lb["选中保存"][i]=v lb["选中保存"][i].state=state[i] end local name={} local lbcadd={} local bool={} local num=0 local PD for k, v in pairs(lb) do num=num+#v table.insert(name,k..#v) table.insert(lbcadd,v) end if num==0 then return end function Cxzdz(StrMenu) local num=0 if PD then return end for k, v in pairs(lb) do num=num+1 if (k==StrMenu) and #v==1 and not PD then PD=true bool[num]=true end end end Cxzdz("选中保存") Cxzdz("保存") Cxzdz("选中搜索") Cxzdz("搜索") if not PD then num=0 for k, v in pairs(lb) do num=num+1 if (k=="搜索") and (#v~=0) and not PD then PD=true bool[num]=true end end end if not PD then num=0 for k, v in pairs(lb) do num=num+1 if (k=="保存") and (#v~=0) and not PD then PD=true bool[num]=true end end end local ret={} local menu=gg.multiChoice(name,bool,"选择扫描地址") if not menu then return end if menu then for k, v in pairs(menu) do if v then for i, v in ipairs(lbcadd[k]) do table.insert(ret,v) end end end end local t=ret if #t==1 then gg.loadResults(gg.getValues(t)) if gg.isVisible(true) then gg.setVisible(false) gg.sleep(10) gg.setVisible(true) end return t end local sz={} if #t~=0 then for i, v in ipairs(t) do table.insert(sz,string.format("0x%X %s %s\n%s", v.address,v.flags,v.state,v.value)) end end local xz if #sz~=0 then xz=gg.choice(sz,nil,"请选择要扫描的值") end if xz then t={t[xz]} end gg.loadResults(gg.getValues(t)) if gg.isVisible(true) then gg.setVisible(false) gg.sleep(10) gg.setVisible(true) end return t end function NtoX(text) return string.format("0x%X",text) end function DtoX(text) if not text or text=="" then return "0x0" end if type(text)=="string" then if string.lower(text):find("0x") then return text end end return string.format("0x%X",text) end function XtoD(text) if not text or text=="0x0" or text=="0X0" or text=="" or text==0 then return 0 end if type(text)=="number" then return tonumber(text,16) end if type(text)=="string" then --if text:match("%w")==nil then return 0 end if string.lower(text):find("0x") then return tonumber(text) end end return tonumber(text,16) end function getFileSD(text,text2) local str="" if text then if type(text)=="string" then str=text else str=tostring(text) end end if text2 then str=str..text2 end return gg['EXT_STORAGE'].."/"..str end function getFileEC(text,text2) local str="" if text then if type(text)=="string" then str=text else str=tostring(text) end end if text2 then str=str..text2 end return gg['EXT_CACHE_DIR'].."/"..str end function getFileEF(text,text2) local str="" if text then if type(text)=="string" then str=text else str=tostring(text) end end if text2 then str=str..text2 end return gg['EXT_FILES_DIR'].."/"..str end function getFileC(text,text2) local str="" if text then if type(text)=="string" then str=text else str=tostring(text) end end if text2 then str=str..text2 end return gg['CACHE_DIR'].."/"..str end function getFileF(text,text2) local str="" if text then if type(text)=="string" then str=text else str=tostring(text) end end if text2 then str=str..text2 end return gg['FILES_DIR'].."/"..str end function BLTQ(Text,TZ) local lb1={} for t,c in tostring(Text):gmatch(TZ) do table.insert(lb1,t) end return lb1 end function mySplit(inputstr, sep) sep = sep or "%s" local t = {} for field, s in string.gmatch(inputstr, "([^" .. sep .. "]*)(" .. sep .. "?)") do table.insert(t, field) if s == "" then end end return t end function main() local Main={} Main.GO=true Main["Sx界面"]=true function Main.DZSH() local dx={ "基址扫描C" , --1 "文本对比C" , --2 "基址过滤pro版本" , --3 "退出" , } local menu = gg.choice(dx,0,"单选") if menu==1 then Main.HZ1() end if menu==2 then Main.HZ2() end if menu==3 then Main.HZ3() end if menu==#dx then Main.GO=false end Main.PD=true end function Main.HZ1() Search_the_base_addressC() end function Main.HZ2() The_text_contrasts() end function Main.HZ3() GLPointer() end if Main["Sx界面"]==true then gg.toast("点击屏幕'Sx'打开功能列表") Main.DZSH() end while Main.GO do if Main["Sx界面"]==true then gg.showUiButton() if gg.isClickedUiButton() then Main.DZSH() end else if gg.isVisible(true) then Main.PD = nil gg.setVisible(false) end if not Main.PD then Main.DZSH() end end end end main()