首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Linux编写跳转以使用mprotect保护内存

Linux编写跳转以使用mprotect保护内存
EN

Stack Overflow用户
提问于 2017-02-10 09:44:20
回答 2查看 757关注 0票数 0

am使用插入值为5字节的跳转的基本x86方法将钩子写入函数。我的代码有点生疏,但我认为我有逻辑。当我对LD_PRELOAD env运行时,会得到一个分段错误。我基本上是用一个替换函数,钩子函数,蹦床功能来修改和返回原来的地址。下面是代码链接。

foo.h

代码语言:javascript
复制
#ifndef foo_h__
#define foo_h__

extern void foo(const char*);

#endif  // foo_h_

foo.c

代码语言:javascript
复制
#include <stdio.h>


void foo(const char*str)
{
    puts(str);
}

main.c

代码语言:javascript
复制
#include <stdio.h>
#include "foo.h"

int main(void)
{const char*str="I am a shared lib!\n";
        int count=1;
    puts("This is a shared library test...");
    while(count!=200){
        printf("%d time!\n",count);    
    foo(str);
    count++;
}
    return 0;
}

hook.c

代码语言:javascript
复制
# include <stdio.h>
# include <unistd.h>
# define __USE_GNU
# include <dlfcn.h>
# include <stdint.h>
# include <sys/mman.h>

const char*str = "Hooked! ma fucker!\n";
struct hookdata
{
    int64_t*origFunc;
    int64_t*newFunc;
    const char*s;
    void (*foo_trampoline)(const char*str);
}*hkd;

void fooHooked(const char*str)
{
    puts(str);
    hkd->foo_trampoline(hkd->s);

}

void hook(void)
{
//Get pointers to the original and new functions and calculate the jump offset
    hkd->origFunc = dlsym(RTLD_NOW, "foo");
    hkd->newFunc = (int64_t*) &fooHooked;
    int64_t offset = hkd->newFunc - (hkd->origFunc + 5);
//Make the memory containing the original funcion writable
//Code from http://stackoverflow.com/questions/20381812/mprotect-always-returns-invalid-arguments
    size_t pageSize = sysconf(_SC_PAGESIZE);
    uintptr_t start = (uintptr_t) hkd->origFunc;
    uintptr_t end = start + 1;
    uintptr_t pageStart = start & -pageSize;
    mprotect((void *) pageStart, end - pageStart,
            PROT_READ | PROT_WRITE | PROT_EXEC);
//Insert the jump instruction at the beginning of the original function
    int32_t instruction = 0xe9 | offset << 8;
    *hkd->origFunc = instruction;
}
void foo(const char*str)
{
    if (*hkd->origFunc == 0xe9)
    {
        printf("hook detected!");
    }
    else
        hook();
}
EN

回答 2

Stack Overflow用户

发布于 2017-02-10 10:04:26

页面访问标志PROT_READ | PROT_WRITE | PROT_EXEC的组合违反了W^X保护,因此这可能是当前的第一个问题。在第一步中,首先设置PROT_READ | PROT_WRITE以替换函数前导,然后将其还原为PROT_READ | PROT_EXEC,这很可能解决了这个问题。

票数 1
EN

Stack Overflow用户

发布于 2017-02-10 10:22:04

如果以4字节类型存储5字节指令,则需要如下所示:

代码语言:javascript
复制
unsigned char instr[5];
instr[0] = 0xe9;
*(int32_t*)(&instr[1]) = offset;
memcpy(hkd->origFunc, instr, 5);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42156145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档