Filthy newline drama?
[craw.git] / craw / exception_handler.cpp
blob84edc880f8c4e5879104ae4c1d2bf12fdd525d18
1 #include <iostream>
2 #include <windows.h>
3 #include <boost/thread/mutex.hpp>
4 #include <ail/string.hpp>
5 #include <ail/types.hpp>
6 #include "exception_handler.hpp"
7 #include "utility.hpp"
8 #include "patch.hpp"
9 #include "interceptor.hpp"
10 #include "arguments.hpp"
11 #include "debug_registers.hpp"
13 typedef std::map<DWORD, debug_register_vector> thread_id_map_type;
15 namespace
17 thread_id_map_type thread_id_map;
18 boost::mutex thread_id_map_mutex;
21 void add_debug_register_manipulation_entry(DWORD thread_id, debug_register_vector const & data)
23 boost::mutex::scoped_lock lock(thread_id_map_mutex);
24 thread_id_map[thread_id] = data;
27 bool process_breakpoint(CONTEXT & thread_context)
29 boost::mutex::scoped_lock lock(thread_id_map_mutex);
30 DWORD thread_id = GetCurrentThreadId();
31 thread_id_map_type::iterator iterator = thread_id_map.find(thread_id);
32 if(iterator == thread_id_map.end())
33 return false;
35 debug_register_vector & data = iterator->second;
37 thread_context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
38 set_debug_registers(thread_context, data);
40 thread_context.Eip++;
42 return true;
45 void set_own_context(debug_register_vector const & data)
47 add_debug_register_manipulation_entry(GetCurrentThreadId(), data);
48 //write_line("set_own_context: " + ail::hex_string_32(reinterpret_cast<unsigned>(&set_own_context)));
49 __asm
51 int 3
55 LONG WINAPI vectored_exception_handler(PEXCEPTION_POINTERS ExceptionInfo)
57 //nasty
58 DWORD const DBG_PRINTEXCEPTION_C = 0x40010006;
60 EXCEPTION_RECORD & exception_record = *(ExceptionInfo->ExceptionRecord);
61 CONTEXT & thread_context = *(ExceptionInfo->ContextRecord);
63 //write_line("Exception type " + ail::hex_string_32(exception_record.ExceptionCode) + " at " + ail::hex_string_32(thread_context.Eip) + " in thread " + ail::hex_string_32(GetCurrentThreadId()));
65 switch(exception_record.ExceptionCode)
67 case EXCEPTION_BREAKPOINT:
68 if(process_breakpoint(thread_context))
69 return EXCEPTION_CONTINUE_EXECUTION;
70 break;
72 case EXCEPTION_SINGLE_STEP:
73 perform_debug_register_check(thread_context);
74 return EXCEPTION_CONTINUE_EXECUTION;
76 case DBG_PRINTEXCEPTION_C:
77 if(verbose)
78 write_line("Debug message");
79 break;
82 return EXCEPTION_CONTINUE_SEARCH;
85 bool install_exception_handler()
87 if(!AddVectoredExceptionHandler(0, &vectored_exception_handler))
89 error("Failed to add vectored exception handler: " + ail::hex_string_32(GetLastError()));
90 return false;
92 return true;