Pre-class remove

develop
Warmist 2012-11-11 11:58:43 +02:00
parent e887c60e93
commit f1d4eac700
8 changed files with 234 additions and 3 deletions

@ -66,8 +66,10 @@ mov eax, [edi+0x8c]
#jmp compare
compare:
push ecx
mark_racepointer:
mov ebx,0xDEADBEEF #write a pointer to the list of allowed races
mov ecx,2000 #write a number of allowed races
mark_racecount:
mov ecx,0xDEADBEEF #write a number of allowed races
loop1:
cmp word[ebx+ecx*2],ax
jz endok
@ -92,11 +94,13 @@ endfinal:
pop ebx
pop eax
mov [0xFEEDBEEF],eax #write a pointer to safe location (usually after this)
mark_safeloc1:
mov [0xDEADBEEF],eax #write a pointer to safe location (usually after this)
pop eax
pushfd
inc eax #skip one instruction
popfd
push eax
mov eax,[0xFEEDBEEF] #write a pointer to safe location (same as above)
mark_safeloc2:
mov eax,[0xDEADBEEF] #write a pointer to safe location (same as above)
ret

@ -4,6 +4,8 @@ local ms=require("memscan")
local MAX_RACES=100
CustomEmbark=defclass(CustomEmbark,dfu.BinaryPlugin)
CustomEmbark.name="CustomEmbark"
print(t)
local myos=dfhack.getOSType()
if myos=="windows" then
CustomEmbark.ATTRS{filename="hack/lua/plugins/dfusion/embark.o",name="CustomEmbark",race_caste_data=DEFAULT_NIL}

@ -0,0 +1,111 @@
local _ENV = mkmodule('plugins.dfusion.friendship')
local dfu=require("plugins.dfusion")
local ms=require("memscan")
local MAX_RACES=100
local MAX_CODE_DIST=250
FriendshipRainbow=defclass(FriendshipRainbow,dfu.BinaryPlugin)
FriendshipRainbow.name="FriendshipRainbow"
-- os independant... I think...
FriendshipRainbow.ATTRS{filename="hack/lua/plugins/dfusion/friendship.o",name="FriendshipRainbow",race_data=DEFAULT_NIL}
FriendshipRainbow.class_status="valid, not installed"
function FriendshipRainbow:find_one(codesg,needle,crace)
dfu.concatTables(needle,dfu.dwordToTable(crace))
return codesg.uint8_t:findall(needle)
end
function FriendshipRainbow:find_all()
local code=ms.get_code_segment()
local locations={}
local _,crace=df.sizeof(df.global.ui:_field("race_id"))
dfu.concatTables(locations,self:find_one(code,{0x66,0xa1},crace)) --mov ax,[ptr]
dfu.concatTables(locations,self:find_one(code,{0xa1},crace)) --mov ax,[ptr]
local registers=
{0x05, -- (e)ax
0x1d, --ebx
0x0d, --ecx
0x15, --edx
0x35, --esi
0x3d, --edi
--0x25, --esp not used?
--0x2d, --ebp not used?
}
for k,reg in ipairs(registers) do
dfu.concatTables(locations,self:find_one(code,{0x0f,0xbf,reg},crace)) --movsx reg,[ptr]
dfu.concatTables(locations,self:find_one(code,{0x66,0x8b,reg},crace)) --mov reg,[ptr]
end
printall(locations)
return self:filter_locations(code,locations)
end
function FriendshipRainbow:filter_locations(codesg,locations)
local ret={}
local registers={0x80,0x83,0x81,0x82,0x86,0x87,
0x98,0x9b,0x99,0x9a,0x9e,0x9f,
0x88,0x8b,0x89,0x8a,0x8e,0x8f,
0x90,0x93,0x91,0x92,0x96,0x97,
0xb0,0xb3,0xb1,0xb2,0xb6,0xb7,
0xb8,0xbb,0xb9,0xba,0xbe,0xbf}
for _,entry in ipairs(locations) do
for _,r in ipairs(registers) do
local idx,addr=codesg.uint8_t:find({0x39,r,0x8c,0x00,0x00,0x00},
codesg.uint8_t:addr2idx(entry[2]),codesg.uint8_t:addr2idx(entry[2])+MAX_CODE_DIST)
if addr then
table.insert(ret,{addr,r})
break
end
idx,addr=codesg.uint8_t:find({0x3b,r,0x8c,0x00,0x00,0x00},
codesg.uint8_t:addr2idx(entry[2]),codesg.uint8_t:addr2idx(entry[2])+MAX_CODE_DIST)
if addr then
table.insert(ret,{addr,r})
break
end
end
end
return ret
end
function FriendshipRainbow:patchCalls(target)
local addrs=self:find_all()
local swaps={}
for k,adr in ipairs(addrs) do
local newval=dfu.makeCall(adr[1],target)
table.insert(newval,adr[2])
for t,val in ipairs(newval) do
swaps[adr[1]+t-1]=val
end
end
dfhack.internal.patchBytes(swaps)
end
function FriendshipRainbow:set_races(arr)
local n_to_id=require("plugins.dfusion.tools").build_race_names()
local ids={}
for k,v in ipairs(self.race_data) do -- to check if all races are valid.
ids[k]=n_to_id[v]
end
for k,v in ipairs(ids) do
arr[k-1]=ids[k]
end
end
function FriendshipRainbow:install(races)
self.race_data=races or self.race_data
if #self.race_data<1 then
error("race count must be bigger than 0")
end
if #self.race_data>MAX_RACES then
error("race count must be less then "..MAX_RACES)
end
local rarr=self:allocate("race_array",'uint16_t',MAX_RACES)
local _,rarr_offset=df.sizeof(rarr)
self:set_marker_dword("racepointer",rarr_offset)
self:set_races(rarr)
self:set_marker_dword("racecount",#self.race_data)
local safe_loc=self:allocate("safe_loc",'uint32_t',1)
local _1,safe_loc_offset=df.sizeof(safe_loc)
self:set_marker_dword("safeloc1",safe_loc_offset)
self:set_marker_dword("safeloc2",safe_loc_offset)
local addr=self:move_to_df()
self:patchCalls(addr)
self.installed=true
end
return _ENV

Binary file not shown.

@ -0,0 +1 @@
as -anl --32 -o friendship.o friendship.asm

@ -0,0 +1,7 @@
.intel_syntax
mov eax , [esp+0x1C] # loop counter
mark_caste:
movsx ecx, word ptr[eax*2+0xdeadbeef]
mark_race:
movzx eax,word ptr [eax*2+0xDEADBEEF]
ret

@ -0,0 +1,106 @@
.intel_syntax
push eax
mov eax,[esp+0x04]
push ebx
pushfd
mov eax,[eax] # get a byte after the call this procedure to analyze what register holds cr ptr
jmptbl:
cmp al,0x81
jz regC
cmp al,0x82
jz regD
cmp al,0x83
jz regB
cmp al,0x85
jz regBP
cmp al,0x86
jz regESI
cmp al,0x87
jz regEDI
cmp al,0x88
jz regA
cmp al,0x8A
jz regD
cmp al,0x8B
jz regB
cmp al,0x8D
jz regBP
cmp al,0x8E
jz regESI
cmp al,0x8F
jz regEDI
cmp al,0x90
jz regA
cmp al,0x91
jz regC
cmp al,0x93
jz regB
cmp al,0x95
jz regBP
cmp al,0x96
jz regESI
cmp al,0x97
jz regEDI
jmp fail
regA:
mov eax, [esp+0x8]
mov eax, [eax+0x8c]
jmp compare
regC:
mov eax, [ecx+0x8c]
jmp compare
regB:
mov eax, [ebx+0x8c]
jmp compare
regD:
mov eax, [edx+0x8c]
jmp compare
regBP:
mov eax, [ebp+0x8c]
jmp compare
regESI:
mov eax, [esi+0x8c]
jmp compare
regEDI:
mov eax, [edi+0x8c]
#jmp compare
compare:
push ecx
mark_racepointer:
mov ebx,0xDEADBEEF #write a pointer to the list of allowed races
mark_racecount:
mov ecx,0xDEADBEEF #write a number of allowed races
loop1:
cmp word[ebx+ecx*2],ax
jz endok
dec ecx
cmp ecx ,-1
jnz loop1
pop ecx
popfd
jmp fail
endok:
pop ecx
popfd
cmp eax,eax
jmp endfinal
fail:
xor ebx,ebx
xor eax,eax
inc eax
cmp eax,ebx
endfinal:
pop ebx
pop eax
mark_safeloc1:
mov [0xDEADBEEF],eax #write a pointer to safe location (usually after this)
pop eax
pushfd
inc eax #skip one instruction
popfd
push eax
mark_safeloc2:
mov eax,[0xDEADBEEF] #write a pointer to safe location (same as above)
ret