Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local cmd = 'NEXT_RIP'
- unregisterAutoAssemblerCommand(cmd)
- registerAutoAssemblerCommand(cmd,function()return ''end)
- local function assembled_bytes(start_addr, tmpl, ctx)
- local rid = '_'..math.random(10000,99999)..'_'
- local ret, prefix, post_code, subfix = {}, {}, {}
- local code = string.format([[
- %X:
- %s
- <END_BYTES>:]], start_addr, tmpl)
- :gsub('<%s*([_%a][_%w]*)%s*>',function(sym)
- local rsym = rid..sym
- if not ret[sym] then
- local idx = 1+#ret
- ret[sym], ret[idx] = idx, sym
- prefix[idx] = string.format('registerSymbol(%s)',rsym)
- post_code[idx] = 'un'..prefix[idx]
- -- print('sym',sym)
- end
- return rsym
- end)
- :gsub('%(%s*%%([xXdDsS])%s+([_%a][_%w]*)%s*%)',function(fms, name)
- local v = ctx[name]
- if v then return string.format('%'..fms,v)end
- end)
- code = table.concat({table.concat(prefix), code}, '\n')
- -- prt(code)
- -- prt(autoAssembleCheck(code))
- if autoAssemble(code)then
- -- print(#ret)
- for i=1,#ret do
- local sym, rsym = ret[i], rid .. ret[i]
- ret[sym] = getAddressSafe(rsym)
- -- prt(string.format('%2d %16X %s', i, ret[sym], sym ))
- end
- autoAssemble(table.concat(post_code,'\n'))-- unreg symbols
- if ret.END_BYTES then
- local len = ret.END_BYTES - start_addr
- return readBytes(start_addr, len, true), len, ret
- end
- end
- end
- if next_rip_reg_asm_id then
- next_rip_reg_asm_id = nil, unregisterAssembler(next_rip_reg_asm_id)
- end
- next_rip_reg_asm_id = registerAssembler(function(adr, inst)
- -- prt.f('%X : %s // %s',adr,inst, disassemble(adr)) local i
- if adr < 0x1000 then return {0x90}end
- local op, ops = inst:lower():match'^%s*([_%a][_%w]*)%s*(.-)%s*$'
- -- prt('op/ops',op,ops)
- if not op then return end -- don't know what to do, let ce handle
- if op:upper():sub(1,#cmd)==cmd then -- next_rip command (to setup lua global next_rip_setup)
- -- prt'>> next_rip'
- local remove_bracket = ops:match'%b()'
- if remove_bracket then ops = remove_bracket:sub(2,-2)end
- ops = ' '..ops..' ' -- spaces to match optional
- local use_reg, base, ofs_rip, ofs_end, sz_rip, rip_read_addr =
- ops:match'^%s*([_%w]-)%s+(%S+)%s+(%x+)%s+(%x+)%s+(%x*)%s+(%S*)$'
- -- prt(ops,'|', use_reg, base, ofs_rip, ofs_end, sz_rip, rip_read_addr)
- if not use_reg then
- return nil,'format : use_reg base ofs_rip ofs_end ?sz_rip ?rip_read_addr'
- end
- if use_reg:len()==0 or use_reg=='_'then use_reg = 'r11'end
- if sz_rip:len()==0 then sz_rip='4' end-- either 4 or 1
- if rip_read_addr:len()==0 then rip_read_addr = '0'end
- next_rip_setup = {
- use_reg = use_reg,
- base = getAddressSafe(base),
- ofs_rip = getAddressSafe(ofs_rip),
- ofs_end = getAddressSafe(ofs_end),
- sz_rip = getAddressSafe(sz_rip),
- rip_read_addr = getAddressSafe(rip_read_addr)
- }
- return {0x90}
- end
- if not next_rip_setup then return end -- the following require next_rip_setup
- local X = next_rip_setup
- next_rip_setup = nil -- clear global next_rip_setup, so it won't use on following wrong instruction
- local use_reg, base, ofs_rip, ofs_end, sz_rip, rip_read_addr =
- X.use_reg, X.base, X.ofs_rip, X.ofs_end, X.sz_rip, X.rip_read_addr
- -- prt(ops,'=', use_reg, base, ofs_rip, ofs_end, sz_rip, rip_read_addr)
- if not (use_reg and base and ofs_rip and ofs_end and sz_rip and rip_read_addr)then
- return nil,'oops'
- end
- local read =
- sz_rip == 4 and function(addr)return readInteger(addr,true)end or -- sz_rip==1
- sz_rip == 1 and function(addr)
- addr = readBytes(addr)
- if addr and addr>0x7f then addr = 0x100 - addr end
- return addr
- end
- if not read then return nil,'only 1 or 4 bytes rip'end
- local RIP_ADDR = rip_read_addr~=0 and read(rip_read_addr)
- RIP_ADDR = not RIP_ADDR and rip_read_addr==0 and read(base + ofs_rip)
- RIP_ADDR = RIP_ADDR and RIP_ADDR + base + ofs_end
- if not RIP_ADDR then-- let ce handle
- elseif op=='jmp' or op=='call'then
- if ops:find('*rip',1,true)then
- return assembled_bytes(adr, [[
- mov (%s reg),(%X RIP_ADDR)
- (%s op) (%s reg)
- __done:
- ]], {
- op = op,
- reg = use_reg,
- RIP_ADDR = RIP_ADDR
- })
- end
- elseif op:match'^j' then --- format 1, should be jcc
- -- prt'>> jmp/call'
- return assembled_bytes(adr, [[
- (%s op) short __yes_path
- no_path:
- jmp short __done
- __yes_path:
- jmp (%X RIP_ADDR)
- __done:
- ]], {
- op = op,
- RIP_ADDR = RIP_ADDR
- })
- elseif ops:match'%[%s*.+%s*%]'then -- format 2
- -- prt'>> memory[rip]'
- local lhs, rhs = ops:match'^(.-%[)%s*.+%s*(%].-)$'
- return assembled_bytes(adr, [[
- push (%s reg)
- mov (%s reg),(%X RIP_ADDR)
- (%s op) (%s lhs)(%s reg)(%s rhs)
- pop (%s reg)
- ]], {
- reg = use_reg,
- op = op,
- lhs = lhs,
- rhs = rhs,
- RIP_ADDR = RIP_ADDR
- })
- end
- -- no other format atm
- return nil
- end)
- ---[===[
- --- may place the following in a memory record, replace 'mov eax,%X' properly
- cnt = type(cnt)=='number'and cnt+0x111111 or 0x10000000
- local code = string.format([[
- globalalloc(__X,$1000)
- __X:
- mov eax,%X
- mov rax,-1
- //// lua53-64.lua_absindex+B:
- //// - 77 13 - ja lua53-64.lua_absindex+20
- reassemble(lua53-64.lua_absindex+B) /// ce seem do it not right, ja * -> jmp *,
- /// but my ce version may be outdated and it already been fixed.
- NEXT_RIP (_ lua53-64.lua_absindex+B 1 2 1) /// note the last 1, set rip_displacment_size 1 byte
- reassemble(lua53-64.lua_absindex+B)
- mov rax,-1
- NEXT_RIP (_ lua53-64.lua_absindex+B 1 2 1)
- je 1 /// jcc following NEXT_RIP can have a dummy target address, the RIP_ADDR will replace it
- mov rax,-1
- //// lua53-64.lua_version+5:
- //// - 48 8D 05 FC7B0600 - lea rax,[lua53-64.dll.rdata+9F28] /// also displace as lua53-64.dll+68F28
- reassemble(lua53-64.lua_version+5)
- mov rax,-1
- NEXT_RIP (rax lua53-64.lua_version+5 3 7) /// note there is 2 number following base addr, rip-size default 4 bytes
- reassemble(lua53-64.lua_version+5)
- mov rax,-1
- NEXT_RIP (rax lua53-64.lua_version+5 3 7)
- mov rbx,[rax] /// similar to jcc, register with NEXT_RIP will replace inside [*dummy]
- mov rax,-1
- NEXT_RIP (rax lua53-64.lua_version+5 3 7)
- call *rip /// normally NEXT_RIP should not apply to direct jmp/call, but if it is '*rip' then RIP_ADDR is replaced
- mov rax,-1
- ret
- @@:
- mov rax,-1
- mov rax,-1
- ]], cnt)
- autoAssembleCheck(code)
- autoAssemble(code)
- --[[ edited output
- __X:
- 048A0000- mov eax,10000000
- 048A0005- mov rax,FFFFFFFFFFFFFFFF
- 048A000F- nop
- 048A0010- nop
- 048A0011- jmp lua53-64.lua_absindex+20 /// ce's reassemble
- 048A001F- nop
- 048A0020- ja 048A0024
- 048A0022- jmp 048A0032
- 048A0024- jmp lua53-64.lua_absindex+20
- 048A0032- mov rax,FFFFFFFFFFFFFFFF
- 048A003C- nop
- 048A003D- je 048A0041
- 048A003F- jmp 048A004F
- 048A0041- jmp lua53-64.lua_absindex+20
- 048A004F- mov rax,FFFFFFFFFFFFFFFF
- 048A0059- mov rax,lua53-64.dll.rdata+9F28
- 048A0063- mov rax,FFFFFFFFFFFFFFFF
- 048A006D- nop
- 048A006E- mov rax,lua53-64.dll.rdata+9F28
- 048A0078- mov rax,FFFFFFFFFFFFFFFF
- 048A0082- nop
- 048A0083- push rax
- 048A0084- mov rax,lua53-64.dll.rdata+9F28
- 048A008E- mov rbx,[rax]
- 048A0091- pop rax
- 048A0092- mov rax,FFFFFFFFFFFFFFFF
- 048A009C- nop
- 048A009D- mov rax,lua53-64.dll.rdata+9F28
- 048A00A7- call rax
- 048A00A9- mov rax,FFFFFFFFFFFFFFFF
- 048A00B3- ret
- 048A00B4- mov rax,FFFFFFFFFFFFFFFF
- 048A00BE- mov rax,FFFFFFFFFFFFFFFF
- --]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement