今天学习了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中)已完成真正的验证。