📄 kwin32.c
字号:
#elif !defined(SH3e)
extern void DSPFlushContext(void);
#if defined(SH3)
extern unsigned int SH3DSP;
#endif
#endif
#elif MIPS
extern void MD_CBRtn(void);
#if defined(MIPS_HAS_FPU)
extern void FPUFlushContext(void);
#endif
#elif ARM
extern void MD_CBRtn(void);
extern void DetectVFP(void);
extern void FPUFlushContext(void);
extern DWORD vfpStat;
#elif x86
extern BOOL (* __abnormal_termination)(VOID);
extern void FPUFlushContext(void);
extern DWORD MD_CBRtn;
extern PTHREAD g_CurFPUOwner;
#endif
BOOL ReadyForStrings;
PPROCESS PowerProc;
FARPROC PowerFunc;
ACCESSKEY PowerKey;
PPROCESS GwesPowerProc;
FARPROC GwesPowerFunc;
ACCESSKEY GwesPowerKey;
extern void MemTrackInit(void);
void (* lpWriteDebugStringFunc)(unsigned short *str) = OEMWriteDebugString;
int (* lpReadDebugByteFunc)(void) = OEMReadDebugByte;
void (* lpWriteDebugByteFunc)(BYTE ch) = OEMWriteDebugByte;
// Ethernet debug functions, pointers set only if platform supports ether debug.
PFN_KITLRegisterDfltClient pKITLRegisterDfltClient;
PFN_KITLInitializeInterrupt pKITLInitializeInterrupt;
PFN_KITLSend pKITLSend;
PFN_KITLRecv pKITLRecv;
DWORD (* pKITLIoCtl) (DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize, LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned);
BOOL fSysStarted;
BOOL (*pfnIsDesktopDbgrExist) ();
//------------------------------------------------------------------------------
// Placeholder for when debugger is not present
//------------------------------------------------------------------------------
static BOOL
FakeKDSanitize(
BYTE* pbClean,
VOID* pvMem,
ULONG nSize,
BOOL fAlwaysCopy
)
{
if (fAlwaysCopy) memcpy(pbClean, pvMem, nSize);
return FALSE;
}
//------------------------------------------------------------------------------
// Placeholder for when debugger is not present
//------------------------------------------------------------------------------
static void
FakeKDReboot(
BOOL fReboot
)
{
return;
}
/* Kernel Debugger interface pointers */
BOOL (*g_pKdInit)(KERNDATA* pKernData) = NULL;
BOOL (*KDSanitize)(BYTE* pbClean, VOID* pvAddrMem, ULONG nSize, BOOL fAlwaysCopy) = FakeKDSanitize;
VOID (*KDReboot)(BOOL fReboot) = FakeKDReboot;
//------------------------------------------------------------------------------
// This function is called when kdstub gets Terminate Message from the debugger
// It simply reverts back KDSanitize and KDReboot function
// pointers to FAKE functions.
//------------------------------------------------------------------------------
BOOL
KDCleanup(void)
{
g_pKdInit = NULL;
KDSanitize = FakeKDSanitize;
KDReboot = FakeKDReboot;
fDebuggerLoaded = FALSE;
return TRUE;
}
//------------------------------------------------------------------------------
// HwTrap - This was HdstubNotify. Added here to give OsAccess capability to set
// HW breakpoint before the kernel is booted into memory.
//------------------------------------------------------------------------------
int g_iHwTrapCount=0;
void HwTrap (void)
{
DebugBreak ();
g_iHwTrapCount++; // This make this function unique enough to prevent ICF optimization (with DoDebugBreak())
}
void FakeNKHaltSystem (void)
{
OutputDebugStringW (_T("Halting system\r\n"));
for (;;)
;
}
void (*lpNKHaltSystem)(void) = FakeNKHaltSystem;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// RestorePrio & KDEnableInt are used by KD to boost thread priority and
// enable and disable interrupts
int g_cInterruptsOff = 0;
static void RestorePrio (SAVED_THREAD_STATE *psvdThread)
{
// doesn't do KCall profiling here since this is part
// of the debugger
if (!psvdThread) return;
if (!psvdThread->fSaved)
{
DEBUGMSG (1, (L"Calling KDEnableInt(TRUE, ...) with invalid psvdThread!!!\r\n"));
return;
}
pCurThread->dwQuantum = psvdThread->dwQuantum;
psvdThread->fSaved = FALSE;
SetThreadBasePrio (hCurThread, psvdThread->bBPrio);
}
static void KDEnableInt (BOOL fEnable, SAVED_THREAD_STATE *psvdThread)
{
if (!pCurThread)
{
DEBUGMSG (1, (L"KDEnableInt with pCurThread == 0!!!\r\n"));
return;
}
if (fEnable)
{
if (psvdThread)
{
if (g_cInterruptsOff < 1)
{
DEBUGMSG (1, (L"Calling KDEnableInt(TRUE, ...) without first calling KDEnableInt(FALSE, ...)!!!\r\n"));
}
else
{
--g_cInterruptsOff;
}
KCall ((FARPROC) RestorePrio, psvdThread);
}
INTERRUPTS_ENABLE(TRUE); // KCall should turn interrupts on for us, this may not be necessary
}
else
{
if (psvdThread)
{
INTERRUPTS_ENABLE(FALSE); // Do not use INTERRUPTS_OFF, it will cause problems with MIPIV FP registers
if (g_cInterruptsOff)
{
DEBUGMSG (1, (L"Recursively calling KDEnableInt(FALSE, psvdThread != NULL) %i time(s). This OK if KdStub stumbling on its own BP.\r\n", g_cInterruptsOff));
}
psvdThread->bCPrio = (BYTE)GET_CPRIO (pCurThread);
psvdThread->bBPrio = (BYTE)GET_BPRIO (pCurThread);
psvdThread->dwQuantum = pCurThread->dwQuantum;
psvdThread->fSaved = TRUE;
pCurThread->dwQuantum = 0;
SET_CPRIO (pCurThread, 0);
SET_BPRIO (pCurThread, 0);
++g_cInterruptsOff;
} else {
if (!g_cInterruptsOff) {
DEBUGMSG (1, (L"Calling KDEnableInt (FALSE, NULL) without previously calling KDEnableInt (FALSE, p)\r\n"));;
} else {
INTERRUPTS_ENABLE(FALSE); // Do not use INTERRUPTS_OFF, it will cause problems with MIPIV FP registers
}
}
//INTERRUPTS_ON(); // un-comment this line if we want KD running with interrupt on
}
}
void kdpInvalidateRange ( PVOID pvAddr, ULONG ulSize)
{
InvalidateRange (pvAddr, ulSize);
}
extern BOOL (*pfnOEMIsRom) (LPVOID pvAddr, DWORD cbSize);
BOOL kdpIsROM (LPVOID pvAddr, DWORD cbSize)
{
BOOL fRet = FALSE;
if (IsKernelVa (pvAddr))
{
fRet = pfnOEMIsRom (pvAddr, cbSize);
}
return fRet;
}
extern BOOL g_fForcedPaging;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
SC_ConnectDebugger(
LPVOID pInit // ignored
)
{
BOOL fRet;
KERNDATA kd =
{
sizeof(KERNDATA),
// OUT params (pass default values, so that Kd can ignore partially some of them)
KDSanitize,
KDReboot,
// IN params
pTOC,
ROMChain,
ProcArray,
(HDATA *) &HandleList,
&KData,
&VAcs,
&NullSection,
&NKSection,
&hCoreDll,
KDCleanup,
KDEnableInt,
&pCaptureDumpFileOnDevice,
pfnIsDesktopDbgrExist,
NKwvsprintfW,
NKDbgPrintfW,
KCall,
DbgVerify,
kdpInvalidateRange,
DoVirtualCopy,
kdpIsROM,
DBG_CallCheck,
NULL, // MD_CBRtn
INTERRUPTS_OFF,
INTERRUPTS_ENABLE,
pKDIoControl,
pKITLIoCtl,
GetObjectPtrByType,
InitializeCriticalSection,
DeleteCriticalSection,
EnterCriticalSection,
LeaveCriticalSection,
SC_CloseHandle,
SC_VirtualFree,
FALSE, // fFPUPresent
FALSE, // fDSPPresent
&g_fForcedPaging,
SC_CacheRangeFlush,
&g_ulHDEventFilter,
HwTrap,
// ...
};
TRUSTED_API (L"SC_ConnectDebugger", FALSE);
DEBUGMSG(ZONE_DEBUGGER, (TEXT("Entering ConnectDebugger\r\n")));
#ifdef SHx
kd.pMD_CBRtn = MD_CBRtn;
kd.p__C_specific_handler = __C_specific_handler;
#if defined(SH4)
kd.FPUFlushContext = FPUFlushContext;
kd.fFPUPresent = TRUE;
#elif !defined(SH3e)
kd.DSPFlushContext = DSPFlushContext;
#if defined(SH3)
kd.fDSPPresent = (1 == SH3DSP);
#endif
#endif
#elif MIPS
kd.pInterlockedDecrement = InterlockedDecrement;
kd.pInterlockedIncrement = InterlockedIncrement;
kd.pMD_CBRtn = MD_CBRtn;
kd.p__C_specific_handler = __C_specific_handler;
#if defined(MIPS_HAS_FPU)
kd.FPUFlushContext = FPUFlushContext;
kd.fFPUPresent = TRUE;
#endif
#elif ARM
kd.pMD_CBRtn = MD_CBRtn;
kd.p__C_specific_handler = __C_specific_handler;
kd.pInSysCall = InSysCall;
kd.FPUFlushContext = FPUFlushContext;
kd.fFPUPresent = (1 == vfpStat);
#elif x86
kd.p__abnormal_termination = __abnormal_termination;
kd.p_except_handler3 = _except_handler3;
kd.FPUFlushContext = FPUFlushContext;
kd.pMD_CBRtn = (VOID (*)(VOID))&MD_CBRtn;
kd.ppCurFPUOwner = &g_CurFPUOwner;
kd.pdwProcessorFeatures = &ProcessorFeatures;
kd.fFPUPresent = TRUE;
#else
#pragma message("ERROR: ConnectDebugger is not supported on this CPU!")
ERRORMSG(1, (TEXT("ConnectDebugger is not supported on this CPU!\r\n")));
return FALSE;
#endif
if (!fDebuggerLoaded)
{
CALLSTACK *pcstk = NULL, cstk;
if (ProcArray != pCurProc) {
SwitchToKernel (pcstk = &cstk);
}
EnterCriticalSection (&LLcs);
if (fRet = (!fNoDebugger && g_pKdInit && HDConnectClient &&
HDConnectClient ((HDSTUB_CLINIT_FUNC)g_pKdInit, &kd)))
{
KDSanitize = kd.pKdSanitize;
KDReboot = kd.pKdReboot;
HDModLoad ((DWORD)&ProcArray[0]);
ReadyForStrings = TRUE;
fDebuggerLoaded = TRUE;
} else {
ERRORMSG(1, (TEXT("ConnectDebugger failed\r\n")));
}
LeaveCriticalSection(&LLcs);
if (pcstk) {
SwitchBack ();
}
}
else
{
DEBUGMSG(ZONE_DEBUGGER, (TEXT(" Nk!SC_ConnectDebugger: Debugger is already connected, ignoring connect request.\r\n")));
fRet = TRUE;
}
return fRet;
}
//------------------------------------------------------------------------------
// HDStub Fake interface (Runs when hd.dll is not loaded.)
//------------------------------------------------------------------------------
ULONG
FakeHDException(
PEXCEPTION_RECORD ExceptionRecord,
CONTEXT *ContextRecord,
BOOLEAN SecondChance
)
{
return FALSE;
}
static void FakeHDPageIn (DWORD dw, BOOL f)
{
}
static void FakeHDModLoad (DWORD dw)
{
}
static void FakeHDModUnload (DWORD dw)
{
}
//------------------------------------------------------------------------------
// HDStub interface
//------------------------------------------------------------------------------
static BOOL s_fHdConnected = FALSE;
BOOL (*g_pHdInit) (HDSTUB_INIT *) = NULL;
ULONG (*HDException) (EXCEPTION_RECORD *, CONTEXT *, BOOLEAN) = FakeHDException;
void (*HDPageIn) (DWORD, BOOL) = FakeHDPageIn;
void (*HDModLoad) (DWORD) = FakeHDModLoad;
void (*HDModUnload) (DWORD) = FakeHDModUnload;
void *pvHDNotifyExdi = (void *)HwTrap;
DWORD *pdwHDTaintedModuleCount = NULL;
BOOL (*HDConnectClient) (HDSTUB_CLINIT_FUNC, void *) = NULL;
HDSTUB_EVENT *g_pHdEvent = NULL;
// Hardware event filter.
ULONG g_ulHDEventFilter = 0;
//------------------------------------------------------------------------------
// OsAccess synchronization block - Aligned on a 64byte boundary. Makes it easier
// to find.
//------------------------------------------------------------------------------
_declspec(align(64)) OSAXS_KERN_POINTERS_2 OsAxsDataBlock_2 =
{
SIGNATURE_OSAXS_KERN_POINTERS_2,
sizeof (OsAxsDataBlock_2),
(DWORD)&KData,
(DWORD)&ProcArray[0],
(DWORD)&pvHDNotifyExdi,
(DWORD)&g_pHdEvent,
(DWORD)&pdwHDTaintedModuleCount,
(DWORD)&g_ulHDEventFilter,
(DWORD)&MD_CBRtn, // Needs to be dereferenced manually
(DWORD)&SystemAPISets[0],
(DWORD)&MemoryInfo,
(DWORD)&pTOC,
FALSE
};
// Compatibility with older versions of PB
_declspec(align(64)) OSAXS_KERN_POINTERS_1 OsAxsDataBlock =
{
SIGNATURE_OSAXS_KERN_POINTERS,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -