Example: add constant expression propagation

This commit is contained in:
Fabrice Desclaux 2017-08-08 11:24:22 +02:00
parent e6f2b1431e
commit d2756cb85f
22 changed files with 442 additions and 2 deletions

View file

@ -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())

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,11 @@
main:
MOV ECX, 10
loop1:
DEC ECX
JNZ less
JMP goon
less:
DEC ECX
goon:
JNZ loop1
RET

View file

@ -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

View file

@ -0,0 +1,7 @@
main:
MOV ECX, 10
loop:
DEC ECX
JNZ loop
MOV EAX, ECX
RET

View file

@ -0,0 +1,10 @@
main:
MOV ECX, 10
MOV EDX, 10
loop:
INC EDX
DEC EDX
DEC ECX
JNZ loop
MOV EAX, EDX
RET

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,8 @@
main:
MOV EBX, 1
ADD EDI, 1
SUB EBX, EDI
SUB EDI, 1
ADD EBX, EDI
MOV EAX, EBX
RET

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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"],