summaryrefslogtreecommitdiff
path: root/lang
diff options
context:
space:
mode:
authorMark Rowe <mrowe@bdash.net.nz>2025-06-09 23:18:22 -0700
committerkat <kat@vector35.com>2025-06-18 10:39:08 -0400
commitb3b06af27b7c706bb01fc215c342c97082975b14 (patch)
tree358fed404d946b7b31962b360b72de48e2b054ab /lang
parent092815158ee7580ea0631dbf14243c11b63de6e3 (diff)
[ObjC] Rewrite a couple of additional runtime calls
objc_opt_self -> [... self], objc_opt_isKindOfClass -> [... isKindOfClass:...], objc_opt_respondsToSelector -> [... respondsToSelector:...]
Diffstat (limited to 'lang')
-rw-r--r--lang/c/pseudoobjc.cpp42
-rw-r--r--lang/c/pseudoobjc.h3
2 files changed, 44 insertions, 1 deletions
diff --git a/lang/c/pseudoobjc.cpp b/lang/c/pseudoobjc.cpp
index 96f0e7c3..7794e938 100644
--- a/lang/c/pseudoobjc.cpp
+++ b/lang/c/pseudoobjc.cpp
@@ -112,6 +112,9 @@ struct RuntimeCall
Autorelease,
RetainAutorelease,
Class,
+ Self,
+ RespondsToSelector,
+ IsKindOfClass
};
Type type;
@@ -129,6 +132,9 @@ constexpr std::array RUNTIME_CALLS = {
std::make_pair("_objc_msgSendSuper2", RuntimeCall::MessageSendSuper),
std::make_pair("_objc_opt_class", RuntimeCall::Class),
std::make_pair("_objc_opt_new", RuntimeCall::New),
+ std::make_pair("_objc_opt_self", RuntimeCall::Self),
+ std::make_pair("_objc_opt_respondsToSelector", RuntimeCall::RespondsToSelector),
+ std::make_pair("_objc_opt_isKindOfClass", RuntimeCall::IsKindOfClass),
std::make_pair("_objc_release", RuntimeCall::Release),
std::make_pair("_objc_retain", RuntimeCall::Retain),
std::make_pair("_objc_retainAutoreleasedReturnValue", RuntimeCall::Retain),
@@ -143,6 +149,9 @@ constexpr std::array RUNTIME_CALLS = {
std::make_pair("j__objc_msgSendSuper2", RuntimeCall::MessageSendSuper),
std::make_pair("j__objc_opt_class", RuntimeCall::Class),
std::make_pair("j__objc_opt_new", RuntimeCall::New),
+ std::make_pair("j__objc_opt_self", RuntimeCall::Self),
+ std::make_pair("j__objc_opt_respondsToSelector", RuntimeCall::RespondsToSelector),
+ std::make_pair("j__objc_opt_isKindOfClass", RuntimeCall::IsKindOfClass),
std::make_pair("j__objc_release", RuntimeCall::Release),
std::make_pair("j__objc_retain", RuntimeCall::Retain),
std::make_pair("j__objc_retainAutoreleasedReturnValue", RuntimeCall::Retain),
@@ -244,7 +253,20 @@ void PseudoObjCFunction::GetExpr_CALL_OR_TAILCALL(const BinaryNinja::HighLevelIL
case RuntimeCall::Class:
runtimeCallTokens = {"class"};
break;
- default:
+ case RuntimeCall::Self:
+ runtimeCallTokens = {"self"};
+ break;
+ case RuntimeCall::RespondsToSelector:
+ case RuntimeCall::IsKindOfClass:
+ std::string_view selectorToken =
+ objCRuntimeCall->type == RuntimeCall::RespondsToSelector ? "respondsToSelector:" : "isKindOfClass:";
+ if (GetExpr_TwoParamObjCRuntimeCall(
+ objCRuntimeCall->address, instr, tokens, settings, parameterExprs, selectorToken))
+ {
+ if (statement)
+ tokens.AppendSemicolon();
+ return;
+ }
break;
}
@@ -332,6 +354,24 @@ bool PseudoObjCFunction::GetExpr_GenericObjCRuntimeCall(uint64_t address, const
return true;
}
+bool PseudoObjCFunction::GetExpr_TwoParamObjCRuntimeCall(uint64_t address, const HighLevelILInstruction& instr,
+ HighLevelILTokenEmitter& tokens, DisassemblySettings* settings,
+ const std::vector<HighLevelILInstruction>& parameterExprs, std::string_view selectorToken)
+{
+ if (parameterExprs.size() < 2)
+ return false;
+
+ tokens.AppendOpenBracket();
+
+ GetExprText(parameterExprs[0], tokens, settings);
+ tokens.Append(TextToken, " ");
+ tokens.Append(CodeSymbolToken, StringReferenceTokenContext, std::string(selectorToken), instr.address, address);
+ GetExprText(parameterExprs[1], tokens, settings, MemberAndFunctionOperatorPrecedence);
+ tokens.AppendCloseBracket();
+
+ return true;
+}
+
void PseudoObjCFunction::GetExpr_CONST_PTR(const BinaryNinja::HighLevelILInstruction& instr,
BinaryNinja::HighLevelILTokenEmitter& tokens, BinaryNinja::DisassemblySettings* settings,
BNOperatorPrecedence precedence, bool statement)
diff --git a/lang/c/pseudoobjc.h b/lang/c/pseudoobjc.h
index 6e49d400..d7d63196 100644
--- a/lang/c/pseudoobjc.h
+++ b/lang/c/pseudoobjc.h
@@ -28,6 +28,9 @@ private:
bool GetExpr_GenericObjCRuntimeCall(uint64_t address, const BinaryNinja::HighLevelILInstruction& expr,
BinaryNinja::HighLevelILTokenEmitter& tokens, BinaryNinja::DisassemblySettings* settings,
const std::vector<BinaryNinja::HighLevelILInstruction>& parameterExprs, const std::vector<std::string_view>& selectorTokens);
+ bool GetExpr_TwoParamObjCRuntimeCall(uint64_t address, const BinaryNinja::HighLevelILInstruction& expr,
+ BinaryNinja::HighLevelILTokenEmitter& tokens, BinaryNinja::DisassemblySettings* settings,
+ const std::vector<BinaryNinja::HighLevelILInstruction>& parameterExprs, std::string_view selectorToken);
bool GetExpr_OBJC_CLASS(const BinaryNinja::Symbol& symbol, uint64_t constant,
const BinaryNinja::HighLevelILInstruction& expr, BinaryNinja::HighLevelILTokenEmitter& tokens,
BinaryNinja::DisassemblySettings* settings, BNOperatorPrecedence precedence, bool statement);