Skip to content

Commit 32b22c6

Browse files
committed
ASTI: more lifting support
1 parent 1b58b6b commit 32b22c6

File tree

5 files changed

+79
-8
lines changed

5 files changed

+79
-8
lines changed

chb/app/CHVersion.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
chbversion: str = "0.3.0-20250404"
1+
chbversion: str = "0.3.0-20250417"

chb/ast/AbstractSyntaxTree.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,13 @@ def storageconstructor(self) -> ASTStorageConstructor:
185185
def set_function_prototype(self, p: AST.ASTVarInfo) -> None:
186186
self.symboltable.set_function_prototype(p)
187187

188+
def has_function_prototype(self) -> bool:
189+
return self.symboltable.has_function_prototype()
190+
191+
@property
192+
def function_prototype(self) -> Optional[AST.ASTVarInfo]:
193+
return self.symboltable.function_prototype
194+
188195
def has_symbol(self, name: str) -> bool:
189196
return self.symboltable.has_symbol(name)
190197

chb/astinterface/ASTInterface.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,13 @@ def parameter_abi(self) -> str:
215215
def srcformals(self) -> List[ASTIFormalVarInfo]:
216216
return self._srcformals
217217

218+
def has_function_prototype(self) -> bool:
219+
return self.astree.has_function_prototype()
220+
221+
@property
222+
def function_prototype(self) -> Optional[AST.ASTVarInfo]:
223+
return self.astree.function_prototype
224+
218225
@property
219226
def annotations(self) -> Dict[int, List[str]]:
220227
return self._annotations

chb/astinterface/ASTInterfaceBasicBlock.py

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
from chb.arm.ARMCfgBlock import ARMCfgBlock
4343
from chb.app.BasicBlock import BasicBlock
4444
from chb.arm.ARMInstruction import ARMInstruction
45+
from chb.arm.opcodes.ARMLogicalShiftLeft import ARMLogicalShiftLeft
46+
from chb.arm.opcodes.ARMReverseSubtract import ARMReverseSubtract
4547
from chb.astinterface.ASTInterface import ASTInterface
4648

4749

@@ -219,6 +221,18 @@ def trampoline_payload_ast(self, astree: "ASTInterface") -> AST.ASTStmt:
219221
STRxx R1, <mem>
220222
MOVxx R1, #1
221223
MOV R0
224+
225+
case 4: fallthrough / exit function (return) on !R0
226+
LDR RO, ...
227+
RSBS R1, R0, #0
228+
ADC R0, R0, R1
229+
BX LR
230+
231+
case 5: fallthrough / goto_xxx
232+
MOVxx R1, #1
233+
LSL R0, R1, #2
234+
BX LR
235+
222236
"""
223237
if not self.trampoline:
224238
raise UF.CHBError("Internal error")
@@ -242,7 +256,7 @@ def trampoline_payload_ast(self, astree: "ASTInterface") -> AST.ASTStmt:
242256
brstmt = astree.mk_branch(cc, rstmt, estmt, "0x0")
243257
return brstmt
244258

245-
elif payloadlen == 7:
259+
elif payloadlen == 7 or payloadlen == 8:
246260
(iaddr3, chkinstr3) = payloadinstrs[-3]
247261
(iaddr4, chkinstr4) = payloadinstrs[-4]
248262
chkinstr3 = cast("ARMInstruction", chkinstr3)
@@ -273,12 +287,23 @@ def trampoline_payload_ast(self, astree: "ASTInterface") -> AST.ASTStmt:
273287
if chkinstr3.mnemonic_stem == "MOV":
274288
if chkinstr3.has_instruction_condition():
275289
condition = chkinstr3.get_instruction_condition()
276-
cstmt = astree.mk_continue_stmt()
277-
estmt = astree.mk_instr_sequence([])
278-
cc = XU.xxpr_to_ast_def_expr(
279-
condition, chkinstr3.xdata, chkinstr3.iaddr, astree)
280-
brstmt = astree.mk_branch(cc, cstmt, estmt, "0x0")
281-
return brstmt
290+
chkopc2 = chkinstr2.opcode
291+
chkopc2 = cast("ARMLogicalShiftLeft", chkopc2)
292+
lslxdata = chkopc2.lsl_xdata(chkinstr2.xdata)
293+
shift = lslxdata.xrm
294+
if str(shift) == "0x1":
295+
cstmt = astree.mk_continue_stmt()
296+
estmt = astree.mk_instr_sequence([])
297+
cc = XU.xxpr_to_ast_def_expr(
298+
condition, chkinstr3.xdata, chkinstr3.iaddr, astree)
299+
brstmt = astree.mk_branch(cc, cstmt, estmt, "0x0")
300+
return brstmt
301+
else:
302+
chklogger.logger.critical(
303+
"trampoline payload cannot be lifted: "
304+
"LSL case %s not yet supported. Contact "
305+
"system maintainer for support",
306+
str(shift))
282307
else:
283308
chklogger.logger.critical(
284309
"trampoline payload cannot be lifted: "
@@ -290,6 +315,32 @@ def trampoline_payload_ast(self, astree: "ASTInterface") -> AST.ASTStmt:
290315
+ "expected a MOV instruction and not a %s. "
291316
+ "Contact system maintainer for support.",
292317
chkinstr3.mnemonic)
318+
319+
# case 4
320+
elif payloadlen == 4 and chkinstr2.mnemonic_stem == "ADC":
321+
(iaddr3, chkinstr3) = payloadinstrs[-3]
322+
chkinstr3 = cast("ARMInstruction", chkinstr3)
323+
if chkinstr3.mnemonic_stem == "RSB":
324+
chkopc3 = chkinstr3.opcode
325+
chkopc3 = cast("ARMReverseSubtract", chkopc3)
326+
rsbxdata = chkopc3.rsb_xdata(chkinstr3.xdata)
327+
cvalue = rsbxdata.xrn
328+
if rsbxdata.is_xxrn_ok:
329+
cvalue = rsbxdata.xxrn
330+
ccval = XU.xxpr_to_ast_def_expr(
331+
cvalue, chkinstr3.xdata, chkinstr3.iaddr, astree)
332+
cc = astree.mk_unary_op("lnot", ccval)
333+
rstmt = astree.mk_return_stmt(None)
334+
estmt = astree.mk_instr_sequence([])
335+
brstmt = astree.mk_branch(cc, rstmt, estmt, "0x0")
336+
return brstmt
337+
else:
338+
chklogger.logger.critical(
339+
"trampoline payload cannot be lifted: "
340+
+ "expected an RSB instruction and not a %s. "
341+
+ "Contact system maintainer for support.",
342+
chkinstr3.mnemonic)
343+
293344
else:
294345
chklogger.logger.critical(
295346
"trampoline payload cannot be lifted: "

chb/invariants/XXprUtil.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,12 @@ def global_variable_to_lval_expression(
568568
subfieldkey = subfieldoffset.ckey
569569
subfieldastoffset = astree.mk_field_offset(
570570
subfieldname, subfieldkey)
571+
elif fieldoffset.offset.is_array_index_offset:
572+
asubfieldoffset = cast(
573+
"VMemoryOffsetArrayIndexOffset", fieldoffset.offset)
574+
subfieldastoffset = array_offset_to_ast_offset(
575+
asubfieldoffset, xdata, iaddr, astree, anonymous=anonymous)
576+
571577
else:
572578
chklogger.logger.error(
573579
"Index sub offset of global offset %s not yet handled at %s",

0 commit comments

Comments
 (0)