运行时的iOS Patch程序指令

C0d*_*ker 21 c assembly jailbreak ios cydia-substrate

如何在应用程序运行时修改应用程序中的各个汇编指令?

我有一个Mobile Substrate调整,我正在为现有的应用程序编写.在tweak的构造函数(MSInitialize)中,我需要能够在应用程序的代码中重写单个指令.我的意思是,我希望修改应用程序的地址空间中的多个位置,但在每个实例中,只需要修改一条指令.我已经为应用程序禁用了ASLR,并且知道要修补的指令的确切内存地址,并且我有新指令的十六进制字节(作为char [],但这是不重要的,并且必要时可以更改).我只需要弄清楚如何进行更改.

我知道iOS使用数据执行保护(DEP)来指定可执行内存页面也不可写,反之亦然,但我知道可以在越狱设备上绕过它.我也知道iDevices使用的ARM处理器有一个指令缓存,需要更新以反映更改.但是,我甚至不知道从哪里开始这样做.

所以,为了回答肯定会被问到的问题,我没有尝试过任何事情.这不是因为我很懒; 相反,这是因为我完全不知道如何实现这一目标.任何帮助都将非常感激.

编辑:

如果它有帮助,我的最终目标是在移动基板调整中使用它来挂钩App Store应用程序.以前,为了修改这个应用程序,必须先破解它来解密应用程序,以便修补二进制文件.我想做到这一点,所以人们不必破解应用程序,因为这可能导致盗版,我强烈反对.我不能正常使用Mobile Substrate,因为所有的工作都是用C++完成的,而不是Objective-C,并且应用程序被剥离,没有任何符号可供使用MSHookFunction.

C0d*_*ker 6

完全忘记了我问的这个问题,所以我将展示我现在得出的结论。评论应说明其工作方式和原因。

#include <stdio.h>
#include <stdbool.h>
#include <mach/mach.h>
#include <libkern/OSCacheControl.h>

#define kerncall(x) ({ \
    kern_return_t _kr = (x); \
    if(_kr != KERN_SUCCESS) \
        fprintf(stderr, "%s failed with error code: 0x%x\n", #x, _kr); \
    _kr; \
})


bool patch32(void* dst, uint32_t data) {
    mach_port_t task;
    vm_region_basic_info_data_t info;
    mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT;
    vm_region_flavor_t flavor = VM_REGION_BASIC_INFO;

    vm_address_t region = (vm_address_t)dst;
    vm_size_t region_size = 0;

    /* Get region boundaries */
    if(kerncall(vm_region(mach_task_self(), &region, &region_size, flavor, (vm_region_info_t)&info, (mach_msg_type_number_t*)&info_count, (mach_port_t*)&task))) return false;
    /* Change memory protections to rw- */
    if(kerncall(vm_protect(mach_task_self(), region, region_size, false, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY))) return false;

    /* Actually perform the write */
    *(uint32_t*)dst = data;

    /* Flush CPU data cache to save write to RAM */
    sys_dcache_flush(dst, sizeof(data));
    /* Invalidate instruction cache to make the CPU read patched instructions from RAM */
    sys_icache_invalidate(dst, sizeof(data));

    /* Change memory protections back to r-x */
    kerncall(vm_protect(mach_task_self(), region, region_size, false, VM_PROT_EXECUTE | VM_PROT_READ));
    return true;
}
Run Code Online (Sandbox Code Playgroud)