@@ -159,13 +159,13 @@ void AnalyzeStubFunction(Ref<Function> func, Ref<MediumLevelILFunction> mlil, Sh
159159 if (defInstr.operation != MLIL_SET_VAR_SSA)
160160 return ;
161161 expr = defInstr.GetSourceExpr <MLIL_SET_VAR_SSA>();
162- // Fallthrough to load ptr .
162+ // Fallthrough to MLIL_LOAD_SSA .
163163 }
164164 case MLIL_LOAD_SSA:
165165 expr = expr.GetSourceExpr <MLIL_LOAD_SSA>();
166166 if (expr.operation != MLIL_CONST_PTR)
167167 return ;
168- // Fallthrough to const ptr .
168+ // Fallthrough to MLIL_CONST_PTR .
169169 case MLIL_CONST_PTR:
170170 {
171171 // First load the stub island, if we _do_ load the stub island stop and reanalyze for constant propagation.'
@@ -183,7 +183,7 @@ void AnalyzeStubFunction(Ref<Function> func, Ref<MediumLevelILFunction> mlil, Sh
183183 }
184184 };
185185
186- auto processTailcallExpr = [&](MediumLevelILInstruction expr) {
186+ auto processTailcallExpr = [&](const MediumLevelILInstruction& expr) {
187187 switch (expr.operation )
188188 {
189189 case MLIL_CONST_PTR:
@@ -222,7 +222,7 @@ void AnalyzeStandardFunction(Ref<Function> func, Ref<MediumLevelILFunction> mlil
222222 auto view = func->GetView ();
223223 auto identifyUnmappedSymbol = [&](uint64_t symbolAddr) {
224224 // Skip if already loaded.
225- if (view->IsValidOffset (symbolAddr))
225+ if (view->IsValidOffset (symbolAddr) || view-> GetSymbolByAddress (symbolAddr) )
226226 return false ;
227227 const auto symbol = controller.GetSymbolAt (symbolAddr);
228228 if (!symbol.has_value ())
@@ -235,52 +235,72 @@ void AnalyzeStandardFunction(Ref<Function> func, Ref<MediumLevelILFunction> mlil
235235 // Skip if already loaded.
236236 if (view->IsValidOffset (regionAddr))
237237 return false ;
238- const auto region = controller.GetRegionContaining (regionAddr);
238+ auto region = controller.GetRegionContaining (regionAddr);
239239 if (!region.has_value ())
240240 return false ;
241- // Only interested in stub islands which would contain the pointers to other image functions.
242- if (region->type != SharedCacheRegionTypeStubIsland )
241+ // Only interested in non image regions, we DON'T want to implicitly load image regions (with functions presumably) .
242+ if (region->type == SharedCacheRegionTypeImage )
243243 return false ;
244-
244+ // Adjust the new region semantics to read only, this helps analysis pickup constant loads in our stub functions.
245+ // NOTE: We do NOT do this for stub island as that contains CODE!
246+ if (region->type != SharedCacheRegionTypeStubIsland)
247+ region->flags = static_cast <BNSegmentFlag>(SegmentReadable | SegmentContainsData);
245248 return controller.ApplyRegion (*view, *region);
246249 };
247250
248- auto processJumpExpr = [&](const MediumLevelILInstruction& expr) {
251+ // Use this to filter out constants that are impossible to be backed by a region.
252+ auto baseAddress = view->GetStart ();
253+
254+ // Promotes a constant to a constant pointer, if it's backed by a shared cache region.
255+ // Constants won't be eligible for symbol rendering so to get it to render we must rewrite the IL to make
256+ // it a constant pointer.
257+ auto promoteUnmappedPointerExpr = [&](MediumLevelILInstruction constExpr) {
258+ const auto unmappedAddr = constExpr.GetConstant <MLIL_CONST>();
259+ if (unmappedAddr < baseAddress || view->IsValidOffset (unmappedAddr))
260+ return false ;
261+ if (!controller.GetRegionContaining (unmappedAddr))
262+ return false ;
263+ // Replace the constant expr with a constant pointer expr
264+ const auto constSrcLoc = ILSourceLocation (constExpr.address , constExpr.sourceOperand );
265+ const auto constPtrExpr = mlil->ConstPointer (constExpr.size , unmappedAddr, constSrcLoc);
266+ // Force the expr type to a pointer as well
267+ const auto ptrType = Type::PointerType (func->GetArchitecture (), Type::VoidType ()->WithConfidence (0 ))->WithConfidence (BN_HEURISTIC_CONFIDENCE);
268+ mlil->SetExprType (constPtrExpr, ptrType);
269+ constExpr.Replace (constPtrExpr);
270+ return true ;
271+ };
272+
273+ auto processUnmappedExpr = [&](const MediumLevelILInstruction& expr) {
249274 switch (expr.operation )
250275 {
251276 case MLIL_CONST_PTR:
252277 loadStubIslandRegion (expr.GetConstant <MLIL_CONST_PTR>());
253278 identifyUnmappedSymbol (expr.GetConstant <MLIL_CONST_PTR>());
254279 break ;
280+ case MLIL_CONST:
281+ // Typically a direct expression load/store will have the constant be promoted to a constant pointer
282+ // however if an expression is only used as an address of and data flow does not fold it in, we won't get a
283+ // constant pointer promotion. This case handles that limitation, by checking to see if a constant falls in
284+ // an unmapped region.
285+ if (promoteUnmappedPointerExpr (expr))
286+ {
287+ // We have promoted a pointer, lets now try and identify its symbol.
288+ // We don't want to rely on this activity being re-invoked and going down the `MLIL_CONST_PTR` path
289+ // so instead we just call the `identifyUnmappedSymbol` after promotion, to ensure that the symbols are identified.
290+ identifyUnmappedSymbol (expr.GetConstant ());
291+ }
292+ break ;
255293 default :
256294 break ;
257295 }
296+ return true ;
258297 };
259298
260- // Load all unmapped STUB regions / images that are called in this function.
299+ // 1. Load all unmapped STUB regions / images that are called in this function.
300+ // 2. Identify loads & stores to unmapped regions and add their respective symbol.
261301 for (const auto & block : mlil->GetBasicBlocks ())
262- {
263302 for (size_t i = block->GetStart (), end = block->GetEnd (); i < end; ++i)
264- {
265- auto instr = mlil->GetInstruction (i);
266- switch (instr.operation )
267- {
268- case MLIL_CALL_SSA:
269- processJumpExpr (instr.GetDestExpr <MLIL_CALL_SSA>());
270- break ;
271- case MLIL_JUMP:
272- processJumpExpr (instr.GetDestExpr <MLIL_JUMP>());
273- break ;
274- default :
275- break ;
276- }
277- // TODO: Check all instructions for accesses to select region types (stub etc...)
278- // TODO: ^ we actually dont really need to do this, the other type of access cont..
279- // TODO: the other two types of accesses (load & save) we dont want to load their regions, just
280- // TODO: their symbol information if available.
281- // TODO: See:
282- }
283- }
303+ mlil->GetInstruction (i).VisitExprs (processUnmappedExpr);
284304}
285305
286306void AnalyzeFunction (Ref<AnalysisContext> ctx)
0 commit comments