Горячая исправление функции - PullRequest
4 голосов
/ 11 ноября 2011

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

Ниже приведены функции, с которыми у меня возникают проблемы.

vm_t* VM_Create( const char *module, intptr_t (*systemCalls)(intptr_t *), vmInterpret_t interpret )
{
    MessageBox(NULL, L"Oh snap! We hooked VM_Create!", L"Success!", MB_OK);
    return NULL;
}

void Hook_VM_Create(void)
{

    DWORD dwBackup;
    VirtualProtect((void*)0x00477C3E, 7, PAGE_EXECUTE_READWRITE, &dwBackup);

    //Patch the original VM_Create to jump to our detoured one.
    BYTE *jmp = (BYTE*)malloc(5);
    uint32_t offset = 0x00477C3E - (uint32_t)&VM_Create; //find the offset of the original function from our own
    memset((void*)jmp, 0xE9, 1);
    memcpy((void*)(jmp+1), &offset, sizeof(offset));
    memcpy((void*)0x00477C3E, jmp, 5);

    free(jmp);
}

У меня есть функция VM_Create, котораяЯ хочу, чтобы меня вызывали вместо оригинальной функции.Я еще не написал батут, поэтому он падает (как и ожидалось).Однако окно сообщения не всплывает, что я отклонил оригинальную виртуальную машину к своей собственной.Я полагаю, что так я перезаписываю оригинальные инструкции.

1 Ответ

4 голосов
/ 11 ноября 2011

Я вижу несколько проблем.

Я предполагаю, что 0x00477C3E - это адрес исходной функции VM_Create.Вы действительно не должны жестко кодировать это.Вместо этого используйте &VM_Create.Конечно, это будет означать, что вам нужно использовать другое имя для функции замены.

Смещение рассчитывается неправильно.Вы ошиблись знаком.Более того, смещение применяется к указателю инструкции в конце инструкции, а не в начале.Поэтому вам нужно сдвинуть его на 5 (размер инструкции).Смещение также должно быть целым числом со знаком.

В идеале, если принять во внимание мою первую точку, код будет выглядеть следующим образом:

int32_t offset = (int32_t)&New_VM_Create - ((int32_t)&VM_Create+5);

Спасибо Гансу Пассанту за исправление моей собственной глупостиПодпишите ошибку в исходной версии!

Если вы работаете на 64-битной машине, вам нужно выполнить арифметику в 64-битном формате и, как только вы вычислили смещение, обрезать его до 32-битного смещения.

Еще один нюанс заключается в том, что после написания новой инструкции JMP необходимо сбросить память только для чтения и вызвать FlushInstructionCache.

...