Last active
November 13, 2018 10:52
-
-
Save kekyo/cc9bace942b8c2aa2484431e047d267d to your computer and use it in GitHub Desktop.
How to unwind the signal handler using the longjmp on Windows environment.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <signal.h> | |
#include <setjmp.h> | |
jmp_buf jb; | |
// Run in windows, this handler called from SEH filter context from "_seh_filter_exe()". | |
// The SEH __try - __except() block contains at "__scrt_common_main_seh()," | |
// the callgraph is: | |
// __scrt_common_main_seh() --> __try --> main() --> [SEGV] --> __except() --> _seh_filter_exe() --> handler() | |
// But the "__except(...)" expression has correct only EBP register except ESP register (!!) | |
// Therefore the "_seh_filter_exe()" called before NO any unroll stacks, | |
// the "handler()" function at deeper stack than "main()," | |
// We can use the longjmp() and unwinding without any stack corruption. | |
// (CAUTION: These descriptions doesn't contain breaking context for async race calls.) | |
// Just before called main (__scrt_common_main_seh() __try block) | |
// EAX = 0012A57C EBX = 006EE000 ECX = 005E0000 EDX = 0012A57C ESI = 0012132A EDI = 0012132A | |
// EIP = 00121D72 ESP = 005DFE38 EBP = 005DFE8C EFL = 00000246 | |
// Just enter __except() expression code | |
// EAX = 00000000 EBX = 00000000 ECX = 00121DC3 EDX = 00000000 ESI = 00000000 EDI = 00000000 | |
// EIP = 00121DC3 ESP = 005DF708 EBP = 005DFE8C EFL = 00000246 (ESP deeper but EBP adjusted at __try block) | |
void handler(int sig) { | |
longjmp(jb, 1); | |
} | |
int main() | |
{ | |
signal(SIGSEGV, handler); | |
// This variable will corrupt if the handler() calls after stack unrolls by SEH __except() handling. | |
volatile int v = 123; | |
if (setjmp(jb) == 0) | |
{ | |
char*p = nullptr; | |
char a = *p; | |
} | |
printf("%d\n", v); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment