|
12 | 12 | #include "GlobalState.h" |
13 | 13 | #include "InfoHandler.h" |
14 | 14 | #include "Performance.h" |
| 15 | +#include "ArchitectureHooks.h" |
15 | 16 |
|
16 | 17 | #include "Core/AnalysisProvider.h" |
17 | 18 | #include "Core/BinaryViewFile.h" |
@@ -119,6 +120,31 @@ void Workflow::rewriteMethodCall(LLILFunctionRef ssa, size_t insnIndex) |
119 | 120 | llil->GenerateSSAForm(); |
120 | 121 | } |
121 | 122 |
|
| 123 | +void Workflow::rewriteCFString(LLILFunctionRef ssa, size_t insnIndex) |
| 124 | +{ |
| 125 | + const auto bv = ssa->GetFunction()->GetView(); |
| 126 | + const auto llil = ssa->GetNonSSAForm(); |
| 127 | + const auto insn = ssa->GetInstruction(insnIndex); |
| 128 | + const auto llilIndex = ssa->GetNonSSAInstructionIndex(insnIndex); |
| 129 | + auto llilInsn = llil->GetInstruction(llilIndex); |
| 130 | + |
| 131 | + auto sourceExpr = insn.GetSourceExpr<LLIL_SET_REG_SSA>(); |
| 132 | + auto destRegister = llilInsn.GetDestRegister(); |
| 133 | + |
| 134 | + auto addr = sourceExpr.GetValue().value; |
| 135 | + auto stringPointer = addr + 0x10; |
| 136 | + uint64_t dest; |
| 137 | + bv->Read(&dest, stringPointer, bv->GetDefaultArchitecture()->GetAddressSize()); |
| 138 | + |
| 139 | + auto targetPointer = llil->ConstPointer(bv->GetAddressSize(), dest, llilInsn); |
| 140 | + auto cfstrCall = llil->Intrinsic({ BinaryNinja::RegisterOrFlag(0, destRegister) }, CFSTRIntrinsicIndex, {targetPointer}, 0, llilInsn); |
| 141 | + |
| 142 | + llilInsn.Replace(cfstrCall); |
| 143 | + |
| 144 | + llil->GenerateSSAForm(); |
| 145 | + llil->Finalize(); |
| 146 | +} |
| 147 | + |
122 | 148 | void Workflow::inlineMethodCalls(AnalysisContextRef ac) |
123 | 149 | { |
124 | 150 | const auto func = ac->GetFunction(); |
@@ -159,6 +185,8 @@ void Workflow::inlineMethodCalls(AnalysisContextRef ac) |
159 | 185 | if (!GlobalState::hasAnalysisInfo(bv)) { |
160 | 186 | SharedAnalysisInfo info; |
161 | 187 | CustomTypes::defineAll(bv); |
| 188 | + CFStringArchitectureHook* currentHook = new CFStringArchitectureHook(bv->GetDefaultArchitecture()); |
| 189 | + bv->GetDefaultArchitecture()->Register(currentHook); |
162 | 190 |
|
163 | 191 | try { |
164 | 192 | auto file = std::make_shared<ObjectiveNinja::BinaryViewFile>(bv); |
@@ -231,27 +259,37 @@ void Workflow::inlineMethodCalls(AnalysisContextRef ac) |
231 | 259 | return; |
232 | 260 | } |
233 | 261 |
|
234 | | - const auto rewriteIfEligible = [msgSendFunctions, ssa](size_t insnIndex) { |
| 262 | + const auto rewriteIfEligible = [bv, msgSendFunctions, ssa](size_t insnIndex) { |
235 | 263 | auto insn = ssa->GetInstruction(insnIndex); |
236 | 264 |
|
237 | | - if (insn.operation != LLIL_CALL_SSA) |
238 | | - return; |
239 | | - |
240 | | - // Filter out calls that aren't to `objc_msgSend`. |
241 | | - auto callExpr = insn.GetDestExpr<LLIL_CALL_SSA>(); |
242 | | - if (!msgSendFunctions.count(callExpr.GetValue().value)) |
243 | | - return; |
244 | | - |
245 | | - // By convention, the selector is the second argument to `objc_msgSend`, |
246 | | - // therefore two parameters are required for a proper rewrite; abort if |
247 | | - // this condition is not met. |
248 | | - auto params = insn.GetParameterExprs<LLIL_CALL_SSA>(); |
249 | | - if (params.size() < 2 |
250 | | - || params[0].operation != LLIL_REG_SSA |
251 | | - || params[1].operation != LLIL_REG_SSA) |
252 | | - return; |
253 | | - |
254 | | - rewriteMethodCall(ssa, insnIndex); |
| 265 | + if (insn.operation == LLIL_CALL_SSA) |
| 266 | + { |
| 267 | + // Filter out calls that aren't to `objc_msgSend`. |
| 268 | + auto callExpr = insn.GetDestExpr<LLIL_CALL_SSA>(); |
| 269 | + if (!msgSendFunctions.count(callExpr.GetValue().value)) |
| 270 | + return; |
| 271 | + |
| 272 | + // By convention, the selector is the second argument to `objc_msgSend`, |
| 273 | + // therefore two parameters are required for a proper rewrite; abort if |
| 274 | + // this condition is not met. |
| 275 | + auto params = insn.GetParameterExprs<LLIL_CALL_SSA>(); |
| 276 | + if (params.size() < 2 |
| 277 | + || params[0].operation != LLIL_REG_SSA |
| 278 | + || params[1].operation != LLIL_REG_SSA) |
| 279 | + return; |
| 280 | + |
| 281 | + rewriteMethodCall(ssa, insnIndex); |
| 282 | + } |
| 283 | + else if (insn.operation == LLIL_SET_REG_SSA) |
| 284 | + { |
| 285 | + auto sourceExpr = insn.GetSourceExpr<LLIL_SET_REG_SSA>(); |
| 286 | + auto addr = sourceExpr.GetValue().value; |
| 287 | + BinaryNinja::DataVariable var; |
| 288 | + if (!bv->GetDataVariableAtAddress(addr, var) || var.type->GetString() != "struct CFString") |
| 289 | + return; |
| 290 | + |
| 291 | + rewriteCFString(ssa, insnIndex); |
| 292 | + } |
255 | 293 | }; |
256 | 294 |
|
257 | 295 | for (const auto& block : ssa->GetBasicBlocks()) |
|
0 commit comments