Created
May 23, 2014 08:48
-
-
Save math314/b7e5ab200954068f091e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ------------------------------ | |
| 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 ; | |
| ------------------------------ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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