Skip to content

Commit

Permalink
[SharedCache] Inline CFStrings
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
WeiN76LQh authored and WeiN76LQh committed Jan 4, 2025
1 parent 958c87b commit c47bec2
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
54 changes: 54 additions & 0 deletions view/sharedcache/workflow/SharedCacheWorkflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -515,14 +515,68 @@ void fixObjCCallTypes(Ref<AnalysisContext> ctx)
}


void inlineCFStrings(Ref<AnalysisContext> ac)
{
const auto func = ac->GetFunction();
const auto bv = func->GetView();
const auto addressSize = bv->GetAddressSize();

const auto llil = ac->GetLowLevelILFunction();
if (!llil) {
return;
}
const auto ssa = llil->GetSSAForm();
if (!ssa) {
return;
}

for (const auto& block : ssa->GetBasicBlocks())
{
for (size_t i = block->GetStart(), end = block->GetEnd(); i < end; ++i)
{
const auto insn = ssa->GetInstruction(i);
if (insn.operation != LLIL_SET_REG_SSA)
continue;

const auto sourceExpr = insn.GetSourceExpr<LLIL_SET_REG_SSA>();
const auto addr = sourceExpr.GetValue().value;
BinaryNinja::DataVariable var;
if (!bv->GetDataVariableAtAddress(addr, var))
continue;
const auto varTypeString = var.type->GetString();
if (varTypeString != "struct CFString" && varTypeString != "struct __NSConstantString")
continue;

const auto llilIndex = ssa->GetNonSSAInstructionIndex(i);
auto llilInsn = llil->GetInstruction(llilIndex);

auto destRegister = llilInsn.GetDestRegister();

auto stringPointer = addr + 0x10;
uint64_t dest;
bv->Read(&dest, stringPointer, addressSize);

auto targetPointer = llil->ConstPointer(addressSize, dest, llilInsn);
auto cfstrCall = llil->Intrinsic({ BinaryNinja::RegisterOrFlag(0, destRegister) }, CFSTRIntrinsicIndex, {targetPointer}, 0, llilInsn);

llilInsn.Replace(cfstrCall);

llil->GenerateSSAForm();
llil->Finalize();
}
}
}


void SharedCacheWorkflow::Register()
{
Ref<Workflow> wf = BinaryNinja::Workflow::Instance("core.function.baseAnalysis")->Clone("core.function.dsc");
wf->RegisterActivity(new BinaryNinja::Activity("core.analysis.dscstubs", &SharedCacheWorkflow::FixupStubs));
wf->RegisterActivity(new BinaryNinja::Activity("core.analysis.fixObjCCallTypes", &fixObjCCallTypes));
wf->RegisterActivity(new BinaryNinja::Activity("core.function.objectiveC.resolveCFStrings", &inlineCFStrings));
wf->Insert("core.function.analyzeTailCalls", "core.analysis.fixObjCCallTypes");
wf->Insert("core.function.analyzeTailCalls", "core.analysis.dscstubs");
wf->Insert("core.function.translateTailCalls", "core.function.objectiveC.resolveCFStrings");

BinaryNinja::Workflow::RegisterWorkflow(wf, workflowInfo);
}
Expand Down
1 change: 1 addition & 0 deletions view/sharedcache/workflow/SharedCacheWorkflow.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ using namespace BinaryNinja;
#ifndef SHAREDCACHE_SHAREDCACHEWORKFLOW_H
#define SHAREDCACHE_SHAREDCACHEWORKFLOW_H

constexpr uint32_t CFSTRIntrinsicIndex = UINT32_MAX - 64;

class SharedCacheWorkflow
{
Expand Down

0 comments on commit c47bec2

Please sign in to comment.