2016-11-26 3 views
0

Я пытаюсь написать прыжок в память, и я не могу найти нигде, что может объяснить мне, как это работает.Write jump to memory

typedef UINT(WINAPI* tResetWriteWatch)(LPVOID lpBaseAddress, SIZE_T dwRegionSize); 

UINT WINAPI ResetWriteWatchHook(LPVOID lpBaseAddress, SIZE_T dwRegionSize){ 
    printf("Function called\n"); 
    return 0; 
} 

void main(){ 
    DWORD64 hookAddr = (DWORD64)&ResetWriteWatch; 
    WriteJump(hookAddr, ResetWriteWatchHook/*Let's say it's 0x7FE12345678*/);//Writes E9 XX XX XX XX to memory 
} 

Моя главная проблема в том, что я не понимаю: как преобразовать ассемблерный JMP 0x7FE12345678 к E9 XX XX XX XX, так что я могу написать это в hookAddr.

Процесс - 64 бит.

+0

Что вы пытаетесь сделать здесь, что нельзя сделать с помощью обычного C++? Связано ли это с углом Detours? – tadman

+0

Я не уверен, что это можно сделать с помощью обычного C++, но я не знаю много функций api windows, поэтому это лучший способ сделать это. (ResetWriteWatch находится в файле kernel32.dll) – ioospa

ответ

0

Я бы предложил использовать ассемблер для генерации правильных байтов. Просто создайте следующий файл и запустить его с помощью NASM:

BITS 64 
JUMP 0x7fe1234 

Результат:

2f e9 fe 12 00 07 (в связи с порядком байтов LE). Это относительный прыжок, поэтому его будет сложно сгенерировать из кода высокого уровня. Вместо этого вы можете использовать опкод EA, который выполняет абсолютный скачок. Затем вы можете просто использовать абсолютный адрес местоположения, в которое хотите перейти.

+0

Я знаю, что xx являются заполнителями, я помещаю их туда, пытаясь сказать, что я не знаю, каковы правильные байты, которые идут туда. Как вы получаете часть «07 FE 12 34»? – ioospa

+0

Это адрес, на который вы прыгали; это то, где нужно выполнить выполнение программы. –

+0

Я отредактирую его за секунду. Реальные адреса более 4 байтов – ioospa

1

Вот как это делается на 32-битной программе (не уверен, насколько отличается на 64 бит), но это должно дать вам представление о том, куда идти. Это относится к окнам из-за VirtualProtect, но вы можете использовать mprotect, если вы на Linux.

#include <stdio.h> 
#include <windows.h> 

void foo() { 
    printf("Foo!"); 
} 

void my_foo() { 
    printf("My foo!"); 
} 

int setJMP(void *from, void *to) { 
    DWORD protection; 
    if (!VirtualProtect(from, 5, PAGE_EXECUTE_READWRITE, &protection)) { // We must be able to write to it (don't necessarily need execute and read) 
     return 0; 
    } 

    *(char *)from = 0xE9; // jmp opcode 
    *(int *)(from + 1) = (int)(to - from - 5); // relative addr 

    return VirtualProtect(from, 5, protection, &protection); // Restore original protection 
} 

int main() { 
    setJMP(foo, my_foo); 
    foo(); // outputs "My foo!" 

    return 0; 
}