📄 mdx86.c
字号:
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 structureNaked 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 hereno_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 freevoid 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 freeLPCWSTR 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 + -