📄 mdarm.c
字号:
break;
case ID_PREFETCH_ABORT: // Code page fault
addr = pctx->Pc;
DEBUGMSG(ZONE_PAGING, (L"ExD: ID_PREFETCH_ABORT\r\n"));
doPageFault:
DEBUGMSG(ZONE_PAGING, (L"ExD: addr = %8.8lx\r\n",addr));
fInKMode = (GetContextMode(pctx) != USER_MODE);
// er.ExceptionInformation[0] == read or write (1 for write)
if (!InSysCall ()
&& (fInKMode || !(addr & 0x80000000))
// writing to shared section require KMode access
&& (!IsInSharedSection(addr) || !er.ExceptionInformation[0] || fInKMode)
&& ProcessPageFault(er.ExceptionInformation[0], addr)) {
pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1);
DEBUGMSG(ZONE_PAGING, (L"ExD: continuing. lr = %8.8lx\r\n", pctx->Lr));
goto continueExecution;
}
er.ExceptionCode = STATUS_ACCESS_VIOLATION;
er.ExceptionInformation[1] = addr;
er.NumberParameters = 2;
break;
case ID_STACK_FAULT: // Stack overflow
er.ExceptionCode = STATUS_STACK_OVERFLOW;
er.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
break;
}
}
if ((er.ExceptionCode != STATUS_BREAKPOINT) && !IsNoFaultMsgSet ()) {
// if we faulted in DllMain doing PROCESS_ATTACH, the process name will
// be pointing to other process's (the creator) address space. Make sure
// we don't fault on displaying process name.
LPWSTR pProcName = pCurProc->lpszProcName? pCurProc->lpszProcName : L"";
LPCWSTR pszNamePC, pszNameRA;
DWORD dwOfstPC = pctx->Pc, dwOfstRA = pctx->Lr;
pszNamePC = FindModuleNameAndOffset (dwOfstPC, &dwOfstPC);
pszNameRA = FindModuleNameAndOffset (dwOfstRA, &dwOfstRA);
if (!((DWORD) pProcName & 0x80000000)
&& (((DWORD) pProcName >> VA_SECTION) != (DWORD) (pCurProc->procnum+1)))
pProcName = L"";
NKDbgPrintfW(L"%a: Thread=%8.8lx Proc=%8.8lx '%s'\r\n",IdStrings[id+1], pth, pCurProc, pProcName);
NKDbgPrintfW(L"AKY=%8.8lx PC=%8.8lx(%s+0x%8.8lx) RA=%8.8lx(%s+0x%8.8lx) BVA=%8.8lx FSR=%8.8lx\r\n",
pCurThread->aky, pctx->Pc, pszNamePC, dwOfstPC, pctx->Lr, pszNameRA, dwOfstRA, addr, fsr);
if (IsNoFaultSet ()) {
NKDbgPrintfW(L"TLSKERN_NOFAULT set... bypassing kernel debugger.\r\n");
}
}
// Unlink the EXCINFO structure from the threads call stack chain.
pth->pcstkTop = (PCALLSTACK)(pexi->linkage & ~1);
if (!(pexi->linkage & 1) && IsValidKPtr (pexi)) {
// from RaiseException, free the callstack structure
FreeMem (pexi, HEAP_CALLSTACK);
}
// Invoke the kernel debugger to attempt to debug the exception before
// letting the program resolve the condition via SEH.
if (!UserDbgTrap(&er, pctx, FALSE) && (IsNoFaultSet () || !HDException(&er, pctx, FALSE))) {
BOOL bHandled = FALSE;
// don't pass a break point exception to NKDispatchException
if (er.ExceptionCode != STATUS_BREAKPOINT) {
// to prevent recursive exception due to user messed-up TLS
KTHRDINFO (pth) &= ~UTLS_INKMODE;
bHandled = NKDispatchException(pth, &er, pctx);
}
if (!bHandled && !UserDbgTrap(&er, pctx, TRUE) && !HDException(&er, pctx, TRUE)) {
if (er.ExceptionCode == STATUS_BREAKPOINT) {
if (!pvHDNotifyExdi || pctx->Pc < (DWORD)pvHDNotifyExdi || pctx->Pc > ((DWORD)pvHDNotifyExdi + HD_NOTIFY_MARGIN))
RETAILMSG(1, (TEXT("DEBUG_BREAK @%8.8lx MD=%2x Ignored.\r\n"), pctx->Pc,
pctx->Psr & 0xFF));
pctx->Pc += ThumbMode ? 2 : 4; // skip over the BREAK instruction
} else {
// Terminate the process.
RETAILMSG(1, (TEXT("\r\nUnhandled exception %8.8lx:\r\n"), er.ExceptionCode));
if (InSysCall()) {
DumpFrame(pth, (PCPUCONTEXT)&pctx->Psr, id, addr, 0);
lpNKHaltSystem ();
FakeNKHaltSystem ();
} else {
if (!GET_DEAD(pth)) {
pcstk = pth->pcstkTop;
while (pcstk && !pcstk->akyLast) {
pth->pcstkTop = (PCALLSTACK) ((DWORD) pcstk->pcstkNext & ~1);
if (IsValidKPtr (pcstk)) {
FreeMem (pcstk, HEAP_CALLSTACK);
}
pcstk = pth->pcstkTop;
}
DEBUGCHK (!pcstk); // should this happen, we have a fault in callback that wasn't handled
// by PSL
// clean up all the temporary callstack
if (er.ExceptionCode == STATUS_STACK_OVERFLOW) {
// stack overflow, not much we can do. Make sure we have enough room to run
// pExcpExitThread
// randomly picked a valid SP
pctx->Sp = (DWORD) pth->tlsPtr - SECURESTK_RESERVE - (PAGE_SIZE >> 1);
}
SET_DEAD(pth);
//pth->tlsSecure[TLSSLOT_KERNEL] |= TLSKERN_TRYINGTODIE;
pctx->Pc = (ULONG)pExcpExitThread;
pctx->R0 = er.ExceptionCode; // argument: exception code
pctx->R1 = (ULONG)er.ExceptionAddress; // argument: exception address
RETAILMSG(1, (TEXT("Terminating thread %8.8lx\r\n"), pth));
} else {
DumpFrame(pth, (PCPUCONTEXT)&pctx->Psr, id, addr, 0);
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 == ID_DATA_ABORT) || (id == ID_PREFETCH_ABORT))
GuardCommit(addr);
continueExecution:
#if defined(THUMBSUPPORT)
//
// Update PSR based on ARM/Thumb continuation:
//
if ( pctx->Pc & 0x01 ){
pctx->Psr |= THUMB_STATE;
} else {
pctx->Psr &= ~THUMB_STATE;
}
#endif
// restore ThrdInfo
KTHRDINFO (pth) = dwThrdInfo;
// 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 == ID_STACK_FAULT)
CLEAR_STACKFAULT(pth);
if (GET_DYING(pth) && !GET_DEAD(pth) && (pCurProc == pth->pOwnerProc)) {
SET_DEAD(pth);
CLEAR_USERBLOCK(pth);
CLEAR_DEBUGWAIT(pth);
pctx->Pc = (ULONG)pExcpExitThread;
pctx->R0 = er.ExceptionCode; // argument: exception code
pctx->R1 = (ULONG)er.ExceptionAddress; // argument: exception address
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
PVOID
Phys2Virt(
DWORD pfn
)
{
int i = 0;
DWORD va; // Virtual Base Address of section
DWORD pa; // Physical Base Address of section
DWORD pau; // Physical Address Upper Bound of section
DWORD pfnmb; // PFN rounded down to 1MB
//
// The end of the table is marked by an entry with a ZERO size.
//
while(g_pOEMAddressTable[i].dwSize) {
va = g_pOEMAddressTable[i].dwVA & 0x1FF00000;
pa = g_pOEMAddressTable[i].dwPA & 0xFFF00000;
pau = pa + (g_pOEMAddressTable[i].dwSize << 20) - 1;
pfnmb = pfn & 0xfff00000;
if ((pfnmb >= pa) && (pfnmb <= pau))
return ((PVOID) ((pfn - pa) + va + 0x80000000));
i++;
}
DEBUGMSG(ZONE_PHYSMEM, (TEXT("Phys2Virt() : PFN (0x%08X) not found!\r\n"), pfn));
return NULL;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPVOID MDValidateKVA (DWORD dwAddr)
{
// kernel data and page table territory...
if ( ((dwAddr >= 0xFFFD0000) && (dwAddr < 0xFFFD4000))
|| ((dwAddr >= 0xFFFF0000) && (dwAddr < 0xFFFF1000))
|| ((dwAddr >= 0xFFFF2000) && (dwAddr < 0xFFFF3000))
|| ((dwAddr >= 0xFFFF4000) && (dwAddr < 0xFFFF5000))
|| ((dwAddr >= 0xFFFFC000) && (dwAddr < 0xFFFFD000)))
return (LPVOID) dwAddr;
if (dwAddr < 0xc0000000) {
int i;
DWORD dwCachedAddr = dwAddr & ~0x20000000; // use cached address to do comparision
// check the OEM address map to see if the address we've been
// handed is indeed mapped...
for (i = 0; g_pOEMAddressTable[i].dwSize; i ++) {
if((g_pOEMAddressTable[i].dwVA <= dwCachedAddr)
&& (dwCachedAddr < (g_pOEMAddressTable[i].dwVA + (g_pOEMAddressTable[i].dwSize << 20)))) {
return (LPVOID) dwAddr;
}
}
}
return NULL;
}
/* Machine dependent constants */
const DWORD cbMDStkAlign = 8; // stack 8 bytes aligned
void MDInitSecureStack(LPBYTE lpStack)
{
}
/* Machine dependent thread creation */
// normal thread stack: from top, TLS then PRETLS then args then free
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
MDCreateThread(
PTHREAD pTh,
LPVOID lpStack,
DWORD cbStack,
LPVOID lpBase,
LPVOID lpStart,
BOOL kmode,
ulong param
)
{
DEBUGCHK ((ulong)lpStack>>VA_SECTION);
pTh->tlsPtr = TLSPTR(lpStack, cbStack);
KSTKBASE(pTh) = (DWORD)lpStack;
// Leave room for arguments and TLS and PRETLS on the stack
pTh->ctx.Sp = (ulong)pTh->tlsPtr - SIZE_PRETLS;
KSTKBOUND(pTh) = pTh->ctx.Sp & ~(PAGE_SIZE-1);
pTh->ctx.R0 = (ulong)lpStart;
pTh->ctx.R1 = param;
pTh->ctx.Lr = 4;
pTh->ctx.Pc = (ULONG)lpBase;
if (kmode || bAllKMode) {
pTh->ctx.Psr = KERNEL_MODE;
KTHRDINFO (pTh) |= UTLS_INKMODE;
} else {
pTh->ctx.Psr = USER_MODE;
KTHRDINFO (pTh) &= ~UTLS_INKMODE;
}
pTh->ctx.Fpscr = 0;
pTh->ctx.FpExc = 0;
memset (pTh->ctx.FpExtra, 0, sizeof (pTh->ctx.FpExtra));
#if defined(THUMBSUPPORT)
if ( (pTh->ctx.Pc & 0x01) != 0 ){
pTh->ctx.Psr |= THUMB_STATE;
}
#endif
DEBUGMSG(ZONE_SCHEDULE, (L"MDCT: pTh=%8.8lx Pc=%8.8lx Psr=%4.4x GP=%8.8lx Sp=%8.8lx\r\n", pTh, pTh->ctx.Pc, pTh->ctx.Psr, pTh->ctx.R9, pTh->ctx.Sp));
}
// main thread stack: from top, TLS then buf then buf2 then buf2 (ascii) then args then free
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
MDSetupMainThread (
PTHREAD pTh,
LPBYTE pCurSP,
LPVOID lpBase,
LPVOID lpStart,
BOOL kmode,
ulong dwModCnt
)
{
LPDWORD pArgs = ((LPDWORD) pCurSP) - 4; // 4 arguments on stack
PPROCESS pprc = pTh->pOwnerProc;
pTh->ctx.Sp = (ulong)pArgs;
KSTKBOUND(pTh) = pTh->ctx.Sp & ~(PAGE_SIZE-1);
pTh->ctx.R0 = (ulong) lpStart; // arg #0
pTh->ctx.R1 = (ulong) pprc->hProc; // arg #1 - hInstance
pTh->ctx.R2 = dwModCnt; // arg #2
pTh->ctx.R3 = (ulong)pprc->pcmdline; // arg #3 - cmdline
pArgs[0] = (DWORD) hCoreDll; // arg #4
pArgs[1] = pprc->e32.e32_sect14rva; // arg #5
pArgs[2] = pprc->e32.e32_sect14size; // arg #6
pArgs[3] = (DWORD) pprc->BasePtr; // arg #7
pTh->ctx.Lr = 4;
pTh->ctx.Pc = (ULONG)lpBase;
if (kmode || bAllKMode) {
pTh->ctx.Psr = KERNEL_MODE;
KTHRDINFO (pTh) |= UTLS_INKMODE;
} else {
pTh->ctx.Psr = USER_MODE;
KTHRDINFO (pTh) &= ~UTLS_INKMODE;
}
pTh->ctx.Fpscr = 0;
pTh->ctx.FpExc = 0;
memset (pTh->ctx.FpExtra, 0, sizeof (pTh->ctx.FpExtra));
#if defined(THUMBSUPPORT)
if ( (pTh->ctx.Pc & 0x01) != 0 ){
pTh->ctx.Psr |= THUMB_STATE;
}
#endif
DEBUGMSG(ZONE_SCHEDULE, (L"MDCMainT: pTh=%8.8lx Pc=%8.8lx Psr=%4.4x TOC=%8.8lx Sp=%8.8lx\r\n", pTh, pTh->ctx.Pc, pTh->ctx.Psr, pTh->ctx.R9, pTh->ctx.Sp));
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
DoThreadGetContext(
HANDLE hTh,
PCONTEXT lpContext
)
{
PTHREAD pth;
if (!(pth = HandleToThread(hTh))) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -