Skip to content

Commit c47bec2

Browse files
WeiN76LQhWeiN76LQh
authored andcommitted
[SharedCache] Inline CFStrings
Basically just copied from the [workflow objc plugin](https://github.com/Vector35/workflow_objc) with [PR Vector35#67](Vector35/workflow_objc#67) applied. Ideally this would not be a copy and these 2 codebases would share the code but its unclear if Vector35 would want to import the Objective-C workflow plugin into the BN API repo and what that would look like. So this is an intermediary solution to get `CFString` inlining working in DSC.
1 parent 958c87b commit c47bec2

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

view/sharedcache/workflow/SharedCacheWorkflow.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,14 +515,68 @@ void fixObjCCallTypes(Ref<AnalysisContext> ctx)
515515
}
516516

517517

518+
void inlineCFStrings(Ref<AnalysisContext> ac)
519+
{
520+
const auto func = ac->GetFunction();
521+
const auto bv = func->GetView();
522+
const auto addressSize = bv->GetAddressSize();
523+
524+
const auto llil = ac->GetLowLevelILFunction();
525+
if (!llil) {
526+
return;
527+
}
528+
const auto ssa = llil->GetSSAForm();
529+
if (!ssa) {
530+
return;
531+
}
532+
533+
for (const auto& block : ssa->GetBasicBlocks())
534+
{
535+
for (size_t i = block->GetStart(), end = block->GetEnd(); i < end; ++i)
536+
{
537+
const auto insn = ssa->GetInstruction(i);
538+
if (insn.operation != LLIL_SET_REG_SSA)
539+
continue;
540+
541+
const auto sourceExpr = insn.GetSourceExpr<LLIL_SET_REG_SSA>();
542+
const auto addr = sourceExpr.GetValue().value;
543+
BinaryNinja::DataVariable var;
544+
if (!bv->GetDataVariableAtAddress(addr, var))
545+
continue;
546+
const auto varTypeString = var.type->GetString();
547+
if (varTypeString != "struct CFString" && varTypeString != "struct __NSConstantString")
548+
continue;
549+
550+
const auto llilIndex = ssa->GetNonSSAInstructionIndex(i);
551+
auto llilInsn = llil->GetInstruction(llilIndex);
552+
553+
auto destRegister = llilInsn.GetDestRegister();
554+
555+
auto stringPointer = addr + 0x10;
556+
uint64_t dest;
557+
bv->Read(&dest, stringPointer, addressSize);
558+
559+
auto targetPointer = llil->ConstPointer(addressSize, dest, llilInsn);
560+
auto cfstrCall = llil->Intrinsic({ BinaryNinja::RegisterOrFlag(0, destRegister) }, CFSTRIntrinsicIndex, {targetPointer}, 0, llilInsn);
561+
562+
llilInsn.Replace(cfstrCall);
563+
564+
llil->GenerateSSAForm();
565+
llil->Finalize();
566+
}
567+
}
568+
}
569+
518570

519571
void SharedCacheWorkflow::Register()
520572
{
521573
Ref<Workflow> wf = BinaryNinja::Workflow::Instance("core.function.baseAnalysis")->Clone("core.function.dsc");
522574
wf->RegisterActivity(new BinaryNinja::Activity("core.analysis.dscstubs", &SharedCacheWorkflow::FixupStubs));
523575
wf->RegisterActivity(new BinaryNinja::Activity("core.analysis.fixObjCCallTypes", &fixObjCCallTypes));
576+
wf->RegisterActivity(new BinaryNinja::Activity("core.function.objectiveC.resolveCFStrings", &inlineCFStrings));
524577
wf->Insert("core.function.analyzeTailCalls", "core.analysis.fixObjCCallTypes");
525578
wf->Insert("core.function.analyzeTailCalls", "core.analysis.dscstubs");
579+
wf->Insert("core.function.translateTailCalls", "core.function.objectiveC.resolveCFStrings");
526580

527581
BinaryNinja::Workflow::RegisterWorkflow(wf, workflowInfo);
528582
}

view/sharedcache/workflow/SharedCacheWorkflow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ using namespace BinaryNinja;
77
#ifndef SHAREDCACHE_SHAREDCACHEWORKFLOW_H
88
#define SHAREDCACHE_SHAREDCACHEWORKFLOW_H
99

10+
constexpr uint32_t CFSTRIntrinsicIndex = UINT32_MAX - 64;
1011

1112
class SharedCacheWorkflow
1213
{

0 commit comments

Comments
 (0)