Hikari源码潜入的第三弹来了,预测亦然临了一篇,该系列著述逐个分析了AntiClassDump、AntiDebug以及本篇AntiHook,主要侧重安全方面的保护,宦囊憨涩,该著述的源码在:https://github.com/61bcdefg/Hikari-LLVM15-Core/blob/main/AntiHooking.cpp 宿舍 自慰,起程点AntiHook的分析。
达成旨趣该PASS主要提供了三大功能,分离是inlinehook的检测、Runtime保护以及注视借助记号重绑定膺惩:
检测和中断潜在的内联hook:通过分析缱绻圭臬中的教唆序列,该Pass不错识别可能的hook代码,即那些可能被膺惩者植入用以截止圭臬行动的代码。一朝检测到这么的教唆模式,Pass会插入异常的查抄,如果检测到违纪操作,就会转到症结惩处经由,从而保护圭臬不被进一步篡改。 保护Objective-C运行时环境:在iOS和macOS等使用Objective-C的环境中,方法达成可能会在运行时被替换或hook,这是常见的动态行动修改妙技。AntiHook Pass通过向代码中插入特定的查抄逻辑,确保Objective-C方法在实施时莫得被违纪替换或修改。 反制动态库的重绑定膺惩:动态库中记号的重绑定(举例通过fishhook)是膺惩者常用的妙技来劫持圭臬中的平淡调用。该Pass通过分析外部函数调用,并修改这些调用以指向安全的存根或替代达成,从而贫乏这种类型的膺惩。 代码分析代码量相对较少,所有这个词三百多行,是以咱们径直针对具体代码来分析,梳理一下具体的达成经由。
0. config领先看到的是ARM A64教唆集的操作码签名,它们界说了特定的教唆的二进制暗示样式。这些签名是凭证ARM架构的官方文档或阐明书中对于教唆编码的部分得到的,在ARM A64架构的A-profile中,每条教唆齐有一个特定的位模式。
AARCH64_SIGNATURE_B 是B教唆(分支教唆)的操作码签名,B教唆用于无条款分支(跳转)。它在Arm A64教唆集的磋磨文档中被指定为0b000101,在二进制中,前缀0b指明接下来的数字是二进制样式。 AARCH64_SIGNATURE_BR 是BR教唆(分支到寄存器教唆)的操作码,BR教唆用于跳转到在某个寄存器中给出的地址。操作码0b1101011000011111000000是这个教唆的二进制模式。 AARCH64_SIGNATURE_BRK 是BRK教唆(中断教唆)的操作码,BRK教唆用于生成一个同步中断,经常用于调试。操作码0b11010100001是BRK教唆的独一象征。这些操作码界说了教唆的基本类型和行动,编译器和汇编器在生成机器码时会使用这些签名来构造正确的二进制教唆。使用这些签名是为了简略识别出特定的二进制教唆模式,主要用于后续进行inlinehook的检测。
树立方面还有以下这些,desc态状的很详备,不再作念过多讲明:
1. initialize该函数的作用是在Pass开动化时建立一些必要的景色和条款。以下是详备的法子分析:
1. 取得缱绻架构的信息领先,它取得当前模块的Triple,它包含了对于缱绻架构的信息,举例架构类型、操作系统等。
2. 构建默许的预编译IR文献旅途接下来,如果PreCompiledIRPath高唱行选项莫得被用户建立(默许为空字符串),那么代码会尝试构建一个默许的旅途。它领先取得用户的主目次,然后在这个目次下创建一个相对旅途,这个旅途指向预编译的抗Hook惩处IR文献。旅途中包含了架构和操作系统的称呼。
3. 查抄预编译IR文献是否存在,潜入并结合预编译的模块使用std::ifstream查抄该旅途指向的文献是否存在且可读。如果文献检测顺利,将会输出磋磨信息,并使用parseIRFile函数将文献内容潜入为Module对象,之后使用Linker::linkModules函数将潜入出的模块与面前的模块结合。这允许将预编译的抗Hook逻辑统一入面前模块中。
4. 笃定是否赞助不透明指针接下来,查抄面前模块是否赞助不透明指针。LLVM的新版块中不透明指针是默许特质,这段代码用来笃定面前高下文是否赞助它。
5. 插入Objective-C磋磨函数声明查抄缱绻架构是否是由Apple提供,况且在面前模块的高下文中是否界说了struct._objc_method。如果这些条款得志,它会插入Objective-C磋磨的函数声明到模块中。这些函数包括用于取得类、注册选拔器以及取得方法达成的函数。这么的函数声明对于后续查抄Objective-C运行时Hook行动是必要的。
通过这个开动化函数,建立了磋磨的hook查抄和惩处机制,确保了代码不错找到正确的预编译IR文献,并将其正确地结合到面前模块。同期,对于Objective-C的运行时,通过查抄模块中是否存在磋磨的类型界说,并在必要时插入异常的函数声明,以便在后续Pass的运行中实施这些安全查抄。
2. runOnModule 逻辑梳理runOnModule函数合座的达成逻辑较为了了,主如果查抄和惩处内联hook、注视记号重绑定(fishhook膺惩妙技)、以及惩处Objective-C运行时hook等,此函数咱们不进行逐行的分析,先梳理它的大要经由:
遍历模块M中的系数函数(Function)对象。
对于每个函数,领先查抄该函数是否应该实施"antihook"操作。判断基于编译时标志(flag)和函数属性。
如果initialized标志为false,调用initialize函数以开动化Pass。
取得当前函数F的ah_inline属性,决定是否需要查抄内联hook。如果属性未建立,使用全局的CheckInlineHook建立。
如果面前的架构是AArch64且CheckInlineHookTemp为true,则对函数F实施HandleInlineHookAArch64惩处。
取得当前函数F的ah_antirebind属性,决定是否需要实施反绑定记号操作。如果属性未建立,使用全局的AntiRebindSymbol建立。
如果AntiRebindSymbolTemp为true,对函数F中的教唆进行遍历。对于每个调用(Call)或调用动态分派(Invoke)教唆,查抄缱绻函数是否为外部结合声明。如果是,创建新的全局变量并替换这些教唆中的调用缱绻。
取得当前函数F的ah_objcruntime属性,决定是否需要查抄Objective-C运行时hook。如果属性未建立,使用全局的CheckObjectiveCRuntimeHook建立。
如果CheckObjectiveCRuntimeHookTemp为false,则跳过面前函数。
对面前函数F的使用者(User)遍历,以笃定是否存在Objective-C方法结构(struct._objc_method)。如果找到,不竭分析其使用者,查找实例方法和类方法列表的全局变量。
如果找到了方法列表全局变量methodListGV和方法结构methodStruct,取得方法选拔器(selector)称呼和类称呼,然后调用HandleObjcRuntimeHook函数惩处Objective-C运行时hook。
临了,函数复返true,暗示Pass顺利完成了对模块的惩处。
要津代码之后再提供要津代码的态状和功能:
此处针对AntiRebindSymbol的达成咱们浅近分析一下,它主如果为了注视动态结合过程中的记号被再行绑定,根绝近似fishhook等框架的诈欺。达成的要津法子如下:
寻找外部结合的函数调用:遍历函数中的系数教唆,寻找调用教唆(CallInst)或动态调用教唆(InvokeInst)。 查抄是否为外部声明:对于每个调用教唆,查抄它是否是对一个外部函数的声明调用。外部函数意味着它在本模块中莫得界说,是在运行时通过动态结合库来潜入的。 创建和开动化全局变量:对于每个这么的外部函数,创建一个新的全局变量。这个变量被开动化为指向该外部函数,且将其结合性建立为独到(PrivateLinkage),使它在模块外部弗概念。 替换原有的函数调用:使用一个新的加载教唆(LoadInst)来加载前边创建的全局变量中的函数地址,然后用BitCastInst来保证类型正确。临了,用这个加载的地址替换原本的函数调用地址。内容是通过在编译时创建一个指向原始函数的新全局变量来使命,由于这个变量是独到的,况且只须在编译时才被创建和开动化,运行时的膺惩者将难以修改这个地址,这么就简略灵验地注视通过修改记号地址来hook函数的膺惩。
3. HandleInlineHookAArch64该函数用于在ARM64(AArch64)体捆绑构上检测和惩处inline hook,咱们分法子进行要津代码段和对应的操作阐明:
1. 取得进口基本块并分割:函数F的进口基本块被存储在变量A中,进口基本块A在第一个不是PHI节点、调试信息或生命周期教唆的教唆处被分割,创建了基本块C。基本块C包含了原始进口基本块中的大部分教唆。
2. 创建相配惩处和检测基本块:基本块B被创建看成hook检测到后将要实施的相配惩处代码块。Detect和Detect2基本块被创建用于存放检测逻辑。
日本人妖 3.修改进口基本块跳转逻辑:进口基本块A的休止教唆(经常是一个跳转教唆)被删除,并用一个跳转到Detect基本块的新分支教唆改姓易代。
4. 构建第一阶段检测逻辑:使用IRBuilder在Detect基本块中构建检测逻辑。查抄函数F的第一个教唆是否包含ARM64上特定的签名值(AARCH64_SIGNATURE_B和AARCH64_SIGNATURE_BRK)。如果检测到这些签名中的任何一个,跳转到相配惩处基本块B。不然,不竭到Detect2进行进一步的检测。
5. 构建第二阶段检测逻辑:在Detect2中,查抄函数F中跟在检测逻辑后的教唆是否包含另一个签名值(AARCH64_SIGNATURE_BR)。如果检测到,跳转到相配惩处基本块B。不然,跳转到原始的进口基本块后半部分C。
6. 相配惩处逻辑:在基本块B中,调用一个相配惩处的函数CreateCallbackAndJumpBack,后续针对该函数进行分析。
4. HandleObjcRuntimeHook该函数用于检测Objective-C方法的达成(Imp)是否被hook篡改。它通过比拟运行时代待的方法达成和面前内容的方法达成来笃定是否存在钩子。
参数阐明:
ObjcMethodImp:指向Objective-C方法达成的函数指针; classname:类名的字符串暗示; selname:选拔器名的字符串暗示; classmethod:一个布尔值,诱骗方法是否是类方法。咱们针对函数实施逻辑进行代码的详备分析:
1. 取得当前函数所在的模块并分割:取得当前函数所在的模块,况且分割进口基本块,创建三个基本块:A,B,C。其中A是运行时钩子检测,B是惩处器,C是原始后续基本块:
2. 使用 IRBuilder 在基本块A和B中构造教唆: 3. 决定Objective-C方法达成是否被hook:取得类对象和选拔器:
凭证是否是类方法取得相应的方法对象:
取得该方法的达成:
比拟取得到的方法达成和原始方法达成是否换取(即检测是否被hook):
4. 凭证比拟成果,决定跳转的场所: 5. 如果检测到hook,则调用回调并跳转回C:此函数领先通过调用Objective-C运行时函式库中的函数来取得运行时的方法达成,况且将其与面前线法达成指针进行比拟。如果不一致,阐明方法达成可能照旧被hook,此时将截止流转变到相配惩处基本块B。在基本块B中,通过调用CreateCallbackAndJumpBack函数,实施磋磨的回调惩处并跳转回平淡实施经由的基本块C。如果达成一致,则径直跳回基本块C不竭实施。
5. CreateCallbackAndJumpBack该函数主邀功能是在特定情况下实施相配惩处或计帐操作,然后确保圭臬简略不竭实施。它凭证面前的环境和树立调用不同的惩处政策,临了,无论给与了哪种惩处政策,截止流齐会跳转回平淡实施旅途的基本块C。给到带磋磨键注视的CreateCallbackAndJumpBack函数:
归来该Pass展现了一种用心想象的安全加固政策,简略以高度选拔性和可树立的款式针对性地为代码提供保护。通过轮廓的架构适配和针对不同膺惩妙技(如hook和绑定膺惩)的挑升看护设施,加固了代码的抗膺惩技巧。此外,接洽了Objective-C运行时环境,简略识别并惩处类和实例方法的挂钩问题。可树立性也极大提高了其适用性,使其简略纯真地合适多种编译场景,况且在提供开阔的安全性赞助的同期,还简略得志不同技俩和斥地者的具体需求。借助最近的相对满足时候,针对Hikari源码分析的系列著述也暂告一段落,如有其他PASS有问题迎接交流。
[培训]《安卓高等研修班(网课)》月薪三万诡计宿舍 自慰,掌抓调试、分析规复ollvm、vmp的方法,定制art捏造机自动化脱壳的方法