Iphone hack handbook 学习

今天学习了iphone hack handbook 的How Code Signing Enforcement Works这一章。感觉还是比较难得。但是难也要学习,那我就干脆尽量翻译下吧。

当可执行代码被装载的时候,内核会检查她是否包含代码签名标志。这个标志是 LC_CODE_SIGNATURE。内核代码会寻找并解析她,再XNU的bsd/kern/mach_loader.c中,我们会找到相关的功能函数parse_machfile函数。

parse_machfile(
       struct vnode       *vp,     
       vm_map_t           map,
       thread_t           thread,
       struct mach_header *header,
       off_t             file_offset,
       off_t             macho_size,
       int                depth,
       int64_t            aslr_offset,
       load_result_t      *result
)
{
...
       case LC_CODE_SIGNATURE:
       /* CODE SIGNING */
...
       ret = load_code_signature(
              (struct linkedit_data_command *) lcp,
              vp,
              file_offset,
              macho_size,
              header->cputype,
             (depth == 1) ? result : NULL);

而真正意义上的标识加载是由名为load_code_signature完成的。

static load_return_t
load_code_signature(
       struct linkedit_data_command *lcp,
       struct vnode                 *vp,
       off_t                        macho_offset,
       off_t                        macho_size,
       cpu_type_t                   cputype,
       load_result_t                *result)
{
...
       kr = ubc_cs_blob_allocate(&addr, &blob_size);
...
       ubc_cs_blob_add(vp,
                       cputype,
                       macho_offset,
                       addr,
                       lcp->datasize))
...

 

而ubc_cs_blob_add函数会检查这个标志是否是可以接受的。

int
ubc_cs_blob_add(
       struct vnode *vp,
       cpu_type_t   cputype,
       off_t        base_offset,
       vm_address_t addr,
       vm_size_t    size)
{
...
       /*
        * Let policy module check whether the blob's signature
        * is accepted.
        */
#if CONFIG_MACF
       error = mac_vnode_check_signature(vp, blob->csb_sha1,
                                        (void*)addr, size);  
       if (error)
              goto out;
#endif

最终,AMFI通过hooking函数vnode_check_signature来完成真正意义上的代码签名检查。

(这里略去amfi_vnode_check_signature的代码,有兴趣的读者可以在IOS Hackers Handbook中的图4.6中看到)

图4.6的代码会调用check_against_static_trust_cache,check_against_dynamic_trust_cache来检查(trust cache?函数的参数为char *hash),并且如果他不能认定它是可信的,那么他会调用一个用户空间的守护进程来决定是否他被正确的签名。图4.7展示了静态的(trust cache)。

(原文:The static trust cache is actually contained right in the kernel. You can see it in IDA Pro. (See Figure 4.8.))

这里不是很理解。不过根据图中的说明,我们可以肯定他说的trust cache应该就是上图中的参数hash。

对于动态trust(hash?)的检查也是相似的,除了这些数据不在是静态的而是动态加载的。对于那些不包含再两者中的情况,AMFI会通过使用Mach RPC询问用户空间的守护进程amfid,如果代码签名是验证过的,amfid会通过Mach RPC访问两个子程序。一个叫做verify_code_directory存在于vnode_check_signature中。这个函数调用MISValidateSignature(存在于libmis.dylib中)。MISValidateSignature又调用SecMSVerify(在Security Framework中)已完成真正的验证。

posted @ 2012-12-27 23:25  I_O_S  阅读(560)  评论(0编辑  收藏  举报