@@ -401,11 +401,11 @@ class PacRetAnalysis
401
401
402
402
public:
403
403
std::vector<MCInstReference>
404
- getLastClobberingInsts (const MCInst Ret , BinaryFunction &BF,
405
- const ArrayRef<MCPhysReg> UsedDirtyRegs) const {
404
+ getLastClobberingInsts (const MCInst &Inst , BinaryFunction &BF,
405
+ const ArrayRef<MCPhysReg> UsedDirtyRegs) {
406
406
if (RegsToTrackInstsFor.empty ())
407
407
return {};
408
- auto MaybeState = getStateAt (Ret );
408
+ auto MaybeState = getStateBefore (Inst );
409
409
if (!MaybeState)
410
410
llvm_unreachable (" Expected State to be present" );
411
411
const State &S = *MaybeState;
@@ -453,6 +453,29 @@ shouldReportReturnGadget(const BinaryContext &BC, const MCInstReference &Inst,
453
453
return std::make_shared<GadgetReport>(RetKind, Inst, RetReg);
454
454
}
455
455
456
+ static std::shared_ptr<Report>
457
+ shouldReportCallGadget (const BinaryContext &BC, const MCInstReference &Inst,
458
+ const State &S) {
459
+ static const GadgetKind CallKind (" non-protected call found" );
460
+ if (!BC.MIB ->isCall (Inst) && !BC.MIB ->isBranch (Inst))
461
+ return nullptr ;
462
+
463
+ bool IsAuthenticated = false ;
464
+ MCPhysReg DestReg = BC.MIB ->getRegUsedAsCallDest (Inst, IsAuthenticated);
465
+ if (IsAuthenticated || DestReg == BC.MIB ->getNoRegister ())
466
+ return nullptr ;
467
+
468
+ LLVM_DEBUG ({
469
+ traceInst (BC, " Found call inst" , Inst);
470
+ traceReg (BC, " Call destination reg" , DestReg);
471
+ traceRegMask (BC, " SafeToDerefRegs" , S.SafeToDerefRegs );
472
+ });
473
+ if (S.SafeToDerefRegs [DestReg])
474
+ return nullptr ;
475
+
476
+ return std::make_shared<GadgetReport>(CallKind, Inst, DestReg);
477
+ }
478
+
456
479
FunctionAnalysisResult
457
480
Analysis::findGadgets (BinaryFunction &BF,
458
481
MCPlusBuilder::AllocatorIdTy AllocatorId) {
@@ -469,7 +492,7 @@ Analysis::findGadgets(BinaryFunction &BF,
469
492
for (BinaryBasicBlock &BB : BF) {
470
493
for (int64_t I = 0 , E = BB.size (); I < E; ++I) {
471
494
MCInstReference Inst (&BB, I);
472
- const State &S = *PRA.getStateAt (Inst);
495
+ const State &S = *PRA.getStateBefore (Inst);
473
496
474
497
// If non-empty state was never propagated from the entry basic block
475
498
// to Inst, assume it to be unreachable and report a warning.
@@ -481,6 +504,8 @@ Analysis::findGadgets(BinaryFunction &BF,
481
504
482
505
if (auto Report = shouldReportReturnGadget (BC, Inst, S))
483
506
Result.Diagnostics .push_back (Report);
507
+ if (auto Report = shouldReportCallGadget (BC, Inst, S))
508
+ Result.Diagnostics .push_back (Report);
484
509
}
485
510
}
486
511
return Result;
0 commit comments