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

📄 mdx86.c

📁 wince下的源代码集合打包
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved. */#include "kernel.h"#define Naked void __declspec(naked)extern FXSAVE_AREA g_InitialFPUState;extern KIDTENTRY g_aIntDescTable[];// Default processor type & revision level information.DWORD CEProcessorType = PROCESSOR_INTEL_486;WORD ProcessorLevel = 0;WORD ProcessorRevision = 0;DWORD ProcessorFeatures = 0;#define FN_BITS_PER_TAGWORD         16#define FN_TAG_EMPTY                0x3#define FN_TAG_MASK                 0x3#define FX_TAG_VALID                0x1#define NUMBER_OF_FP_REGISTERS      8#define BYTES_PER_FP_REGISTER       10#define BYTES_PER_FX_REGISTER       16#define TS_MASK                     0x00000008#define FPTYPE_HARDWARE 1#define FPTYPE_SOFTWARE 2DWORD dwFPType;void DumpDwords(PDWORD pdw, int len) {    int lc;    lc = 0;    NKDbgPrintfW(L"Dumping %d dwords", len);    for (lc = 0 ; len ; ++pdw, ++lc, --len) {        if (!(lc & 3))            NKDbgPrintfW(L"\r\n%8.8lx -", pdw);        NKDbgPrintfW(L" %8.8lx", *pdw);    }    NKDbgPrintfW(L"\r\n");}void DumpFrame(PTHREAD pth, PCONTEXT pctx, int id, int level) {    NKDbgPrintfW(L"Exception %02x Thread=%8.8lx AKY=%8.8lx EIP=%8.8lx\r\n",    		id, pth, pCurThread->aky, pctx->Eip);    NKDbgPrintfW(L"Eax=%8.8lx Ebx=%8.8lx Ecx=%8.8lx Edx=%8.8lx\r\n",            pctx->Eax, pctx->Ebx, pctx->Ecx, pctx->Edx);    NKDbgPrintfW(L"Esi=%8.8lx Edi=%8.8lx Ebp=%8.8lx Esp=%8.8lx\r\n",            pctx->Esi, pctx->Edi, pctx->Ebp, pctx->Esp);    NKDbgPrintfW(L"CS=%4.4lx DS=%4.4lx ES=%4.4lx SS=%4.4lx FS=%4.4lx GS=%4.4lx\r\n",            pctx->SegCs, pctx->SegDs, pctx->SegEs, pctx->SegSs, pctx->SegFs, pctx->SegGs);    NKDbgPrintfW(L"Flags=%8.8lx\r\n",            pctx->EFlags);}void DumpTctx(PTHREAD pth, int id, ulong addr, int level) {    ulong espValue, ssValue;    if ((pth->ctx.TcxCs&0xFFFF) == KGDT_R0_CODE) {        espValue = pth->ctx.TcxNotEsp+16;        ssValue = KGDT_R0_DATA;    } else {        espValue = pth->ctx.TcxEsp;        ssValue = pth->ctx.TcxSs;    }    NKDbgPrintfW(L"Exception %02x Thread=%8.8lx Proc=%8.8lx '%s'\r\n",   			id, pth, hCurProc, pCurProc->lpszProcName ? pCurProc->lpszProcName : L"");    NKDbgPrintfW(L"EIP=%8.8lx AKY=%8.8lx Flags=%8.8lx EA=%8.8lx\r\n",             pth->ctx.TcxEip, pCurThread->aky, pth->ctx.TcxEFlags, addr);    NKDbgPrintfW(L"Eax=%8.8lx Ebx=%8.8lx Ecx=%8.8lx Edx=%8.8lx\r\n",            pth->ctx.TcxEax, pth->ctx.TcxEbx, pth->ctx.TcxEcx, pth->ctx.TcxEdx);    NKDbgPrintfW(L"Esi=%8.8lx Edi=%8.8lx Ebp=%8.8lx Esp=%8.8lx\r\n",            pth->ctx.TcxEsi, pth->ctx.TcxEdi, pth->ctx.TcxEbp, espValue);    NKDbgPrintfW(L"CS=%4.4lx DS=%4.4lx ES=%4.4lx SS=%4.4lx FS=%4.4lx GS=%4.4lx\r\n",            pth->ctx.TcxCs, pth->ctx.TcxDs, pth->ctx.TcxEs, ssValue,            pth->ctx.TcxFs, pth->ctx.TcxGs);   	if (level > 1) {   	    DWORD addr;   	    PDWORD pdw;   	    int count = 16;   		addr = espValue;	    if (pth->ctx.TcxEbp >= espValue)	        count = (pth->ctx.TcxEbp+16 - espValue) / 4;	    pdw = VerifyAccess((PVOID)addr, VERIFY_KERNEL_OK, CurAKey);	    if (pdw)		    DumpDwords((PDWORD)addr, count);    }}typedef struct ExcInfo {    DWORD   linkage;	ULONG	oldEip;	UINT    oldMode;	UCHAR	id;	UCHAR   oldTFlag;	USHORT  error;	ULONG	info;	UCHAR	lowSp;	UCHAR	pad[3];} EXCINFO;typedef EXCINFO *PEXCINFO;ERRFALSE(sizeof(EXCINFO) <= sizeof(CALLSTACK));ERRFALSE(offsetof(EXCINFO,linkage) == offsetof(CALLSTACK,pcstkNext));ERRFALSE(offsetof(EXCINFO,oldEip) == offsetof(CALLSTACK,retAddr));ERRFALSE(offsetof(EXCINFO,oldMode) == offsetof(CALLSTACK,pprcLast));ERRFALSE(64 >= sizeof(CALLSTACK));Naked CpuIdTrap6Handler(void){    __asm {        // Illegal opcode handler when executing cpuid instruction        add     dword ptr [esp], 2  // skip the cpuid instr by incrementing eip        xor     eax, eax        // simulate an unsupported cpuid instruction        xor     ebx, ebx        // by returning 0 for return values        xor     ecx, ecx        xor     edx, edx        iretd    }}void IdentifyCpu(void){    __asm {        pushfd        cli        mov     ecx, offset g_aIntDescTable        push    dword ptr [ecx+30h]     // Save Trap06 handler in case        push    dword ptr [ecx+34h]     // the CPUID instruction faults        mov     eax, offset CpuIdTrap6Handler        mov     word ptr [ecx+30h], ax  // Set LowWord        shr     eax, 16        mov     word ptr [ecx+36h], ax  // Set HighWord        xor     eax, eax                // argument to CPUID        _emit   0fh                     // cpuid instruction        _emit   0a2h                    // sets eax, ebx, ecx, edx        cmp     ebx, 756e6547h          // check for "Genu" string        jne     short cpuid_trap        // not an Intel processor        cmp     edx, 49656e69h          // check for "ineI" string        jne     short cpuid_trap        // not an Intel processor        cmp     ecx, 6c65746eh          // check for "ntel" string        jne     short cpuid_trap        // not an Intel processor        cmp     eax, 1                  // make sure level 1 is supported        jc      short cpuid_trap        // no, then keep defaults        mov     eax, 1                  // get the family and stepping        _emit   0fh                     // cpuid instruction        _emit   0a2h        mov     ebx, eax        mov     ecx, eax        shr     ebx, 4        and     ebx, 0Fh                // (ebx) = model        and     ecx, 0Fh                // (ecx) = stepping        shr     eax, 8        and     eax, 0Fh                // (eax) = family        cmp     eax, 4        jne     cpu_not_p4        mov     eax, PROCESSOR_INTEL_486        jmp     short cpuid_storecpu_not_p4:        cmp     eax, 5        jne     short cpu_not_p5        mov     eax, PROCESSOR_INTEL_PENTIUM        jmp     short cpuid_storecpu_not_p5:        mov     eax, PROCESSOR_INTEL_PENTIUMIIcpuid_store:        mov     CEProcessorType, eax        mov     ProcessorLevel, bx        mov     ProcessorRevision, cx        mov     ProcessorFeatures, edxcpuid_trap:        mov     ecx, offset g_aIntDescTable        pop     dword ptr [ecx+34h]     // restore trap6 handler        pop     dword ptr [ecx+30h]        popfd    }}BOOL HandleException(PTHREAD pth, int id, ulong addr) {	PEXCINFO pexi;	DWORD stackaddr;	KCALLPROFON(0);#if 0    NKDbgPrintfW(L"Exception %02x Thread=%8.8lx(%8.8lx) IP=%8.8lx EA=%8.8lx Err=%4.4x\r\n",   			id, pCurThread,pth, pth->ctx.TcxEip, addr, pth->ctx.TcxError & 0xFFFF);#endif    pexi = (struct ExcInfo *)((pth->ctx.TcxEsp & ~63) - sizeof(CALLSTACK));    if (!((DWORD)pexi & 0x80000000) && DemandCommit((DWORD)pexi)) {		stackaddr = (DWORD)pexi & ~(PAGE_SIZE-1);		if ((stackaddr >= pth->dwStackBound) || (stackaddr < pth->dwStackBase) ||			((pth->dwStackBound = stackaddr) >= (pth->dwStackBase + MIN_STACK_RESERVE)) ||			TEST_STACKFAULT(pth)) {			KCALLPROFOFF(0);			return 1; // restart instruction		}		SET_STACKFAULT(pth);		id = 0xFF;		// stack fault exception code		addr = (DWORD)pexi;	}	// Setup to capture the exception context in kernel mode but	// running in thread context to allow preemption and stack growth.	if (pth->ctx.TcxEip != (ulong)CaptureContext) {		pexi->id = id;		pexi->lowSp = (CHAR)(pth->ctx.TcxEsp & 63);		pexi->oldEip = pth->ctx.TcxEip;		pexi->oldMode = GetThreadMode(pth);		pexi->info = addr;		if (id != 16)			pexi->error = (USHORT)pth->ctx.TcxError;		else {			WORD status;		    _asm fnstsw status;		    pexi->error = status;			_asm fnclex;					}		pexi->oldTFlag = (UCHAR)(pth->ctx.TcxEFlags >> 8) & 1;        pexi->linkage = (DWORD)pCurThread->pcstkTop | 1;        pCurThread->pcstkTop = (PCALLSTACK)pexi;        pth->ctx.TcxEsp = (DWORD)pexi;		pth->ctx.TcxEFlags &= ~0x0100; // Unset TF while in the debugger		pth->ctx.TcxEip = (ulong)CaptureContext;		if (pexi->oldMode != KERNEL_MODE)    		SetThreadMode(pth, KERNEL_MODE);    	KCALLPROFOFF(0);		return TRUE;			// continue execution	}	DumpTctx(pth, id, addr, 10);	RETAILMSG(1, (TEXT("Halting thread %8.8lx\r\n"), pCurThread));	SurrenderCritSecs();	SET_RUNSTATE(pth,RUNSTATE_BLOCKED);	RunList.pth = 0;	SetReschedule();	KCALLPROFOFF(0);	return 0;}typedef struct _EXCARGS {	DWORD dwExceptionCode;		/* exception code	*/	DWORD dwExceptionFlags;		/* continuable exception flag	*/	DWORD cArguments;			/* number of arguments in array	*/	DWORD *lpArguments;			/* address of array of arguments	*/} EXCARGS;typedef EXCARGS *PEXCARGS;BOOL SetCPUHardwareWatch(LPVOID lpv, DWORD dwFlags) {    static PPROCESS pOwnerProc;        if (!InSysCall())         return KCall((PKFN)SetCPUHardwareWatch, lpv, dwFlags);            KCALLPROFON(73);    if (lpv == 0) {        // dwFlags=0 means check to see if we want to take this breakpoint        if (dwFlags == (DWORD)-1) {            // check to see which breakpoint went off and            // clear the debug register            DWORD dwReason;            DWORD dwMask=~0xf;            _asm {                mov eax, dr6                mov dwReason, eax                and eax, dwMask                mov dr6, eax            }            // was the zeroptr breakpoint hit?            if (dwReason&0x2 && pOwnerProc != pCurProc) {                OutputDebugString(L"zero mapped breakpoint hit in wrong process!\r\n");                KCALLPROFOFF(73);                return 0;            }            KCALLPROFOFF(73);            return 1;        } else {            // dwFlags=1 means disable the data watchpoint            dwFlags = ~0xf;            _asm {                mov eax, dr7                and eax, dwFlags                mov dr7, eax            }            KCALLPROFOFF(73);            return 1;        }    } else {        DWORD dwMask=~0xff000f;        LPVOID lpvZero=(LPVOID)UnMapPtr(lpv);        if (dwFlags == HARDWARE_WATCH_READ) {            dwFlags = 0xff000a;        } else {            dwFlags = 0xdd000a;        }        _asm {            mov eax, lpv            mov dr0, eax            mov eax, lpvZero            mov dr1, eax            mov eax, dr7            and eax, dwMask            or  eax, dwFlags            mov dr7, eax        }        pOwnerProc = pCurProc;        KCALLPROFOFF(73);        return 1;    }    KCALLPROFOFF(73);}    void ExceptionDispatch(PCONTEXT pctx) {	PTHREAD pth;	PEXCINFO pexi;	int id;	ULONG info;	BOOL bHandled;	PEXCARGS pea;	EXCEPTION_RECORD er;	pth = pCurThread;	pexi = (PEXCINFO)pth->pcstkTop;	DEBUGMSG(ZONE_SEH, (TEXT("ExceptionDispatch: pexi=%8.8lx Eip=%8.8lx id=%x\r\n"),			pexi, pexi->oldEip, pexi->id));	// Update CONTEXT with infomation saved in the EXCINFO structure	pctx->Eip = pexi->oldEip;	pctx->Esp = (DWORD)pctx + sizeof(CONTEXT);	SetContextMode(pctx, pexi->oldMode);	memset(&er, 0, sizeof(er));	er.ExceptionAddress = (PVOID)pctx->Eip;    // Check for RaiseException call versus a CPU detected exception.    // RaiseException just becomes a call to CaptureContext as a KPSL.    // HandleExcepion sets the LSB of the callstack linkage but ObjectCall    // does not.    if (!(pexi->linkage & 1)) {        NK_PCR *pcr = (NK_PCR *)((char *)pth->tlsPtr - offsetof(NK_PCR, tls));		// Fill in exception record information from the parameters passed to		// the RaiseException call.		// Restore exception list linkage.		DEBUGCHK(pcr->ExceptionList == -2);		pcr->ExceptionList = ((PCALLSTACK)pexi)->extra;				pea = (PEXCARGS)(pctx->Esp + 4);		id = -1;		pctx->Esp += 4;     // Remove return address from the stack		DEBUGMSG(ZONE_SEH, (TEXT("Raising exception %x flags=%x args=%d pexi=%8.8lx\r\n"),				pea->dwExceptionCode, pea->dwExceptionFlags, pea->cArguments, pexi));		er.ExceptionCode = pea->dwExceptionCode;		er.ExceptionFlags = pea->dwExceptionFlags;		if (pea->lpArguments && pea->cArguments) {			if (pea->cArguments > EXCEPTION_MAXIMUM_PARAMETERS) {				er.ExceptionCode = STATUS_INVALID_PARAMETER;				er.ExceptionFlags = EXCEPTION_NONCONTINUABLE;			} else {				memcpy(er.ExceptionInformation, pea->lpArguments,						pea->cArguments*sizeof(DWORD));				er.NumberParameters = pea->cArguments;			}		}    } else {        // CPU detected exception. Extract some additional information about        // the cause of the exception from the EXCINFO (CALLSTACK) structure.    	id = pexi->id;    	info = pexi->info;        pctx->EFlags |= pexi->oldTFlag << 8;        pctx->Esp += pexi->lowSp + sizeof(CALLSTACK);		if ((id == 14) && AutoCommit(info)) {			pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1);			goto continueExecution;		}    	// Construct an EXCEPTION_RECORD from the EXCINFO structure    	er.ExceptionInformation[1] = info;    	switch (id) {    	case 14:	// Page fault    		er.ExceptionInformation[0] = (pexi->error >> 1) & 1;    		goto accessError;    	case 13:		// General Protection Fault    		er.ExceptionInformation[0] = 1; accessError:    		if (ProcessPageFault(er.ExceptionInformation[0], info)) {            	pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1);    			goto continueExecution;    		}    		er.ExceptionCode = STATUS_ACCESS_VIOLATION;    		er.NumberParameters = 2;    		break;    	case 3:		// Breakpoint    		er.ExceptionInformation[0] = 1; // DEBUGBREAK_STOP_BREAKPOINT    		er.ExceptionCode = STATUS_BREAKPOINT;    		break;    	case 2: // Stop thread breakpoint    		er.ExceptionInformation[0] = 3; // DEBUG_THREAD_SWITCH_BREAKPOINT    		er.ExceptionCode = STATUS_BREAKPOINT;    		break;    	case 1:		// Breakpoint    		er.ExceptionInformation[0] = 0;    		er.ExceptionCode = STATUS_SINGLE_STEP;            // If you are using the SetCPUHardware watch function you will probably             // want to uncomment the following lines so that it will clear the register            // automatically on exception/*    		    		if(!SetCPUHardwareWatch(0, (DWORD)-1)) {

⌨️ 快捷键说明

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