Skip to content

Commit

Permalink
enable eliminate deadcode
Browse files Browse the repository at this point in the history
  • Loading branch information
tkmru committed Dec 15, 2016
1 parent 654380d commit fc75881
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 19 deletions.
64 changes: 54 additions & 10 deletions ida_plugin/eliminate.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,71 @@
from unicorn import *
from unicorn.x86_const import *
import copy


def check_deadcode(instruction_list):
begin_address = instruction_list[0][0]
all_opcodes = make_opcodes(instruction_list)

# ready to unicorn
mu = Uc(UC_ARCH_X86, UC_MODE_32)
page_address = begin_address - begin_address % 0x1000
mu.mem_map(page_address, 0x400000) # map 4MB for this emulation

origin_registers = emulate(mu, begin_address, all_opcodes)
return judge(mu, instruction_list, origin_registers)


def make_opcodes(instruction_list):
all_opcodes = ''
for i in instruction_list:
opcode = i[1]
disasm = i[2]
if ('call' != disasm[:4]) and ('leave' != disasm[:5]) and \
('ret' != disasm[:3]) and ('[esp]' not in disasm):
all_opcodes += opcode
else:
all_opcodes += b'\x90' * len(opcode)

return all_opcodes

for i in instruction_list[0:-4]:
if ('offset' not in i[2]) and ('call' not in i[2]) and ('ret' not in i[2]):
all_opcodes += i[1]

origin_regs = emulate(begin_address, all_opcodes)
def judge(mu, instruction_list, origin_registers):
length = len(instruction_list)
begin_address = instruction_list[0][0]
for i in xrange(length):
disasm = instruction_list[i][2]
opcode = instruction_list[i][1]

# ls enable to emulate?, not already found ?
if ('call' != disasm[:4]) and ('leave' != disasm[:5]) and \
('ret' != disasm[:3]) and ('[esp]' not in disasm) and (opcode[0] != b'\x90'):
replaced_instruction_list = copy.deepcopy(instruction_list)
target_opcode_length = len(opcode)
replaced_instruction_list[i][1] = b'\x90' * target_opcode_length # replace to NOP
replaced_opcodes = make_opcodes(replaced_instruction_list)
registers = emulate(mu, begin_address, replaced_opcodes)
if origin_registers == registers:
return judge(mu, replaced_instruction_list, origin_registers)

return instruction_list

def emulate(begin_address, opcodes):
mu = Uc(UC_ARCH_X86, UC_MODE_32)
page_address = begin_address - begin_address % 0x1000
mu.mem_map(page_address, 4 * 1024 * 1024) # map 4MB for this emulation

def emulate(mu, begin_address, opcodes):
mu.mem_write(begin_address, opcodes)

# initialize stack
mu.reg_write(UC_X86_REG_ESP, ADDRESS + 0x200000)
mu.reg_write(UC_X86_REG_ESP, begin_address + 0x200000)
mu.reg_write(UC_X86_REG_EBP, begin_address + 0x200100)

# initialize registers
mu.reg_write(UC_X86_REG_EAX, 0x1234)
mu.reg_write(UC_X86_REG_EBX, 0x1234)
mu.reg_write(UC_X86_REG_ECX, 0x1234)
mu.reg_write(UC_X86_REG_EDX, 0x1234)
mu.reg_write(UC_X86_REG_EDI, 0x1234)
mu.reg_write(UC_X86_REG_ESI, 0x1234)

# initialize flags
mu.reg_write(UC_X86_REG_EFLAGS, 0x0)

Expand All @@ -37,4 +81,4 @@ def emulate(begin_address, opcodes):
r_ebp = mu.reg_read(UC_X86_REG_EBP)
r_eflags = mu.reg_read(UC_X86_REG_EFLAGS)

return r_eax, r_ebx, r_ecx, r_edx, r_edi, r_esi, r_esp, r_ebp, r_eflags
return r_eax, r_ebx, r_ecx, r_edx, r_edi, r_esi, r_esp, r_ebp
15 changes: 6 additions & 9 deletions ida_plugin/plugin.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
# -----------------------------------------------------------------------
#

import idaapi
import idautils
import idc
import os
import binascii
import eliminate

# ----------------------------------------------------------------------

class asm_colorizer_t(object):
def is_id(self, ch):
return ch == '_' or ch.isalpha() or '0' <= ch <= '9'
Expand Down Expand Up @@ -80,7 +77,7 @@ def colorize(self, lines):
x += 1
self.add_line(s)

# -----------------------------------------------------------------------

class asmview_t(idaapi.simplecustviewer_t, asm_colorizer_t):
def Create(self):
# Create the customview
Expand Down Expand Up @@ -140,13 +137,13 @@ def colorize_file(self, ea):
opcode = binascii.a2b_hex(hex(int_opcode)[2:].zfill(2))
row_opcode += opcode

instruction_list.append((row_begin_addr, row_opcode, disasm))
instruction_list.append([row_begin_addr, row_opcode, disasm])

checked_instruction_list = eliminate.check_deadcode(instruction_list)

lines = ''
for i in checked_instruction_list:
lines += str(format(i[0], 'x')).upper() + ": " + i[2] + '\n'
if b'\x90' != i[1][0]: # eliminate deadcode
lines += str(format(i[0], 'x')).upper() + ": " + i[2] + '\n'

self.ClearLines()
self.colorize(lines)
Expand Down Expand Up @@ -225,7 +222,7 @@ def OnKeydown(self, vkey, shift):
"""
return True

# -----------------------------------------------------------------------

def main():
def cb():
view = asmview_t()
Expand Down

0 comments on commit fc75881

Please sign in to comment.