Advertisement
panraven

next_rip

Feb 26th, 2023 (edited)
466
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.56 KB | None | 0 0
  1. local cmd = 'NEXT_RIP'
  2. unregisterAutoAssemblerCommand(cmd)
  3. registerAutoAssemblerCommand(cmd,function()return ''end)
  4.  
  5. local function assembled_bytes(start_addr, tmpl, ctx)
  6.   local rid = '_'..math.random(10000,99999)..'_'
  7.   local ret, prefix, post_code, subfix = {}, {}, {}
  8.   local code = string.format([[
  9.   %X:
  10.   %s
  11.   <END_BYTES>:]], start_addr, tmpl)
  12.     :gsub('<%s*([_%a][_%w]*)%s*>',function(sym)
  13.       local rsym = rid..sym
  14.       if not ret[sym] then
  15.         local idx = 1+#ret
  16.         ret[sym], ret[idx] = idx, sym
  17.         prefix[idx] = string.format('registerSymbol(%s)',rsym)
  18.         post_code[idx] = 'un'..prefix[idx]
  19. --        print('sym',sym)
  20.       end
  21.       return rsym
  22.     end)
  23.     :gsub('%(%s*%%([xXdDsS])%s+([_%a][_%w]*)%s*%)',function(fms, name)
  24.       local v = ctx[name]
  25.       if v then return string.format('%'..fms,v)end
  26.     end)
  27.   code = table.concat({table.concat(prefix), code}, '\n')
  28. --  prt(code)
  29. --  prt(autoAssembleCheck(code))
  30.   if autoAssemble(code)then
  31. --    print(#ret)
  32.     for i=1,#ret do
  33.       local sym, rsym = ret[i], rid .. ret[i]
  34.       ret[sym] = getAddressSafe(rsym)
  35. --      prt(string.format('%2d %16X %s', i, ret[sym], sym ))
  36.     end
  37.     autoAssemble(table.concat(post_code,'\n'))-- unreg symbols
  38.     if ret.END_BYTES then
  39.       local len = ret.END_BYTES - start_addr
  40.       return readBytes(start_addr, len, true), len, ret
  41.     end
  42.   end
  43. end
  44.  
  45.  
  46.  
  47. if next_rip_reg_asm_id then
  48.   next_rip_reg_asm_id = nil, unregisterAssembler(next_rip_reg_asm_id)
  49. end
  50. next_rip_reg_asm_id = registerAssembler(function(adr, inst)
  51. --  prt.f('%X : %s  //  %s',adr,inst, disassemble(adr))  local i
  52.   if adr < 0x1000 then return {0x90}end
  53.   local op, ops = inst:lower():match'^%s*([_%a][_%w]*)%s*(.-)%s*$'
  54. --    prt('op/ops',op,ops)
  55.   if not op then return end -- don't know what to do, let ce handle
  56.   if op:upper():sub(1,#cmd)==cmd then -- next_rip command (to setup lua global next_rip_setup)
  57. --    prt'>> next_rip'
  58.     local remove_bracket = ops:match'%b()'
  59.     if remove_bracket then ops = remove_bracket:sub(2,-2)end
  60.     ops = ' '..ops..'  ' -- spaces to match optional
  61.     local use_reg, base, ofs_rip, ofs_end, sz_rip, rip_read_addr =
  62.       ops:match'^%s*([_%w]-)%s+(%S+)%s+(%x+)%s+(%x+)%s+(%x*)%s+(%S*)$'
  63. --    prt(ops,'|', use_reg, base, ofs_rip, ofs_end, sz_rip, rip_read_addr)
  64.     if not use_reg then
  65.       return nil,'format : use_reg base ofs_rip ofs_end ?sz_rip ?rip_read_addr'
  66.     end
  67.     if use_reg:len()==0 or use_reg=='_'then use_reg = 'r11'end
  68.     if sz_rip:len()==0 then sz_rip='4' end-- either 4 or 1
  69.     if rip_read_addr:len()==0 then rip_read_addr = '0'end
  70.     next_rip_setup = {
  71.       use_reg = use_reg,
  72.       base = getAddressSafe(base),
  73.       ofs_rip = getAddressSafe(ofs_rip),
  74.       ofs_end = getAddressSafe(ofs_end),
  75.       sz_rip = getAddressSafe(sz_rip),
  76.       rip_read_addr = getAddressSafe(rip_read_addr)
  77.     }
  78.     return {0x90}
  79.   end
  80.   if not next_rip_setup then return end -- the following require next_rip_setup
  81.   local X = next_rip_setup
  82.   next_rip_setup = nil -- clear global next_rip_setup, so it won't use on following wrong instruction
  83.   local use_reg, base, ofs_rip, ofs_end, sz_rip, rip_read_addr =
  84.     X.use_reg, X.base, X.ofs_rip, X.ofs_end, X.sz_rip, X.rip_read_addr
  85. --    prt(ops,'=', use_reg, base, ofs_rip, ofs_end, sz_rip, rip_read_addr)
  86.   if not (use_reg and base and ofs_rip and ofs_end and sz_rip and rip_read_addr)then
  87.     return nil,'oops'
  88.   end
  89.   local read =
  90.     sz_rip == 4 and function(addr)return readInteger(addr,true)end or -- sz_rip==1
  91.     sz_rip == 1 and function(addr)
  92.       addr = readBytes(addr)
  93.       if addr and addr>0x7f then addr = 0x100 - addr end
  94.       return addr
  95.     end
  96.   if not read then return nil,'only 1 or 4 bytes rip'end
  97.   local RIP_ADDR = rip_read_addr~=0 and read(rip_read_addr)
  98.   RIP_ADDR = not RIP_ADDR and rip_read_addr==0 and read(base + ofs_rip)
  99.   RIP_ADDR = RIP_ADDR and RIP_ADDR + base + ofs_end
  100.   if not RIP_ADDR then-- let ce handle
  101.   elseif op=='jmp' or op=='call'then
  102.     if ops:find('*rip',1,true)then
  103.     return assembled_bytes(adr, [[
  104.         mov  (%s reg),(%X RIP_ADDR)
  105.         (%s op)  (%s reg)
  106.         __done:
  107.       ]], {
  108.         op = op,
  109.         reg = use_reg,
  110.         RIP_ADDR = RIP_ADDR
  111.       })
  112.     end
  113.   elseif op:match'^j' then --- format 1, should be jcc
  114.   --  prt'>> jmp/call'
  115.     return assembled_bytes(adr, [[
  116.       (%s op) short __yes_path
  117.       no_path:
  118.       jmp short __done
  119.       __yes_path:
  120.       jmp  (%X RIP_ADDR)
  121.       __done:
  122.     ]], {
  123.       op = op,
  124.       RIP_ADDR = RIP_ADDR
  125.     })
  126.   elseif ops:match'%[%s*.+%s*%]'then -- format 2
  127. --    prt'>> memory[rip]'
  128.     local lhs, rhs = ops:match'^(.-%[)%s*.+%s*(%].-)$'
  129.     return assembled_bytes(adr, [[
  130.       push     (%s reg)
  131.         mov    (%s reg),(%X RIP_ADDR)
  132.         (%s op) (%s lhs)(%s reg)(%s rhs)
  133.       pop      (%s reg)
  134.     ]], {
  135.       reg = use_reg,
  136.       op = op,
  137.       lhs = lhs,
  138.       rhs = rhs,
  139.       RIP_ADDR = RIP_ADDR
  140.     })
  141.   end
  142.   -- no other format atm
  143.   return nil
  144. end)
  145. ---[===[
  146.  
  147. --- may place the following in a memory record, replace 'mov eax,%X' properly
  148.  
  149. cnt = type(cnt)=='number'and cnt+0x111111 or 0x10000000
  150.  
  151. local code = string.format([[
  152. globalalloc(__X,$1000)
  153. __X:
  154. mov eax,%X
  155. mov rax,-1
  156.  
  157. //// lua53-64.lua_absindex+B:
  158. //// - 77 13                 - ja lua53-64.lua_absindex+20
  159.  
  160. reassemble(lua53-64.lua_absindex+B) /// ce seem do it not right, ja * -> jmp *,
  161.                                     /// but my ce version may be outdated and it already been fixed.
  162. NEXT_RIP (_ lua53-64.lua_absindex+B 1 2 1) /// note the last 1, set rip_displacment_size 1 byte
  163. reassemble(lua53-64.lua_absindex+B)
  164. mov rax,-1
  165. NEXT_RIP (_ lua53-64.lua_absindex+B 1 2 1)
  166. je 1 /// jcc following NEXT_RIP can have a dummy target address, the RIP_ADDR will replace it
  167. mov rax,-1
  168.  
  169. //// lua53-64.lua_version+5:
  170. //// - 48 8D 05 FC7B0600     - lea rax,[lua53-64.dll.rdata+9F28] /// also displace as lua53-64.dll+68F28
  171.  
  172. reassemble(lua53-64.lua_version+5)
  173. mov rax,-1
  174. NEXT_RIP (rax lua53-64.lua_version+5 3 7) /// note there is 2 number following base addr, rip-size default 4 bytes
  175. reassemble(lua53-64.lua_version+5)
  176. mov rax,-1
  177. NEXT_RIP (rax lua53-64.lua_version+5 3 7)
  178. mov    rbx,[rax] /// similar to jcc, register with NEXT_RIP will replace inside [*dummy]
  179. mov rax,-1
  180. NEXT_RIP (rax lua53-64.lua_version+5 3 7)
  181. call   *rip /// normally NEXT_RIP should not apply to direct jmp/call, but if it is '*rip' then RIP_ADDR is replaced
  182. mov rax,-1
  183. ret
  184. @@:
  185. mov rax,-1
  186. mov rax,-1
  187. ]], cnt)
  188.  
  189. autoAssembleCheck(code)
  190. autoAssemble(code)
  191. --[[  edited output
  192. __X:
  193. 048A0000- mov   eax,10000000
  194. 048A0005- mov   rax,FFFFFFFFFFFFFFFF
  195. 048A000F- nop
  196. 048A0010- nop
  197. 048A0011- jmp   lua53-64.lua_absindex+20   ///  ce's reassemble
  198. 048A001F- nop
  199. 048A0020- ja    048A0024
  200. 048A0022- jmp   048A0032
  201. 048A0024- jmp   lua53-64.lua_absindex+20
  202. 048A0032- mov   rax,FFFFFFFFFFFFFFFF
  203. 048A003C- nop
  204. 048A003D- je    048A0041
  205. 048A003F- jmp   048A004F
  206. 048A0041- jmp   lua53-64.lua_absindex+20
  207. 048A004F- mov   rax,FFFFFFFFFFFFFFFF
  208. 048A0059- mov   rax,lua53-64.dll.rdata+9F28
  209. 048A0063- mov   rax,FFFFFFFFFFFFFFFF
  210. 048A006D- nop
  211. 048A006E- mov   rax,lua53-64.dll.rdata+9F28
  212. 048A0078- mov   rax,FFFFFFFFFFFFFFFF
  213. 048A0082- nop
  214. 048A0083- push  rax
  215. 048A0084- mov   rax,lua53-64.dll.rdata+9F28
  216. 048A008E- mov   rbx,[rax]
  217. 048A0091- pop   rax
  218. 048A0092- mov   rax,FFFFFFFFFFFFFFFF
  219. 048A009C- nop
  220. 048A009D- mov   rax,lua53-64.dll.rdata+9F28
  221. 048A00A7- call  rax
  222. 048A00A9- mov   rax,FFFFFFFFFFFFFFFF
  223. 048A00B3- ret
  224. 048A00B4- mov   rax,FFFFFFFFFFFFFFFF
  225. 048A00BE- mov   rax,FFFFFFFFFFFFFFFF
  226.  
  227.  
  228. --]]
  229.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement