//======================================================
// DiscoverBytePointerPosInModules Function
Definition.
//======================================================
static VOID ExamineUserModule( IN
VAD* pvadMatchingNode, IN BYTE* pbBytePointer, IN BOOLEAN bTouchPages, IN ULONG
ulSizeOfSzImageName, OUT VOID** P_pvMatchingModuleStart, OUT ULONG*
P_ulMatchingModuleLength, OUT IMAGE_NT_HEADERS** P_pinhMatchingModuleNtHeaders,
OUT CHAR* P_szImageName )
{
DWORD dwImageBase;
IMAGE_DOS_HEADER* pidhDosHdr;
IMAGE_NT_HEADERS* pinhNtHdrs;
DWORD* pdwDwordPtr;
WORD* pwImageNameLengthPtr;
WORD wImageNameLength;
DWORD* pdwImageNameUnicodePtrPtr;
WORD* pwImageNameUnicodePtr;
WORD* pwWordPtr;
CHAR* pcCharPtr;
ULONG ulI;
//
Check the Flags of the Matching Node.
if
( ( pvadMatchingNode->dwFlags & 0x80000000 ) == 0 &&
( pvadMatchingNode->dwFlags & 0x00100000 ) )
{
dwImageBase = ( (DWORD) pvadMatchingNode->pvStartingAddress
) << 12;
// Check the DOS Header.
pidhDosHdr = (IMAGE_DOS_HEADER*) dwImageBase;
if (
IsPagePresentAndTouch_BYTERANGE( (BYTE*) pidhDosHdr, sizeof(
IMAGE_DOS_HEADER ), bTouchPages ) )
{
if ( pidhDosHdr->e_magic ==
IMAGE_DOS_SIGNATURE &&
pidhDosHdr->e_lfarlc
>= 0x40 )
{
// Check the NT Headers.
pinhNtHdrs =
(IMAGE_NT_HEADERS*) ( dwImageBase + pidhDosHdr->e_lfanew );
if ( IsPagePresentAndTouch_BYTERANGE( (BYTE*)
pinhNtHdrs, sizeof( IMAGE_NT_HEADERS ),
bTouchPages ) )
{
if ( pinhNtHdrs->Signature == IMAGE_NT_SIGNATURE )
{
if (
pbBytePointer == NULL ||
((DWORD)pbBytePointer) <= dwImageBase +
pinhNtHdrs->OptionalHeader.SizeOfImage - 1 )
{
// Setup the
Variables required later.
* P_pvMatchingModuleStart = (VOID*)
dwImageBase;
* P_ulMatchingModuleLength =
pinhNtHdrs->OptionalHeader.SizeOfImage;
* P_pinhMatchingModuleNtHeaders =
pinhNtHdrs;
// Get the Full
Name of the Specified Module.
if (
pvadMatchingNode->dwUndocumented_DWORD )
{
pdwDwordPtr
= (DWORD*) ( pvadMatchingNode->dwUndocumented_DWORD +
MACRO_VADTREE_UNDOCUMENTED_DISP_0 );
if ( IsPagePresentAndTouch_DWORD( pdwDwordPtr,
bTouchPages ) )
{
pwImageNameLengthPtr
= (WORD*) ( *pdwDwordPtr + MACRO_VADTREE_UNDOCUMENTED_DISP_1 );
// Get the Full Name of the Module.
if ( IsPagePresentAndTouch_WORD(
pwImageNameLengthPtr, bTouchPages ) )
{
wImageNameLength = * pwImageNameLengthPtr
/ sizeof( WORD );
if (
wImageNameLength != 0 &&
wImageNameLength <= ulSizeOfSzImageName
- 1 )
{
pdwImageNameUnicodePtrPtr = (DWORD*) (
*pdwDwordPtr +
MACRO_VADTREE_UNDOCUMENTED_DISP_1
+ FIELD_OFFSET( UNICODE_STRING, Buffer ) );
if (
IsPagePresentAndTouch_DWORD( pdwImageNameUnicodePtrPtr, bTouchPages ) )
{
pwImageNameUnicodePtr
= (WORD*) * pdwImageNameUnicodePtrPtr;
if ( pwImageNameUnicodePtr != NULL &&
IsPagePresentAndTouch(
pwImageNameUnicodePtr, bTouchPages ) &&
IsPagePresentAndTouch_WORD(
pwImageNameUnicodePtr + wImageNameLength - 1, bTouchPages ) )
{
pwWordPtr
= pwImageNameUnicodePtr;
pcCharPtr
= P_szImageName;
for ( ulI = 0; ulI < wImageNameLength; ulI ++ )
* pcCharPtr ++ = (CHAR) ( ( * pwWordPtr ++
) & 0xFF );
*
pcCharPtr = '\0';
}
}
}
}
}
}
}
}
}
}
}
}
//
Return to the Caller.
return;
}
typedef struct
_VADTREEWALKFN_PARAMS
{
/*IN*/
BYTE* pbBytePointer;
/*IN*/
BOOLEAN bTouchPages;
/*IN*/
PFNUSERMODULESNAMELISTENUM pfnUserModListCallBack;
/*IN*/
BOOLEAN* pbExitNOW;
/*IN*/
DWORD dwUserModListCallBackPARAM;
} VADTREEWALKFN_PARAMS, *PVADTREEWALKFN_PARAMS;
static BOOLEAN
InvokeUserModListCallBack( OUT VAD** ppvRetVal, IN VAD* pvadNode, IN
VADTREEWALKFN_PARAMS* ppParams )
{
CHAR szImageName[ 256 ] = "";
VOID* pvMatchingModuleStart = NULL;
ULONG ulMatchingModuleLength = 0;
IMAGE_NT_HEADERS* pinhMatchingModuleNtHeaders = NULL;
//
Invoke the Callback Function.
ExamineUserModule( pvadNode,
NULL, ppParams->bTouchPages, sizeof(
szImageName ),
& pvMatchingModuleStart, & ulMatchingModuleLength,
& pinhMatchingModuleNtHeaders, szImageName );
if
( strlen( szImageName ) && pvMatchingModuleStart &&
ulMatchingModuleLength && pinhMatchingModuleNtHeaders )
if (
ppParams->pfnUserModListCallBack( szImageName, pvMatchingModuleStart,
ulMatchingModuleLength, pinhMatchingModuleNtHeaders,
ppParams->dwUserModListCallBackPARAM ) == FALSE )
{
* ppParams->pbExitNOW = TRUE;
* ppvRetVal = NULL;
return TRUE;
}
return
FALSE;
}
static VAD* VadTreeWalk( IN VAD*
pvadNode, IN VADTREEWALKFN_PARAMS* ppParams )
{
VAD* pvadTemp;
DWORD dwStart, dwEnd;
//
Check this Node.
if
( pvadNode == NULL ||
IsPagePresentAndTouch_BYTERANGE( (BYTE*) pvadNode, sizeof( VAD ), ppParams->bTouchPages ) == FALSE )
return NULL;
pvadTemp = VadTreeWalk(
pvadNode->pvadLeftLink, ppParams );
if
( pvadTemp )
return pvadTemp;
dwStart = ( (DWORD)
pvadNode->pvStartingAddress ) << 12;
dwEnd = ( ( ( (DWORD)
pvadNode->pvEndingAddress ) + 1 ) << 12 ) - 1;
if
( ppParams->pbBytePointer &&
( (DWORD) ppParams->pbBytePointer ) >= dwStart &&
( (DWORD) ppParams->pbBytePointer ) <= dwEnd )
{
return pvadNode;
}
else
if( ppParams->pfnUserModListCallBack )
{
if ( * ppParams->pbExitNOW )
return NULL;
if ( InvokeUserModListCallBack(
& pvadTemp, pvadNode, ppParams ) )
return pvadTemp;
}
pvadTemp = VadTreeWalk(
pvadNode->pvadRightLink, ppParams );
if
( pvadTemp )
return pvadTemp;
return
NULL;
}
VOID DiscoverBytePointerPosInModules( OUT CHAR* pszOutputBuffer, IN
BYTE* pbBytePointer, IN VOID* pvNtoskrnlDriverSection, IN VOID*
pvMmUserProbeAddress, IN VOID* pvPCRAddress, IN OUT DISCVBPTR_ADDPARAMS*
pdbpAddParams )
{
VOID* pvMatchingModuleStart;
ULONG ulMatchingModuleLength;
IMAGE_NT_HEADERS* pinhMatchingModuleNtHeaders;
WORD* pwImageNameLengthPtr;
WORD wImageNameLength;
WORD* pwWordPtr;
CHAR* pcCharPtr;
ULONG ulI;
WORD* pwImageNameUnicodePtr;
DWORD* pdwImageNameUnicodePtrPtr;
DWORD dwImageBase;
IMAGE_DOS_HEADER* pidhDosHdr;
IMAGE_NT_HEADERS* pinhNtHdrs;
BOOLEAN bTouchPages = FALSE;
CHAR szSectionName[ 64 ];
CHAR szImageName[ 256 ];
BOOLEAN bVadWalkExit;
VADTREEWALKFN_PARAMS vtwfpWalkParams;
if
( pdbpAddParams && pdbpAddParams->bTouchPages )
bTouchPages = TRUE;
if
( pszOutputBuffer )
strcpy( pszOutputBuffer, ""
);
if
( pdbpAddParams )
{
pdbpAddParams->bIsBytePointerAtTheBeginning = FALSE;
}
//
Check whether the Pointer refers to User Memory or Kernel Memory.
pvMatchingModuleStart = NULL;
ulMatchingModuleLength = 0;
pinhMatchingModuleNtHeaders =
NULL;
strcpy( szImageName, "" );
if
( (DWORD) pbBytePointer < (DWORD) pvMmUserProbeAddress )
{
BYTE* pbPcr
= (BYTE*) pvPCRAddress;
BYTE* pbKteb;
BYTE* pbKpeb;
VAD* pvadVadRoot;
VAD* pvadMatchingNode;
DWORD dwDword;
//
// USER SPACE.
//
// Get the Root Address of the VAT.
pbKteb = (BYTE*) ( * (DWORD*) ( pbPcr +
MACRO_KTEBPTR_FIELDOFFSET_IN_PCR ) );
if ( pbKteb )
{
if ( pdbpAddParams &&
pdbpAddParams->pbKpeb )
pbKpeb =
pdbpAddParams->pbKpeb;
else
pbKpeb = (BYTE*) ( *
(DWORD*) ( pbKteb + MACRO_KPEBPTR_FIELDOFFSET_IN_KTEB ) );
if ( pbKpeb )
{
pvadVadRoot = (VAD*)
( * (DWORD*) ( pbKpeb + MACRO_VADROOT_FIELDOFFSET_IN_KPEB ) );
if ( pvadVadRoot )
{
if ( IsPagePresentAndTouch_BYTERANGE( (BYTE*)
pvadVadRoot, sizeof( VAD ), bTouchPages ) )
{
bVadWalkExit = FALSE;
vtwfpWalkParams.pbBytePointer =
pbBytePointer;
vtwfpWalkParams.bTouchPages = bTouchPages;
vtwfpWalkParams.pfnUserModListCallBack =
pdbpAddParams && pdbpAddParams->pfnUserModListCallBack ?
pdbpAddParams->pfnUserModListCallBack : NULL;
vtwfpWalkParams.pbExitNOW = &
bVadWalkExit;
vtwfpWalkParams.dwUserModListCallBackPARAM
= pdbpAddParams ? pdbpAddParams->dwUserModListCallBackPARAM : 0;
pvadMatchingNode = VadTreeWalk(
pvadVadRoot, & vtwfpWalkParams );
if (
pvadMatchingNode )
ExamineUserModule( pvadMatchingNode,
pbBytePointer, bTouchPages, sizeof( szImageName
),
&
pvMatchingModuleStart, & ulMatchingModuleLength, &
pinhMatchingModuleNtHeaders, szImageName );
}
}
}
}
}
else
{
LIST_ENTRY* pleListNodePtr;
DWORD* pdwImageBasePtr;
//
// KERNEL SPACE.
//
pleListNodePtr = (LIST_ENTRY*) pvNtoskrnlDriverSection;
while( TRUE )
{
if ( pleListNodePtr == NULL )
break;
// Check the Module Start Address.
pdwImageBasePtr = (DWORD*) ( ( (BYTE*) pleListNodePtr ) +
MACRO_IMAGEBASE_FIELDOFFSET_IN_DRVSEC );
if (
IsPagePresentAndTouch_DWORD( pdwImageBasePtr, bTouchPages ) )
{
dwImageBase = *
pdwImageBasePtr;
// Compare the Image Base and the Specified Pointer.
if ( ( (DWORD) pbBytePointer ) >= dwImageBase )
{
// Check the DOS Header.
pidhDosHdr =
(IMAGE_DOS_HEADER*) dwImageBase;
if ( IsPagePresentAndTouch_BYTERANGE( (BYTE*)
pidhDosHdr, sizeof( IMAGE_DOS_HEADER ),
bTouchPages ) )
{
if (
pidhDosHdr->e_magic == IMAGE_DOS_SIGNATURE &&
pidhDosHdr->e_lfarlc >= 0x40 )
{
// Check the NT
Headers.
pinhNtHdrs = (IMAGE_NT_HEADERS*) (
dwImageBase + pidhDosHdr->e_lfanew );
if (
IsPagePresentAndTouch_BYTERANGE( (BYTE*) pinhNtHdrs, sizeof(
IMAGE_NT_HEADERS ), bTouchPages ) )
{
if ( pinhNtHdrs->Signature == IMAGE_NT_SIGNATURE )
{
if ( ( (DWORD) pbBytePointer ) <= dwImageBase +
pinhNtHdrs->OptionalHeader.SizeOfImage - 1 )
{
// Setup the
Variables required later.
pvMatchingModuleStart = (VOID*)
dwImageBase;
ulMatchingModuleLength =
pinhNtHdrs->OptionalHeader.SizeOfImage;
pinhMatchingModuleNtHeaders = pinhNtHdrs;
// Get the Name
of the Module.
pwImageNameLengthPtr = (WORD*) ( ( (BYTE*)
pleListNodePtr ) + MACRO_IMAGENAME_FIELDOFFSET_IN_DRVSEC );
if (
IsPagePresentAndTouch_WORD( pwImageNameLengthPtr, bTouchPages ) )
{
wImageNameLength = * pwImageNameLengthPtr
/ sizeof( WORD );
if (
wImageNameLength != 0 &&
wImageNameLength
<= sizeof( szImageName ) - 1 )
{
pdwImageNameUnicodePtrPtr
= (DWORD*) ( ( (BYTE*) pleListNodePtr ) +
MACRO_IMAGENAME_FIELDOFFSET_IN_DRVSEC
+ FIELD_OFFSET( UNICODE_STRING, Buffer ) );
if (
IsPagePresentAndTouch_DWORD( pdwImageNameUnicodePtrPtr, bTouchPages ) )
{
pwImageNameUnicodePtr
= (WORD*) * pdwImageNameUnicodePtrPtr;
if ( pwImageNameUnicodePtr != NULL &&
IsPagePresentAndTouch(
pwImageNameUnicodePtr, bTouchPages ) &&
IsPagePresentAndTouch_WORD(
pwImageNameUnicodePtr + wImageNameLength - 1, bTouchPages ) )
{
pwWordPtr = pwImageNameUnicodePtr;
pcCharPtr = szImageName;
for ( ulI = 0; ulI < wImageNameLength; ulI ++ )
* pcCharPtr ++ = (CHAR) ( ( * pwWordPtr ++
) & 0xFF );
* pcCharPtr = '\0';
}
}
}
}
// Exit from the
Loop.
break;
}
}
}
}
}
}
}
// Get the Pointer to the Next Node.
if (
IsPagePresentAndTouch_DWORD( (DWORD*) ( ( (BYTE*) pleListNodePtr ) +
FIELD_OFFSET( LIST_ENTRY, Flink ) ), bTouchPages ) == FALSE )
break;
pleListNodePtr = pleListNodePtr->Flink;
if ( pleListNodePtr == NULL ||
pleListNodePtr ==
(LIST_ENTRY*) pvNtoskrnlDriverSection ||
IsPagePresentAndTouch(
pleListNodePtr, bTouchPages ) == FALSE )
break;
}
}
//
Check whether there is a Match.
if
( pszOutputBuffer &&
pvMatchingModuleStart && ulMatchingModuleLength
&& pinhMatchingModuleNtHeaders &&
strlen( szImageName ) )
{
IMAGE_SECTION_HEADER* pishSectionList;
ULONG ulI;
IMAGE_SECTION_HEADER* pishThis;
DWORD dwStart, dwEnd, dwOffset;
CHAR* pszImageNameToBePrinted;
BOOLEAN bPreserveModuleFileExtension;
if ( pdbpAddParams == NULL ||
pdbpAddParams->bPreserveModuleFileExtension == FALSE )
bPreserveModuleFileExtension = FALSE;
else
bPreserveModuleFileExtension = TRUE;
// Set the Pointer to the Image Name
String.
pszImageNameToBePrinted = & szImageName[ strlen(
szImageName ) - 1 ];
for( ; pszImageNameToBePrinted
>= szImageName; pszImageNameToBePrinted -- )
if ( * pszImageNameToBePrinted
== '.' &&
bPreserveModuleFileExtension == FALSE )
*
pszImageNameToBePrinted = '\0';
else if
( * pszImageNameToBePrinted == '\\' ||
*
pszImageNameToBePrinted == '/' )
break;
pszImageNameToBePrinted ++;
if ( strlen( pszImageNameToBePrinted
) )
{
// Check the Sections of the Image.
pishSectionList = (IMAGE_SECTION_HEADER*) ( ( (BYTE*)
pinhMatchingModuleNtHeaders ) + sizeof(
IMAGE_NT_HEADERS ) );
if (
IsPagePresentAndTouch_BYTERANGE( (BYTE*) pishSectionList, pinhMatchingModuleNtHeaders->FileHeader.NumberOfSections
* sizeof( IMAGE_SECTION_HEADER ), bTouchPages )
)
{
// Iterate through the Section List Items.
if ( !( pdbpAddParams &&
pdbpAddParams->ulSplitInfoNoSectionStringMaxLen ) )
{
for ( ulI = 0; ulI <
pinhMatchingModuleNtHeaders->FileHeader.NumberOfSections; ulI ++ )
{
pishThis = & pishSectionList[ ulI ];
if (
pishThis->SizeOfRawData == 0 )
continue;
dwStart = ( (DWORD) pvMatchingModuleStart
) + pishThis->VirtualAddress;
dwEnd = dwStart +
pishThis->SizeOfRawData - 1;
if ( (
(DWORD) pbBytePointer ) >= dwStart &&
( (DWORD) pbBytePointer ) <= dwEnd )
{
dwOffset = ( (DWORD) pbBytePointer ) -
dwStart;
// Compose the
Required String.
memset( szSectionName, 0, sizeof( szSectionName ) );
memcpy( szSectionName, pishThis->Name,
IMAGE_SIZEOF_SHORT_NAME );
if (
dwOffset )
{
sprintf(
pszOutputBuffer, "%s!%s+%.8X",
pszImageNameToBePrinted,
szSectionName, dwOffset );
}
else
{
sprintf(
pszOutputBuffer, "%s!%s",
pszImageNameToBePrinted,
szSectionName );
}
// Return to the
Caller.
return;
}
}
}
// Compose the Required String without Section Information.
dwOffset = ( (DWORD)
pbBytePointer ) - ( (DWORD) pvMatchingModuleStart );
if ( dwOffset &&
!(
pdbpAddParams && pdbpAddParams->ulSplitInfoNoSectionStringMaxLen ) )
{
sprintf(
pszOutputBuffer, "%s+%.8X",
pszImageNameToBePrinted, dwOffset );
}
else
{
sprintf(
pszOutputBuffer, "%s",
pszImageNameToBePrinted );
if ( pdbpAddParams )
pdbpAddParams->bIsBytePointerAtTheBeginning
= TRUE;
}
if ( pdbpAddParams &&
pdbpAddParams->ulSplitInfoNoSectionStringMaxLen )
{
pdbpAddParams->dwSplittedOffsetNoSection
= dwOffset;
pszOutputBuffer[
pdbpAddParams->ulSplitInfoNoSectionStringMaxLen ] = '\0';
}
}
}
}
//
Return to the Caller.
return;
}