iOS Mach-O - Сделать сегмент __TEXT временно доступным для записи - PullRequest
1 голос
/ 03 июня 2019

Я очень старался, чтобы наконец-то это заработало, но оно все еще не работает.Я пытаюсь изменить некоторые переменные в разделе __TEXT, который по умолчанию доступен только для чтения, как, например, изменение cryptid (и других вещей)

Это работало некоторое время назад на 32-битных устройствах.Но почему-то всегда происходит сбой после использования 64-битных команд.

В настоящее время происходит сбой, если я нажимаю следующие строки: tseg->maxprot = tseg->initprot = VM_PROT_READ | VM_PROT_EXECUTE или crypt->cryptid = 1.

    struct mach_header_64* mach = (struct mach_header_64*) _dyld_get_image_header(0);

    uint64_t header_size = 0;

    struct encryption_info_command_64 *crypt;
    struct segment_command_64 *tseg;
    struct dylib_command *protector_cmd;


    // clean up some commands
    void *curloc = (void *)mach + sizeof(struct mach_header);
    for (int i=0;i<mach->ncmds;i++) {
        struct load_command *lcmd = curloc;
        if (lcmd->cmd == LC_ENCRYPTION_INFO_64) {
            // save crypt cmd
            crypt = curloc;
        } else if (lcmd->cmd == LC_SEGMENT_64) {
            struct segment_command_64 *seg = curloc;
            if (seg->fileoff == 0 && seg->filesize != 0) {
                header_size = seg->vmsize;
                tseg = curloc;
            }
        }
        if(i == mach->ncmds-1){
            protector_cmd = curloc;
        }
        curloc += lcmd->cmdsize;
    }
    kern_return_t err;

    // make __TEXT temporarily writable
    err = vm_protect(mach_task_self(), (vm_address_t)mach, (vm_size_t)header_size, false, VM_PROT_ALL);
    if (err != KERN_SUCCESS) exit(1);

    // modify the load commands
    // change protection of __TEXT segment
    tseg->maxprot = tseg->initprot = VM_PROT_READ | VM_PROT_EXECUTE;

    // change cryptid
    crypt->cryptid = 1;

1 Ответ

3 голосов
/ 03 июня 2019

Нет смысла менять команду загрузки.Команды загрузки уже были обработаны, когда программа была загружена (что должно быть до того, как ваш код сможет работать).Они больше не влияют на защиту страниц.

Вы, вероятно, уже знаете о функции vm_protect().Так почему же вы не используете это, чтобы сделать текстовый сегмент доступным для записи, а не пытаетесь сделать команды загрузки доступными для записи?

И, безусловно, проще использовать getsegmentdata() для определения местоположения сегмента в памяти, чем смотреть наКоманды загрузки (к которым вам нужно добавить слайд).

Помимо этого, я был бы удивлен, если бы iOS позволила вам это сделать.Существует общий запрет на изменяемый код во время выполнения (с очень узкими исключениями).

...