Skip to content

Instantly share code, notes, and snippets.

@AXDOOMER
Last active January 22, 2024 22:30
Show Gist options
  • Save AXDOOMER/99c95ef032b8883f970e8c6d31d4d638 to your computer and use it in GitHub Desktop.
Save AXDOOMER/99c95ef032b8883f970e8c6d31d4d638 to your computer and use it in GitHub Desktop.
Handling interrupts with signals on Linux
#include <stdio.h>
#include <stdlib.h> // exit
#include <string.h> // memset
#include <unistd.h> // sleep
#include <signal.h>
// Enum for when the program is 32 bits
// Source: https://sites.uclouvain.be/SystInfo/usr/include/sys/ucontext.h.html
enum
{
REG_GS = 0,
REG_FS,
REG_ES,
REG_DS,
REG_EDI,
REG_ESI,
REG_EBP,
REG_ESP,
REG_EBX,
REG_EDX,
REG_ECX,
REG_EAX,
REG_TRAPNO,
REG_ERR,
REG_EIP,
REG_CS,
REG_EFL,
REG_UESP,
REG_SS
};
/*
// Enum for when the program is 64 bits
// Source: https://code.woboq.org/userspace/glibc/sysdeps/unix/sysv/linux/x86/sys/ucontext.h.html
enum
{
REG_R8 = 0,
REG_R9,
REG_R10,
REG_R11,
REG_R12,
REG_R13,
REG_R14,
REG_R15,
REG_RDI,
REG_RSI,
REG_RBP,
REG_RBX,
REG_RDX,
REG_RAX,
REG_RCX,
REG_RSP,
REG_RIP,
REG_EFL,
REG_CSGSFS, // Actually short cs, gs, fs, __pad0.
REG_ERR,
REG_TRAPNO,
REG_OLDMASK,
REG_CR2
};*/
int count = 0;
void dumpbytes(unsigned char *data, int count)
{
int i;
printf("\n");
for (i = 0; i < count; i++)
{
if (i % 16 == 0)
{
printf("\n");
}
printf("%02X ", data[i]);
}
printf("\n\n");
}
// http://courses.cms.caltech.edu/cs124/lectures-wi2016/CS124Lec15.pdf
void singal_handler(int sig, siginfo_t *sinfo, void *ctxt)
{
count++;
ucontext_t *context = (ucontext_t *)ctxt;
// https://github.molgen.mpg.de/git-mirror/glibc/blob/master/sysdeps/unix/sysv/linux/x86/sys/ucontext.h#L152
printf("EAX: %X\n", context->uc_mcontext.gregs[REG_EAX]);
printf("EBX: %X\n", context->uc_mcontext.gregs[REG_EBX]);
printf("ECX: %X\n", context->uc_mcontext.gregs[REG_ECX]);
printf("EDX: %X\n", context->uc_mcontext.gregs[REG_EDX]);
printf("ESI: %X\n", context->uc_mcontext.gregs[REG_ESI]);
printf("EDI: %X\n", context->uc_mcontext.gregs[REG_EDI]);
printf("EBP: %X\n", context->uc_mcontext.gregs[REG_EBP]);
printf("ESP: %X\n", context->uc_mcontext.gregs[REG_ESP]);
// address of instruction that triggered the signal
printf("EIP: %X\n", context->uc_mcontext.gregs[REG_EIP]);
sleep(1);
printf("±±±±±±±±±±±±±±±±±±±±±±±±±±±±\n");
if (count >= 3) {
// Dump a few bytes
dumpbytes(context->uc_mcontext.gregs[REG_EIP], 32);
// Skip over the 2 bytes that caused the interrupt
context->uc_mcontext.gregs[REG_EIP] += 2;
}
}
int main()
{
struct sigaction act;
memset(&act, 0, sizeof(struct sigaction));
sigemptyset(&act.sa_mask);
act.sa_sigaction = singal_handler;
act.sa_flags = SA_SIGINFO;
if (sigaction(SIGSEGV, &act, NULL) < 0)
{
printf("sigaction() error! couldn't set handler.");
exit(1);
}
printf("hello world\n");
// interrupt, causes a segmentation fault
asm(".byte 0xCD");
asm(".byte 0xFF");
printf("skipped the bytes\n");
sleep(1);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment