我的蹦床不会弹跳(绕道,C++,海湾合作委员会)
My trampoline won't bounce (detouring, C++, GCC)
感觉就像我在滥用Stackoverflow的所有问题,但它毕竟是一个问答论坛:)无论如何,我已经使用弯路一段时间了,但我还没有实现我自己的一个(我之前使用过包装器(。因为我想完全控制我的代码(谁不想?我决定自己实现一个功能齐全的绕行器,这样我就可以理解代码的每个字节。
代码(下面(尽可能简单,但问题并非如此。我已经成功地实现了绕道(即钩到我自己的功能(,但我无法实现蹦床。
每当我调用蹦床时,根据我使用的偏移量,我都会得到"分段错误"或"非法指令"。不过,这两种情况的结局都是一样的;"核心倾销"。我认为这是因为我混淆了"相对地址"(注意:我对 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 testingn");
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
编译
不分青红皂白地将 Test(( 的前 5 个字节复制到你的蹦床上,然后跳转到 Test(( 的第 6 个指令字节,因为你不知道前 5 个字节是否包含整数个 x86 可变长度指令。 为此,您必须至少对 Test(( 函数进行最少量的自动反汇编,以便找到比函数开头多 5 个或更多字节的指令边界,然后将适当数量的字节复制到您的蹦床上,然后附加您的跳跃(不会在您的蹦床内固定偏移(。 请注意,在典型的RISC处理器(如PPC(上,您不会遇到此问题,因为所有指令的宽度都相同。
- 海湾合作委员会 ARM 性能下降
- 海湾合作委员会手册中提到的"C++ ABI Specification"是什么?
- 比较 -INT_MIN (海湾合作委员会)
- 使用海湾合作委员会进行消毒,导致意外提前退出
- 为什么海湾合作委员会在实施is_nothrow_constructible时需要static_cast?
- 海湾合作委员会中 -faligned-new 的值
- 如何在进程之间共享大量数据而不重复?(国际刑罚委员会)
- 我们可以直接致电海湾合作委员会的simd_fast_mersenne_twister_engine(sfmt19937_64)吗?
- 如何(以及谁可以)实现C++委员会定义的标准库功能
- 海湾合作委员会在升压源中的警告
- 海湾合作委员会制作的不可拆卸的符号
- "this" Lambda 捕获的是不正确的。海湾合作委员会编译器错误?
- 为什么不能在 Visual C++ 中动态分配堆栈内存?但海湾合作委员会可以做到
- 海湾合作委员会非法指导
- 海湾合作委员会"__builtin_popcount"如何运作?
- 为什么海湾合作委员会抱怨"declaration of 'foo' shadows a previous call [-Werror=shadow]"
- CodeBlocks成功地编译了,但海湾合作委员会失败了,为什么
- 海湾合作委员会和Clang在lambda的constexpr-ness上存在分歧?
- 海湾合作委员会中的通用 lambda
- 写信给工会,与海湾合作委员会