Skip to content

Instantly share code, notes, and snippets.

@zxmarcos
Created December 6, 2019 19:04
Show Gist options
  • Save zxmarcos/1632f66541cb38b80db587a38497f11a to your computer and use it in GitHub Desktop.
Save zxmarcos/1632f66541cb38b80db587a38497f11a to your computer and use it in GitHub Desktop.
#include <thread>
#include <windows.h>
#include <cstdio>
using namespace std;
extern "C" void interrupt_trampoline();
extern "C" void throw_cancel() { throw std::exception(); }
__asm__("_interrupt_trampoline: call _throw_cancel; ret \n");
void interrupt_thread(std::thread &t) {
auto pthread = t.native_handle();
HANDLE handle = pthread_gethandle(pthread);
int res = SuspendThread(handle);
if (res == -1) {
printf("Falha ao suspender thread %x", HRESULT_FROM_WIN32(GetLastError()));
} else {
CONTEXT ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.ContextFlags = CONTEXT_CONTROL;
res = GetThreadContext(handle, &ctx);
if (res != -1) {
DWORD *stack = (DWORD *) ctx.Esp;
--stack;
*stack = ctx.Eip;
printf("EIP %x\n", ctx.Eip);
ctx.Eip = (DWORD) &interrupt_trampoline;
ctx.Esp = (DWORD) stack;
res = SetThreadContext(handle, &ctx);
if (res != -1) {
ResumeThread(handle);
}
}
}
}
struct foo {
int *buffer;
foo(int n) {
buffer = new int[n];
}
~foo() {
printf("~foo");
delete[] buffer;
}
};
int main(int argc, char *argv[])
{
auto thread = std::thread([]() {
try {
foo a(100);
for (;;) {}
} catch (...) {
printf("Catch!");
}
});
interrupt_thread(thread);
thread.join();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment