2016-11-26 6 views
0

私はメモリへのジャンプを書こうとしています。どのように動作するのか説明できる場所を見つけることができません。メモリへのジャンプの書き出し

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 
} 

私の主な問題は、私は理解していないということです:どのように私は私がhookAddrでそれを書くことができE9 XX XX XX XXにASM JMP 0x7FE12345678を変換します。

プロセスは64ビットです。

+0

従来のC++ではできないことをここでは何をしようとしていますか?これはデトウアーズの角度に関連していますか? – tadman

+0

私はそれが従来のC++を使って行うことができるかどうかはわかりませんが、私はWindowsのAPI関数の多くを知らないので、これを実行する最善の方法と思われました。 (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のためにWindowsに特有ですが、Linuxの場合はmprotectを使用できます。

#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; 
} 
関連する問題