我的蹦床不会反弹(绕行,C ++,GCC)(My trampoline won't boun

2019-09-17 00:47发布

这感觉就像我跟我所有的问题虐待#1,但它是一个Q&所有:)无论如何,我一直在使用的弯路,现在经过一段时间的论坛,但我还没有实现我自己的一个(我用的包装纸更早)。 因为我想有过我的代码完全控制(谁不?)我已经决定实施对我自己的一个功能齐全的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;
}

在感兴趣的情况下,这是一个正常运行期间的输出(与上面的确切的代码):

  这是测试  这是**  非法指令(核心转储) 
并且这是结果如果我使用+/-的sizeof(jmpOp)在第66行:

This is testing
This is ******
Segmentation fault (core dumped)

注:我运行Ubuntu 32位,并编译g++ global.cpp main.cpp -o main -Iinclude

Answer 1:

你不会是能够将前5个字节测试()的照搬到你的蹦床,然后跳转到测试()的第六指令字节,因为你不知道,如果前5个字节包括整数的86可变长度指令。 要做到这一点,你将不得不做,以便找到一个指令边界这5首或更多个字节过去的函数开始至少测试()功能的自动拆卸的最小量,然后复制适当的数位元组到您的蹦床,然后追加你的跳跃(该不会是在一个固定的蹦床中的偏移量)。 请注意,在一个典型的RISC处理器(如PPC),你不会有这个问题,因为所有的指令都是相同的宽度。



文章来源: My trampoline won't bounce (detouring, C++, GCC)