Beggining of auto-offset finder port. (not working yet)

Signed-off-by: Warmist <Warmist@gmail.com>
develop
Warmist 2011-08-04 20:57:53 +03:00
parent e7174e6736
commit e66a03e654
6 changed files with 437 additions and 22 deletions

@ -1,23 +1,4 @@
offsets=offsets or {}
offsets._toff={}
offsets.get = function (name)
return offsets._toff[name]
end
offsets.getEx = function (name)
return offsets._toff[name]+Process.getBase()
end
offsets.load = function ()
local f=io.open("dfusion/offsets.txt")
local line=f:read()
while line~=nil do
--print(line)
local sppliter=string.find(line,":")
offsets._toff[string.sub(line,1,sppliter-2)]=tonumber(string.sub(line,sppliter+2))
line=f:read()
end
end
offsets.load()
dofile("dfusion/offsets_misc.lua")
STD_STRING=0
DWORD=1
WORD=2
@ -42,6 +23,24 @@ function GetTextRegion()
end
return nil
end
function GetRegionIn(pos)
local ranges=Process.getMemRanges()
for k,v in pairs(ranges) do
--for k2,v2 in pairs(v) do
-- print(string.format("%d %s->%s",k,tostring(k2),tostring(v2)))
--end
--local num
--num=0
--if(v["read"])then num=num+1 end
--if(v["write"])then num=num+10 end
--if(v["execute"]) then num=num+100 end
--print(string.format("%d %x->%x %s %d",k,v["start"],v["end"],v.name,num))
if pos>=v.start and pos<=v["end"] then
return v
end
end
return nil
end
function unlockDF()
local reg=GetTextRegion()
reg["write"]=true
@ -260,7 +259,7 @@ function findVectors()
loc1=engine.peekd(v+2)
loc2=engine.peekd(v+8)
--print(string.format("%x - %x=%x",loc1,loc2,loc1-loc2))
if(math.abs(loc1-loc2)==4) then
if(loc1-loc2==4) then
if T[loc1-4]~=nil then
T[loc1-4]=T[loc1-4]+1
else

@ -34,6 +34,6 @@ unlockDF()
plugins={}
table.insert(plugins,{"simple_embark","A simple embark dwarf count editor"})
table.insert(plugins,{"items","A collection of item hacking tools"})
table.insert(plugins,{"offsets","Find all offsets"})
mainmenu(plugins)

@ -0,0 +1,310 @@
function f_dwarves()
pos=offsets.find(0,0x24,0x14,0x07,0,0,0,0xeb,0x08,0x8d) --search pattern
if pos~=0 then
return pos+2-offsets.base();
else
return 0;
end
end
offsets.new("StartDwarfs",f_dwarves) -- finds the starting dwarf count
function f_creatures()
--01C48034-base=0x1258034
local val=0
--print("Enter creature count:");
--local r=io.stdin:read()
for k,v in pairs(offsets.getvectors()) do
if (v>60) and (v<100) then --used count changed some time ago... two hits second one is the right one. Maybe some smarter way could be better?
--new version first one is right?? needs more testing thou...
val= k-offsets.base()
print(string.format("%x",val))
break;
end
--vec=engine.peek(k,ptr_vector);
--[[if(vec:size()==tonumber(r)) then
val=k-offsets.base()
print(string.format("off:%x",k))
end--]]
end
offsets.new("AdvCreatureVec",val)
return val
end
offsets.new("CreatureVec",f_creatures)
function f_words()
local val=0
for k,v in pairs(offsets.getvectors()) do
local toff=engine.peekd(engine.peekd(k))
if(engine.peekstr(toff)=="ABBEY") then
val=k-offsets.base()
end
end
return val
end
offsets.newlazy("WordVec",f_words)
function f_creatureptr() --a creature number under the pointer
pos=offsets.find(0,0xa1,ANYDWORD,0x83,0xf8,0xff,0x75)
print("Offset="..pos)
if pos~=0 then
pos=engine.peekd(pos+1)
return pos-offsets.base()
else
return 0
end
end
offsets.new("CreaturePtr",f_creatureptr)
function f_creaturegloss() --creature race vector
for k,v in pairs(offsets.getvectors()) do
if k~=0 then
--print("Looking into:"..string.format("%x",k).." used:"..v)
local vec=engine.peek(k,ptr_vector)
if vec:size()>0 and vec:size()<100000 and vec:getval(0)~=0 then
--print("\tval:"..string.format("%x",vec:getval(0)))
local token=engine.peek(vec:getval(0),ptt_dfstring)
--print("\t\tval:".. token:getval())
if token:getval()=="TOAD" then -- more offsets could be found this way
return k-offsets.base()
end
end
end
end
return 0
end
offsets.new("CreatureGloss",f_creaturegloss)
--reaction vec: search for TAN_A_HIDE
function f_racevec() --current race
--find all movsx anyreg,address
local den={}
local pos=offsets.findall(0,0x0f,0xbf,ANYBYTE,ADDRESS)
for k,v in pairs(pos) do
local add
if v~=0 then
add=engine.peekd(v+3)
if den[add]~=nil then
den[add]= den[add]+1
else
den[add]=1
end
end
end
for k,v in pairs(den) do
if v <60 then
den[k]=nil
end
end
for k,v in pairs(den) do
print("Looking into:"..string.format("%x",k).." used:"..v.." Race:"..engine.peekw(k))
if engine.peekw(k) >0 and engine.peekw(k)<1000 then
return k-offsets.base()
end
end
return 0
end
offsets.new("CurrentRace",f_racevec)
function f_pointer() --adventure (not only?) pointer x,y,z
print("\n")
local den={}
local pos=0
repeat
pos=offsets.find(pos+3,0x0f,0xb7,ANYBYTE,ADDRESS)
local add=engine.peekd(pos+3)
local add2=engine.peekd(pos+13)
local add3=engine.peekd(pos+23)
if( math.abs(add-add2)==4 or math.abs(add-add3)==4) then
if den[add]~=nil then
den[add]= den[add]+1
else
den[add]=1
end
end
until pos==0
for k,v in pairs(den) do
print("Looking into:"..string.format("%x",k).." used:"..v)
return k-offsets.base()-4
end
return 0
end
offsets.new("Xpointer",f_pointer)
function f_adventure()
RaceTable=RaceTable or BuildNameTable() -- this gets all the races' numbers
--[[print("input chars race:")
repeat
r=io.stdin:read()
if RaceTable[r]==nil then print("Incorrect race...") end
until RaceTable[r]~=nil -- query till correct race is inputed
rnum=RaceTable[r] --get its num
print("Race:"..rnum)]]--
myoff=0
print("input player's creature's name (lowercaps):")
r=io.stdin:read()
for k,v in pairs(offsets.getvectors()) do -- now lets look through all vector offsets
off=engine.peekd(k) --get vector start
off=engine.peekd(off) --get 0 element (or first) in adventurer mode its our hero
name=engine.peekstr(off)
if(name==r) then
--if engine.peek(off+140)==rnum then -- creature start+140 is the place where race is kept
print(string.format("%x race:%x",k,engine.peekw(off+140)))
myoff=k -- ok found it
break
end
end
if myoff~=0 then
crvec=engine.peek(myoff,ptr_vector)
print(string.format("player offset:%x",crvec:getval(0)))
local legidVec=engine.peek(crvec:getval(0),ptr_Creature.legends)
print(string.format("legends offset:%x",legidVec:getval(0)))
local vtable=engine.peekd(legidVec:getval(0))
print(string.format("vtable offset:%x",vtable))
offsets.new("vtableLegends",vtable-offsets.base())
return myoff-offsets.base() --save the offset for laters
else
return 0 --indicate failure
end
end
offsets.newlazy("AdvCreatureVec",f_adventure) -- register a way to find this offset
--7127F0
function f_legends()
pos=1
T={}
repeat
pos=offsets.find(pos+1,0x50,0xb8,ANYDWORD,0xe8,ANYDWORD,0x8b,0xf0)
off=engine.peekd(pos+2)
vec=engine.peek(off,ptr_vector)
if vec:size()~=0 then
if T[off]~=nil then
T[off].c=T[off].c+1
else
T[off]={c=1,vsize=vec:size()}
end
end
until pos==0
for k,v in pairs(T) do
vec=engine.peek(k,ptr_vector)
print(string.format("off:%x used:%i size:%d",k,v.c,v.vsize))
print(string.format("fith elements id:%d",engine.peekd(vec:getval(5))))
if engine.peekd(vec:getval(5))==5 then
--if v.c==2 and v.vsize>1000 then
return k-offsets.base()
end
end
return 0
end
offsets.newlazy("Legends",f_legends)
function f_playerlegendid()
local off=offsets.getEx("Legends")
local pos=1
repeat
pos=offsets.find(pos+1,0xa1,DWORD_,off+4,0x2b,0x05,DWORD_,off)
val=engine.peekd(pos+16)
if engine.peekd(val)~=0 then
--if val >offsets.base() then
return val-offsets.base()
end
--print(string.format("%x",val))
until pos==0
return 0
end
offsets.newlazy("PlayerLegend",f_playerlegendid)
function f_world()
local pos=offsets.base()
T={}
while pos~=0 do
--pos=offsets.find(pos+6,0xa1,DWORD_,mapoffset,0x8b,0x4c,0x88,0xFC)
pos=offsets.find(pos+6,0x8b,0x35,ANYDWORD,0x85,0xf6)--,0x8b,0x4c,0x88,0xFC)
--pos2=offsets.find(pos,0x8b,0x34,0x88)
if pos~=0 then
add=engine.peekd(pos+2);
--if pos2 ~=0 and pos2-pos<25 then
-- print(string.format("Address:%x dist:%d Map:%x",pos2,pos2-pos,add))
--
--end
if add~=0 then
if T[add]~=nil then
T[add]=T[add]+1
else
T[add]=1
end
end
end
end
local kk,vv
vv=0
for k,v in pairs(T) do
if v>vv then
vv=v
kk=k
end
--print(string.format("Address:%x, times used:%d",k,v))
end
return kk-offsets.base()
end
offsets.new("WorldData",f_world)
function f_sites()
local pos=offsets.base()
T={}
while pos~=0 do
pos=offsets.find(pos+17,0xA1,ANYDWORD, --mov eax, ptr to some biger thing
0x8B,0x90,0x24,0x01,0x00,0x00, --mov edx [eax+0x124]
0x2b,0x90,0x20,0x01,0x00,0x00, --sub edx [eax+0x120]
EOL)
if pos~=0 then
add=engine.peekd(pos+1)
return add-offsets.base()
end
end
return 0
end
offsets.newlazy("SiteData",f_sites) --actually has a lot more data...
function f_items()
local pos=offsets.base()
while pos~= 0 do
pos=offsets.find(pos+17,0x8b,0x0d,ANYDWORD, --mov eax, ptr to some biger thing
0x8B,0x54,0x24,0x34)
if pos~=0 then
--print(string.format("%x",engine.peekd(pos+2)))
local ret=engine.peekd(pos+2)-offsets.base()
return ret
end
end
return 0
end
offsets.new("Items",f_items)
function f_materials()
for k,v in pairs(offsets.getvectors()) do
--print("Looking into:"..string.format("%x",k).." used:"..v)
local vec=engine.peek(k,ptr_vector)
if vec:getval(0)~=0 then
--print("\tval:"..string.format("%x",vec:getval(0)))
local token=engine.peek(vec:getval(0),ptt_dfstring)
if token:getval()~=""then
--print("\t\tval:".. token:getval())
if token:getval()=="IRON" then
--print("Found:"..string.format("%x",k).." used:"..v)
return k-offsets.base()
end
end
end
end
return 0
end
offsets.new("Materials",f_materials)

@ -0,0 +1,2 @@
offsets.searchoffsets()
offsets.save()

@ -0,0 +1,103 @@
offsets=offsets or {}
offsets._toff={}
offsets._foff={}
offsets.get = function (name)
if offsets._toff[name] == nil then
offsets.searchoffset(name,true)
end
return offsets._toff[name]
end
offsets.getEx = function (name)
--return offsets._toff[name]+Process.getBase()
return offsets.get(name)+Process.getBase()
end
offsets.load = function ()
local f=io.open("dfusion/offsets.txt")
local line=f:read()
while line~=nil do
--print(line)
local sppliter=string.find(line,":")
offsets._toff[string.sub(line,1,sppliter-2)]=tonumber(string.sub(line,sppliter+2))
line=f:read()
end
end
offsets.save = function ()
local f=io.open("dfusion/offsets.txt","w")
for k,v in pairs(offsets._toff) do
f:write(string.format("%s : 0x%x\n",k,v))
end
f:close()
end
function offsets.new(name, func)
if type(func)=="function" then
table.insert(offsets._foff,{name,func,false})
else
offsets._toff[name]=func
end
--offsets._foff[name]={func,false}
end
function offsets.newlazy(name, func)
table.insert(offsets._foff,{name,func,true})
--offsets._foff[name]={func,true}
end
function offsets.searchoffset(num,forcelazy)
v=offsets._foff[num]
print("Finding offset:"..v[1])
if (v[3] and focelazy) or not v[3] then
local pos=v[2]()
if pos== 0 then
error("Offset not found for:"..v[1])
else
offsets._toff[v[1]]=pos
end
end
end
function offsets.searchoffsets(forcelazy)
for k,v in pairs(offsets._foff) do
offsets.searchoffset(k,forcelazy)
end
end
function offsets.find(startoffset,...)
local endadr;
if startoffset== 0 then
local text=GetTextRegion()
--print("searching in:"..text.name)
startoffset=text.start
endadr=text["end"]
else
local reg=GetRegionIn(startoffset)
--print("searching in:"..reg.name)
endadr=reg["end"]
end
local h=hexsearch(startoffset,endadr,...)
local pos=h:find()
h=nil
return pos
end
function offsets.findall(startoffset,...)
local endadr;
if startoffset== 0 then
local text=GetTextRegion()
--print("searching in:"..text.name)
startoffset=text.start
endadr=text["end"]
else
local reg=GetRegionIn(startoffset)
--print("searching in:"..reg.name)
endadr=reg["end"]
end
local h=hexsearch(startoffset,endadr,...)
local pos=h:findall()
h=nil
return pos
end
function offsets.base()
return Process.getBase()
end
function offsets.getvectors()
return findVectors()
end
offsets.load()
ADDRESS=ANYDWORD
dofile("dfusion/offsets.lua")

@ -68,6 +68,7 @@ function ptr_vector:size()
end
ptr_vector.type=DWORD
function ptr_vector:getval(num)
if self.st==0 then return 0 end
return engine.peek(self.st+engine.sizeof(self.type)*num,self.type)
end
function ptr_vector:setval(num,val)