Skip to content

Commit 54df8ea

Browse files
committed
[SharedCache] Add symbolizing of all accesses to non-loaded images in functions
1 parent 8cc094c commit 54df8ea

File tree

1 file changed

+51
-31
lines changed

1 file changed

+51
-31
lines changed

view/sharedcache/workflow/SharedCacheWorkflow.cpp

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -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

286306
void AnalyzeFunction(Ref<AnalysisContext> ctx)

0 commit comments

Comments
 (0)