#やりたいこと
64bitゲームのアセンブリの特定の命令をjmp 空いてるメモリ領域
に変更し、ジャンプ先で自分のアセンブリを実行してから元の位置に戻るというのをC++でやりたいです。
Cheat EngineのCode injectionの模倣のようなことです
例えば
armasm
1 sub [rbx+54],edi 2 mov rcx,rsi
をjmp アドレス
に変更し、その先で
armasm
1 mov edi, (int)0 2 sub [rbx+54],edi 3 mov rcx,rsi 4 jmp 元居たアドレス
のようにしてアセンブリを挟みたいんです!
#分かっていること
メモリにアセンブリを書き込むのはmemcpy
関数を使うことでできるみたいですね
cpp
1BYTE* dest = アドレス 2memset(dest, (BYTE*)"\x50\x8D\x4C\x24", 4)
こんな感じです。(書いてませんが、VirtualProtect関数で書き込み権限を得る必要はあります。)
#僕が参考にした動画
この動画を見たんですが、これはx86アーキテクチャを対象としたもので、x64だとそもそもインラインアセンブリが使えない上に特定のレジスタも使えないので、肝心の部分があまり参考になりませんでした。
ただ、一体どの部分で空いているメモリ領域のアドレスを探しているのかも僕にはわからないので、わかる方いたらそれだけでも教えていただけませんか?
以下の部分です
cpp
1bool mem::HookCode(void* toHook, void* ourFunct, int len) { 2 if (len < 5) { //Hook元が5以下なら(jmp に5バイト必要なので) 3 return false; 4 } 5 DWORD oldprotect; 6 VirtualProtect(toHook, len, PAGE_EXECUTE_READWRITE, &oldprotect); 7 memset(toHook, 0x90, len); 8 DWORD relativeAddress = ((DWORD)ourFunct - (DWORD)toHook) - 5; 9 10 *(BYTE*)toHook = 0xE9; //E9はjmpを表すバイト 11 *(DWORD*)((DWORD)toHook + 1) = relativeAddress; //+1をすることでE9を上書きしない(?) 12 13 DWORD temp; 14 VirtualProtect(toHook, len, oldprotect, &temp); 15 return true; 16}