iOS安全—阻止tweak注入hook api【转】

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS安全—阻止tweak注入hook api【转】相关的知识,希望对你有一定的参考价值。

参考技术A 在网上看到一种方法可以通过在Other Linker Flags中添加:

的方法来阻止dylib注入。

便动手试了一下,编写一个测试Demo不添加任何linker flags,然后使用 theos 对其进行hook。

启动后使用image list –o –f 来查看加载的动态库:
[145] 0x0025f000 /Library/MobileSubstrate/MobileSubstrate.dylib(0x000000000025f000)
[152] 0x003c0000 /Library/MobileSubstrate/DynamicLibraries/TestLog.dylib(0x00000000003c0000)
发现我们用来hook编写的dylib已经被加载,自然能看到hook成功的log。
2015-11-10 15:21:50.824 myTest[21906:273137] viewDidLoad — 你已经被我Hook了。。。。。。

然后使用linker flags:

重新编译生成。

运行后在所有加载的动态库中已找不到hook的dylib,hook失败了,说明这是有效的。

再来看看生成的macho文件多了一个__RESTRICT/__restrict section。

在这里找到了答案: http://www.opensource.apple.com/source/dyld/dyld-210.2.3/src/dyld.cpp

也就是说下面三种情况,可以让环境变量:DYLD_INSERT_LIBRARIES被无视
1.Set restricted status by entitlements
This option is only available to applications on OS X with special entitlements.

2.setuid and setgid
Any application that makes these two calls are going to be marked as restricted by the linker as a security measure.

3.Restricted Segment of Header
The final way to mark a binary as restricted is by telling the linker to add new section to the binary header that is named “__RESTRICT” and has a section named “__restrict” when you compile it.

所以编译生成的含有__RESTRICT/__restrict section的app会忽略DYLD_INSERT_LIBRARIES。

当然解决办法也是有的,把section的名字修改一下即可。
用010 editor打开可执行文件,找到section的名字:

又可以成功注入了!

参考链接:
http://bbs.iosre.com/t/tweak-app-app-tweak/438
http://www.opensource.apple.com/source/dyld/dyld-210.2.3/src/dyld.cpp
http://www.samdmarshall.com/blog/blocking_code_injection_on_ios_and_os_x.html

转自 iOS安全—阻止tweak注入hook api

关于注入linker flags之后通常会出现看不到Hierachy的现象。所以本尊一般会把其放在Release位置。

IAT Hook

  • IAT Hook 工作原理

    IAT Hook是通过修改IAT中保存的API地址来钩取某个API函数。

     

    在进程中调用某个API函数,是在目标进程中的导入表中查找函数地址来进行调用,不同于GetProcAddress函数。此函数是在模块的导出表中进行查找函数地址的。

     

    所以我们可以注入动态库到目标进程,来实现对目标API的钩取。关于动态库的注入可以参考其他博文。

  • 代码实现
      1 // include
      2 #include "stdio.h"
      3 #include "wchar.h"
      4 #include "windows.h"
      5 
      6 
      7 // typedef
      8 typedef BOOL (WINAPI *PFSETWINDOWTEXTW)(HWND hWnd, LPWSTR lpString);
      9 
     10 
     11 
     12 FARPROC OldFunction = NULL;
     13 
     14 
     15 // 修改后再显示
     16 BOOL WINAPI MySetWindowTextW(HWND hWnd, LPWSTR lpString)
     17 {
     18     wchar_t* pNum = L"康老捞伙荤坷腊磨迫备"; 
     19     wchar_t temp[2] = {0,};
     20     int i = 0, nLen = 0, nIndex = 0;
     21 
     22     nLen = wcslen(lpString);
     23     for(i = 0; i < nLen; i++)
     24     {
     25         
     26         if( L0 <= lpString[i] && lpString[i] <= L9 )
     27         {
     28             temp[0] = lpString[i];
     29             nIndex = _wtoi(temp);
     30             lpString[i] = pNum[nIndex];
     31         }
     32     }
     33 
     34    
     35     return ((PFSETWINDOWTEXTW)OldFunction)(hWnd, lpString);
     36 }
     37 
     38 
     39 // hook_iat
     40 //   泅犁 橇肺技胶狼 IAT 甫 八祸秦辑
     41 //   pfnOrg 蔼阑 pfnNew 蔼栏肺 函版矫糯
     42 BOOL HOOKIAT(LPCSTR szDllName, PROC OldFunction, PROC NewFunction)
     43 {
     44     HMODULE ModuleHandle;
     45     LPCSTR szLibName;
     46     PIMAGE_IMPORT_DESCRIPTOR pImportDesc; 
     47     PIMAGE_THUNK_DATA pThunk;
     48     DWORD dwOldProtect, dwRVA;
     49     PBYTE AddressOfImage;
     50 
     51     // DOSHeader
     52     ModuleHandle = GetModuleHandle(NULL);
     53     AddressOfImage = (PBYTE)ModuleHandle;
     54 
     55     // AddressOfImage = VA to PE signature (IMAGE_NT_HEADERS)
     56     AddressOfImage += *((DWORD*)&AddressOfImage[0x3C]);
     57 
     58     // dwRVA = RVA to IMAGE_IMPORT_DESCRIPTOR Table
     59     dwRVA = *((DWORD*)&AddressOfImage[0x80]);
     60 
     61     // pImportDesc = VA to IMAGE_IMPORT_DESCRIPTOR Table
     62     pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)ModuleHandle +dwRVA);
     63 
     64     for( ; pImportDesc->Name; pImportDesc++ )
     65     {
     66         // szLibName = VA to IMAGE_IMPORT_DESCRIPTOR.Name
     67         szLibName = (LPCSTR)((DWORD)ModuleHandle + pImportDesc->Name);
     68         if( !_stricmp(szLibName, szDllName) )
     69         {
     70             // pThunk = IMAGE_IMPORT_DESCRIPTOR.FirstThunk
     71             //        = VA to IAT(Import Address Table)
     72             pThunk = (PIMAGE_THUNK_DATA)((DWORD)ModuleHandle +
     73                                          pImportDesc->FirstThunk);
     74 
     75             // pThunk->u1.Function API函数的虚拟地址
     76             for( ; pThunk->u1.Function; pThunk++ )
     77             {
     78                 if( pThunk->u1.Function == (DWORD)OldFunction)
     79                 {
     80                     // 修改内存页为可读可写可执行
     81                     VirtualProtect((LPVOID)&pThunk->u1.Function, 
     82                                    4, 
     83                                    PAGE_EXECUTE_READWRITE, 
     84                                    &dwOldProtect);
     85 
     86                     // 修改函数地址
     87                     pThunk->u1.Function = (DWORD)NewFunction;
     88                 
     89                     VirtualProtect((LPVOID)&pThunk->u1.Function, 
     90                                    4, 
     91                                    dwOldProtect, 
     92                                    &dwOldProtect);                        
     93 
     94                     return TRUE;
     95                 }
     96             }
     97         }
     98     }
     99 
    100     return FALSE;
    101 }
    102 
    103 
    104 
    105 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    106 {
    107     switch( fdwReason )
    108     {
    109         case DLL_PROCESS_ATTACH : 
    110           
    111                OldFunction = GetProcAddress(GetModuleHandle(L"user32.dll"), 
    112                                         "SetWindowTextW");
    113 
    114             //HOOK
    115             HOOKIAT("user32.dll", OldFunction, (PROC)MySetWindowTextW);
    116             break;
    117 
    118         case DLL_PROCESS_DETACH :
    119             //UNHOOK
    120             HOOKIAT("user32.dll", (PROC)MySetWindowTextW, OldFunction);
    121             break;
    122     }
    123 
    124     return TRUE;
    125 }

    参考《逆向工程核心原理》

 

以上是关于iOS安全—阻止tweak注入hook api【转】的主要内容,如果未能解决你的问题,请参考以下文章

IOS逆向学习-Tweak

android inline hook

进程动态拦截注入API HOOK

iOS:在非越狱手机上进行Hook注入

转学习使用 Node.js 中 async-hooks 模块

IAT Hook