Skip to content

Instantly share code, notes, and snippets.

@math314
Created May 23, 2014 08:48
Show Gist options
  • Select an option

  • Save math314/b7e5ab200954068f091e to your computer and use it in GitHub Desktop.

Select an option

Save math314/b7e5ab200954068f091e to your computer and use it in GitHub Desktop.
------------------------------
8048d1c: 55 push ebp;
8048d1d: 89 e5 mov ebp,esp;
8048d1f: 57 push edi;
8048d20: 53 push ebx;
8048d21: 81 ec a0 02 00 00 sub esp,0x2a0;
8048d27: 8b 45 08 mov eax,DWORD PTR [ebp+0x8];
8048d2a: 89 85 84 fd ff ff mov DWORD PTR [ebp-0x27c],eax;
8048d30: 65 a1 14 00 00 00 mov eax,gs:0x14;
8048d36: 89 45 f4 mov DWORD PTR [ebp-0xc],eax;
8048d39: 31 c0 xor eax,eax;
8048d3b: 8b 85 84 fd ff ff mov eax,DWORD PTR [ebp-0x27c];
8048d41: 83 c0 02 add eax,0x2;
8048d44: 85 c0 test eax,eax;
if(state) {
8048d46: 75 24 jne 8048d6c <calloc@plt+0x52c>; ['if']
8048d48: c7 44 24 04 00 01 00 00 mov DWORD PTR [esp+0x4],0x100;
8048d50: 8d 85 f4 fd ff ff lea eax,[ebp-0x20c];
8048d56: 89 04 24 mov DWORD PTR [esp],eax;
8048d59: e8 42 fa ff ff call 80487a0 <getcwd@plt>;
8048d5e: 8d 85 f4 fd ff ff lea eax,[ebp-0x20c];
8048d64: 89 85 e4 fd ff ff mov DWORD PTR [ebp-0x21c],eax;
8048d6a: eb 0f jmp 8048d7b <calloc@plt+0x53b>; ['(jump to end if)']
} else {
8048d6c: 8b 85 84 fd ff ff mov eax,DWORD PTR [ebp-0x27c]; ['else']
8048d72: 83 c0 02 add eax,0x2;
8048d75: 89 85 e4 fd ff ff mov DWORD PTR [ebp-0x21c],eax;
} //end if
8048d7b: 8b 85 e4 fd ff ff mov eax,DWORD PTR [ebp-0x21c]; ['end if']
8048d81: 89 04 24 mov DWORD PTR [esp],eax;
8048d84: e8 a7 fa ff ff call 8048830 <opendir@plt>;
8048d89: 89 85 e8 fd ff ff mov DWORD PTR [ebp-0x218],eax;
8048d8f: 83 bd e8 fd ff ff 00 cmp DWORD PTR [ebp-0x218],0x0;
if(state) {
8048d96: 75 11 jne 8048da9 <calloc@plt+0x569>; ['if']
8048d98: c7 04 24 2a 9e 04 08 mov DWORD PTR [esp],0x8049e2a;
8048d9f: e8 c5 fb ff ff call 8048969 <calloc@plt+0x129>;
8048da4: e9 c4 01 00 00 jmp 8048f6d <calloc@plt+0x72d>; ['(jump to end if)']
} else {
8048da9: 8b 85 84 fd ff ff mov eax,DWORD PTR [ebp-0x27c]; ['else']
8048daf: 0f b6 10 movzx edx,BYTE PTR [eax];
8048db2: b8 3c 9e 04 08 mov eax,0x8049e3c;
8048db7: 0f b6 00 movzx eax,BYTE PTR [eax];
8048dba: 38 c2 cmp dl,al;
if(state) {
8048dbc: 75 6e jne 8048e2c <calloc@plt+0x5ec>; ['if']
8048dbe: eb 4a jmp 8048e0a <calloc@plt+0x5ca>; ['begin for']
for(init; cond; loop-expression) {
8048dc0: 8d 85 f4 fd ff ff lea eax,[ebp-0x20c]; ['for']
8048dc6: 89 c3 mov ebx,eax;
8048dc8: b8 00 00 00 00 mov eax,0x0;
8048dcd: ba 40 00 00 00 mov edx,0x40;
8048dd2: 89 df mov edi,ebx;
8048dd4: 89 d1 mov ecx,edx;
8048dd6: f3 ab rep stos DWORD PTR es:[edi],eax;
8048dd8: 8b 85 ec fd ff ff mov eax,DWORD PTR [ebp-0x214];
8048dde: 8d 50 0b lea edx,[eax+0xb];
8048de1: b8 3e 9e 04 08 mov eax,0x8049e3e;
8048de6: 89 54 24 08 mov DWORD PTR [esp+0x8],edx;
8048dea: 89 44 24 04 mov DWORD PTR [esp+0x4],eax;
8048dee: 8d 85 f4 fd ff ff lea eax,[ebp-0x20c];
8048df4: 89 04 24 mov DWORD PTR [esp],eax;
8048df7: e8 14 fa ff ff call 8048810 <sprintf@plt>;
8048dfc: 8d 85 f4 fd ff ff lea eax,[ebp-0x20c];
8048e02: 89 04 24 mov DWORD PTR [esp],eax;
8048e05: e8 5f fb ff ff call 8048969 <calloc@plt+0x129>;
8048e0a: 8b 85 e8 fd ff ff mov eax,DWORD PTR [ebp-0x218]; ['for(loop-expression)']
8048e10: 89 04 24 mov DWORD PTR [esp],eax;
8048e13: e8 e8 f9 ff ff call 8048800 <readdir@plt>;
8048e18: 89 85 ec fd ff ff mov DWORD PTR [ebp-0x214],eax;
8048e1e: 83 bd ec fd ff ff 00 cmp DWORD PTR [ebp-0x214],0x0;
8048e25: 75 99 jne 8048dc0 <calloc@plt+0x580>; ['continue']
} //end for
8048e27: e9 32 01 00 00 jmp 8048f5e <calloc@plt+0x71e>; ['end for', '(jump to end if)']
} else {
8048e2c: 8b 85 84 fd ff ff mov eax,DWORD PTR [ebp-0x27c]; ['else']
8048e32: 0f b6 10 movzx edx,BYTE PTR [eax];
8048e35: b8 43 9e 04 08 mov eax,0x8049e43;
8048e3a: 0f b6 00 movzx eax,BYTE PTR [eax];
8048e3d: 38 c2 cmp dl,al;
if(state) {
8048e3f: 0f 85 19 01 00 00 jne 8048f5e <calloc@plt+0x71e>; ['if']
8048e45: e9 f3 00 00 00 jmp 8048f3d <calloc@plt+0x6fd>; ['begin for']
for(init; cond; loop-expression) {
8048e4a: 8b 85 ec fd ff ff mov eax,DWORD PTR [ebp-0x214]; ['for']
8048e50: 0f b6 40 0b movzx eax,BYTE PTR [eax+0xb];
8048e54: 3c 2e cmp al,0x2e;
if(state) {
8048e56: 0f 84 e0 00 00 00 je 8048f3c <calloc@plt+0x6fc>; ['if']
8048e5c: 8d 85 f4 fe ff ff lea eax,[ebp-0x10c];
8048e62: 89 c3 mov ebx,eax;
8048e64: b8 00 00 00 00 mov eax,0x0;
8048e69: ba 40 00 00 00 mov edx,0x40;
8048e6e: 89 df mov edi,ebx;
8048e70: 89 d1 mov ecx,edx;
8048e72: f3 ab rep stos DWORD PTR es:[edi],eax;
8048e74: 8d 85 f4 fd ff ff lea eax,[ebp-0x20c];
8048e7a: 89 c3 mov ebx,eax;
8048e7c: b8 00 00 00 00 mov eax,0x0;
8048e81: ba 40 00 00 00 mov edx,0x40;
8048e86: 89 df mov edi,ebx;
8048e88: 89 d1 mov ecx,edx;
8048e8a: f3 ab rep stos DWORD PTR es:[edi],eax;
8048e8c: 8b 85 ec fd ff ff mov eax,DWORD PTR [ebp-0x214];
8048e92: 8d 50 0b lea edx,[eax+0xb];
8048e95: b8 45 9e 04 08 mov eax,0x8049e45;
8048e9a: 89 54 24 0c mov DWORD PTR [esp+0xc],edx;
8048e9e: 8b 95 e4 fd ff ff mov edx,DWORD PTR [ebp-0x21c];
8048ea4: 89 54 24 08 mov DWORD PTR [esp+0x8],edx;
8048ea8: 89 44 24 04 mov DWORD PTR [esp+0x4],eax;
8048eac: 8d 85 f4 fe ff ff lea eax,[ebp-0x10c];
8048eb2: 89 04 24 mov DWORD PTR [esp],eax;
8048eb5: e8 56 f9 ff ff call 8048810 <sprintf@plt>;
8048eba: 8d 85 f4 fe ff ff lea eax,[ebp-0x10c];
8048ec0: 8d 95 8c fd ff ff lea edx,[ebp-0x274];
8048ec6: 89 54 24 04 mov DWORD PTR [esp+0x4],edx;
8048eca: 89 04 24 mov DWORD PTR [esp],eax;
8048ecd: e8 2e 0e 00 00 call 8049d00 <calloc@plt+0x14c0>;
8048ed2: 8b 85 9c fd ff ff mov eax,DWORD PTR [ebp-0x264];
8048ed8: 89 04 24 mov DWORD PTR [esp],eax;
8048edb: e8 5a fd ff ff call 8048c3a <calloc@plt+0x3fa>;
8048ee0: 89 85 f0 fd ff ff mov DWORD PTR [ebp-0x210],eax;
8048ee6: 8b 95 b8 fd ff ff mov edx,DWORD PTR [ebp-0x248];
8048eec: 8b 85 ec fd ff ff mov eax,DWORD PTR [ebp-0x214];
8048ef2: 8d 58 0b lea ebx,[eax+0xb];
8048ef5: b8 4b 9e 04 08 mov eax,0x8049e4b;
8048efa: 8b 8d f0 fd ff ff mov ecx,DWORD PTR [ebp-0x210];
8048f00: 89 4c 24 10 mov DWORD PTR [esp+0x10],ecx;
8048f04: 89 54 24 0c mov DWORD PTR [esp+0xc],edx;
8048f08: 89 5c 24 08 mov DWORD PTR [esp+0x8],ebx;
8048f0c: 89 44 24 04 mov DWORD PTR [esp+0x4],eax;
8048f10: 8d 85 f4 fd ff ff lea eax,[ebp-0x20c];
8048f16: 89 04 24 mov DWORD PTR [esp],eax;
8048f19: e8 f2 f8 ff ff call 8048810 <sprintf@plt>;
8048f1e: 8b 85 f0 fd ff ff mov eax,DWORD PTR [ebp-0x210];
8048f24: 89 04 24 mov DWORD PTR [esp],eax;
8048f27: e8 a4 f7 ff ff call 80486d0 <free@plt>;
8048f2c: 8d 85 f4 fd ff ff lea eax,[ebp-0x20c];
8048f32: 89 04 24 mov DWORD PTR [esp],eax;
8048f35: e8 2f fa ff ff call 8048969 <calloc@plt+0x129>;
8048f3a: eb 01 jmp 8048f3d <calloc@plt+0x6fd>; ['(jump to end if)']
} else {
8048f3c: 90 nop ; ['else']
} //end if
8048f3d: 8b 85 e8 fd ff ff mov eax,DWORD PTR [ebp-0x218]; ['for(loop-expression)', 'end if']
8048f43: 89 04 24 mov DWORD PTR [esp],eax;
8048f46: e8 b5 f8 ff ff call 8048800 <readdir@plt>;
8048f4b: 89 85 ec fd ff ff mov DWORD PTR [ebp-0x214],eax;
8048f51: 83 bd ec fd ff ff 00 cmp DWORD PTR [ebp-0x214],0x0;
8048f58: 0f 85 ec fe ff ff jne 8048e4a <calloc@plt+0x60a>; ['continue']
} //end for
} //end if
} //end if
8048f5e: 8b 85 e8 fd ff ff mov eax,DWORD PTR [ebp-0x218]; ['end for', 'end if', 'end if']
8048f64: 89 04 24 mov DWORD PTR [esp],eax;
8048f67: e8 b4 f8 ff ff call 8048820 <closedir@plt>;
8048f6c: 90 nop ;
} //end if
8048f6d: 8b 45 f4 mov eax,DWORD PTR [ebp-0xc]; ['end if']
8048f70: 65 33 05 14 00 00 00 xor eax,DWORD PTR gs:0x14;
if(state) {
8048f77: 74 05 je 8048f7e <calloc@plt+0x73e>; ['if']
8048f79: e8 92 f7 ff ff call 8048710 <__stack_chk_fail@plt>;
} //end if
8048f7e: 81 c4 a0 02 00 00 add esp,0x2a0; ['end if']
8048f84: 5b pop ebx;
8048f85: 5f pop edi;
8048f86: 5d pop ebp;
8048f87: c3 ret ;
------------------------------
#coding=utf-8
import sys,os
import re
from collections import namedtuple
from itertools import *
class Asm(object):
def __init__(self,address,binary,opecode,operand):
self.address = address
self.binary = binary
self.opecode = opecode
self.operand = operand
self.indent = 0
self.comment = ''
self.attribute = []
def next_address(self):
return self.address + len(self.binary)
def __str__(self):
indent = ' ' * self.indent
address = "%x" % self.address
binary = ' '.join(['%02x' % i for i in self.binary])
opecode = self.opecode if self.opecode is not None else ''
operand = self.operand if self.operand is not None else ''
comment = self.comment if self.comment is not None else ''
attribute = str(self.attribute) if len(self.attribute) != 0 else ''
ret = []
if 'if' in self.attribute:
ret.append(' ' * (self.indent - 1) + 'if(state) {')
elif 'for' in self.attribute:
ret.append(' ' * (self.indent - 1) + 'for(init; cond; loop-expression) {')
elif 'while' in self.attribute:
ret.append(' ' * (self.indent - 1) + 'while(true) {')
elif 'else' in self.attribute:
ret.append(' ' * (self.indent - 1) + '} else {')
end_blacket_indent = self.indent - 1
for attr in self.attribute:
if attr in ('end if','end for','end while'): end_blacket_indent += 1
for attr in self.attribute:
if attr in ('end if','end for','end while'):
ret.append(' ' * end_blacket_indent + '} //' + attr);
end_blacket_indent -= 1
ret.append("%s%s:\t%-22s\t%s\t%s; %s %s" % \
(indent,address,binary,opecode,operand,comment,attribute) \
)
if self.opecode[0] == 'j' and len(self.attribute) == 0:
ret[-1] += 'no attr?'
return '\n'.join(ret)
def load_assembler(file_name):
part = re.compile(r"\s(?P<address>\w+):\s+(?P<binary>(\w\w\s)+)\s+((?P<opecode>\w+)(\s+(?P<operand>.*))?)?$")
data = [i.strip('\n') for i in open(file_name)]
ret = []
i = 0
text_section = False
while i < len(data):
line = data[i]
if line == "Disassembly of section .text:":
print line
text_section = True
i += 3
continue
if text_section:
if line == "":
break
m = part.match(line)
address = int(m.group("address"),16)
binary = [int(j,16) for j in m.group("binary").split()]
opecode = m.group("opecode")
operand = m.group("operand")
asm = Asm(address,binary,opecode,operand)
ret.append(asm)
i += 1
return ret
def divide_to_function(asms):
next_instruction_address = asms[0].address
current_graph = []
for asm in asms:
if next_instruction_address < asm.address:
yield current_graph
current_graph = []
next_instruction_address = asm.address
current_graph.append(asm)
if asm.opecode == 'ret':
continue
elif asm.opecode == 'jmp':
jump_to = int(asm.operand.split()[0],16)
next_instruction_address = max(next_instruction_address,jump_to)
elif asm.opecode.startswith('j'):
jump_to = int(asm.operand.split()[0],16)
to = max(jump_to,asm.next_address())
next_instruction_address = max(next_instruction_address,to)
else:
next_instruction_address = max(next_instruction_address,asm.next_address())
def set_loopblock_indent(graph,loop_start_addresses,loop_end_addresses):
addresses = []
for start in loop_start_addresses:
addresses.append((start,1))
for end in loop_end_addresses:
addresses.append((end,-1))
addresses.sort()
i = 0
indent = 0
for asm in graph:
while i < len(addresses) and addresses[i][0] <= asm.address:
indent += addresses[i][1]
if addresses[i][1] > 0:
asm.attribute.append('loop')
else:
asm.attribute.append('end loop')
i += 1
asm.indent = indent
def set_continue_statement(graph):
for asm in graph:
if asm.opecode.startswith('j'):
jump_to = int(asm.operand.split()[0],16)
if jump_to < asm.address:
asm.attribute.append('continue')
def set_break_statement(graph):
for asm in graph:
if asm.opecode.startswith('j'):
jump_to = int(asm.operand.split()[0],16)
to_asm = filter(lambda _asm: _asm.address == jump_to,graph)[0]
if asm.indent > to_asm.indent:
asm.attribute.append('break')
def set_for_statement(graph,loop_end_addresses):
for asm in graph:
if asm.opecode.startswith('j'):
jump_to = int(asm.operand.split()[0],16)
to_asm = filter(lambda _asm: _asm.address == jump_to,graph)[0]
if asm.indent < to_asm.indent:
continue_stat = filter(lambda _asm: _asm.next_address() in loop_end_addresses,dropwhile(lambda _asm: _asm.address < asm.address,graph))[0]
end_loop_asm = filter(lambda _asm: _asm.address == continue_stat.next_address(),graph)[0]
begin_loop_address = int(continue_stat.operand.split()[0],16)
begin_loop_asm = filter(lambda _asm: _asm.address == begin_loop_address,graph)[0]
loop_expression_address = int(asm.operand.split()[0],16)
loop_expression_asm = filter(lambda _asm: _asm.address == loop_expression_address,graph)[0]
asm.attribute.append('begin for')
loop_expression_asm.attribute.append('for(loop-expression)')
begin_loop_asm.attribute.remove('loop')
end_loop_asm.attribute.remove('end loop')
begin_loop_asm.attribute.append('for')
end_loop_asm.attribute.append('end for')
def set_while_statement(graph):
for asm in graph:
if 'loop' in asm.attribute:
asm.attribute.remove('loop')
asm.attribute.append('while')
elif 'end loop' in asm.attribute:
asm.attribute.remove('end loop')
asm.attribute.append('end while')
def set_if_indent(graph):
for asm in graph:
if asm.opecode == 'jmp':
jump_to = int(asm.operand.split()[0],16)
to_asm = filter(lambda _asm: _asm.address == jump_to,graph)[0]
next_address = asm.next_address()
next_asm = filter(lambda _asm: _asm.address == next_address,graph)[0]
if 'end if' in next_asm.attribute:
next_asm.attribute.remove('end if')
asm.attribute.append('(jump to end if)')
next_asm.attribute.append('else')
to_asm.attribute.append('end if')
elif asm.opecode.startswith('j'):
jump_to = int(asm.operand.split()[0],16)
if jump_to < asm.address: continue
to_asm = filter(lambda _asm: _asm.address == jump_to,graph)[0]
if to_asm.indent == asm.indent:
asm.attribute.append('if')
to_asm.attribute.append('end if')
additional_indent = 0
for asm in graph:
for attr in asm.attribute:
if attr == 'if': additional_indent += 1
if attr == 'end if': additional_indent -= 1
asm.indent += additional_indent
def analyze_graph(graph):
loop_jump_asms = {}
for asm in graph:
if asm.opecode.startswith('j'):
jump_to = int(asm.operand.split()[0],16)
if jump_to <= asm.address:
loop_jump_asms[jump_to] = asm # 最後に来た命令で更新する
loop_jump_asms = list(sorted(loop_jump_asms.items()))
loop_start_addresses = list(starmap(lambda to,asm : to,loop_jump_asms))
loop_end_addresses = list(starmap(lambda to,asm :asm.next_address(),loop_jump_asms))
#1. loop検出
set_loopblock_indent(graph,loop_start_addresses,loop_end_addresses)
#2. loop continue 検出
set_continue_statement(graph)
#3. break検出
set_break_statement(graph)
#4-1. begin for,loop -> for検出
set_for_statement(graph,loop_end_addresses)
#4-2. loop -> while検出
set_while_statement(graph)
#5 if検出
set_if_indent(graph)
def main():
asms = load_assembler(sys.argv[1])
for graph in divide_to_function(asms):
print "-" * 30
analyze_graph(graph)
print "-" * 30
for i in graph:
print i
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment