基本方法
这个概念很简单(但实现它以保护您的应用程序免受黑客攻击很麻烦)。函数实现存储在内存中,因此有一个内存地址。这就是您可以在示例中使用函数指针的原因。
为了查看函数是否已被挂钩,您只需:
- 保存原始函数实现的地址(使用 获取函数指针的地址
&orig_SSLHandshake
)。当应用程序调用第一个ApplicationDelegate
方法时,实现全部加载到内存中。
- 每次需要时,将当前实现的地址与您存储的原始地址进行比较。
如果你不在乎被外界勾住,那么这个解决方案可能会让你满意。
保护您的应用程序免遭攻击者钩住
在这里,我假设您想保护您的应用程序免受黑客所做的函数挂钩(而不是自己挂钩该函数)。
在 iOS 中挂钩函数的最简单方法之一是使用 MobileSubstrate。它可以在应用程序启动过程的早期挂钩函数实现(在 in 时已经挂钩application:didFinishLaunching...
),因此当您尝试获取原始函数的地址 ( & originalFunction
) 时,您实际上会获得被挂钩函数的地址。您将永远无法获得原始地址。
因为函数挂钩可以在应用程序启动过程的早期发生,所以您必须使用一些技巧。
基本上,您将验证要存储为原始函数的实现是否确实是原始函数。
您可以决定使用一些全局变量(尽管这不是一种好的编程风格)并让您的原始函数对它们执行一些操作并输出一个期望值。
然后,如果攻击者已经钩住了你的函数,你就会知道(在调用你的函数之后),因为它不会在全局变量上产生预期的输出。您可以为这些检查向您的函数添加一个额外的参数。
但是,重要的是要注意,黑客可以访问您的原始函数实现和您在尝试调用该函数时传递的参数。
因此,尽管在攻击者未调用您的原始函数(使用预期参数)的情况下,先前的解决方案使验证安全,但如果他在完成自己的修改之前或之后调用您的函数,则无济于事。
void hookedImplementation (type1 arg1, type2 arg2){
// ... the hacker does stuffs
// he calls your original function with the arguments you passed.
originalFunction(arg1,arg2);
// .. other hooking
}
关于这一切,我唯一的回答是你不能 100% 确定你的原始函数没有被攻击者钩住。但是,您可能会劝阻大多数黑客,也许这对您的情况就足够了。
如果您在一家全球银行机构的 IT 部门工作,请注意这一点(因为这很重要)。