mirror of
https://github.com/cea-sec/miasm
synced 2026-08-17 10:26:03 -04:00
Example: add constant expression propagation
This commit is contained in:
parent
e6f2b1431e
commit
d2756cb85f
22 changed files with 442 additions and 2 deletions
54
example/expression/constant_propagation.py
Normal file
54
example/expression/constant_propagation.py
Normal 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())
|
||||
21
test/samples/x86_32/cst_propag/x86_32_sc_1.S
Normal file
21
test/samples/x86_32/cst_propag/x86_32_sc_1.S
Normal 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
|
||||
17
test/samples/x86_32/cst_propag/x86_32_sc_10.S
Normal file
17
test/samples/x86_32/cst_propag/x86_32_sc_10.S
Normal 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
|
||||
11
test/samples/x86_32/cst_propag/x86_32_sc_11.S
Normal file
11
test/samples/x86_32/cst_propag/x86_32_sc_11.S
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
main:
|
||||
MOV ECX, 10
|
||||
loop1:
|
||||
DEC ECX
|
||||
JNZ less
|
||||
JMP goon
|
||||
less:
|
||||
DEC ECX
|
||||
goon:
|
||||
JNZ loop1
|
||||
RET
|
||||
12
test/samples/x86_32/cst_propag/x86_32_sc_12.S
Normal file
12
test/samples/x86_32/cst_propag/x86_32_sc_12.S
Normal 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
|
||||
7
test/samples/x86_32/cst_propag/x86_32_sc_13.S
Normal file
7
test/samples/x86_32/cst_propag/x86_32_sc_13.S
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
main:
|
||||
MOV ECX, 10
|
||||
loop:
|
||||
DEC ECX
|
||||
JNZ loop
|
||||
MOV EAX, ECX
|
||||
RET
|
||||
10
test/samples/x86_32/cst_propag/x86_32_sc_14.S
Normal file
10
test/samples/x86_32/cst_propag/x86_32_sc_14.S
Normal 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
|
||||
16
test/samples/x86_32/cst_propag/x86_32_sc_15.S
Normal file
16
test/samples/x86_32/cst_propag/x86_32_sc_15.S
Normal 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
|
||||
17
test/samples/x86_32/cst_propag/x86_32_sc_16.S
Normal file
17
test/samples/x86_32/cst_propag/x86_32_sc_16.S
Normal 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
|
||||
8
test/samples/x86_32/cst_propag/x86_32_sc_17.S
Normal file
8
test/samples/x86_32/cst_propag/x86_32_sc_17.S
Normal 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
|
||||
33
test/samples/x86_32/cst_propag/x86_32_sc_18.S
Normal file
33
test/samples/x86_32/cst_propag/x86_32_sc_18.S
Normal 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
|
||||
16
test/samples/x86_32/cst_propag/x86_32_sc_19.S
Normal file
16
test/samples/x86_32/cst_propag/x86_32_sc_19.S
Normal 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
|
||||
21
test/samples/x86_32/cst_propag/x86_32_sc_2.S
Normal file
21
test/samples/x86_32/cst_propag/x86_32_sc_2.S
Normal 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
|
||||
19
test/samples/x86_32/cst_propag/x86_32_sc_20.S
Normal file
19
test/samples/x86_32/cst_propag/x86_32_sc_20.S
Normal 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
|
||||
15
test/samples/x86_32/cst_propag/x86_32_sc_3.S
Normal file
15
test/samples/x86_32/cst_propag/x86_32_sc_3.S
Normal 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
|
||||
15
test/samples/x86_32/cst_propag/x86_32_sc_4.S
Normal file
15
test/samples/x86_32/cst_propag/x86_32_sc_4.S
Normal 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
|
||||
24
test/samples/x86_32/cst_propag/x86_32_sc_5.S
Normal file
24
test/samples/x86_32/cst_propag/x86_32_sc_5.S
Normal 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
|
||||
37
test/samples/x86_32/cst_propag/x86_32_sc_6.S
Normal file
37
test/samples/x86_32/cst_propag/x86_32_sc_6.S
Normal 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
|
||||
16
test/samples/x86_32/cst_propag/x86_32_sc_7.S
Normal file
16
test/samples/x86_32/cst_propag/x86_32_sc_7.S
Normal 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
|
||||
18
test/samples/x86_32/cst_propag/x86_32_sc_8.S
Normal file
18
test/samples/x86_32/cst_propag/x86_32_sc_8.S
Normal 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
|
||||
36
test/samples/x86_32/cst_propag/x86_32_sc_9.S
Normal file
36
test/samples/x86_32/cst_propag/x86_32_sc_9.S
Normal 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
|
||||
|
|
@ -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"],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue