First, let me say that I am doing here that most people have no legal basis for EVERYONE. 99.99 ...% of all segfaults should lead to a certain end and fun to process them in any, but the simplest situations, will lead to really bad behavior and a damaged stack. If you came here to solve segfault, go to the following link: https://www.securecoding.cert.org/confluence/display/seccode/SIG35-C.+Do+not+return+from+a+computational+exception + signal + handler
However, I am working on the implementation of an environment from an external standard, which has defined the behavior for returning from the signal processor of the computational logic as a missing command. I understand that this is bad, but I do not control it; I cannot just mislead the definition, as for an embedded system with other program elements already written that depend on a certain behavior (they are often security critical and should be able to gracefully exit even when they do ridiculous or terrible things in I don’t have a source further, so I can’t just fix segfault and any existing bad segfault / crash behavior is really desirable, because I imitate the behavior of an existing system).
While the system itself should run on PowerPC with a fixed instruction length, our development takes place in a parallel x86 / x64 environment where instructions do not have a fixed length. I know that the following code works, albeit badly for x86:
#define _GNU_SOURCE #include <signal.h> #include <stdio.h> #include <ucontext.h> #include <sys/mman.h> #define CRASHME *((int*)NULL) = 0 //for x86 #ifdef REG_EIP #define INCREMENT(x) (x)->uc_mcontext.gregs[REG_EIP]++ //for x64 #elif defined REG_RIP #define INCREMENT(x) (x)->uc_mcontext.gregs[REG_RIP]++ //for PPC arch #elif defined PT_NIP #define INCREMENT(x) (x)->uc_mcontext.uc_regs->gregs[PT_NIP]+=4 #endif static void handler(int sig, siginfo_t *si, void *vcontext) { ucontext_t *context = (ucontext_t *)vcontext; INCREMENT(context); } void crashme_function(void) { printf("entered new context, segfaulting!\n"); CRASHME; printf("SEGFAULT handled!\n"); } int main (int argc, char* args) { struct sigaction sa; printf("Printing a thing\n"); sa.sa_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); sa.sa_sigaction = handler; sigaction(SIGSEGV, &sa, NULL); printf("Entering new context...\n"); crashme_function(); printf("context exited successfully\n"); return(0); }
The result of executing this code will advance the instruction pointer to 1 in an Intel-based architecture running the Linux 3.11.X kernel, and it will eventually go beyond the instruction. I know that this probably will not work in all instructions. In fact, when executed in my test environment, the handler is entered 6 times (for 6 bytes of instruction), and then execution continues after CRASHME.
It seems that the trivial task is simply to direct the given pointer to the next command, given the existing instruction; the processor does this every cycle. Other settings say: “Look at the instruction table and create your own” or “execute the disassembler”. They are neither necessary nor necessary for the task, since both of them were already made by others and placed (almost?) Exclusively in places of the Internet, where my working computer cannot go, and to which I do not believe, to send my home PC. But where can I find such tables or libraries to perform only the calculation of commands, and without looking at the site on which I already know, I can’t access?