diff options
22 files changed, 442 insertions, 2 deletions
diff --git a/example/expression/constant_propagation.py b/example/expression/constant_propagation.py new file mode 100644 index 00000000..70394580 --- /dev/null +++ b/example/expression/constant_propagation.py @@ -0,0 +1,54 @@ +""" +Example of "constant expression" propagation. +A "constant expression" is an expression based on constants or init regs. + +""" + +from argparse import ArgumentParser + +from miasm2.arch.x86.disasm import dis_x86_32 as dis_engine +from miasm2.analysis.machine import Machine +from miasm2.analysis.binary import Container +from miasm2.analysis.cst_propag import propagate_cst_expr +from miasm2.analysis.data_flow import dead_simp +from miasm2.expression.simplifications import expr_simp + + +parser = ArgumentParser("Constant expression propagation") +parser.add_argument('filename', help="File to analyze") +parser.add_argument('address', help="Starting address for disassembly engine") +parser.add_argument('-s', "--simplify", action="store_true", + help="Apply simplifications rules (liveness, graph simplification, ...)") + +args = parser.parse_args() + + +machine = Machine("x86_32") + +cont = Container.from_stream(open(args.filename)) +ira, dis_engine = machine.ira, machine.dis_engine +mdis = dis_engine(cont.bin_stream) +ir_arch = ira(mdis.symbol_pool) +addr = int(args.address, 0) + + +blocks = mdis.dis_multiblock(addr) +for block in blocks: + ir_arch.add_block(block) + + +init_infos = ir_arch.arch.regs.regs_init +cst_propag_link = propagate_cst_expr(ir_arch, addr, init_infos) + +if args.simplify: + ir_arch.simplify(expr_simp) + modified = True + while modified: + modified = False + modified |= dead_simp(ir_arch) + modified |= ir_arch.remove_empty_assignblks() + modified |= ir_arch.remove_jmp_blocks() + modified |= ir_arch.merge_blocks() + + +open("%s.propag.dot" % args.filename, 'w').write(ir_arch.graph.dot()) diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_1.S b/test/samples/x86_32/cst_propag/x86_32_sc_1.S new file mode 100644 index 00000000..0fe12e04 --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_1.S @@ -0,0 +1,21 @@ +main: + PUSH EBP + MOV EBP, ESP + MOV ECX, 1 + MOV EDX, 2 + LEA ECX, DWORD PTR [ECX+0x4] + LEA EBX, DWORD PTR [ECX+0x1] + CMP CL, 0x1 + JZ test1 + LEA EBX, DWORD PTR [EBX-1] + JMP end +test1: + LEA EBX, DWORD PTR [EBX-1] +end: + MOV EAX, EBX + LEA EAX, DWORD PTR [EAX + EDX] + MOV EDX, DWORD PTR [EBP+0xC] + LEA EAX, DWORD PTR [EAX + EDX] + MOV ESP, EBP + POP EBP + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_10.S b/test/samples/x86_32/cst_propag/x86_32_sc_10.S new file mode 100644 index 00000000..84eae85b --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_10.S @@ -0,0 +1,17 @@ +main: + PUSH EBP + MOV EBP, ESP + MOV ECX, DWORD PTR [ESP+0x8] + INC EBX + CMP CL, 0x1 + JZ test1 + MOV EAX, 8 + JMP end +test1: + MOV EAX, 4 +end: + LEA EBX, DWORD PTR [EAX+EBX] + MOV EAX, EBX + MOV ESP, EBP + POP EBP + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_11.S b/test/samples/x86_32/cst_propag/x86_32_sc_11.S new file mode 100644 index 00000000..272c76da --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_11.S @@ -0,0 +1,11 @@ +main: + MOV ECX, 10 +loop1: + DEC ECX + JNZ less + JMP goon +less: + DEC ECX +goon: + JNZ loop1 + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_12.S b/test/samples/x86_32/cst_propag/x86_32_sc_12.S new file mode 100644 index 00000000..3420b882 --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_12.S @@ -0,0 +1,12 @@ +main: + MOV EBX, 1 + MOV ECX, 2 + CMP EDX, 3 + JNZ test1 + ADD EBX, 1 + JMP goon +test1: + ADD ECX, 1 +goon: + LEA EAX, DWORD PTR [EBX+ECX] + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_13.S b/test/samples/x86_32/cst_propag/x86_32_sc_13.S new file mode 100644 index 00000000..08b9a891 --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_13.S @@ -0,0 +1,7 @@ +main: + MOV ECX, 10 +loop: + DEC ECX + JNZ loop + MOV EAX, ECX + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_14.S b/test/samples/x86_32/cst_propag/x86_32_sc_14.S new file mode 100644 index 00000000..17cad5d7 --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_14.S @@ -0,0 +1,10 @@ +main: + MOV ECX, 10 + MOV EDX, 10 +loop: + INC EDX + DEC EDX + DEC ECX + JNZ loop + MOV EAX, EDX + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_15.S b/test/samples/x86_32/cst_propag/x86_32_sc_15.S new file mode 100644 index 00000000..03a3c121 --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_15.S @@ -0,0 +1,16 @@ +main: + ADD EDI, 1 + MOV ECX, 10 +loop1: + MOV EDX, 10 + INC EDI +loop2: + ADD EDI, 2 + SUB EDI, 2 + SUB EDX, 1 + JNZ loop2 + DEC EDI + SUB ECX, 1 + JNZ loop1 + MOV EAX, EDI + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_16.S b/test/samples/x86_32/cst_propag/x86_32_sc_16.S new file mode 100644 index 00000000..d54e2657 --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_16.S @@ -0,0 +1,17 @@ +main: + MOV EBX, 1 + ADD EDI, 1 + MOV ECX, 10 +loop1: + MOV EDX, 10 + INC EDI +loop2: + LEA EDI, DWORD PTR [EDI+EBX] + LEA EDI, DWORD PTR [EDI-1] + SUB EDX, 1 + JNZ loop2 + DEC EDI + SUB ECX, 1 + JNZ loop1 + MOV EAX, EDI + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_17.S b/test/samples/x86_32/cst_propag/x86_32_sc_17.S new file mode 100644 index 00000000..576c02e2 --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_17.S @@ -0,0 +1,8 @@ +main: + MOV EBX, 1 + ADD EDI, 1 + SUB EBX, EDI + SUB EDI, 1 + ADD EBX, EDI + MOV EAX, EBX + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_18.S b/test/samples/x86_32/cst_propag/x86_32_sc_18.S new file mode 100644 index 00000000..7d29abdb --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_18.S @@ -0,0 +1,33 @@ +main: + PUSH EBP + MOV EBP, ESP + MOV EAX, DWORD PTR [EBP+0x8] + MOV EBX, DWORD PTR [EBP+0xC] + ADD EAX, EBX + TEST EAX, EAX + JNZ test + PUSH 1 + PUSH 2 + PUSH DWORD PTR [EBP+0x10] + CALL func1 + ADD ESP, 0xC + JMP goon +test: + MOV ECX, 10 +loop: + PUSH 1 + PUSH 2 + CALL func2 + ADD ESP, 0x8 + DEC ECX + JNZ loop +goon: + MOV ESP, EBP + POP EBP + RET + + +func1: + RET +func2: + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_19.S b/test/samples/x86_32/cst_propag/x86_32_sc_19.S new file mode 100644 index 00000000..0b0e0837 --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_19.S @@ -0,0 +1,16 @@ +main: + + MOV EBX, 1 + MOV ECX, 1 + CMP EDX, 10 + JZ test1 + ADD EBX, 1 + ADD ECX, 1 + JMP gogon +test1: + ADD EBX, 2 + ADD ECX, 2 +gogon: + ADD EAX, EBX + ADD EAX, ECX + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_2.S b/test/samples/x86_32/cst_propag/x86_32_sc_2.S new file mode 100644 index 00000000..96e10fa6 --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_2.S @@ -0,0 +1,21 @@ +main: + PUSH EBP + MOV EBP, ESP + MOV ECX, DWORD PTR [ESP+0x8] + MOV EDX, DWORD PTR [EBP+0xC] + LEA ECX, DWORD PTR [ECX+0x4] + LEA EBX, DWORD PTR [EBX+0x1] + CMP CL, 0x1 + JZ test1 + LEA EBX, DWORD PTR [EBX-1] + JMP end +test1: + LEA EBX, DWORD PTR [EBX+0x1] +end: + MOV EAX, EBX + LEA EAX, DWORD PTR [EAX + EDX] + MOV EDX, DWORD PTR [EBP+0xC] + LEA EAX, DWORD PTR [EAX + EDX] + MOV ESP, EBP + POP EBP + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_20.S b/test/samples/x86_32/cst_propag/x86_32_sc_20.S new file mode 100644 index 00000000..4f2b82c6 --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_20.S @@ -0,0 +1,19 @@ +main: + MOV EBX, 0 + MOV ECX, 0 + + CMP EDX, 0 + JNZ test1 + JMP goon +test1: + MOV EDX, 1 + LEA EDX, DWORD PTR [EDX+0xF] + LEA EBX, DWORD PTR [EBX+EDX] + MOV EDX, 2 + LEA EDX, DWORD PTR [EDX+0xE] + MOV ECX, EDX + LEA EBX, DWORD PTR [EBX+ECX] + JNZ test1 +goon: + MOV EAX, EBX + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_3.S b/test/samples/x86_32/cst_propag/x86_32_sc_3.S new file mode 100644 index 00000000..46d2afff --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_3.S @@ -0,0 +1,15 @@ +main: + PUSH EBP + MOV EBP, ESP + MOV ECX, DWORD PTR [EBP+0x8] +loop: + SUB ECX, 1 + JZ end + PUSH EDX + POP ESI + JMP loop +end: + MOV EAX, DWORD PTR [ESP+0xC] + MOV ESP, EBP + POP EBP + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_4.S b/test/samples/x86_32/cst_propag/x86_32_sc_4.S new file mode 100644 index 00000000..1f9e82a3 --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_4.S @@ -0,0 +1,15 @@ +main: + PUSH EBP + MOV EBP, ESP + MOV ECX, DWORD PTR [EBP+0x8] +loop: + PUSH EDX + POP ESI + SUB ECX, 1 + JZ end + JMP loop +end: + MOV EAX, DWORD PTR [ESP+0xC] + MOV ESP, EBP + POP EBP + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_5.S b/test/samples/x86_32/cst_propag/x86_32_sc_5.S new file mode 100644 index 00000000..b9d7e08a --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_5.S @@ -0,0 +1,24 @@ +main: + PUSH EBP + MOV EBP, ESP + MOV ECX, DWORD PTR [EBP+0x8] + + SUB ECX, 1 + JZ test1 + SUB ECX, 1 + JZ test2 + SUB ECX, 1 + JZ test3 + + JMP end +test1: + INC EAX +test2: + INC EAX +test3: + INC EAX +end: + INC EAX + MOV ESP, EBP + POP EBP + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_6.S b/test/samples/x86_32/cst_propag/x86_32_sc_6.S new file mode 100644 index 00000000..65fc2b8b --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_6.S @@ -0,0 +1,37 @@ +main: + PUSH EBP + MOV EBP, ESP + MOV ECX, DWORD PTR [EBP+0x8] + + INC EAX + SUB ECX, 1 + JZ test1 + ADD EAX, 1 + JMP go1 +test1: + ADD EAX, 2 +go1: + + + INC EAX + SUB ECX, 1 + JZ test2 + ADD EAX, 0x10 + JMP go2 +test2: + ADD EAX, 0x20 +go2: + + INC EAX + SUB ECX, 1 + JZ test3 + ADD EAX, 0x30 + JMP go3 +test3: + ADD EAX, 0x40 +go3: + + INC EAX + MOV ESP, EBP + POP EBP + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_7.S b/test/samples/x86_32/cst_propag/x86_32_sc_7.S new file mode 100644 index 00000000..96c5fc6e --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_7.S @@ -0,0 +1,16 @@ +main: + PUSH EBP + MOV EBP, ESP + MOV ECX, DWORD PTR [EBP+0x8] + INC EAX + +loop: + INC EAX + DEC EAX + SUB ECX, 1 + JZ loop + + INC EAX + MOV ESP, EBP + POP EBP + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_8.S b/test/samples/x86_32/cst_propag/x86_32_sc_8.S new file mode 100644 index 00000000..5127c0fa --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_8.S @@ -0,0 +1,18 @@ +main: + PUSH EBP + MOV EBP, ESP + MOV ECX, DWORD PTR [EBP+0x8] + INC EAX + +loop: + MOV EDX, 1 + MOV ESI, 1 + ADD EAX, EDX + SUB EAX, ESI + SUB ECX, 1 + JZ loop + + INC EAX + MOV ESP, EBP + POP EBP + RET diff --git a/test/samples/x86_32/cst_propag/x86_32_sc_9.S b/test/samples/x86_32/cst_propag/x86_32_sc_9.S new file mode 100644 index 00000000..0b01305b --- /dev/null +++ b/test/samples/x86_32/cst_propag/x86_32_sc_9.S @@ -0,0 +1,36 @@ +main: + PUSH EBP + MOV EBP, ESP + MOV ECX, 10 ; DWORD PTR [EBP+0x8] + + MOV EBX, 0x1000 ; + INC EBX ; EBX = 0x1001 + MOV EAX, EBX ; EAX = 0x1001 + MOV EBX, 0x10001 ; EBX = 0x10001 + DEC EBX ; EBX = 0x10000 + MOV ESI, EBX ; ESI = 0x10000 + ; + ADD EDI, EAX ; EDI += 0x1001 + ADD EDI, ESI ; EDI += 0x10000 + ;; EDI = EDI + 0x11001 + +loop: + MOV EBX, 0x1000 ; + MOV EAX, EBX ; + MOV EBX, 0x100001 ; + MOV ESI, EBX ; + MUL ESI ; EAX = 0x1000 + MOV EBX, 0x1 ; + ADD EDI, EBX ; EDI += 1 + MOV EBX, 0x1000 ; + ADD EDI, EBX ; EDI += 0x1000 + SUB EDI, EAX ; EDI -= 0x1000 + DEC EDI ; EDI -= 1 + SUB ECX, 1 + JNZ loop + + INC EDI + MOV EAX, EDI + MOV ESP, EBP + POP EBP + RET diff --git a/test/test_all.py b/test/test_all.py index 07542f6a..17193d9f 100755 --- a/test/test_all.py +++ b/test/test_all.py @@ -188,8 +188,9 @@ class SemanticTestAsm(RegressionTest): self.command_line = [self.shellcode_script, arch, input_filename, - output_filename, - self.container_dct.get(container, '')] + output_filename] + if container in self.container_dct: + self.command_line.append(self.container_dct[container]) self.products = [output_filename, "graph.dot"] @@ -304,6 +305,17 @@ testset += RegressionTest(["data_flow.py"], base_dir="analysis", for test_nb in xrange(1, 18)) for fname in fnames]) +for i in xrange(1, 21): + input_name = "cst_propag/x86_32_sc_%d" % i + bin_name = "samples/x86_32/%s.bin" % input_name + test_x86_32_cst = SemanticTestAsm("x86_32", None, [input_name]) + testset+= test_x86_32_cst + testset += RegressionTest(["../example/expression/constant_propagation.py", "-s", bin_name, "0"], + depends=[test_x86_32_cst], + products=["%s.propag.dot" % bin_name]) + + + ## Degraph class TestDepgraph(RegressionTest): """Dependency graph test""" @@ -565,6 +577,11 @@ testset += ExampleExpression(["access_c.py", Example.get_sample("human.bin")], testset += ExampleExpression(["expr_c.py"], tags=[TAGS["cparser"]]) + +testset += ExampleExpression(["constant_propagation.py", + Example.get_sample("simple_test.bin"), "-s", "0"], + products=["%s.propag.dot" % Example.get_sample("simple_test.bin")]) + for script in [["basic_op.py"], ["basic_simplification.py"], ["simplification_tools.py"], |