📄 mdx86.c
字号:
if ((lpContext->ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS) { } } SETCURKEY(ulOldKey); return TRUE;}BOOL DoThreadSetContext(HANDLE hTh, const CONTEXT *lpContext) { PTHREAD pth; PFXSAVE_AREA FxArea; DWORD i, j, TagWord; ACCESSKEY ulOldKey; if (!(pth = HandleToThread(hTh))) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } if (lpContext->ContextFlags & ~(CONTEXT_FULL|CONTEXT_FLOATING_POINT|CONTEXT_DEBUG_REGISTERS)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } SWITCHKEY(ulOldKey,0xffffffff); if (pth->pThrdDbg && pth->pThrdDbg->psavedctx) { if ((lpContext->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) { pth->pThrdDbg->psavedctx->Ebp = lpContext->Ebp; pth->pThrdDbg->psavedctx->Eip = lpContext->Eip; pth->pThrdDbg->psavedctx->SegCs = lpContext->SegCs; pth->pThrdDbg->psavedctx->EFlags = (pth->pThrdDbg->psavedctx->EFlags & 0xfffff200) | (lpContext->EFlags& 0x00000dff); pth->pThrdDbg->psavedctx->Esp = lpContext->Esp; pth->pThrdDbg->psavedctx->SegSs = lpContext->SegSs; } if ((lpContext->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) { pth->pThrdDbg->psavedctx->Edi = lpContext->Edi; pth->pThrdDbg->psavedctx->Esi = lpContext->Esi; pth->pThrdDbg->psavedctx->Ebx = lpContext->Ebx; pth->pThrdDbg->psavedctx->Edx = lpContext->Edx; pth->pThrdDbg->psavedctx->Ecx = lpContext->Ecx; pth->pThrdDbg->psavedctx->Eax = lpContext->Eax; } if ((lpContext->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) { pth->pThrdDbg->psavedctx->SegGs = lpContext->SegGs; pth->pThrdDbg->psavedctx->SegFs = lpContext->SegFs; pth->pThrdDbg->psavedctx->SegEs = lpContext->SegEs; pth->pThrdDbg->psavedctx->SegDs = lpContext->SegDs; } if ((lpContext->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT) { FPUFlushContext(); pth->pThrdDbg->psavedctx->FloatSave = lpContext->FloatSave; } if ((lpContext->ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS) { } } else { if ((lpContext->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) { pth->ctx.TcxEbp = lpContext->Ebp; pth->ctx.TcxEip = lpContext->Eip; pth->ctx.TcxCs = lpContext->SegCs; pth->ctx.TcxEFlags = (pth->ctx.TcxEFlags & 0xfffff200) | (lpContext->EFlags& 0x00000dff); pth->ctx.TcxEsp = lpContext->Esp; pth->ctx.TcxSs = lpContext->SegSs; } if ((lpContext->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) { pth->ctx.TcxEdi = lpContext->Edi; pth->ctx.TcxEsi = lpContext->Esi; pth->ctx.TcxEbx = lpContext->Ebx; pth->ctx.TcxEdx = lpContext->Edx; pth->ctx.TcxEcx = lpContext->Ecx; pth->ctx.TcxEax = lpContext->Eax; } if ((lpContext->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) { pth->ctx.TcxGs = lpContext->SegGs; pth->ctx.TcxFs = lpContext->SegFs; pth->ctx.TcxEs = lpContext->SegEs; pth->ctx.TcxDs = lpContext->SegDs; } if ((lpContext->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT) { FPUFlushContext(); if (ProcessorFeatures & CPUID_FXSR) { // Convert from fnsave format in CONTEXT to fxsave format in PCR FxArea = (PFXSAVE_AREA) PTH_TO_FLTSAVEAREAPTR(pth); FxArea->ControlWord = (USHORT) lpContext->FloatSave.ControlWord; FxArea->StatusWord = (USHORT) lpContext->FloatSave.StatusWord; FxArea->TagWord = 0; TagWord = lpContext->FloatSave.TagWord; for (i = 0; i < FN_BITS_PER_TAGWORD; i+=2) { if (((TagWord >> i) & FN_TAG_MASK) != FN_TAG_EMPTY) FxArea->TagWord |= (FX_TAG_VALID << (i/2)); } FxArea->ErrorOffset = lpContext->FloatSave.ErrorOffset; FxArea->ErrorSelector = lpContext->FloatSave.ErrorSelector & 0xffff; FxArea->ErrorOpcode = (USHORT) ((lpContext->FloatSave.ErrorSelector >> 16) & 0xFFFF); FxArea->DataOffset = lpContext->FloatSave.DataOffset; FxArea->DataSelector = lpContext->FloatSave.DataSelector; memset(&FxArea->RegisterArea[0], 0, SIZE_OF_FX_REGISTERS); for (i = 0; i < NUMBER_OF_FP_REGISTERS; i++) { for (j = 0; j < BYTES_PER_FP_REGISTER; j++) { FxArea->RegisterArea[i*BYTES_PER_FX_REGISTER+j] = lpContext->FloatSave.RegisterArea[i*BYTES_PER_FP_REGISTER+j]; } } } else { *(PTH_TO_FLTSAVEAREAPTR(pth)) = lpContext->FloatSave; } } if ((lpContext->ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS) { } } SETCURKEY(ulOldKey); return TRUE;}//// ExecuteHandler is the common tail for RtlpExecuteHandlerForException// and RtlpExecuteHandlerForUnwind.//// (edx) = handler (Exception or Unwind) address/////ExceptionRecord equ [ebp+8]///EstablisherFrame equ [ebp+12]///ContextRecord equ [ebp+16]///DispatcherContext equ [ebp+20]///ExceptionRoutine equ [ebp+24]#pragma warning(disable:4035)EXCEPTION_DISPOSITION __declspec(naked) ExecuteHandler(IN PEXCEPTION_RECORD ExceptionRecord,IN PVOID EstablisherFrame,IN OUT PCONTEXT ContextRecord,IN OUT PDISPATCHER_CONTEXT DispatcherContext,IN PEXCEPTION_ROUTINE ExceptionRoutine,IN ULONG ExceptionMode) { __asm { push ebp mov ebp, esp push EstablisherFrame // Save context of exception handler // that we're about to call. push edx // Set Handler address push dword ptr fs:[0] // Set next pointer mov fs:[0], esp // Link us on// Call the specified exception handler. push DispatcherContext push ContextRecord push EstablisherFrame push ExceptionRecord call [ExceptionRoutine] mov esp, fs:[0]// Don't clean stack here, code in front of ret will restore initial state// Disposition is in eax, so all we do is deregister handler and return pop dword ptr fs:[0] mov esp, ebp pop ebp ret }}//++//// EXCEPTION_DISPOSITION// ExceptionHandler (// IN PEXCEPTION_RECORD ExceptionRecord,// IN PVOID EstablisherFrame,// IN OUT PCONTEXT ContextRecord,// IN OUT PVOID DispatcherContext// )//// Routine Description://// This function is called when a nested exception occurs. Its function// is to retrieve the establisher frame pointer and handler address from// its establisher's call frame, store this information in the dispatcher// context record, and return a disposition value of nested exception.//// Arguments://// ExceptionRecord (exp+4) - Supplies a pointer to an exception record.//// EstablisherFrame (esp+8) - Supplies the frame pointer of the establisher// of this exception handler.//// ContextRecord (esp+12) - Supplies a pointer to a context record.//// DispatcherContext (esp+16) - Supplies a pointer to the dispatcher context// record.//// Return Value://// A disposition value ExceptionNestedException is returned if an unwind// is not in progress. Otherwise a value of ExceptionContinueSearch is// returned.////--Naked ExceptionHandler(void) { __asm { mov ecx, dword ptr [esp+4] // (ecx) -> ExceptionRecord test dword ptr [ecx.ExceptionFlags], EXCEPTION_UNWINDING mov eax, ExceptionContinueSearch // Assume unwind jnz eh10 // unwind, go return// Unwind is not in progress - return nested exception disposition. mov ecx,[esp+8] // (ecx) -> EstablisherFrame mov edx,[esp+16] // (edx) -> DispatcherContext mov eax,[ecx+8] // (eax) -> EstablisherFrame for the // handler active when we // nested. mov [edx], eax // Set DispatcherContext field. mov eax, ExceptionNestedExceptioneh10: ret }}//++//// EXCEPTION_DISPOSITION// RtlpExecuteHandlerForException (// IN PEXCEPTION_RECORD ExceptionRecord,// IN PVOID EstablisherFrame,// IN OUT PCONTEXT ContextRecord,// IN OUT PVOID DispatcherContext,// IN PEXCEPTION_ROUTINE ExceptionRoutine,// IN BOOL ExceptionMode// )//// Routine Description://// This function allocates a call frame, stores the handler address and// establisher frame pointer in the frame, establishes an exception// handler, and then calls the specified exception handler as an exception// handler. If a nested exception occurs, then the exception handler of// of this function is called and the handler address and establisher// frame pointer are returned to the exception dispatcher via the dispatcher// context parameter. If control is returned to this routine, then the// frame is deallocated and the disposition status is returned to the// exception dispatcher.//// Arguments://// ExceptionRecord (ebp+8) - Supplies a pointer to an exception record.//// EstablisherFrame (ebp+12) - Supplies the frame pointer of the establisher// of the exception handler that is to be called.//// ContextRecord (ebp+16) - Supplies a pointer to a context record.//// DispatcherContext (ebp+20) - Supplies a pointer to the dispatcher context// record.//// ExceptionRoutine (ebp+24) - supplies a pointer to the exception handler// that is to be called.//// Return Value://// The disposition value returned by the specified exception handler is// returned as the function value.////--EXCEPTION_DISPOSITION __declspec(naked) RtlpExecuteHandlerForException(IN PEXCEPTION_RECORD ExceptionRecord,IN PVOID EstablisherFrame,IN OUT PCONTEXT ContextRecord,IN OUT PDISPATCHER_CONTEXT DispatcherContext,IN PEXCEPTION_ROUTINE ExceptionRoutine,IN ULONG ExceptionMode) { __asm { mov edx,offset ExceptionHandler // Set who to register jmp ExecuteHandler // jump to common code }}//++// EXCEPTION_DISPOSITION// UnwindHandler(// IN PEXCEPTION_RECORD ExceptionRecord,// IN PVOID EstablisherFrame,// IN OUT PCONTEXT ContextRecord,// IN OUT PVOID DispatcherContext)//// Routine Description:// This function is called when a collided unwind occurs. Its function// is to retrieve the establisher frame pointer and handler address from// its establisher's call frame, store this information in the dispatcher// context record, and return a disposition value of nested unwind.//// Arguments:// ExceptionRecord (esp+4) - Supplies a pointer to an exception record.//// EstablisherFrame (esp+8) - Supplies the frame pointer of the establisher// of this exception handler.//// ContextRecord (esp+12) - Supplies a pointer to a context record.//// DispatcherContext (esp+16) - Supplies a pointer to the dispatcher context// record.//// Return Value:// A disposition value ExceptionCollidedUnwind is returned if an unwind is// in progress. Otherwise a value of ExceptionContinueSearch is returned.//--Naked UnwindHandler(void) { __asm { mov ecx,dword ptr [esp+4] // (ecx) -> ExceptionRecord test dword ptr [ecx.ExceptionFlags], EXCEPTION_UNWINDING mov eax,ExceptionContinueSearch // Assume NOT unwind jz uh10 // not unwind, go return// Unwind is in progress - return collided unwind disposition. mov ecx,[esp+8] // (ecx) -> EstablisherFrame mov edx,[esp+16] // (edx) -> DispatcherContext mov eax,[ecx+8] // (eax) -> EstablisherFrame for the // handler active when we // nested. mov [edx],eax // Set DispatcherContext field. mov eax,ExceptionCollidedUnwinduh10: ret }}//++//// EXCEPTION_DISPOSITION// RtlpExecuteHandlerForUnwind (// IN PEXCEPTION_RECORD ExceptionRecord,// IN PVOID EstablisherFrame,// IN OUT PCONTEXT ContextRecord,// IN OUT PVOID DispatcherContext,// IN PEXCEPTION_ROUTINE ExceptionRoutine// IN BOOL ExceptionMode// )//// Routine Description://// This function allocates a call frame, stores the handler address and// establisher frame pointer in the frame, establishes an exception// handler, and then calls the specified exception handler as an unwind// handler. If a collided unwind occurs, then the exception handler of// of this function is called and the handler address and establisher// frame pointer are returned to the unwind dispatcher via the dispatcher// context parameter. If control is returned to this routine, then the// frame is deallocated and the disposition status is returned to the// unwind dispatcher.//// Arguments://// ExceptionRecord (ebp+8) - Supplies a pointer to an exception record.//// EstablisherFrame (ebp+12) - Supplies the frame pointer of the establisher// of the exception handler that is to be called.//// ContextRecord (ebp+16) - Supplies a pointer to a context record.//// DispatcherContext (ebp+20) - Supplies a pointer to the dispatcher context// record.//// ExceptionRoutine (ebp+24) - supplies a pointer to the exception handler// that is to be called.//// Return Value://// The disposition value returned by the specified exception handler is// returned as the function value.////--EXCEPTION_DISPOSITION __declspec(naked) RtlpExecuteHandlerForUnwind(IN PEXCEPTION_RECORD ExceptionRecord,IN PVOID EstablisherFrame,IN OUT PCONTEXT ContextRecord,IN OUT PDISPATCHER_CONTEXT DispatcherContext,IN PEXCEPTION_ROUTINE ExceptionRoutine,IN ULONG ExceptionMode) { __asm { mov edx,offset UnwindHandler jmp ExecuteHandler // jump to common code }}#pragma warning(default:4035)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -