📄 kdctrl.c
字号:
//
// Set up for a stackwalk of the current thread
//
DEBUGGERMSG(KDZONE_STACKW, (L"++WriteCtrl HANDLE_STACKWALK_REQUEST\r\n"));
if (!fThreadWalk)
{
pStk = pCurThread->pcstkTop;
pLastProc = pCurProc;
pWalkThread = pCurThread;
g_fTopFrame = TRUE;
}
else
{
DEBUGGERMSG(KDZONE_STACKW, (L" WriteCtrl Thread stackwalk in progress - not updating state\r\n"));
}
DEBUGGERMSG(KDZONE_STACKW, (L" WriteCtrl pStk=%8.8lx pLastProc=%8.8lx pWalkThread=%8.8lx\r\n", pStk, pLastProc, pCurThread));
pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS;
DEBUGGERMSG(KDZONE_STACKW, (L"--WriteCtrl HANDLE_STACKWALK_REQUEST\r\n"));
break;
// TODO: Change this to manipulate data directly
case HANDLE_DELETE_HANDLE:
if (AdditionalData->Length < sizeof(HANDLE))
{
pdbgkdCmdPacket->dwReturnStatus = STATUS_BUFFER_TOO_SMALL;
}
else if (KdCloseHandle(*((HANDLE *) AdditionalData->Buffer)))
{
pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS;
}
else
{
pdbgkdCmdPacket->dwReturnStatus = STATUS_UNSUCCESSFUL;
}
break;
default:
break; // Unsuccessful
}
KdpSendKdApiCmdPacket (&MessageHeader, AdditionalData);
DEBUGGERMSG(KDZONE_CTRL, (L"--KdpWriteControlSpace\r\n"));
}
VOID
KdpReadIoSpace (
IN DBGKD_COMMAND *pdbgkdCmdPacket,
IN PSTRING AdditionalData,
IN BOOL fSendPacket
)
/*++
Routine Description:
This function is called in response of a read io space command
message. Its function is to read system io
locations.
Arguments:
pdbgkdCmdPacket - Supplies the state manipulation message.
AdditionalData - Supplies any additional data for the message.
fSendPacket - TRUE send packet to Host, otherwise not
Return Value:
None.
--*/
{
DBGKD_READ_WRITE_IO *a = &pdbgkdCmdPacket->u.ReadWriteIo;
STRING MessageHeader;
#if !defined(x86)
PUCHAR b;
PUSHORT s;
PULONG l;
#endif
MessageHeader.Length = sizeof(*pdbgkdCmdPacket);
MessageHeader.Buffer = (PCHAR)pdbgkdCmdPacket;
KD_ASSERT(AdditionalData->Length == 0);
pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS;
//
// Check Size and Alignment
//
switch ( a->dwDataSize ) {
#if defined (x86) // x86 processor have a separate io mapping
case 1:
a->dwDataValue = _inp( (SHORT) a->qwTgtIoAddress);
break;
case 2:
a->dwDataValue = _inpw ((SHORT) a->qwTgtIoAddress);
break;
case 4:
a->dwDataValue = _inpd ((SHORT) a->qwTgtIoAddress);
break;
#else // all processors other than x86 use the default memory mapped version
case 1:
b = (PUCHAR) (a->qwTgtIoAddress);
if ( b ) {
a->dwDataValue = (ULONG)*b;
} else {
pdbgkdCmdPacket->dwReturnStatus = STATUS_ACCESS_VIOLATION;
}
break;
case 2:
if ((ULONG)a->qwTgtIoAddress & 1 ) {
pdbgkdCmdPacket->dwReturnStatus = STATUS_DATATYPE_MISALIGNMENT;
} else {
s = (PUSHORT) (a->qwTgtIoAddress);
if ( s ) {
a->dwDataValue = (ULONG)*s;
} else {
pdbgkdCmdPacket->dwReturnStatus = STATUS_ACCESS_VIOLATION;
}
}
break;
case 4:
if ((ULONG)a->qwTgtIoAddress & 3 ) {
pdbgkdCmdPacket->dwReturnStatus = STATUS_DATATYPE_MISALIGNMENT;
} else {
l = (PULONG) (a->qwTgtIoAddress);
if ( l ) {
a->dwDataValue = (ULONG)*l;
} else {
pdbgkdCmdPacket->dwReturnStatus = STATUS_ACCESS_VIOLATION;
}
}
break;
#endif
default:
pdbgkdCmdPacket->dwReturnStatus = STATUS_INVALID_PARAMETER;
}
if (fSendPacket)
{
KdpSendKdApiCmdPacket (&MessageHeader, NULL);
}
}
VOID
KdpWriteIoSpace (
IN DBGKD_COMMAND *pdbgkdCmdPacket,
IN PSTRING AdditionalData,
IN BOOL fSendPacket
)
/*++
Routine Description:
This function is called in response of a write io space command
message. Its function is to write to system io
locations.
Arguments:
pdbgkdCmdPacket - Supplies the state manipulation message.
AdditionalData - Supplies any additional data for the message.
fSendPacket - TRUE send packet to Host, otherwise not
Return Value:
None.
--*/
{
DBGKD_READ_WRITE_IO *a = &pdbgkdCmdPacket->u.ReadWriteIo;
STRING MessageHeader;
#if !defined(x86)
PUCHAR b;
PUSHORT s;
PULONG l;
#endif
MessageHeader.Length = sizeof(*pdbgkdCmdPacket);
MessageHeader.Buffer = (PCHAR)pdbgkdCmdPacket;
KD_ASSERT(AdditionalData->Length == 0);
pdbgkdCmdPacket->dwReturnStatus = STATUS_SUCCESS;
//
// Check Size and Alignment
//
switch ( a->dwDataSize ) {
#if defined(x86) // x86 processor have a separate io mapping
case 1:
_outp ((SHORT) a->qwTgtIoAddress, a->dwDataValue);
break;
case 2:
_outpw ((SHORT) a->qwTgtIoAddress, (WORD) a->dwDataValue);
break;
case 4:
_outpd ((SHORT) a->qwTgtIoAddress, (DWORD) a->dwDataValue);
break;
#else // all processors other than x86 use the default memory mapped version
case 1:
b = (PUCHAR) (a->qwTgtIoAddress);
if ( b ) {
WRITE_REGISTER_UCHAR(b,(UCHAR)a->dwDataValue);
} else {
pdbgkdCmdPacket->dwReturnStatus = STATUS_ACCESS_VIOLATION;
}
break;
case 2:
if ((ULONG)a->qwTgtIoAddress & 1 ) {
pdbgkdCmdPacket->dwReturnStatus = STATUS_DATATYPE_MISALIGNMENT;
} else {
s = (PUSHORT) (a->qwTgtIoAddress);
if ( s ) {
WRITE_REGISTER_USHORT(s,(USHORT)a->dwDataValue);
} else {
pdbgkdCmdPacket->dwReturnStatus = STATUS_ACCESS_VIOLATION;
}
}
break;
case 4:
if ((ULONG)a->qwTgtIoAddress & 3 ) {
pdbgkdCmdPacket->dwReturnStatus = STATUS_DATATYPE_MISALIGNMENT;
} else {
l = (PULONG) (a->qwTgtIoAddress);
if ( l ) {
WRITE_REGISTER_ULONG(l,a->dwDataValue);
} else {
pdbgkdCmdPacket->dwReturnStatus = STATUS_ACCESS_VIOLATION;
}
}
break;
#endif
default:
pdbgkdCmdPacket->dwReturnStatus = STATUS_INVALID_PARAMETER;
}
if (fSendPacket)
{
KdpSendKdApiCmdPacket (&MessageHeader, NULL);
}
}
DWORD ReloadAllSymbols(LPBYTE lpBuffer, BOOL fDoCopy)
{
int i;
DWORD dwSize, dwTimeStamp;
PMODULE pMod;
WCHAR *szModName;
DWORD dwBasePtr, dwModuleSize, dwRwDataStart, dwRwDataEnd;
DBGKD_RELOAD_MOD_INFO_BASE rmib;
DBGKD_RELOAD_MOD_INFO_V8 rmi8;
DBGKD_RELOAD_MOD_INFO_V14 rmi14;
DBGKD_RELOAD_MOD_INFO_V15 rmi15;
dwSize = 0;
for (i=0; i < MAX_PROCESSES; i++)
{
if (kdProcArray[i].dwVMBase)
{
szModName = kdProcArray[i].lpszProcName;
dwBasePtr = (DWORD) kdProcArray[i].BasePtr;
if (0 == i)
{ // kernel
dwRwDataStart = ((COPYentry *)(pTOC->ulCopyOffset))->ulDest;
dwRwDataEnd = dwRwDataStart + ((COPYentry *)(pTOC->ulCopyOffset))->ulDestLen - 1;
}
else
{
dwRwDataStart = 0xFFFFFFFF;
dwRwDataEnd = 0x00000000;
}
dwTimeStamp = kdProcArray[i].e32.e32_timestamp;
if (dwBasePtr == 0x10000)
{
dwBasePtr |= kdProcArray[i].dwVMBase;
}
dwModuleSize = kdProcArray[i].e32.e32_vsize;
if (fDoCopy) kdbgWtoA(szModName,lpBuffer+dwSize);
dwSize = dwSize+kdbgwcslen(szModName)+1;
if (fDoCopy)
{
rmib.dwBasePtr = dwBasePtr;
rmib.dwModuleSize = dwModuleSize;
memcpy(lpBuffer + dwSize, &rmib, sizeof(rmib));
}
dwSize += sizeof(rmib);
// Pass Relocated RW Data
if (fDoCopy)
{
rmi8.dwRwDataStart = dwRwDataStart;
rmi8.dwRwDataEnd = dwRwDataEnd;
memcpy(lpBuffer + dwSize, &rmi8, sizeof(rmi8));
}
dwSize += sizeof(rmi8);
// Pass file time stamp data (Used for PDB matching)
if (fDoCopy)
{
rmi14.dwTimeStamp = dwTimeStamp;
memcpy(lpBuffer + dwSize, &rmi14, sizeof(rmi14));
}
dwSize += sizeof(rmi14);
if (fDoCopy)
{
rmi15.hDll = NULL; // not valid for processes
rmi15.dwInUse = 1 << kdProcArray[i].procnum;
rmi15.wFlags = 0;
rmi15.bTrustLevel = kdProcArray[i].bTrustLevel;
memcpy(lpBuffer + dwSize, &rmi15, sizeof(rmi15));
}
dwSize += sizeof(rmi15);
}
}
pMod = pModList;
while(pMod)
{
szModName = pMod->lpszModName;
dwBasePtr = ZeroPtr(pMod->BasePtr);
dwModuleSize = pMod->e32.e32_vsize;
dwRwDataStart = pMod->rwLow;
dwRwDataEnd = pMod->rwHigh;
dwTimeStamp = pMod->e32.e32_timestamp;
if (fDoCopy) kdbgWtoA(szModName, lpBuffer+dwSize);
dwSize = dwSize+kdbgwcslen(szModName)+1;
if (fDoCopy)
{
rmib.dwBasePtr = dwBasePtr;
rmib.dwModuleSize = dwModuleSize;
memcpy(lpBuffer + dwSize, &rmib, sizeof(rmib));
}
dwSize += sizeof(rmib);
// Pass Relocated RW Data
if (fDoCopy)
{
rmi8.dwRwDataStart = dwRwDataStart;
rmi8.dwRwDataEnd = dwRwDataEnd;
memcpy(lpBuffer + dwSize, &rmi8, sizeof(rmi8));
}
dwSize += sizeof(rmi8);
// Pass file time stamp data (Used for PDB matching)
if (fDoCopy)
{
rmi14.dwTimeStamp = dwTimeStamp;
memcpy(lpBuffer + dwSize, &rmi14, sizeof(rmi14));
}
dwSize += sizeof(rmi14);
if (fDoCopy)
{
rmi15.hDll = (HMODULE) pMod;
rmi15.dwInUse = pMod->inuse;
rmi15.wFlags = pMod->wFlags;
rmi15.bTrustLevel = pMod->bTrustLevel;
memcpy(lpBuffer + dwSize, &rmi15, sizeof(rmi15));
}
dwSize += sizeof(rmi15);
pMod=pMod->pMod;
}
if (!fDoCopy)
{
memcpy( lpBuffer, &dwSize, sizeof(DWORD));
}
return dwSize;
}
/*++
Routine Name:
GetModuleRefCount
Routine Description:
This routine is used to process the HANDLE_MODULE_REFCOUNT_REQUEST
command. It returns the reference count for the DLL requested as well
as process handle information. The latter is required to determine
which reference count entries are valid. (If the process entry is not
in use, it will be NULL.)
Arguments:
hDll - [in] Handle to requested DLL (ptr to Module structure)
pBuffer - [out] Pointer to packet buffer
pnLength - [out] Pointer to length of packet data returned
Return Value:
Error status:
STATUS_SUCCESS Success
STATUS_INVALID_PARAMETER hDll is not a valid handle
--*/
static NTSTATUS GetModuleRefCount(HMODULE hDll, LPVOID pBuffer, USHORT *pnLength)
{
DBGKD_GET_MODULE_REFCNT *pGMRC = (DBGKD_GET_MODULE_REFCNT *) pBuffer;
DBGKD_GET_MODULE_REFCNT_PROC *pGMRP;
PMODULE pMod;
NTSTATUS status;
UINT i, j, nProcs;
*pnLength = 0;
/* Verify valid module */
pMod = pModList;
while(pMod != (PMODULE) hDll && pMod != NULL)
pMod = pMod->pMod;
if (pMod == NULL)
{
status = STATUS_INVALID_PARAMETER;
goto Error;
}
nProcs = 0;
for(i = 0; i < MAX_PROCESSES; i++)
{
/* If process slot is valid... */
if (kdProcArray[i].dwVMBase != 0)
{
pGMRP = &pGMRC->pGMRCP[nProcs++];
pGMRP->wRefCount = pMod->refcnt[i];
/* We don't have strncpy in KdStub. */
j = 0;
do
{
pGMRP->szProcName[j] = kdProcArray[i].lpszProcName[j];
}
while(j < lengthof(pGMRP->szProcName) &&
kdProcArray[i].lpszProcName[j++] != L'\0');
}
}
pGMRC->nProcs = nProcs;
*pnLength = (USHORT) offsetof(DBGKD_GET_MODULE_REFCNT, pGMRCP[nProcs]);
return STATUS_SUCCESS;
Error:
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -