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

📄 mdx86.c

📁 See Hanoi.cpp for the implementation of this cla
💻 C
📖 第 1 页 / 共 3 页
字号:
            	pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1);
    			goto continueExecution;
    		}
*/   		
	   		break;

    	case 0:		// Divide by zero
    		er.ExceptionInformation[0] = 0;
    		er.ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO;
    		break;

    	case 6:	// Reserved instruction
    		er.ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
    		break;

		case 16: {
			if (pexi->error & 0x01)
				er.ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
			else if (pexi->error & 0x4)
				er.ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
			else if (pexi->error & 0x8)
				er.ExceptionCode = STATUS_FLOAT_OVERFLOW;
			else if (pexi->error & 0x10)
				er.ExceptionCode = STATUS_FLOAT_UNDERFLOW;
			else if (pexi->error & 0x20)
				er.ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
			else
				er.ExceptionCode = STATUS_FLOAT_DENORMAL_OPERAND;
			break;
		}
    	case 0xFF:  // Stack overflow
    	    er.ExceptionCode = STATUS_STACK_OVERFLOW;
    		er.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
    	    break;
    	    
    	}
    }
	if (id != 1 && id != 3) {
	    NKDbgPrintfW(L"Exception %03x Thread=%8.8lx Proc=%8.8lx '%s'\r\n",
    			id, pth, hCurProc, 
    			pCurProc->lpszProcName ? pCurProc->lpszProcName : L"");
	    NKDbgPrintfW(L"AKY=%8.8lx PC=%8.8lx ESP=%8.8lx EA=%8.8lx\r\n",
    			pCurThread->aky, pctx->Eip, pctx->Esp, info);
	    if (UTlsPtr()[TLSSLOT_KERNEL] & TLSKERN_NOFAULT) {
	        NKDbgPrintfW(L"TLSKERN_NOFAULT set... bypassing kernel debugger.\r\n");
	    }
    }
    // Invoke the kernel debugger to attempt to debug the exception before
    // letting the program resolve the condition via SEH.
	pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1);
	if (!UserDbgTrap(&er,pctx,FALSE) && ((UTlsPtr()[TLSSLOT_KERNEL] & TLSKERN_NOFAULT) || !KDTrap(&er, pctx, FALSE))) {
		bHandled = NKDispatchException(pth, &er, pctx);
		if (!bHandled) {
			if (!UserDbgTrap(&er, pctx, TRUE) && !KDTrap(&er, pctx, TRUE)) {
				if (er.ExceptionCode == STATUS_BREAKPOINT) {
					RETAILMSG(1, (TEXT("DEBUG_BREAK @%8.8lx Ignored.\r\n"), pctx->Eip));
					DumpFrame(pth, pctx, id, 0);
					if (*(uchar*)pctx->Eip == 0xCC)
					    ++pctx->Eip;
					else if (*(uchar*)pctx->Eip == 0xCD)
					    pctx->Eip += 2;
				} else {
					// Terminate the process.
					RETAILMSG(1, (TEXT("\r\nUnhandled exception %8.8lx:\r\n"),
							er.ExceptionCode));
					DumpFrame(pth, pctx, id, 2);
					if (InSysCall()) {
	    			    OutputDebugStringW(L"Halting system\r\n");
	    			    for (;;)
	    			        ;
	    			} else {
	    				if (!GET_DEAD(pth)) {
	    					SET_DEAD(pth);
		    				pctx->Eip = (ULONG)pExitThread;
							((ulong*)pctx->Esp)[1] = 0;
    						RETAILMSG(1, (TEXT("Terminating thread %8.8lx\r\n"), pth));
    					} else {
    						RETAILMSG(1, (TEXT("Can't terminate thread %8.8lx, sleeping forever\r\n"), pth));
							SurrenderCritSecs();
							Sleep(INFINITE);
							DEBUGCHK(0);    // should never get here
    					}
	    			}
				}
			}
		}
	}
	if (id == 14)
		GuardCommit(info);
continueExecution:
	// If returning from handling a stack overflow, reset the thread's stack overflow
	// flag. It would be good to free the tail of the stack at this time
	// so that the thread will stack fault again if the stack gets too big. But we
	// are currently using that stack page.
	if (id == 0xFF)
    	CLEAR_STACKFAULT(pth);
    if (GET_DYING(pth) && !GET_DEAD(pth) && (pCurProc == pth->pOwnerProc)) {
		SET_DEAD(pth);
		CLEAR_USERBLOCK(pth);
		CLEAR_DEBUGWAIT(pth);
		pctx->Eip = (ULONG)pExitThread;
		((ulong*)pctx->Esp)[1] = 0;
	}   
}

// Capture processor state into a full CONTEXT structure for debugging
// and exception handling.
//
//  (eax) = ptr to EXCINFO structure

Naked CaptureContext(void) {
    __asm {
        push    ss
        push    esp     // will be repaired by ExceptionDispatch
        pushfd
        push    cs
        push    eax     // Eip filled in by ExceptionDispatch
        push    ebp
        push    eax
        push    ecx
        push    edx
        push    ebx
        push    esi
        push    edi
        push    ds
        push    es
        push    fs
        push    gs
        mov     ecx, KGDT_R3_DATA
        mov     ds, cx
        mov     es, cx
        cld
	    sub     esp, size FLOATING_SAVE_AREA
        push    0       // dr7
        push    0       // dr6
        push    0       // dr3
        push    0       // dr2
        push    0       // dr1
        push    0       // dr0
        push    CONTEXT_FULL
        mov     ebx, esp        // (ebx) = ptr to context structure
        push    ebx             // (arg0) = ptr to CONTEXT
        call    ExceptionDispatch

        // Reload processor state from possibly edited 
        lea     esp, [ebx].SegGs
        pop     gs
        pop     fs
        pop     es
        pop     ds
        pop     edi
        pop     esi
        pop     ebx
        pop     edx
        pop     ecx
        mov     ax, cs              // (ax) = current code selector
        xor     eax, [esp+12]       // (ax) = CS ^ target selector
        and     eax, 0000fffcH      // (eax) = selector bits that differ
        jz      short no_ring_switch
        pop     eax
        pop     ebp
        iretd

// Restore frame without a ring switch.  Special care must be taken here because
// we need to restore Esp but an IRETD without a ring switch will not restore
// the SS:ESP.  Since we are returning the same ring, all that needs to be restored
// are Esp and Eip. This is done by copying the new Eip and new Ebp values onto the
// new stack, switching to the new stack and then restoring Ebp and returning.
// The return must be via an IRETD so that single stepping works correctly.
//
// At this point the stack frame is:
//      24  ss
//      20  esp
//      16  flags
//      12  cs
//      08  eip
//      04  ebp
//      00  eax
//      ---------< esp points here

no_ring_switch:
        mov     ebp, [esp+20]       // (ebp) = new stack pointer
        mov     eax, [esp+16]       // (eax) = new EFlags
        mov     [ebp-4], eax        // may overwrite SS value
        mov     eax, [esp+8]        // (eax) = new eip
        mov     [ebp-12], eax       // may overwrite EFlags value
        mov     eax, [esp+4]        // (eax) = new ebp
        mov     [ebp-16], eax       // may overwrite CS value
        mov     [ebp-8], cs
        pop     eax                 // restore Eax
        lea     esp, [ebp-16]       // (esp) = new stack (with Ebp & IRET frame pushed on)
        pop     ebp                 // (ebp) = original Ebp
        iretd                       // continue at the desired address
    }
}

// normal thread stack: from top, TLS then args then free

void MDCreateThread(PTHREAD pTh, LPVOID lpStack, DWORD cbStack, LPVOID lpBase, LPVOID lpStart, DWORD dwVMBase, BOOL kmode, ulong param) {
    ulong *args;
    NK_PCR *pcr;
	if (!((ulong)lpStack>>VA_SECTION))
		lpStack = (LPVOID)((ulong)(lpStack) + dwVMBase);
	pTh->dwStackBase = (DWORD)lpStack;
	// Allocate space for TLS & PCR info.
	pcr = (NK_PCR *)((ulong)lpStack+cbStack - sizeof(NK_PCR));
	// Allocate space for arguments to the start function.
	pTh->ctx.TcxEsp = (ulong)pcr - 3*4;
	pTh->dwStackBound = pTh->ctx.TcxEsp & ~(PAGE_SIZE-1);
	args = (ulong*)pTh->ctx.TcxEsp;
	pcr->ExceptionList = 0;
	pcr->InitialStack = pTh->ctx.TcxEsp;
	pcr->StackLimit = (DWORD)lpStack;
	pTh->tlsPtr = pcr->tls;
	args[1] = (ulong)lpStart;
	args[2] = param;
	args[0] = 0;                        // set return address to fault
	pTh->ctx.TcxEip = (ULONG)lpBase;
	pTh->ctx.TcxDs = KGDT_R3_DATA;
	pTh->ctx.TcxEs = KGDT_R3_DATA;
	pTh->ctx.TcxFs = KGDT_PCR;
	pTh->ctx.TcxGs = 0;
	pTh->ctx.TcxEFlags = 0x3200;        // IOPL=3, IF=1
	if (dwFPType == FPTYPE_HARDWARE) {
        if (ProcessorFeatures & CPUID_FXSR)  {
            memcpy(&pcr->tcxExtended, &g_InitialFPUState, 
                sizeof(pcr->tcxExtended));
        } else {
            memcpy(&pcr->tcxFPU, &g_InitialFPUState, (sizeof(pcr->tcxFPU)+16));
        }
    } else if (dwFPType == FPTYPE_SOFTWARE)
        memset(pcr->Emx87Data, 0, sizeof(pcr->Emx87Data));
	SetThreadMode(pTh, ((kmode || bAllKMode) ? KERNEL_MODE : USER_MODE));
}

// main thread stack: from top, PCR then buf then buf2 then buf2 (ascii) then args then free

LPCWSTR MDCreateMainThread1(PTHREAD pTh, LPVOID lpStack, DWORD cbStack, DWORD dwVMBase,
	LPBYTE buf, ulong buflen, LPBYTE buf2, ulong buflen2) {
    LPBYTE buffer;
	LPCWSTR pcmdline;
	if (!((ulong)lpStack>>VA_SECTION))
		lpStack = (LPVOID)((ulong)(lpStack) + dwVMBase);
	pTh->dwStackBase = (DWORD)lpStack;
    // Allocate space for extra parameters on the stack and copy the bytes there.
    buffer = (LPBYTE)((ulong)lpStack+cbStack-sizeof(NK_PCR) - (buflen+3&~3));
    pcmdline = (LPCWSTR)buffer;
    memcpy(buffer, buf, buflen);
    buffer -= (buflen2+3&~3);
    memcpy(buffer, buf2, buflen2);
	KPlpvTls = pTh->tlsPtr = ((NK_PCR *)(pTh->dwStackBase+cbStack - sizeof(NK_PCR)))->tls;
	pTh->pOwnerProc->lpszProcName = (LPWSTR)buffer;
	return pcmdline;
}

void MDCreateMainThread2(PTHREAD pTh, DWORD cbStack, LPVOID lpBase, LPVOID lpStart, BOOL kmode,
	ulong p1, ulong p2, ulong buflen, ulong buflen2, ulong p4) {
    LPBYTE buffer;
    ulong *args;
    NK_PCR *pcr;
	// Allocate space for TLS & PCR info.
	pcr = (NK_PCR *)(pTh->dwStackBase+cbStack - sizeof(NK_PCR));
	pcr->ExceptionList = 0;
	pcr->InitialStack = pTh->ctx.TcxEsp;
	pcr->StackLimit = pTh->dwStackBase;
	KPlpvTls = pTh->tlsPtr = pcr->tls;
	// Allocate space for arguments to the start function.
    buffer = (LPBYTE)(pTh->dwStackBase+cbStack-sizeof(NK_PCR) - (buflen+3&~3));
    buffer -= (buflen2+3&~3);
	pTh->ctx.TcxEsp = (ulong)buffer - 6*4;
	pTh->dwStackBound = pTh->ctx.TcxEsp & ~(PAGE_SIZE-1);
	args = (ulong*)pTh->ctx.TcxEsp;
	args[1] = (ulong)lpStart;
	args[2] = p1;
	args[3] = p2;
	args[4] = pTh->dwStackBase+cbStack-sizeof(NK_PCR) - (buflen+3&~3);
	args[5] = p4;
	args[0] = 0;                        // set return address to fault
	pTh->ctx.TcxEip = (ULONG)lpBase;
	pTh->ctx.TcxDs = KGDT_R3_DATA;
	pTh->ctx.TcxEs = KGDT_R3_DATA;
	pTh->ctx.TcxFs = KGDT_PCR;
	pTh->ctx.TcxGs = 0;
	pTh->ctx.TcxEFlags = 0x3200;        // IOPL=3, IF=1
	if (dwFPType == FPTYPE_HARDWARE)  {
        if (ProcessorFeatures & CPUID_FXSR)  {
            memcpy(&pcr->tcxExtended, &g_InitialFPUState, 
                sizeof(pcr->tcxExtended));
        } else {
            memcpy(&pcr->tcxFPU, &g_InitialFPUState, (sizeof(pcr->tcxFPU)+16));
        }
    } else if (dwFPType == FPTYPE_SOFTWARE)
        memset(pcr->Emx87Data, 0, sizeof(pcr->Emx87Data));
	SetThreadMode(pTh, ((kmode || bAllKMode) ? KERNEL_MODE : USER_MODE));
}

void ZeroPage(void *pvPage) {
    _asm {
        mov edi, pvPage
        mov ecx, PAGE_SIZE/4
        xor eax, eax
        rep stosd
    }
}

extern void FPUFlushContext(void);
 
BOOL DoThreadGetContext(HANDLE hTh, LPCONTEXT lpContext) {
	PTHREAD pth;
	PFXSAVE_AREA FxArea;
	PFLOATING_SAVE_AREA FnArea;
    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) {
			lpContext->Ebp = pth->pThrdDbg->psavedctx->Ebp;
			lpContext->Eip = pth->pThrdDbg->psavedctx->Eip;
			lpContext->SegCs = pth->pThrdDbg->psavedctx->SegCs;
			lpContext->EFlags = pth->pThrdDbg->psavedctx->EFlags;
			lpContext->Esp = pth->pThrdDbg->psavedctx->Esp;
			lpContext->SegSs = pth->pThrdDbg->psavedctx->SegSs;
		}
		if ((lpContext->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
			lpContext->Edi = pth->pThrdDbg->psavedctx->Edi;
			lpContext->Esi = pth->pThrdDbg->psavedctx->Esi;
			lpContext->Ebx = pth->pThrdDbg->psavedctx->Ebx;
			lpContext->Edx = pth->pThrdDbg->psavedctx->Edx;
			lpContext->Ecx = pth->pThrdDbg->psavedctx->Ecx;
			lpContext->Eax = pth->pThrdDbg->psavedctx->Eax;
		}
		if ((lpContext->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) {
			lpContext->SegGs = pth->pThrdDbg->psavedctx->SegGs;
			lpContext->SegFs = pth->pThrdDbg->psavedctx->SegFs;
			lpContext->SegEs = pth->pThrdDbg->psavedctx->SegEs;
			lpContext->SegDs = pth->pThrdDbg->psavedctx->SegDs;
		}
		if ((lpContext->ContextFlags & CONTEXT_FLOATING_POINT) == 
            CONTEXT_FLOATING_POINT) {
			FPUFlushContext();
			lpContext->FloatSave = pth->pThrdDbg->psavedctx->FloatSave;
		}
		if ((lpContext->ContextFlags & CONTEXT_DEBUG_REGISTERS) == 
            CONTEXT_DEBUG_REGISTERS) {

		}
	} else {
		if ((lpContext->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
			lpContext->Ebp = pth->ctx.TcxEbp;
			lpContext->Eip = pth->ctx.TcxEip;
			lpContext->SegCs = pth->ctx.TcxCs;
			lpContext->EFlags = pth->ctx.TcxEFlags;
			lpContext->Esp = pth->ctx.TcxEsp;
			lpContext->SegSs = pth->ctx.TcxSs;
		}
		if ((lpContext->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
			lpContext->Edi = pth->ctx.TcxEdi;
			lpContext->Esi = pth->ctx.TcxEsi;
			lpContext->Ebx = pth->ctx.TcxEbx;
			lpContext->Edx = pth->ctx.TcxEdx;
			lpContext->Ecx = pth->ctx.TcxEcx;
			lpContext->Eax = pth->ctx.TcxEax;
		}
		if ((lpContext->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) {
			lpContext->SegGs = pth->ctx.TcxGs;
			lpContext->SegFs = pth->ctx.TcxFs;
			lpContext->SegEs = pth->ctx.TcxEs;
			lpContext->SegDs = pth->ctx.TcxDs;
		}
		if ((lpContext->ContextFlags & CONTEXT_FLOATING_POINT) == 
            CONTEXT_FLOATING_POINT) {
            if (ProcessorFeatures & CPUID_FXSR)  {
                FxArea = (PFXSAVE_AREA) PTH_TO_FLTSAVEAREAPTR(pth);
                FnArea = &lpContext->FloatSave;
                __asm {
                    // We won't get here if emulating FP, so CR0.EM will be 0
                    call    FPUFlushContext     // FPUFlushContext sets CR0.TS
                    clts 
                    mov     eax, FxArea
                    FXRESTOR_EAX                // convert from fxsave format
                    mov     eax, FnArea         // in NK_PCR to fnsave format
                    fnsave  [eax]               // in CONTEXT structure
                    fwait
                    mov     eax, cr0 
                    or      eax, TS_MASK
                    mov     cr0, eax
                }
            } else {
    			                FPUFlushContext();
                lpContext->FloatSave = *(PTH_TO_FLTSAVEAREAPTR(pth));
            }
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -