-
Notifications
You must be signed in to change notification settings - Fork 281
Expand file tree
/
Copy pathwf_rewrite_push_pop.py
More file actions
149 lines (137 loc) · 5.87 KB
/
wf_rewrite_push_pop.py
File metadata and controls
149 lines (137 loc) · 5.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import json
from binaryninja import Workflow, Activity, AnalysisContext
from binaryninja.lowlevelil import *
def rewrite_action(context: AnalysisContext):
def translate_instr(
new_func: LowLevelILFunction,
old_block: LowLevelILBasicBlock,
old_instr: LowLevelILInstruction
) -> ExpressionIndex:
"""
Copy and translate ``old_instr`` in ``old_block`` into ``new_func``
:param new_func: new function to receive translated instructions
:param old_block: original block containing old_instr
:param old_instr: original instruction
:return: expression index of newly created instruction in ``new_func``
"""
if old_instr.operation == LowLevelILOperation.LLIL_PUSH:
# push(x)
# -----------------------
# sp = sp - sizeof(void*)
# *(sp) = x
old_instr: LowLevelILPush
# sp = sp - sizeof(void*)
new_func.append(
new_func.set_reg(
old_instr.size,
old_block.arch.stack_pointer,
new_func.sub(
old_instr.size,
new_func.reg(
old_instr.size,
old_block.arch.stack_pointer,
loc=ILSourceLocation.from_instruction(old_instr)
),
new_func.const(
old_instr.size,
old_block.arch.address_size,
loc=ILSourceLocation.from_instruction(old_instr)
),
loc=ILSourceLocation.from_instruction(old_instr)
),
loc=ILSourceLocation.from_instruction(old_instr)
)
)
# *(sp) = x
return new_func.store(
old_instr.size,
new_func.reg(
old_instr.size,
old_block.arch.stack_pointer,
loc=ILSourceLocation.from_instruction(old_instr)
),
old_instr.src.copy_to(new_func),
loc=ILSourceLocation.from_instruction(old_instr)
)
elif old_instr.operation == LowLevelILOperation.LLIL_POP:
# pop
# -----------------------
# sp = sp + sizeof(void*)
# *(sp - sizeof(void*))
# We need to append any helper instructions first and then return an expression
# that replaces the ``pop`` in the original IL (since ``pop`` has a value).
# So anything that is ``rax = pop`` becomes ``sp = sp + 8 ; rax = *(sp - 8)``
old_instr: LowLevelILPop
# sp = sp + sizeof(void*)
new_func.append(
new_func.set_reg(
old_instr.size,
old_block.arch.stack_pointer,
new_func.add(
old_instr.size,
new_func.reg(
old_instr.size,
old_block.arch.stack_pointer,
loc=ILSourceLocation.from_instruction(old_instr)
),
new_func.const(
old_instr.size,
old_block.arch.address_size,
loc=ILSourceLocation.from_instruction(old_instr)
),
loc=ILSourceLocation.from_instruction(old_instr)
),
loc=ILSourceLocation.from_instruction(old_instr)
)
)
# *(sp - sizeof(void*))
return new_func.load(
old_instr.size,
new_func.sub(
old_instr.size,
new_func.reg(
old_instr.size,
old_block.arch.stack_pointer,
loc=ILSourceLocation.from_instruction(old_instr)
),
new_func.const(
old_instr.size,
old_block.arch.address_size,
loc=ILSourceLocation.from_instruction(old_instr)
),
loc=ILSourceLocation.from_instruction(old_instr)
),
loc=ILSourceLocation.from_instruction(old_instr)
)
else:
# All other instructions: copy as-is
return old_instr.copy_to(
new_func,
lambda sub_instr: translate_instr(new_func, old_block, sub_instr)
)
# Modify the existing Lifted IL function by our translator above
translated_func = context.lifted_il.translate(translate_instr)
# Clean up blocks and prepare this function for the rest of analysis
translated_func.finalize()
# Tell the analysis to use the new form of this function
context.lifted_il = translated_func
# Create and register the workflow for translating these instructions
wf = Workflow("core.function.metaAnalysis").clone("RewritePushPop")
# Define the custom activity configuration
wf.register_activity(Activity(
configuration=json.dumps({
"name": "extension.rewrite_push_pop.rewrite_action",
"title": "Rewrite LLIL_PUSH/LLIL_POP",
"description": "Rewrites LLIL_PUSH/LLIL_POP instructions into their component store/load/register parts, demonstrating modifying and inserting Lifted IL instructions.",
"eligibility": {
"auto": {
"default": True
}
}
}),
action=rewrite_action
))
# This action is run right after generateLiftedIL so we can poke the IL before LLIL flag and stack
# adjustment resolution happens.
wf.insert_after("core.function.generateLiftedIL", ["extension.rewrite_push_pop.rewrite_action"])
wf.register()