私はすべての質問で Stackoverflow を悪用しているように感じますが、結局のところ Q&A フォーラムです :) とにかく、私はしばらく回り道を使用してきましたが、まだ独自のものを実装していません (ラッパーを使用しました)。ついさっき)。私は自分のコードを完全に制御したいので (そうでない人はいないでしょうか?)、完全に機能する detour'er を自分で実装することにしました。これにより、コードのすべてのバイトを理解できるようになります。
コード (以下) は可能な限り単純ですが、問題はそうではありません。迂回路 (つまり、自分の関数へのフック) を正常に実装しましたが、トランポリンを実装できませんでした。
トランポリンを呼び出すたびに、使用するオフセットに応じて、「セグメンテーション違反」または「不正な命令」のいずれかが表示されます。ただし、どちらの場合も同じように終了します。「コアダンプ」。「相対アドレス」を混同したためだと思います(注:私はLinuxにかなり慣れていないため、GDBを習得するにはほど遠いです)。
sizeof(jmpOp)
コードでコメントされているように、 (66 行目) に応じて、不正な命令またはセグメンテーション違反が発生します。当たり前のことでしたらすみません、夜更かししてしまいました...
// Header files
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include "global.h" // Contains typedefines for byte, ulong, ushort etc...
#include <cstring>
bool ProtectMemory(void * addr, int flags)
{
// Constant holding the page size value
const size_t pageSize = sysconf(_SC_PAGE_SIZE);
// Calculate relative page offset
size_t temp = (size_t) addr;
temp -= temp % pageSize;
// Update address
addr = (void*) temp;
// Update memory area protection
return !mprotect(addr, pageSize, flags);
}
const byte jmpOp[] = { 0xE9, 0x00, 0x00, 0x00, 0x00 };
int Test(void)
{
printf("This is testing\n");
return 5;
}
int MyTest(void)
{
printf("This is ******\n");
return 9;
}
typedef int (*TestType)(void);
int main(int argc, char * argv[])
{
// Fetch addresses
byte * test = (byte*) &Test;
byte * myTest = (byte*) &MyTest;
// Call original
Test();
// Update memory access for 'test' function
ProtectMemory((void*) test, PROT_EXEC | PROT_WRITE | PROT_READ);
// Allocate memory for the trampoline
byte * trampoline = new byte[sizeof(jmpOp) * 2];
// Do copy operations
memcpy(trampoline, test, sizeof(jmpOp));
memcpy(test, jmpOp, sizeof(jmpOp));
// Setup trampoline
trampoline += sizeof(jmpOp);
*trampoline = 0xE9;
// I think this address is incorrect, how should I calculate it? With the current
// status (commented 'sizeof(jmpOp)') the compiler complains about "Illegal Instruction".
// If I uncomment it, and use either + or -, a segmentation fault will occur...
*(uint*)(trampoline + 1) = ((uint) test - (uint) trampoline)/* + sizeof(jmpOp)*/;
trampoline -= sizeof(jmpOp);
// Make the trampoline executable (and read/write)
ProtectMemory((void*) trampoline, PROT_EXEC | PROT_WRITE | PROT_READ);
// Setup detour
*(uint*)(test + 1) = ((uint) myTest - (uint) test) - sizeof(jmpOp);
// Call 'detoured' func
Test();
// Call trampoline (crashes)
((TestType) trampoline)();
return 0;
}
参考までに、これは通常の実行中の出力です (上記の正確なコードを使用)。
これはテスト中です これは**です 不正な命令 (コアダンプ)これは、66 行目で +/- sizeof(jmpOp) を使用した場合の結果です。
これはテスト中です これは ****** セグメンテーション違反 (コアダンプ)
注:Ubuntu 32ビットを実行しており、コンパイルしますg++ global.cpp main.cpp -o main -Iinclude