📄 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, ExceptionNestedException
eh10: 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,ExceptionCollidedUnwind
uh10: 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 + -