Skip to content

Instantly share code, notes, and snippets.

@coolxv
Last active November 13, 2023 03:23
Show Gist options
  • Save coolxv/22e92aa307cd9346fb6172385fb23fa8 to your computer and use it in GitHub Desktop.
Save coolxv/22e92aa307cd9346fb6172385fb23fa8 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <signal.h>
#include <execinfo.h>
#include<iostream>
using namespace std;
unsigned char old;
unsigned char *inst;
void *addr;
void *addr_stub;
// RIP距离stack的当前位置正好192字节,详情参见rt_sigframe结构
#define PC_OFFSET 192
void breakpoint(char *inst)
{
/*
Opcode Instruction Op/En 64-Bit Mode Compat/Leg Mode Description
--------- ------------- ------- ------------- ----------------- ----------------------------------------------------------------------
CC INT3 ZO Valid Valid Generate breakpoint trap.
CD _ib_ INT _imm8_ I Valid Valid Generate software interrupt with vector specified by immediate byte.
CE INTO ZO Invalid Valid Generate overflow trap if overflow flag is 1.
F1 INT1 ZO Valid Valid Generate debug trap.
Instruction Operand Encoding ¶
------- ----------- ----------- ----------- -----------
Op/En Operand 1 Operand 2 Operand 3 Operand 4
ZO NA NA NA NA
I imm8 NA NA NA
------- ----------- ----------- ----------- -----------
*/
old = *inst;
//*inst = 0xce; //int0
*inst = 0xcc; //int3
}
void recover(char *inst)
{
*inst = old;
}
void trap(int unused)
{
// 恢复断点需要两步:
// 1. 恢复单字节为保存的指令。
// 2. PC寄存器回退一个字节。
unsigned long *p;
// 恢复断点需要两步:
// 1. 恢复单字节为保存的指令。
// 2. PC寄存器回退一个字节。
p = (unsigned long*)((unsigned char *)&p + PC_OFFSET); //PC_OFFSET 如何确定?? rt_sigframe?? Signal Frame??
printf("current RIP: :%lx n", *p);
recover((char*)addr);
*p = *p - 1;
//size = backtrace (array, 10);
cout<<"I am signal:"<< endl;
}
int foo(int a)
{
cout<<"I am foo"<<endl;
return 0;
}
int foo_stub(int a)
{
cout<<"I am foo_stub"<<endl;
return 0;
}
int main(int argc, char **argv)
{
addr = (void*)&foo;
addr_stub = (void*)&foo_stub;
unsigned char *page;
page = (unsigned char *)((unsigned long)addr & ~(4096 - 1));
if(0 == mprotect((void *)page, 4096, PROT_WRITE|PROT_READ|PROT_EXEC))
{
breakpoint((char*)addr);
signal(SIGTRAP, trap);
//signal(SIGILL, trap);
foo(1);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment