当从ARM64反编译代码时,如何知道无条件分支指令b是否是到同一函数中的标签的分支,而不是到某个其他函数的分支?

How do state of the art decompilers recognize if a branch target is still in the function or is it a new function? Do they rely on the branch target's value and see if it lands on a different section in the TEXT segment?
What about branch targets that are in the same sections but are still considered new functions? Is there a rule of thumb for ARM64 saying that if a branch target is too far by some threshold from the current address it's considered a new boundary thus a new function? Like in x86 where you have different encodings for far jump and short jump, where short jump may be considered a label in a function and far jump probably not.

我可能会补充说,我现在正在判断的目标二进制文件是用Objective-C编写的Machos,我试图使用Ghidra来验证我的发现,所以它可能会使用一些更多的启发式方法,比如查看跳转目标是在__stubs节还是__objc_stubs节中,或者甚至分析块 struct 来识别更多的过程(尽管从Ghidra反编译的最后一点似乎没有识别这些 struct )?

推荐答案

当从ARM64反编译代码时,如何知道无条件分支指令b是否是指向同一函数中的标签的分支,而不是指向某个其他函数的分支?

你不可能真的know岁.你充其量只能做出一个有根据的猜测.根据我的经验,即使是最先进的反编译器也不擅长这一点.好的允许用户手动覆盖这种检测.

核心问题是,在程序集合级上没有"功能"的概念.输出到高级语言(如C)的标签应该符合特定的ABI,但对于其他任何东西,所有的赌注都是错误的.即使是出口的东西,如果你面对的是恶意作者(考虑:恶意软件),那么他们可能也会 Select destruct 这份合同,以掩盖二进制文件的工作原理.但即使是非恶意的二进制文件,如果有人使用苹果支持的ARM64目标-O3 -flto -moutline,你也会受到伤害.

不过,您可以使用一些启发式方法:

  • Has x30 been saved somewhere?
    Usually this will happen by an stp x29, x30, [sp, ...] instruction, and go along with decreasing sp. If this is the case, then with b you're likely looking at a branch within the same function. If this is not the case, then you don't know whether this is a tail call or a jump within the same function.

    假设:使用X30作为链路寄存器.混乱器可以使用其他东西,例如,通过adr x17, ...; b _func来进行函数调用,然后x17将是链接寄存器.这也可以按功能随机化.

  • Are there any functions in between the current address and the jump target?
    Maybe your binary has symbols, maybe LC_FUNCTION_STARTS, maybe your decompilation has already identified function units, etc.

    假设:函数的所有基本块都是紧邻在一起的,并且不是零碎的和分散的.通常情况是这样的,但同样,作为混淆技术的一部分,这一假设可能会被打破.

  • Is the jump target jumped to from any other function?
    If there are other callsites from code that you have already determined belongs to a different function, then the jump target can't belong to either of those functions.

    注意:功能概述,请参见下一点.

  • Does the called code maintain the ABI in and out that you expect from a function?
    ABI violations should be trivial to determine. ABI conformance would need something like explicit register spilling to give you confidence. But if it conforms to the expected ABI, then it most likely is its own function. If not, then it's probably either part of the function that jumps to it, or it's code that was outlined.

但这些都不能保证会发生,而且总会有两种 Select 都有可能的情况.

Objective-c相关问答推荐

如何用零填充左侧的整数?

为什么 UICollectionView 的 UICollectionViewCell 没有在用户时突出显示?

为什么 NSDateFormatter 为这 4 个时区返回 nil 日期?

iOS 中 textField 上的Electron邮件验证

如何删除 xcode 5 中的旧配置文件?

如何将 .plist 文件中的数据 struct 读入 NSArray

如何确定 UICollectionView flowLayout 中单元格之间的间距

iOS6:supportedInterfaceOrientations 不起作用(被调用但界面仍然旋转)

NSURLConnection sendAsynchronousRequest:queue:completionHandler:连续发出多个请求?

强制iOS应用程序崩溃的最快方法是什么?

我可以在 Objective-C switch 语句中声明变量吗?

iPhone 正确使用 Application Delegate

创建 NSTextField标签的示例代码?

笔尖中的原型单元而不是故事板

`[super viewDidLoad]` 约定

从视图中删除所有子图层

如何判断 WkWebView 是否在 Objective-C 中完成加载?

带有 UIImage 的 UIBarButtonItem 始终着色 iOS 7

如何调整 UIToolBar 左右内边距

更改导航栏的字体