⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mdx86.c

📁 See Hanoi.cpp for the implementation of this cla
💻 C
📖 第 1 页 / 共 3 页
字号:
		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 + -