【发布时间】:2012-01-02 17:33:41
【问题描述】:
我查看了与此相关的各种主题,但找不到我遇到的这个具体问题。
我看过的东西: Injecting code into executable at runtime C SIGSEGV Handler & Mprotect Can I write-protect every page in the address space of a Linux process? How to write a signal handler to catch SIGSEGV?
当需要在处理程序中将保护设置为 PROT_READ 或 PROT_WRITE 时,我能够优雅地处理 SIGSEGV。但是,当我尝试使用 mmap 注入指令,然后使用 mprotect 将其设置为仅 PROT_READ,然后通过内联汇编执行指令时,它会按预期导致 SIGSEGV,但处理程序无法获取导致信号,所以我无法将它保护到 PROT_READ | PROT_EXEC。
例子:
void sigHandler(int signum, siginfo_t *info, void *ptr) {
printf("Received signal number: %d\n", signum);
printf("Signal originates from process %lu\n",
(unsigned long)info->si_pid);
printf("SIGSEGV caused by this address: ? %p\n", info->si_addr);
char * alignedbaseAddr = (((unsigned int)(info->si_addr)) >> 12) * getPageSize();
printf("Aligning to %p\n", alignedbaseAddr);
//flip this page to be r+x
mprotect(alignedbaseAddr, getPageSize(), PROT_READ | PROT_EXEC);
}
void setupSignalHandler() {
action.sa_sigaction = sigHandler;
action.sa_flags = SA_SIGINFO;
sigemptyset(&action.sa_mask);
sigaction(SIGSEGV, &action, NULL);
}
int main(int argc, char *argv[]) {
char * baseAddr = (char*)mmap(NULL, getDiskSize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if(baseAddr == MAP_FAILED) {
perror("Unable to mmap.");
}
printf("Process address space is %d\n", getDiskSize());
//no-op filler
for(int i = 0; i < (getDiskSize()) - 1; i++) {
baseAddr[i] = 0x90;
}
//ret instruction
baseAddr[i] = 0xc3;
if( mprotect(baseAddr, getDiskSize(), PROT_READ) == -1) {
perror("mprotect");
exit(1);
}
printf("Protecting addresses: %p to %p for READ_ONLY\n", baseAddr, baseAddr + getDiskSize() - 1);
setupSignalHandler();
__asm__
(
"call %%eax;"
: "=a" (output)
: "a" (baseAddr)
);
printf("Will this ever print?");
//close fd, and unmap memory
cleanUp();
return EXIT_SUCCESS;
}
这是结果输出:
接收信号数:11
信号来自进程 0
此地址引起的 SIGSEGV: ? (无)
//上面的输出重复循环,因为它无法“重新保护”那个页面。
架构: x86 32 位 操作系统: Ubuntu 11.04 - Linux 版本 2.6.38-12-generic (buildd@vernadsky) (gcc 版本 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4))
有什么想法吗?上述逻辑适用于简单地读取和写入内存。有没有 与内联汇编相比,在运行时执行指令的更好方法?
提前致谢!
【问题讨论】:
-
请缩进您的代码以使其更具可读性!
-
对不起。预览有点欺骗性。现在已经更正了。
标签: loader mmap virtual-memory segmentation-fault mprotect