📄 wdbgexts.h
字号:
}
}
return flag;
}
__inline
ULONG
ReadListEntry(
ULONG64 Address,
PLIST_ENTRY64 List
)
{
ULONG cb;
if (IsPtr64()) {
return (ReadMemory(Address, (PVOID)List, sizeof(*List), &cb) && cb == sizeof(*List));
} else {
LIST_ENTRY32 List32;
ULONG Status;
Status = ReadMemory(Address,
(PVOID)&List32,
sizeof(List32),
&cb);
if (Status && cb == sizeof(List32)) {
List->Flink = (ULONG64)(LONG64)(LONG)List32.Flink;
List->Blink = (ULONG64)(LONG64)(LONG)List32.Blink;
return 1;
}
return 0;
}
}
__inline
ULONG
ReadPointer(
ULONG64 Address,
PULONG64 Pointer
)
{
ULONG cb;
if (IsPtr64()) {
return (ReadMemory(Address, (PVOID)Pointer, sizeof(*Pointer), &cb) && cb == sizeof(*Pointer));
} else {
ULONG Pointer32;
ULONG Status;
Status = ReadMemory(Address,
(PVOID)&Pointer32,
sizeof(Pointer32),
&cb);
if (Status && cb == sizeof(Pointer32)) {
*Pointer = (ULONG64)(LONG64)(LONG)Pointer32;
return 1;
}
return 0;
}
}
__inline
ULONG
WritePointer(
ULONG64 Address,
ULONG64 Pointer
)
{
ULONG cb;
if (IsPtr64()) {
return (WriteMemory(Address, &Pointer, sizeof(Pointer), &cb) && cb == sizeof(Pointer));
} else {
ULONG Pointer32 = (ULONG)Pointer;
ULONG Status;
Status = WriteMemory(Address,
&Pointer32,
sizeof(Pointer32),
&cb);
return (Status && cb == sizeof(Pointer32)) ? 1 : 0;
}
}
/**
This does Ioctl call for type info and returns size of the type on success.
**/
__inline
ULONG
GetTypeSize (
IN LPCSTR Type
)
{
SYM_DUMP_PARAM Sym = {
sizeof (SYM_DUMP_PARAM), (PUCHAR)Type, DBG_DUMP_NO_PRINT | DBG_DUMP_GET_SIZE_ONLY, 0,
NULL, NULL, NULL, 0, NULL
};
return Ioctl( IG_GET_TYPE_SIZE, &Sym, Sym.size );
}
/**
GetFieldData
Copies the value of the specified field into pOutValue assuming TypeAddress
points to start of the type in debugee.
If the Field is NULL and the size of Type is <= 8 Whole type value is read into
pOutValue. This is to allow to read in primitive types suchas ULONG, PVOID etc.
If address is zero this considers Type a global variable.
It raises an exception if OutSize is less than size to be copied.
Returns 0 on success, errorvalue (defined with SYM_DUMP_PARAM) otherwise.
**/
__inline
ULONG
GetFieldData (
IN ULONG64 TypeAddress,
IN LPCSTR Type,
IN LPCSTR Field,
IN ULONG OutSize,
OUT PVOID pOutValue
)
{
FIELD_INFO flds = {(PUCHAR)Field, NULL, 0, DBG_DUMP_FIELD_FULL_NAME | DBG_DUMP_FIELD_COPY_FIELD_DATA | DBG_DUMP_FIELD_RETURN_ADDRESS, 0, pOutValue};
SYM_DUMP_PARAM Sym = {
sizeof (SYM_DUMP_PARAM), (PUCHAR)Type, DBG_DUMP_NO_PRINT, TypeAddress,
NULL, NULL, NULL, 1, &flds
};
ULONG RetVal;
if (!Field) {
Sym.nFields =0; Sym.Options |= DBG_DUMP_COPY_TYPE_DATA;
Sym.Context = pOutValue;
}
ZeroMemory(pOutValue, OutSize);
RetVal = Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size );
if (OutSize < ((Field == NULL) ? 8 : flds.size)) {
// Fail
dprintf("Not enough space to read %s-%s\n", Type, Field);
RaiseException(EXCEPTION_ACCESS_VIOLATION, 0, 0, NULL);
return 0;
}
return RetVal;
}
//
// Typecast the buffer where value is to be read
//
#define GetFieldValue(Addr, Type, Field, OutValue) \
GetFieldData(Addr, Type, Field, sizeof(OutValue), (PVOID) &(OutValue))
//
// Used to read in value of a short (<= 8 bytes) fields
//
__inline
ULONG64
GetShortField (
IN ULONG64 TypeAddress,
IN LPCSTR Name,
IN USHORT StoreAddress
)
{
static ULONG64 SavedAddress;
static PUCHAR SavedName;
static ULONG ReadPhysical;
FIELD_INFO flds = {(PUCHAR) Name, NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL};
SYM_DUMP_PARAM Sym = {
sizeof (SYM_DUMP_PARAM), SavedName, DBG_DUMP_NO_PRINT | ((StoreAddress & 2) ? DBG_DUMP_READ_PHYSICAL : 0),
SavedAddress, NULL, NULL, NULL, 1, &flds
};
if (StoreAddress) {
Sym.sName = (PUCHAR) Name;
Sym.nFields = 0;
SavedName = (PUCHAR) Name;
Sym.addr = SavedAddress = TypeAddress;
ReadPhysical = (StoreAddress & 2);
return SavedAddress ? Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size ) : MEMORY_READ_ERROR; // zero on success
} else {
Sym.Options |= ReadPhysical ? DBG_DUMP_READ_PHYSICAL : 0;
}
if (!Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size )) {
return flds.address;
}
return 0;
}
//
// Stores the address and type name for future reads
//
#define InitTypeRead(Addr, Type) GetShortField(Addr, #Type, 1)
//
// Stores the address and type name for future reads
//
#define InitTypeReadPhysical(Addr, Type) GetShortField(Addr, #Type, 3)
//
// Returns the field's value as ULONG64 if size of field is <= sizeof (ULONG64)
//
#define ReadField(Field) GetShortField(0, #Field, 0)
//
// Read in a pointer value
//
__inline
ULONG
ReadPtr(
ULONG64 Addr,
PULONG64 pPointer
)
{
return GetFieldData(Addr, "PVOID", NULL, sizeof(ULONG64), (PVOID) pPointer);
}
/*
* ListType
*
* Routine ListType gives a callback on each element in the list of Type.
*
* Type : Name of the type to be listed
*
* NextPointer : Name of field which gives address of next element in list
*
* Context, CallbackRoutine :
* Context and the callback routine. The address field in PFIELD_INFO
* parameter of callback contains the address of next Type element in list.
*
* Address, ListByFieldAddress :
* if ListByFieldAddress is 0, Adress is the address of first element of Type List.
*
* Lists by LIST_ENTRY are also handled implicitly (by Ioctl). If the NextPointer
* is a pointer to LIST_ENTRY type, the type address is properly calculated by
* subtracting the offsets.
*
* If ListByFieldAddress is 1, the Address is considered to be the address of field
* "NextPointer" of the first Type element and first element address is derived
* from it.
*
*/
__inline
ULONG
ListType (
IN LPCSTR Type,
IN ULONG64 Address,
IN USHORT ListByFieldAddress,
IN LPCSTR NextPointer,
IN PVOID Context,
IN PSYM_DUMP_FIELD_CALLBACK CallbackRoutine
)
{
FIELD_INFO flds = {(PUCHAR)NextPointer, NULL, 0, 0, 0, NULL};
SYM_DUMP_PARAM Sym = {
sizeof (SYM_DUMP_PARAM), (PUCHAR) Type, DBG_DUMP_NO_PRINT | DBG_DUMP_LIST, Address,
&flds, Context, CallbackRoutine, 0, NULL
};
if (ListByFieldAddress==1) {
//
// Address is the address of "NextPointer"
//
Sym.Options |= DBG_DUMP_ADDRESS_OF_FIELD;
}
return Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size );
}
/**
Routine to get offset of a "Field" of "Type" on a debugee machine. This uses
Ioctl call for type info.
Returns 0 on success, Ioctl error value otherwise.
**/
__inline
ULONG
GetFieldOffset (
IN LPCSTR Type,
IN LPCSTR Field,
OUT PULONG pOffset
)
{
FIELD_INFO flds = {
(PUCHAR)Field,
(PUCHAR)"",
0,
DBG_DUMP_FIELD_FULL_NAME | DBG_DUMP_FIELD_RETURN_ADDRESS,
0,
NULL};
SYM_DUMP_PARAM Sym = {
sizeof (SYM_DUMP_PARAM),
(PUCHAR)Type,
DBG_DUMP_NO_PRINT,
0,
NULL,
NULL,
NULL,
1,
&flds
};
ULONG Err;
Sym.nFields = 1;
Err = Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size );
*pOffset = (ULONG) (flds.address - Sym.addr);
return Err;
}
#endif // defined(KDEXT_64BIT)
__inline VOID
GetCurrentProcessHandle(
PHANDLE hp
)
{
Ioctl(IG_GET_CURRENT_PROCESS_HANDLE, hp, sizeof(HANDLE));
}
__inline VOID
GetTebAddress(
PULONGLONG Address
)
{
GET_TEB_ADDRESS gpt;
gpt.Address = 0;
Ioctl(IG_GET_TEB_ADDRESS, (PVOID)&gpt, sizeof(gpt));
*Address = gpt.Address;
}
__inline VOID
GetPebAddress(
ULONG64 CurrentThread,
PULONGLONG Address
)
{
GET_PEB_ADDRESS gpt;
gpt.CurrentThread = CurrentThread;
gpt.Address = 0;
Ioctl(IG_GET_PEB_ADDRESS, (PVOID)&gpt, sizeof(gpt));
*Address = gpt.Address;
}
__inline VOID
GetCurrentThreadAddr(
DWORD Processor,
PULONG64 Address
)
{
GET_CURRENT_THREAD_ADDRESS ct;
ct.Processor = Processor;
Ioctl(IG_GET_CURRENT_THREAD, (PVOID)&ct, sizeof(ct));
*Address = ct.Address;
}
__inline VOID
GetCurrentProcessAddr(
DWORD Processor,
ULONG64 CurrentThread,
PULONG64 Address
)
{
GET_CURRENT_PROCESS_ADDRESS cp;
cp.Processor = Processor;
cp.CurrentThread = CurrentThread;
Ioctl(IG_GET_CURRENT_PROCESS, (PVOID)&cp, sizeof(cp));
*Address = cp.Address;
}
__inline VOID
SearchMemory(
ULONG64 SearchAddress,
ULONG64 SearchLength,
ULONG PatternLength,
PVOID Pattern,
PULONG64 FoundAddress
)
{
SEARCHMEMORY sm;
sm.SearchAddress = SearchAddress;
sm.SearchLength = SearchLength;
sm.FoundAddress = 0;
sm.PatternLength = PatternLength;
sm.Pattern = Pattern;
Ioctl(IG_SEARCH_MEMORY, (PVOID)&sm, sizeof(sm));
*FoundAddress = sm.FoundAddress;
}
__inline ULONG
GetInputLine(
PCSTR Prompt,
PSTR Buffer,
ULONG BufferSize
)
{
GET_INPUT_LINE InLine;
InLine.Prompt = Prompt;
InLine.Buffer = Buffer;
InLine.BufferSize = BufferSize;
if (Ioctl(IG_GET_INPUT_LINE, (PVOID)&InLine, sizeof(InLine)))
{
return InLine.InputSize;
}
else
{
return 0;
}
}
__inline BOOL
GetExpressionEx(
PCSTR Expression,
ULONG64* Value,
PCSTR* Remainder
)
{
GET_EXPRESSION_EX Expr;
Expr.Expression = Expression;
if (Ioctl(IG_GET_EXPRESSION_EX, (PVOID)&Expr, sizeof(Expr)))
{
*Value = Expr.Value;
if (Remainder != NULL)
{
*Remainder = Expr.Remainder;
}
return TRUE;
}
return FALSE;
}
__inline BOOL
TranslateVirtualToPhysical(
ULONG64 Virtual,
ULONG64* Physical
)
{
TRANSLATE_VIRTUAL_TO_PHYSICAL VToP;
VToP.Virtual = Virtual;
if (Ioctl(IG_TRANSLATE_VIRTUAL_TO_PHYSICAL, (PVOID)&VToP, sizeof(VToP)))
{
*Physical = VToP.Physical;
return TRUE;
}
return FALSE;
}
__inline BOOL
GetDebuggerCacheSize(
OUT PULONG64 CacheSize
)
{
return Ioctl(IG_GET_CACHE_SIZE, (PVOID) CacheSize, sizeof(ULONG64));
}
#endif
#ifdef __cplusplus
}
#endif
#endif // _WDBGEXTS_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -