Подтвердить что ты не робот

Инструкция программы патча iOS во время выполнения

Как можно изменить индивидуальные инструкции по сборке в приложении во время его запуска?

У меня есть настройка Mobile Substrate, которую я пишу для существующего приложения. В конструкторе tweak (MSInitialize) мне нужно переписать отдельные инструкции в коде приложения. Я имею в виду, что в адресном пространстве приложения может быть несколько мест, которые я хочу изменить, но в каждом случае необходимо изменить только одну команду. Я уже отключил ASLR для приложения и знаю точный адрес памяти инструкции для исправления, и у меня есть шестнадцатеричные байты (как char [], но это не имеет значения и может быть изменено в случае необходимости) нового инструкция. Мне просто нужно выяснить, как выполнить изменения.

Я знаю, что iOS использует Data Execution Prevention (DEP), чтобы указать, что страницы исполняемой памяти не могут быть записаны и наоборот, но я знаю, что это возможно обойти это на взломанном устройстве. Я также знаю, что процессор ARM, используемый iDevices, имеет кеш команд, который необходимо обновить, чтобы отразить изменение. Однако я даже не знаю, с чего начать это делать.

Итак, чтобы ответить на вопрос, который в противном случае был бы задан, я ничего не пробовал. Это не потому, что я ленив; Скорее, это потому, что я совершенно не понимаю, как это можно сделать. Любая помощь вообще была бы оценена.

Изменить:

Если это вообще помогает, моя конечная цель - использовать это в настройке Mobile Substrate, которая перехватывает приложение App Store. Раньше, чтобы модифицировать это приложение, нужно было сначала взломать его, чтобы расшифровать приложение, чтобы двоичный файл мог быть исправлен. Я хочу сделать так, чтобы людям не пришлось взломать приложение, поскольку это может привести к пиратству, против которого я категорически против. Я не могу использовать Mobile Substrate обычно, потому что вся работа выполняется на С++, а не Objective-C, и приложение удаляется, не оставляя никаких символов для использования MSHookFunction on.

4b9b3361

Ответ 1

Полностью забыл, что задал этот вопрос, поэтому покажу, с чем я закончил. Комментарии должны объяснить, как и почему это работает.

#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;
}

Ответ 2

vm_protect to w ^ x, предполагая, что вы джейлбрейк с приличным джейлбрейком (например, если mobilesubstrate работает)

Ответ 3

Запись в память команд из регистров процессора, как говорят другие выше, немного сложна. Особенно с iPhone, поскольку Apple пытается сохранить детали процессора в секрете.

Разрешения на доступ к памяти - первая проблема. Исполняемая память обычно не доступна для записи. Однако, если это будет преодолено, то есть немного танца, чтобы пройти, чтобы получить данные из регистров процессора и в конвейер команд. В общем, есть инструкции синхронизации, которые вынуждают определенный порядок доступа к памяти до и после них и команды кэша, которые заставляют грязные записи записывать данные в память и вымывают чистые и, возможно, устаревшие данные чтения. Оба они сильно зависят от детальной реализации процессора.

Рука В Интернете есть приятные руководства, которые подробно объясняют их для конкретных процессоров. Однако, говорят ли процессоры внутри iPhone о том, что говорят публичные ручные руководства, я понятия не имею.

Здесь место для начала понимания модели синхронизации памяти руки для одного процессора: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0092b/ch04s03s04.html и далее идет о том, как очистить кеш команд путем записи в регистр управления. Конечно, можно написать самомодифицирующийся код для процессоров Arm, потому что где-то в этом руководстве я нашел выражение, в котором говорилось, что это иногда неизбежно, и его необходимо поддерживать.

(Я не утверждаю, что это ответ, но он не вписывается в комментарий.)