/*** kdutil.c - KD Extension Utility Functions * * This module contains KD Extension Utility Functions. * * Copyright (c) 1999 Microsoft Corporation * Author: Michael Tsang (MikeTs) * Created 06/22/99 * * MODIFICATION HISTORY */ #include "pch.h" /***EP MemZero - Fill target buffer with zeros * * ENTRY * uipAddr - target buffer address * dwSize - target buffer size * * EXIT * None */ VOID MemZero(ULONG_PTR uipAddr, ULONG dwSize) { PUCHAR pbBuff; // // LPTR will zero init the buffer // if ((pbBuff = LocalAlloc(LPTR, dwSize)) != NULL) { if (!WriteMemory(uipAddr, pbBuff, dwSize, NULL)) { DBG_ERROR(("MemZero: failed to write memory")); } LocalFree(pbBuff); } else { DBG_ERROR(("MemZero: failed to allocate buffer")); } } //MemZero /***EP ReadMemByte - Read a byte from target address * * ENTRY * uipAddr - target address * * EXIT * None */ BYTE ReadMemByte(ULONG_PTR uipAddr) { BYTE bData = 0; if (!ReadMemory(uipAddr, &bData, sizeof(bData), NULL)) { DBG_ERROR(("ReadMemByte: failed to read address %x", uipAddr)); } return bData; } //ReadMemByte /***EP ReadMemWord - Read a word from target address * * ENTRY * uipAddr - target address * * EXIT * None */ WORD ReadMemWord(ULONG_PTR uipAddr) { WORD wData = 0; if (!ReadMemory(uipAddr, &wData, sizeof(wData), NULL)) { DBG_ERROR(("ReadMemWord: failed to read address %x", uipAddr)); } return wData; } //ReadMemWord /***EP ReadMemDWord - Read a dword from target address * * ENTRY * uipAddr - target address * * EXIT * None */ DWORD ReadMemDWord(ULONG_PTR uipAddr) { DWORD dwData = 0; if (!ReadMemory(uipAddr, &dwData, sizeof(dwData), NULL)) { DBG_ERROR(("ReadMemDWord: failed to read address %x", uipAddr)); } return dwData; } //ReadMemDWord /***EP ReadMemUlongPtr - Read a ulong ptr from target address * * ENTRY * uipAddr - target address * * EXIT * None */ ULONG_PTR ReadMemUlongPtr(ULONG_PTR uipAddr) { ULONG_PTR uipData = 0; if (!ReadMemory(uipAddr, &uipData, sizeof(uipData), NULL)) { DBG_ERROR(("ReadMemUlongPtr: failed to read address %x", uipAddr)); } return uipData; } //ReadMemUlongPtr /***LP GetObjBuff - Allocate and read object buffer * * ENTRY * pdata -> object data * * EXIT * return the allocated object buffer pointer */ PVOID LOCAL GetObjBuff(POBJDATA pdata) { PVOID pbuff; if ((pbuff = LocalAlloc(LPTR, pdata->dwDataLen)) == NULL) { DBG_ERROR(("failed to allocate object buffer (size=%d)", pdata->dwDataLen)); } else if (!ReadMemory((ULONG_PTR)pdata->pbDataBuff, pbuff, pdata->dwDataLen, NULL)) { DBG_ERROR(("failed to read object buffer at %x", pdata->pbDataBuff)); LocalFree(pbuff); pbuff = NULL; } return pbuff; } //GetObjBuff /***LP GetNSObj - Find a name space object * * ENTRY * pszObjPath -> object path string * pnsScope - object scope to start the search (NULL means root) * puipns -> to hold the pnsobj address if found * pns -> buffer to hold the object found * dwfNS - flags * * EXIT-SUCCESS * returns DBGERR_NONE * EXIT-FAILURE * returns DBGERR_ code */ LONG LOCAL GetNSObj(PSZ pszObjPath, PNSOBJ pnsScope, PULONG_PTR puipns, PNSOBJ pns, ULONG dwfNS) { LONG rc = DBGERR_NONE; BOOLEAN fSearchUp = (BOOLEAN)(!(dwfNS & NSF_LOCAL_SCOPE) && (pszObjPath[0] != '\\') && (pszObjPath[0] != '^') && (STRLEN(pszObjPath) <= sizeof(NAMESEG))); BOOLEAN fMatch = TRUE; PSZ psz; NSOBJ NSObj, NSChildObj; if (*pszObjPath == '\\') { psz = &pszObjPath[1]; pnsScope = NULL; } else { for (psz = pszObjPath; (*psz == '^') && (pnsScope != NULL) && (pnsScope->pnsParent != NULL); psz++) { if (!ReadMemory((ULONG_PTR)pnsScope->pnsParent, &NSObj, sizeof(NSObj), NULL)) { DBG_ERROR(("failed to read parent object at %x", pnsScope->pnsParent)); rc = DBGERR_CMD_FAILED; break; } else { pnsScope = &NSObj; } } if ((rc == DBGERR_NONE) && (*psz == '^')) { if (dwfNS & NSF_WARN_NOTFOUND) { DBG_ERROR(("object %s not found", pszObjPath)); } rc = DBGERR_CMD_FAILED; } } if ((rc == DBGERR_NONE) && (pnsScope == NULL)) { if ((*puipns = READSYMULONGPTR("gpnsNameSpaceRoot")) == 0) { DBG_ERROR(("failed to get root object address")); rc = DBGERR_CMD_FAILED; } else if (!ReadMemory(*puipns, &NSObj, sizeof(NSObj), NULL)) { DBG_ERROR(("failed to read NameSpace root object at %x", *puipns)); rc = DBGERR_CMD_FAILED; } else { pnsScope = &NSObj; } } while ((rc == DBGERR_NONE) && (*psz != '\0')) { if (pnsScope->pnsFirstChild == NULL) { fMatch = FALSE; } else { PSZ pszEnd = STRCHR(psz, '.'); ULONG dwLen = (ULONG)(pszEnd? (pszEnd - psz): STRLEN(psz)); if (dwLen > sizeof(NAMESEG)) { DBG_ERROR(("invalid name path %s", pszObjPath)); rc = DBGERR_CMD_FAILED; } else { NAMESEG dwName = NAMESEG_BLANK; BOOLEAN fFound = FALSE; ULONG_PTR uip; ULONG_PTR uipFirstChild = (ULONG_PTR)pnsScope->pnsFirstChild; MEMCPY(&dwName, psz, dwLen); // // Search all siblings for a matching NameSeg. // for (uip = uipFirstChild; (uip != 0) && ReadMemory(uip, &NSChildObj, sizeof(NSObj), NULL); uip = ((ULONG_PTR)NSChildObj.list.plistNext == uipFirstChild)? 0: (ULONG_PTR)NSChildObj.list.plistNext) { if (NSChildObj.dwNameSeg == dwName) { *puipns = uip; fFound = TRUE; NSObj = NSChildObj; pnsScope = &NSObj; break; } } if (fFound) { psz += dwLen; if (*psz == '.') { psz++; } } else { fMatch = FALSE; } } } if ((rc == DBGERR_NONE) && !fMatch) { if (fSearchUp && (pnsScope->pnsParent != NULL)) { if (!ReadMemory((ULONG_PTR)pnsScope->pnsParent, &NSObj, sizeof(NSObj), NULL)) { DBG_ERROR(("failed to read parent object at %x", pnsScope->pnsParent)); rc = DBGERR_CMD_FAILED; } else { fMatch = TRUE; pnsScope = &NSObj; } } else { if (dwfNS & NSF_WARN_NOTFOUND) { DBG_ERROR(("object %s not found", pszObjPath)); } rc = DBGERR_CMD_FAILED; } } } if (rc != DBGERR_NONE) { *puipns = 0; } else if (pns != NULL) { MEMCPY(pns, pnsScope, sizeof(NSObj)); } return rc; } //GetNSObj /***LP ParsePackageLen - parse package length * * ENTRY * ppbOp -> instruction pointer * ppbOpNext -> to hold pointer to next instruction (can be NULL) * * EXIT * returns package length */ ULONG LOCAL ParsePackageLen(PUCHAR *ppbOp, PUCHAR *ppbOpNext) { ULONG dwLen; UCHAR bFollowCnt, i; if (ppbOpNext != NULL) *ppbOpNext = *ppbOp; dwLen = (ULONG)(**ppbOp); (*ppbOp)++; bFollowCnt = (UCHAR)((dwLen & 0xc0) >> 6); if (bFollowCnt != 0) { dwLen &= 0x0000000f; for (i = 0; i < bFollowCnt; ++i) { dwLen |= (ULONG)(**ppbOp) << (i*8 + 4); (*ppbOp)++; } } if (ppbOpNext != NULL) *ppbOpNext += dwLen; return dwLen; } //ParsePackageLen /***LP NameSegString - convert a NameSeg to an ASCIIZ stri * * ENTRY * dwNameSeg - NameSeg * * EXIT * returns string */ PSZ LOCAL NameSegString(ULONG dwNameSeg) { static char szNameSeg[sizeof(NAMESEG) + 1] = {0}; STRCPYN(szNameSeg, (PSZ)&dwNameSeg, sizeof(NAMESEG)); return szNameSeg; } //NameSegString