Advertisement
ProgramCrafter

ElfEXEC

Feb 24th, 2021
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.12 KB | None | 0 0
  1. -- .ELF file runner (v-1.-1.-1)
  2. -- (c) ProgramCrafter
  3.  
  4. local function ByteStream()
  5.   local t = {}
  6.   local cidx = 0
  7.  
  8.   local bitstream = {
  9.     extend = function(len, value)
  10.       for i = 1, len do
  11.         t[cidx + i] = value or 0
  12.       end
  13.       cidx = cidx + len
  14.     end,
  15.     put = function(...)
  16.       for i = 1, table.pack(...).n do
  17.         t[cidx + 1] = select(i, ...) or 0
  18.         cidx = cidx + 1
  19.       end
  20.     end,
  21.     puts = function(s)
  22.       for i = 1, #s do
  23.         t[cidx + i] = s:byte(i)
  24.       end
  25.       cidx = cidx + #s
  26.     end,
  27.     read = function(len)
  28.       cidx = cidx + len
  29.       return table.unpack(t, cidx - len + 1, cidx)
  30.     end,
  31.     seek = function(new_idx)
  32.       if not new_idx then return cidx end
  33.       cidx = new_idx
  34.     end,
  35.     len = function()
  36.       return #t
  37.     end,
  38.     __raw = t
  39.   }
  40.  
  41.   return bitstream
  42. end
  43.  
  44. local function is_like(t1, t2)
  45.   if #t1 ~= #t2 then return false end
  46.   for i = 1, #t1 do
  47.     if t1[i] ~= t2[i] and t2[i] then return false end
  48.   end
  49.   return true
  50. end
  51. local function assert_like(msg, t, pattern)
  52.   local a = is_like(t, pattern) and '\27[32mOK:  ' or '\27[33mFAIL: '
  53.   print(a .. msg .. '\27[37m')
  54.   if a:find('FAIL') then
  55.     print('Found', table.unpack(t))
  56.     print('Needs', table.unpack(pattern))
  57.     error('Assertion failure')
  58.   end
  59. end
  60. local function lton(t)
  61.   local n = 0
  62.   for i = #t, 1, -1 do
  63.     n = n * 256 + t[i]
  64.   end
  65.   return n
  66. end
  67.  
  68. local F = false
  69.  
  70. local elf_code = '\x7F\x45\x4C\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x10\x02\x00\x03\x00\x01\x00\x00\x00\x80\x80\x04\x08\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x20\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x80\x00\x00\x00\x80\x80\x04\x08\x00\x00\x00\x00\x24\x00\x00\x00\x24\x00\x00\x00\x05\x00\x00\x00\x00\x10\x00\x00\x01\x00\x00\x00\xA4\x00\x00\x00\xA4\x80\x04\x08\x00\x00\x00\x00\x20\x00\x00\x00\x20\x00\x00\x00\x07\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xBB\x01\x00\x00\x00\xB8\x04\x00\x00\x00\xB9\xA4\x80\x04\x08\xBA\x0D\x00\x00\x00\xCD\x80\xB8\x01\x00\x00\x00\xBB\x5D\x00\x00\x00\xCD\x80\x00\x00\x48\x65\x6C\x6C\x6F\x20\x57\x6F\x72\x6C\x64\x21\x0A'
  71. local elf_stream = ByteStream()
  72. elf_stream.puts(elf_code)
  73. elf_stream.seek(0)
  74.  
  75. assert_like('E_IDENT',   {elf_stream.read(16)}, {0x7F,0x45,0x4C,0x46, 1,1,1, F,F,F,F,F,F,F,F, 16})
  76. assert_like('E_TYPE',    {elf_stream.read(2)},  {0x02,0x00})
  77. assert_like('E_MACHINE', {elf_stream.read(2)},  {0x03,0x00})
  78. assert_like('E_VERSION', {elf_stream.read(4)},  {0x01,0x00,0x00,0x00})
  79. local e_entry = lton {elf_stream.read(4)}
  80. local e_phoff = lton {elf_stream.read(4)}
  81. local e_shoff = lton {elf_stream.read(4)}
  82. local e_flags = lton {elf_stream.read(4)}
  83. assert_like('E_EHSIZE',   {elf_stream.read(2)},  {0x34,0x00})
  84. assert_like('E_PHENTSIZE',{elf_stream.read(2)},  {0x20,0x00})
  85. local e_phnum = lton {elf_stream.read(2)}
  86. assert_like('E_SH...',    {elf_stream.read(6)},  {0,0,0,0,0,0})
  87.  
  88. local appmem = ByteStream()
  89.  
  90. local segments = {}
  91. elf_stream.seek(e_phoff)
  92. for i = 1, e_phnum do
  93.   print('---- Segment #' .. tostring(i) .. ' ----')
  94.   assert_like('P_TYPE', {elf_stream.read(4)}, {1,0,0,0})
  95.   local p_offset = lton {elf_stream.read(4)}
  96.   local p_vaddr  = lton {elf_stream.read(4)}
  97.   assert_like('P_PADDR',{elf_stream.read(4)}, {0,0,0,0})
  98.   local p_filesz = lton {elf_stream.read(4)}
  99.   local p_memsz  = lton {elf_stream.read(4)}
  100.   local p_flags  = lton {elf_stream.read(4)}
  101.   assert_like('P_ALIGN',{elf_stream.read(4)}, {0,0x10,0,0})
  102.  
  103.   segments[i] = {r_offset = p_offset, w_offset = p_vaddr, r_len = p_filesz, w_len = p_memsz}
  104. end
  105.  
  106. for i = 1, e_phnum do
  107.   local cs = segments[i]
  108.   elf_stream.seek(cs.r_offset)
  109.   appmem.seek(cs.w_offset)
  110.   appmem.put(elf_stream.read(cs.r_len))
  111.   appmem.extend(cs.w_len - cs.r_len)
  112.  
  113.   print('---- Segment #' .. tostring(i) .. ' loaded into VM ----')
  114. end
  115.  
  116. local bit32 = require 'bit32'
  117. local band, bor, bxor, brs = bit32.band, bit32.bor, bit32.bxor, bit32.rshift
  118.  
  119. appmem.seek(e_entry)
  120. local registers = {EAX = 0, EBX = 0, ECX = 0, EDX = 0}
  121. local ridxs = {[0] = 'EAX', [3] = 'EBX', [1] = 'ECX', [2] = 'EDX'}
  122. while true do
  123.   local command = appmem.read(1)
  124.   print('Command:', command)
  125.   local opcode = band(command, 248)
  126.   if opcode == 0xB8 then
  127.     local target = ridxs[band(command, 7)]
  128.     local value = lton {appmem.read(4)}
  129.     print('Opcode: MOV ' .. tostring(value) .. ' ' .. target)
  130.     registers[target] = value
  131.   elseif command == 0xCD then
  132.     local itype = appmem.read(1)
  133.     if itype == 0x80 then
  134.       print('Requested system call', registers.EAX)
  135.       if registers.EAX == 1 then
  136.         print('\27[32mExit code: ' .. tostring(registers.EBX) .. '\27[37m')
  137.         return
  138.       elseif registers.EAX == 4 then
  139.         local cp = appmem.seek()
  140.         appmem.seek(registers.ECX)
  141.         local data = {appmem.read(registers.EDX)}
  142.         print('Memory data:', table.unpack(data))
  143.         print('\27[33m' .. string.char(table.unpack(data)) .. '\27[37m')
  144.         appmem.seek(cp)
  145.       end
  146.     else
  147.       print('Requested interrupt', registers.EAX)
  148.     end
  149.   else
  150.     error('Unknown opcode')
  151.   end
  152.  
  153.   os.sleep(0)
  154. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement