You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1032 lines
23 KiB
1032 lines
23 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
context.c
|
|
|
|
Abstract:
|
|
|
|
Dumps the AML Context Structure in Human-Readable-Form (HRF)
|
|
|
|
Author:
|
|
|
|
Stephane Plante (splante) 21-Mar-1997
|
|
|
|
Environment:
|
|
|
|
User Mode.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "pch.h"
|
|
|
|
VOID
|
|
dumpAccessFieldObject(
|
|
IN ULONG_PTR AccessFieldAddress,
|
|
IN ULONG Verbose,
|
|
IN ULONG IndentLevel
|
|
)
|
|
{
|
|
ACCFIELDOBJ fieldObj;
|
|
BOOL result;
|
|
UCHAR buffer[80];
|
|
ULONG returnLength;
|
|
|
|
//
|
|
// Initialize the indent buffer
|
|
//
|
|
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
|
memset( buffer, ' ', IndentLevel );
|
|
buffer[IndentLevel] = '\0';
|
|
|
|
result = ReadMemory(
|
|
AccessFieldAddress,
|
|
&fieldObj,
|
|
sizeof(ACCFIELDOBJ),
|
|
&returnLength
|
|
);
|
|
if (result != TRUE ||
|
|
returnLength != sizeof(ACCFIELDOBJ) ||
|
|
fieldObj.FrameHdr.dwSig != SIG_ACCFIELDOBJ) {
|
|
|
|
dprintf(
|
|
"%sdumpAccessFieldUnit: Coult not read ACCFIELDOBJ %08lx\n",
|
|
buffer,
|
|
AccessFieldAddress
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
dprintf(
|
|
"%sAccess Field Object - %08lx\n"
|
|
"%s Field Data Object: %08lx\n",
|
|
buffer, AccessFieldAddress,
|
|
buffer, fieldObj.pdataObj
|
|
);
|
|
if (fieldObj.pdataObj != NULL && (Verbose & VERBOSE_CONTEXT)) {
|
|
|
|
dumpPObject(
|
|
(ULONG_PTR) fieldObj.pdataObj,
|
|
Verbose,
|
|
IndentLevel + 4
|
|
);
|
|
|
|
}
|
|
dprintf(
|
|
"%s Target Buffer: %08lx - %08lx\n"
|
|
"%s Access Size: %08lx\n"
|
|
"%s # of Accesses: %08lx\n"
|
|
"%s Data Mask: %08lx\n"
|
|
"%s # of Left Bits: %08lx\n"
|
|
"%s # of Right Bits: %08lx\n"
|
|
"%s Index to #/Accesses: %08lx\n"
|
|
"%s Temp Data: %08lx\n",
|
|
buffer, fieldObj.pbBuff, fieldObj.pbBuffEnd,
|
|
buffer, fieldObj.dwAccSize,
|
|
buffer, fieldObj.dwcAccesses,
|
|
buffer, fieldObj.dwDataMask,
|
|
buffer, fieldObj.iLBits,
|
|
buffer, fieldObj.iRBits,
|
|
buffer, fieldObj.iAccess,
|
|
buffer, fieldObj.dwData
|
|
);
|
|
|
|
dprintf(
|
|
"%s Field Descriptor: %p\n",
|
|
buffer,
|
|
( (ULONG_PTR) &(fieldObj.fd) - (ULONG_PTR) &fieldObj + AccessFieldAddress )
|
|
);
|
|
dumpFieldAddress(
|
|
( (ULONG_PTR) &(fieldObj.fd) - (ULONG_PTR) &fieldObj + AccessFieldAddress ),
|
|
Verbose,
|
|
IndentLevel + 4
|
|
);
|
|
|
|
}
|
|
|
|
VOID
|
|
dumpAccessFieldUnit(
|
|
IN ULONG_PTR AccessFieldAddress,
|
|
IN ULONG Verbose,
|
|
IN ULONG IndentLevel
|
|
)
|
|
{
|
|
ACCFIELDUNIT fieldUnit;
|
|
BOOL result;
|
|
UCHAR buffer[80];
|
|
ULONG returnLength;
|
|
|
|
//
|
|
// Initialize the indent buffer
|
|
//
|
|
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
|
memset( buffer, ' ', IndentLevel );
|
|
buffer[IndentLevel] = '\0';
|
|
|
|
result = ReadMemory(
|
|
AccessFieldAddress,
|
|
&fieldUnit,
|
|
sizeof(ACCFIELDUNIT),
|
|
&returnLength
|
|
);
|
|
if (result != TRUE ||
|
|
returnLength != sizeof(ACCFIELDUNIT) ||
|
|
fieldUnit.FrameHdr.dwSig != SIG_ACCFIELDUNIT) {
|
|
|
|
dprintf(
|
|
"%sdumpAccessFieldUnit: Coult not read ACCFIELDUNIT %08lx\n",
|
|
buffer,
|
|
AccessFieldAddress
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
dprintf(
|
|
"%sAccess Field Unit - %08lx\n"
|
|
"%s Field Data Object: %08lx\n",
|
|
buffer, AccessFieldAddress,
|
|
buffer, fieldUnit.pdataObj
|
|
);
|
|
if (fieldUnit.pdataObj != NULL && (Verbose & VERBOSE_CONTEXT)) {
|
|
|
|
dumpPObject(
|
|
(ULONG_PTR) fieldUnit.pdataObj,
|
|
Verbose,
|
|
IndentLevel + 4
|
|
);
|
|
|
|
}
|
|
dprintf(
|
|
"%s Source/Result Object: %08lx\n",
|
|
buffer,
|
|
fieldUnit.pdata
|
|
);
|
|
if (fieldUnit.pdata != NULL && (Verbose & VERBOSE_CONTEXT)) {
|
|
|
|
dumpPObject(
|
|
(ULONG_PTR) fieldUnit.pdata,
|
|
Verbose,
|
|
IndentLevel + 4
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VOID
|
|
dumpAmlTerm(
|
|
IN ULONG_PTR AmlTermAddress,
|
|
IN ULONG Verbose,
|
|
IN ULONG IndentLevel
|
|
)
|
|
{
|
|
AMLTERM amlTerm;
|
|
BOOL result;
|
|
INT i;
|
|
UCHAR buffer[80];
|
|
ULONG returnLength;
|
|
|
|
//
|
|
// Initialize the indent buffer
|
|
//
|
|
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
|
memset( buffer, ' ', IndentLevel );
|
|
buffer[IndentLevel] = '\0';
|
|
|
|
result = ReadMemory(
|
|
AmlTermAddress,
|
|
&amlTerm,
|
|
sizeof(AMLTERM),
|
|
&returnLength
|
|
);
|
|
if (result != TRUE || returnLength != sizeof(AMLTERM)) {
|
|
|
|
dprintf(
|
|
"\n%sdumpAmlTerm: Could not read AMLTERM 0x%08lx\n",
|
|
buffer,
|
|
AmlTermAddress
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
if (amlTerm.pszTermName != NULL) {
|
|
|
|
result = ReadMemory(
|
|
(ULONG_PTR) amlTerm.pszTermName,
|
|
Buffer,
|
|
32,
|
|
&returnLength
|
|
);
|
|
if (result && returnLength <= 32) {
|
|
|
|
Buffer[returnLength] = '\0';
|
|
dprintf(" - %s\n", Buffer );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VOID
|
|
dumpCall(
|
|
IN ULONG_PTR CallAddress,
|
|
IN ULONG Verbose,
|
|
IN ULONG IndentLevel
|
|
)
|
|
{
|
|
BOOL result;
|
|
CALL call;
|
|
INT i;
|
|
UCHAR buffer[80];
|
|
ULONG returnLength;
|
|
|
|
//
|
|
// Initialize the indent buffer
|
|
//
|
|
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
|
memset( buffer, ' ', IndentLevel );
|
|
buffer[IndentLevel] = '\0';
|
|
|
|
result = ReadMemory(
|
|
CallAddress,
|
|
&call,
|
|
sizeof(CALL),
|
|
&returnLength
|
|
);
|
|
if (result != TRUE ||
|
|
returnLength != sizeof(CALL) ||
|
|
call.FrameHdr.dwSig != SIG_CALL) {
|
|
|
|
dprintf(
|
|
"%sdumpCall: Coult not read CALL %08lx\n",
|
|
buffer,
|
|
CallAddress
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
dprintf(
|
|
"%sCall - %08lx\n", buffer, CallAddress
|
|
);
|
|
|
|
//
|
|
// Method
|
|
//
|
|
dprintf(
|
|
"%s Method: %08lx\n",
|
|
buffer,
|
|
call.pnsMethod
|
|
);
|
|
if (call.pnsMethod != NULL && (Verbose & VERBOSE_CONTEXT)) {
|
|
|
|
dumpNSObject( (ULONG_PTR) call.pnsMethod, Verbose, IndentLevel + 4);
|
|
|
|
}
|
|
|
|
//
|
|
// Previous Call Frame
|
|
//
|
|
if (Verbose & VERBOSE_CALL) {
|
|
|
|
dprintf(
|
|
"%s Previous Call Frame: %08lx\n"
|
|
"%s Previous Owner: %08lx\n",
|
|
buffer,
|
|
call.pcallPrev,
|
|
buffer,
|
|
call.pownerPrev
|
|
);
|
|
if (call.pownerPrev != NULL && (Verbose & VERBOSE_CONTEXT)) {
|
|
|
|
dumpObjectOwner(
|
|
(ULONG_PTR) call.pownerPrev,
|
|
IndentLevel + 2
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (Verbose & VERBOSE_CONTEXT) {
|
|
|
|
//
|
|
// Dump arguments
|
|
//
|
|
dprintf(
|
|
"%s Arguments (Current): %1d (%1d)\n",
|
|
buffer,
|
|
call.icArgs,
|
|
call.iArg
|
|
);
|
|
for (i = 0; i < call.icArgs; i++) {
|
|
|
|
dprintf(
|
|
"%s Argument(%d): %p\n",
|
|
buffer,
|
|
i,
|
|
(ULONG_PTR) (call.pdataArgs + i)
|
|
);
|
|
dumpPObject(
|
|
(ULONG_PTR) (call.pdataArgs + i),
|
|
Verbose,
|
|
IndentLevel + 4
|
|
);
|
|
|
|
}
|
|
|
|
dprintf(
|
|
"%s Result: %08lx\n",
|
|
buffer,
|
|
call.pdataResult
|
|
);
|
|
if (call.pdataResult != NULL) {
|
|
|
|
dumpPObject(
|
|
(ULONG_PTR) call.pdataResult,
|
|
Verbose,
|
|
IndentLevel + 4
|
|
);
|
|
|
|
}
|
|
|
|
if (Verbose & VERBOSE_CALL) {
|
|
|
|
dprintf(
|
|
"%s Locals:\n",
|
|
buffer
|
|
);
|
|
for (i = 0; i < MAX_NUM_LOCALS; i++) {
|
|
|
|
dumpObject(
|
|
(ULONG) ( (PUCHAR) &(call.Locals[i]) - (PUCHAR) &call) +
|
|
CallAddress,
|
|
&(call.Locals[i]),
|
|
Verbose,
|
|
IndentLevel + 4
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VOID
|
|
dumpContext(
|
|
IN ULONG_PTR ContextAddress,
|
|
IN ULONG Verbose
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine dumps a context structure in HRF
|
|
|
|
Arguments:
|
|
|
|
ContextAddress - Where on the target machine the context is located
|
|
Verbose - How verbose we should be
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
ULONG_PTR displacement;
|
|
BOOL result;
|
|
CTXT context;
|
|
ULONG returnLength;
|
|
|
|
//
|
|
// Read the context from the target
|
|
//
|
|
result = ReadMemory(
|
|
ContextAddress,
|
|
&context,
|
|
sizeof(CTXT),
|
|
&returnLength
|
|
);
|
|
if (result != TRUE || returnLength != sizeof(CTXT) ) {
|
|
|
|
dprintf(
|
|
"dumpContext: could not read CTXT %08lx\n",
|
|
ContextAddress
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// Is it a context?
|
|
//
|
|
if (context.dwSig != SIG_CTXT) {
|
|
|
|
dprintf(
|
|
"dumpContext: Signature (%08lx) != SIG_CTXT (%08lx)\n",
|
|
context.dwSig,
|
|
SIG_CTXT
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
dprintf("Context - %08lx-%08lx\n",ContextAddress, context.pbCtxtEnd );
|
|
if (Verbose & VERBOSE_CONTEXT) {
|
|
|
|
dprintf(
|
|
" AllocatedContextList: F:%08lx B:%08lx\n"
|
|
" QueingContextList: F:%08lx B:%08lx\n"
|
|
" ContextListHead: %08lx\n"
|
|
" SynchronizeLevel: %08lx\n"
|
|
" CurrentOpByte: %08lx\n"
|
|
" AsyncCallBack: %08lx",
|
|
context.listCtxt.plistNext, context.listCtxt.plistPrev,
|
|
context.listQueue.plistNext, context.listQueue.plistPrev,
|
|
context.pplistCtxtQueue,
|
|
context.dwSyncLevel,
|
|
context.pbOp,
|
|
context.pfnAsyncCallBack
|
|
);
|
|
if (context.pfnAsyncCallBack != NULL) {
|
|
|
|
GetSymbol(
|
|
context.pfnAsyncCallBack,
|
|
Buffer,
|
|
&displacement
|
|
);
|
|
dprintf(" %s",
|
|
Buffer
|
|
);
|
|
}
|
|
dprintf(
|
|
"\n"
|
|
" AsyncCallBackContext: %08lx\n"
|
|
" AsyncDataCallBack: %08lx\n",
|
|
context.pvContext,
|
|
context.pdataCallBack
|
|
);
|
|
|
|
}
|
|
dprintf(
|
|
" Flags: %08lx",
|
|
context.dwfCtxt
|
|
);
|
|
if (context.dwfCtxt & CTXTF_TIMER_PENDING) {
|
|
|
|
dprintf(" Timer");
|
|
|
|
}
|
|
if (context.dwfCtxt & CTXTF_TIMEOUT) {
|
|
|
|
dprintf(" Timeout");
|
|
|
|
}
|
|
if (context.dwfCtxt & CTXTF_READY) {
|
|
|
|
dprintf(" Ready");
|
|
|
|
}
|
|
if (context.dwfCtxt & CTXTF_NEED_CALLBACK) {
|
|
|
|
dprintf(" CallBack");
|
|
|
|
}
|
|
dprintf("\n");
|
|
|
|
dprintf(
|
|
" NameSpace Object: %08lx\n",
|
|
context.pnsObj
|
|
);
|
|
if (Verbose & VERBOSE_CONTEXT) {
|
|
|
|
dprintf(
|
|
" NameSpace Scope: %08lx\n"
|
|
" NameSpace Owner: %08lx\n",
|
|
context.pnsScope,
|
|
context.powner
|
|
);
|
|
if (context.powner != NULL) {
|
|
|
|
dumpObjectOwner(
|
|
(ULONG_PTR) context.powner,
|
|
2
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dprintf(
|
|
" Current Call Frame: %08lx\n",
|
|
context.pcall
|
|
);
|
|
if (context.pcall != NULL) {
|
|
|
|
dumpCall(
|
|
(ULONG_PTR) context.pcall,
|
|
(Verbose & ~VERBOSE_CONTEXT),
|
|
4
|
|
);
|
|
|
|
}
|
|
|
|
dumpStack(
|
|
ContextAddress,
|
|
&context,
|
|
Verbose,
|
|
2
|
|
);
|
|
|
|
}
|
|
|
|
VOID
|
|
dumpFieldAddress(
|
|
IN ULONG_PTR FieldAddress,
|
|
IN ULONG Verbose,
|
|
IN ULONG IndentLevel
|
|
)
|
|
{
|
|
FIELDDESC fd;
|
|
BOOL result;
|
|
UCHAR buffer[80];
|
|
ULONG returnLength;
|
|
|
|
//
|
|
// Initialize the indent buffer
|
|
//
|
|
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
|
memset( buffer, ' ', IndentLevel );
|
|
buffer[IndentLevel] = '\0';
|
|
|
|
result = ReadMemory(
|
|
FieldAddress,
|
|
&fd,
|
|
sizeof(FIELDDESC),
|
|
&returnLength
|
|
);
|
|
if (result != TRUE ||
|
|
returnLength != sizeof(FIELDDESC) ) {
|
|
|
|
dprintf(
|
|
"%sdumpFieldAddress: Coult not read FIELDDESC %08lx\n",
|
|
buffer,
|
|
FieldAddress
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
dprintf(
|
|
"%sField Descriptor - %08lx\n"
|
|
"%s ByteOffset: %08lx\n"
|
|
"%s Start Bit Position: %08lx\n"
|
|
"%s Number of Bits: %08lx\n"
|
|
"%s Flags: %08lx\n",
|
|
buffer, FieldAddress,
|
|
buffer, fd.dwByteOffset,
|
|
buffer, fd.dwStartBitPos,
|
|
buffer, fd.dwNumBits,
|
|
buffer, fd.dwFieldFlags
|
|
);
|
|
}
|
|
|
|
VOID
|
|
dumpListContexts(
|
|
IN VOID
|
|
)
|
|
/*++
|
|
|
|
--*/
|
|
{
|
|
PLIST pList;
|
|
PLIST pListNext;
|
|
}
|
|
|
|
VOID
|
|
dumpObjectOwner(
|
|
IN ULONG_PTR ObjOwnerAddress,
|
|
IN ULONG IndentLevel
|
|
)
|
|
{
|
|
BOOL result;
|
|
OBJOWNER objowner;
|
|
UCHAR buffer[80];
|
|
ULONG returnLength;
|
|
|
|
//
|
|
// Initialize the indent buffer
|
|
//
|
|
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
|
memset( buffer, ' ', IndentLevel );
|
|
buffer[IndentLevel] = '\0';
|
|
|
|
result = ReadMemory(
|
|
ObjOwnerAddress,
|
|
&objowner,
|
|
sizeof(OBJOWNER),
|
|
&returnLength
|
|
);
|
|
if (result == TRUE &&
|
|
returnLength == sizeof(OBJOWNER) &&
|
|
objowner.dwSig == SIG_OBJOWNER) {
|
|
|
|
dprintf(
|
|
"%sObjectOwner - %08lx\n"
|
|
"%s NameSpaceObject: %08lx\n"
|
|
"%s List: F:%08lx B:%08lx\n",
|
|
buffer,
|
|
ObjOwnerAddress,
|
|
buffer,
|
|
objowner.pnsObjList,
|
|
buffer,
|
|
objowner.list.plistNext,
|
|
objowner.list.plistPrev
|
|
);
|
|
|
|
} else {
|
|
|
|
dprintf(
|
|
"%sdumpObjectOwner: Could not read OBJOWNER %08lx\n",
|
|
buffer,ObjOwnerAddress
|
|
);
|
|
|
|
}
|
|
}
|
|
|
|
VOID
|
|
dumpScope(
|
|
IN ULONG_PTR ScopeAddress,
|
|
IN ULONG Verbose,
|
|
IN ULONG IndentLevel
|
|
)
|
|
{
|
|
BOOL result;
|
|
SCOPE scope;
|
|
UCHAR indent[80];
|
|
ULONG returnLength;
|
|
|
|
//
|
|
// Initialize the indent buffer
|
|
//
|
|
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
|
memset( indent, ' ', IndentLevel );
|
|
indent[IndentLevel] = '\0';
|
|
|
|
|
|
result = ReadMemory(
|
|
ScopeAddress,
|
|
&scope,
|
|
sizeof(SCOPE),
|
|
&returnLength
|
|
);
|
|
if (result != TRUE ||
|
|
returnLength != sizeof(SCOPE) ||
|
|
scope.FrameHdr.dwSig != SIG_SCOPE) {
|
|
|
|
dprintf(
|
|
"%sdumpScope: Coult not read SCOPE %08lx\n",
|
|
indent,
|
|
ScopeAddress
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
dprintf(
|
|
"%sScope - %08lx\n",
|
|
indent,
|
|
ScopeAddress
|
|
);
|
|
|
|
dprintf(
|
|
"%s ScopeEnd: %08lx\n"
|
|
"%s ReturnAddress: %08lx\n"
|
|
"%s Previous Scope: %08lx\n",
|
|
indent,
|
|
scope.pbOpEnd,
|
|
indent,
|
|
scope.pbOpRet,
|
|
indent,
|
|
scope.pnsPrevScope
|
|
);
|
|
if (Verbose & VERBOSE_CALL) {
|
|
|
|
dumpNSObject( (ULONG_PTR) scope.pnsPrevScope, Verbose, IndentLevel + 4);
|
|
|
|
}
|
|
|
|
dprintf(
|
|
"%s Previous Owner: %08lx\n",
|
|
indent,
|
|
scope.pownerPrev
|
|
);
|
|
if (Verbose & VERBOSE_CALL) {
|
|
|
|
dumpObjectOwner(
|
|
(ULONG_PTR) scope.pownerPrev,
|
|
IndentLevel + 4
|
|
);
|
|
|
|
}
|
|
|
|
dprintf(
|
|
"%s Result Object: %08lx\n",
|
|
indent,
|
|
scope.pdataResult
|
|
);
|
|
if (scope.pdataResult != NULL && (Verbose & VERBOSE_CALL) ) {
|
|
|
|
dumpPObject(
|
|
(ULONG_PTR) scope.pdataResult,
|
|
Verbose,
|
|
IndentLevel + 4
|
|
);
|
|
|
|
}
|
|
}
|
|
|
|
VOID
|
|
dumpStack(
|
|
IN ULONG_PTR ContextAddress,
|
|
IN PCTXT Context,
|
|
IN ULONG Verbose,
|
|
IN ULONG IndentLevel
|
|
)
|
|
{
|
|
ULONG_PTR displacement;
|
|
BOOL result;
|
|
FRAMEHDR frame;
|
|
PUCHAR frameAddress;
|
|
UCHAR indent[80];
|
|
UCHAR buffer[5];
|
|
ULONG returnLength;
|
|
|
|
//
|
|
// Initialize the indent buffer
|
|
//
|
|
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
|
memset( indent, ' ', IndentLevel );
|
|
indent[IndentLevel] = '\0';
|
|
buffer[4] = '\0';
|
|
|
|
dprintf(
|
|
"%sStack - %p-%08lx (%08lx)\n",
|
|
indent,
|
|
ContextAddress,
|
|
Context->LocalHeap.pbHeapEnd,
|
|
Context->pbCtxtEnd
|
|
);
|
|
|
|
//
|
|
// Calculate where the first frame lies
|
|
//
|
|
frameAddress = Context->LocalHeap.pbHeapEnd;
|
|
while (frameAddress < Context->pbCtxtEnd) {
|
|
|
|
result = ReadMemory(
|
|
(ULONG_PTR) frameAddress,
|
|
&frame,
|
|
sizeof(FRAMEHDR),
|
|
&returnLength
|
|
);
|
|
if (result != TRUE ||
|
|
returnLength != sizeof(FRAMEHDR)) {
|
|
|
|
dprintf(
|
|
"%sdumpStack: could not read FRAMEHDR %08lx\n",
|
|
indent,
|
|
(ULONG_PTR) frameAddress
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
memcpy( buffer, (PUCHAR) &(frame.dwSig), 4 );
|
|
dprintf(
|
|
"%s %p: %s - (Length %08lx) (Flags %08lx)\n"
|
|
"%s ParseFunction %08lx",
|
|
indent,
|
|
(ULONG_PTR) frameAddress,
|
|
buffer,
|
|
frame.dwLen,
|
|
frame.dwfFrame,
|
|
indent,
|
|
frame.pfnParse
|
|
);
|
|
if (frame.pfnParse != NULL) {
|
|
|
|
GetSymbol(
|
|
frame.pfnParse,
|
|
Buffer,
|
|
&displacement
|
|
);
|
|
dprintf(" %s",
|
|
Buffer
|
|
);
|
|
|
|
}
|
|
dprintf("\n");
|
|
|
|
//
|
|
// Do we know how to crack the frame?
|
|
//
|
|
switch(frame.dwSig) {
|
|
case SIG_CALL:
|
|
|
|
dumpCall(
|
|
(ULONG_PTR) frameAddress,
|
|
Verbose,
|
|
IndentLevel + 4
|
|
);
|
|
break;
|
|
case SIG_SCOPE:
|
|
|
|
dumpScope(
|
|
(ULONG_PTR) frameAddress,
|
|
Verbose,
|
|
IndentLevel + 4
|
|
);
|
|
break;
|
|
|
|
case SIG_TERM:
|
|
|
|
dumpTerm(
|
|
(ULONG_PTR) frameAddress,
|
|
Verbose,
|
|
IndentLevel + 4
|
|
);
|
|
break;
|
|
|
|
case SIG_ACCFIELDUNIT:
|
|
|
|
dumpAccessFieldUnit(
|
|
(ULONG_PTR) frameAddress,
|
|
Verbose,
|
|
IndentLevel + 4
|
|
);
|
|
break;
|
|
|
|
case SIG_ACCFIELDOBJ:
|
|
|
|
dumpAccessFieldObject(
|
|
(ULONG_PTR) frameAddress,
|
|
Verbose,
|
|
IndentLevel + 4
|
|
);
|
|
break;
|
|
|
|
}
|
|
|
|
//
|
|
// Make sure that there is some white space present
|
|
//
|
|
dprintf("\n\n");
|
|
|
|
//
|
|
// Next11
|
|
//
|
|
frameAddress += frame.dwLen;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VOID
|
|
dumpTerm(
|
|
IN ULONG_PTR TermAddress,
|
|
IN ULONG Verbose,
|
|
IN ULONG IndentLevel
|
|
)
|
|
{
|
|
BOOL result;
|
|
INT i;
|
|
TERM term;
|
|
UCHAR indent[80];
|
|
ULONG returnLength;
|
|
|
|
//
|
|
// Initialize the indent buffer
|
|
//
|
|
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
|
|
memset( indent, ' ', IndentLevel );
|
|
indent[IndentLevel] = '\0';
|
|
|
|
result = ReadMemory(
|
|
TermAddress,
|
|
&term,
|
|
sizeof(TERM),
|
|
&returnLength
|
|
);
|
|
if (result != TRUE ||
|
|
returnLength != sizeof(TERM) ||
|
|
term.FrameHdr.dwSig != SIG_TERM) {
|
|
|
|
dprintf(
|
|
"%sdumpTerm: Coult not read TERM %08lx\n",
|
|
indent,
|
|
TermAddress
|
|
);
|
|
return;
|
|
|
|
}
|
|
|
|
dprintf(
|
|
"%sTerm - %08lx\n",
|
|
indent,
|
|
TermAddress
|
|
);
|
|
|
|
dprintf(
|
|
"%s OpCodeStart: %08lx\n"
|
|
"%s OpCodeEnd: %08lx\n"
|
|
"%s ScopeEnd: %08lx\n"
|
|
"%s NameSpaceObject: %08lx\n",
|
|
indent,
|
|
term.pbOpTerm,
|
|
indent,
|
|
term.pbOpEnd,
|
|
indent,
|
|
term.pbScopeEnd,
|
|
indent,
|
|
term.pnsObj
|
|
);
|
|
if ( term.pnsObj != NULL && (Verbose & VERBOSE_CALL)) {
|
|
|
|
dumpNSObject( (ULONG_PTR) term.pnsObj, Verbose, IndentLevel + 4);
|
|
|
|
}
|
|
|
|
dprintf(
|
|
"%s Aml Term: %08lx",
|
|
indent,
|
|
term.pamlterm
|
|
);
|
|
if (term.pamlterm != NULL) {
|
|
|
|
dumpAmlTerm( (ULONG_PTR) term.pamlterm, Verbose, IndentLevel + 4);
|
|
|
|
} else {
|
|
|
|
dprintf("\n");
|
|
|
|
}
|
|
|
|
//
|
|
// Dump arguments
|
|
//
|
|
dprintf(
|
|
"%s Arguments (Current): %1d (%1d)\n",
|
|
indent,
|
|
term.icArgs,
|
|
term.iArg
|
|
);
|
|
|
|
for (i = 0; i < term.icArgs; i++) {
|
|
|
|
dprintf(
|
|
"%s Argument(%d): %p\n",
|
|
indent,
|
|
i,
|
|
(ULONG_PTR) (term.pdataArgs + i)
|
|
);
|
|
|
|
if (Verbose & VERBOSE_CALL) {
|
|
|
|
dumpPObject(
|
|
(ULONG_PTR) (term.pdataArgs + i),
|
|
Verbose,
|
|
IndentLevel + 4
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dprintf(
|
|
"%s Result: %08lx\n",
|
|
indent,
|
|
term.pdataResult
|
|
);
|
|
if (term.pdataResult != NULL && (Verbose & VERBOSE_CALL) ) {
|
|
|
|
dumpPObject(
|
|
(ULONG_PTR) term.pdataResult,
|
|
Verbose,
|
|
IndentLevel + 4
|
|
);
|
|
|
|
}
|
|
|
|
}
|