📄 except.c
字号:
/*
This is a C++ run-time library for Windows kernel-mode drivers.
Copyright (C) 2004 Bo Brant閚.
*/
/*
The following is a modified subset of wine/dlls/msvcrt/cppexcept.c
and wine/dlls/msvcrt/cppexcept.h from version wine20040505.
*/
/*
* msvcrt C++ exception handling
*
* Copyright 2002 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <ntddk.h>
#include "cxx.h"
void __cdecl _global_unwind2(void * pRegistFrame);
typedef void (__cdecl *_se_translator_function)(unsigned int, struct _EXCEPTION_POINTERS*);
_se_translator_function _se_translator;
_se_translator_function __cdecl _set_se_translator(_se_translator_function _new_se_translator)
{
_se_translator_function _prev_se_translator = _se_translator;
_se_translator = _new_se_translator;
return _prev_se_translator;
}
/* * The exception frame, used for registering exception handlers * Win32 cares only about this, but compilers generally emit * larger exception frames for their own use. */struct __EXCEPTION_FRAME;typedef EXCEPTION_DISPOSITION (__stdcall *PEXCEPTION_HANDLER)(PEXCEPTION_RECORD,struct __EXCEPTION_FRAME*, PCONTEXT,struct __EXCEPTION_FRAME **);typedef struct __EXCEPTION_FRAME{ struct __EXCEPTION_FRAME *Prev; PEXCEPTION_HANDLER Handler;} EXCEPTION_FRAME, *PEXCEPTION_FRAME;/* * From OS/2 2.0 exception handling * Win32 seems to use the same flags as ExceptionFlags in an EXCEPTION_RECORD */#define EH_NONCONTINUABLE 0x01#define EH_UNWINDING 0x02#define EH_EXIT_UNWIND 0x04#define EH_STACK_INVALID 0x08#define EH_NESTED_CALL 0x10
typedef void (*vtable_ptr)();
/* the object the typeid operator returns a reference to */typedef struct _type_info{ vtable_ptr *vtable; /* pointer to the objects vtable */ void *data; /* unused in drivers, dynamically allocated undecorated type name in Win32 */ char name[1]; /* decorated (raw) type name */} type_info;/* the extended exception frame used by C++ */typedef struct _cxx_exception_frame{ EXCEPTION_FRAME frame; /* the standard exception frame */ int trylevel; /* current trylevel */ ULONG ebp; /* saved ebp */} cxx_exception_frame;/* info about a single catch {} block */typedef struct _catchblock_info{ unsigned int flags; /* flags (see TYPE_FLAG_* flags below) */ type_info *type_info; /* C++ type caught by this block */ int offset; /* stack offset to copy exception object to */ void (*handler)(); /* catch block handler code */} catchblock_info;#define TYPE_FLAG_CONST 1#define TYPE_FLAG_VOLATILE 2#define TYPE_FLAG_REFERENCE 8/* info about a single try {} block */typedef struct _tryblock_info{ int start_level; /* start trylevel of that block */ int end_level; /* end trylevel of that block */ int catch_level; /* initial trylevel of the catch block */ int catchblock_count; /* count of catch blocks in array */ catchblock_info *catchblock; /* array of catch blocks */} tryblock_info;/* info about the unwind handler for a given trylevel */typedef struct _unwind_info{ int prev; /* prev trylevel unwind handler, to run after this one */ void (*handler)(); /* unwind handler */} unwind_info;/* descriptor of all try blocks of a given function */typedef struct _cxx_function_descr{ unsigned int magic; /* must be CXX_FRAME_MAGIC */ int unwind_count; /* number of unwind handlers */ unwind_info *unwind_table; /* array of unwind handlers */ unsigned int tryblock_count; /* number of try blocks */ tryblock_info *tryblock; /* array of try blocks */ unsigned int unknown[3];} cxx_function_descr;
typedef void (*cxx_copy_ctor)(void);
/* complete information about a C++ type */typedef struct _cxx_type_info{ unsigned int flags; /* flags (see CLASS_* flags below) */ type_info *type_info; /* C++ type info */ int this_offset; /* offset of base class this pointer from start of object */ int vbase_descr; /* offset of virtual base class descriptor */ int vbase_offset; /* offset of this pointer offset in virtual base class descriptor */ size_t size; /* object size */
cxx_copy_ctor copy_constructor; /* copy constructor */} cxx_type_info;#define CLASS_IS_SIMPLE_TYPE 1#define CLASS_HAS_VIRTUAL_BASE_CLASS 4/* table of C++ types that apply for a given object */typedef struct _cxx_type_info_table{ unsigned int count; /* number of types */ const cxx_type_info *cxx_type_info[1]; /* array of types */} cxx_type_info_table;
/* type information for an exception object */typedef struct _cxx_exception_type{ unsigned int flags; /* TYPE_FLAG_* flags */ void (*destructor)(); /* exception object destructor */ void* custom_handler; /* custom handler for this exception */ const cxx_type_info_table *type_info_table; /* list of types for this exception object */} cxx_exception_type;/* installs a new exception handler */#define cxx_push_handler(handler) __asm { \
__asm push offset handler \
__asm mov eax, dword ptr fs:[0] \
__asm push eax \
__asm mov dword ptr fs:[0], esp \
}
/* restores the previous exception handler */
#define cxx_pop_handler() __asm { \
__asm mov eax, dword ptr [esp] \
__asm mov dword ptr fs:[0], eax \
__asm add esp, 8 \
}
/* called when an unrecoverable error has been detected */void terminate(){
DbgPrint("terminate was called\n");
KeBugCheck(STATUS_DRIVER_INTERNAL_ERROR);
}
/* exception handler for unexpected exceptions thrown while handling an exception */static EXCEPTION_DISPOSITION __stdcall unexpected_handler(PEXCEPTION_RECORD rec, PEXCEPTION_FRAME frame,
PCONTEXT context, void *dispatch)
{
DbgPrint("unexpected exception\n");
KeBugCheck(STATUS_DRIVER_INTERNAL_ERROR);
return ExceptionContinueSearch;
}
/* frame pointer register 'ebp' modified by inline assembly code */
#pragma warning(disable:4731)
/* call a function with a given ebp */static void *cxx_call_handler(void *func, void *func_ebp){ void *result; __asm
{
mov eax, func
push ebp
mov ebp, func_ebp
call eax
pop ebp
mov result, eax
}
return result;
}#pragma warning(default:4731)/* call a copy constructor */static void cxx_call_copy_constructor(void *func, void *object, void *src_object, int has_vbase){ __asm
{
mov ecx, object
cmp has_vbase, 0
je no_vbase push 1
no_vbase:
push src_object
call func
}
}/* call the destructor of an object */static void cxx_call_destructor(void *func, void *object){ __asm
{
mov ecx, object
call func
}
}/* compute the this pointer for a base class of a given type */static void *get_this_pointer(const cxx_type_info *type, void *object){ void *this_ptr; int *offset_ptr; if (!type || !object) return NULL; this_ptr = (char *)object + type->this_offset; if (type->vbase_descr >= 0) { /* move this ptr to vbase descriptor */ this_ptr = (char *)this_ptr + type->vbase_descr; /* and fetch additional offset from vbase descriptor */ offset_ptr = (int *)(*(char **)this_ptr + type->vbase_offset); this_ptr = (char *)this_ptr + *offset_ptr; } return this_ptr;}/* check if the exception type is caught by a given catch block, and return the type that matched */static const cxx_type_info *find_caught_type(cxx_exception_type *exception_type, catchblock_info *catchblock){ unsigned int i; if (!catchblock->type_info) { return exception_type->type_info_table->cxx_type_info[0]; /* catch(...) matches any type */ } for (i = 0; i < exception_type->type_info_table->count; i++) { const cxx_type_info *type = exception_type->type_info_table->cxx_type_info[i]; if (catchblock->type_info != type->type_info) { if (strcmp(catchblock->type_info->name, type->type_info->name)) continue; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -