📄 wdbgexts.h
字号:
is.AddressSpace = addressspace;
Ioctl( IG_READ_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
*data = is.Data;
*size = is.Length;
}
__inline VOID
ReadIoSpaceEx32(
ULONG address,
PULONG data,
PULONG size,
ULONG interfacetype,
ULONG busnumber,
ULONG addressspace
)
{
IOSPACE_EX32 is;
is.Address = address;
is.Length = *size;
is.Data = 0;
is.InterfaceType = interfacetype;
is.BusNumber = busnumber;
is.AddressSpace = addressspace;
Ioctl( IG_READ_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
*data = is.Data;
*size = is.Length;
}
__inline VOID
ReadIoSpaceEx64(
ULONG64 address,
PULONG data,
PULONG size,
ULONG interfacetype,
ULONG busnumber,
ULONG addressspace
)
{
IOSPACE_EX64 is;
is.Address = address;
is.Length = *size;
is.Data = 0;
is.InterfaceType = interfacetype;
is.BusNumber = busnumber;
is.AddressSpace = addressspace;
Ioctl( IG_READ_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
*data = is.Data;
*size = is.Length;
}
__inline VOID
WriteIoSpaceEx(
ULONG address,
ULONG data,
PULONG size,
ULONG interfacetype,
ULONG busnumber,
ULONG addressspace
)
{
IOSPACE_EX is;
is.Address = (ULONG)address;
is.Length = *size;
is.Data = data;
is.InterfaceType = interfacetype;
is.BusNumber = busnumber;
is.AddressSpace = addressspace;
Ioctl( IG_WRITE_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
*size = is.Length;
}
__inline VOID
WriteIoSpaceEx32(
ULONG address,
ULONG data,
PULONG size,
ULONG interfacetype,
ULONG busnumber,
ULONG addressspace
)
{
IOSPACE_EX32 is;
is.Address = address;
is.Length = *size;
is.Data = data;
is.InterfaceType = interfacetype;
is.BusNumber = busnumber;
is.AddressSpace = addressspace;
Ioctl( IG_WRITE_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
*size = is.Length;
}
__inline VOID
WriteIoSpaceEx64(
ULONG64 address,
ULONG data,
PULONG size,
ULONG interfacetype,
ULONG busnumber,
ULONG addressspace
)
{
IOSPACE_EX64 is;
is.Address = address;
is.Length = *size;
is.Data = data;
is.InterfaceType = interfacetype;
is.BusNumber = busnumber;
is.AddressSpace = addressspace;
Ioctl( IG_WRITE_IO_SPACE_EX, (PVOID)&is, sizeof(is) );
*size = is.Length;
}
__inline VOID
ReloadSymbols(
IN PSTR Arg OPTIONAL
)
/*++
Routine Description:
Calls the debugger to reload symbols.
Arguments:
Args - Supplies the tail of a !reload command string.
!reload [flags] [module[=address]]
flags: /n do not load from usermode list
/u unload symbols, no reload
/v verbose
A value of NULL is equivalent to an empty string
Return Value:
None
--*/
{
Ioctl(IG_RELOAD_SYMBOLS, (PVOID)Arg, Arg?(strlen(Arg)+1):0);
}
__inline VOID
GetSetSympath(
IN PSTR Arg,
OUT PSTR Result OPTIONAL,
IN int Length
)
/*++
Routine Description:
Calls the debugger to set or retrieve symbol search path.
Arguments:
Arg - Supplies new search path. If Arg is NULL or string is empty,
the search path is not changed and the current setting is
returned in Result. When the symbol search path is changed,
a call to ReloadSymbols is made implicitly.
Result - OPTIONAL Returns the symbol search path setting.
Length - Supplies the size of the buffer supplied by Result.
Return Value:
None
--*/
{
GET_SET_SYMPATH gss;
gss.Args = Arg;
gss.Result = Result;
gss.Length = Length;
Ioctl(IG_GET_SET_SYMPATH, (PVOID)&gss, sizeof(gss));
}
#if defined(KDEXT_64BIT)
__inline
ULONG
IsPtr64(
void
)
{
static ULONG flag = -1;
ULONG dw;
if (flag == -1) {
if (Ioctl(IG_IS_PTR64, &dw, sizeof(dw))) {
flag = ((dw != 0) ? 1 : 0);
} else {
flag = 0;
}
}
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 PUCHAR Type
)
{
SYM_DUMP_PARAM Sym = {
sizeof (SYM_DUMP_PARAM), 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 < size to be copied.
Returns size of the type on success, 0 otherwise.
**/
__inline
ULONG
GetFieldData (
IN ULONG64 TypeAddress,
IN PUCHAR Type,
IN PUCHAR Field,
IN ULONG OutSize,
OUT PVOID pOutValue
)
{
FIELD_INFO flds = {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), 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(0, EXCEPTION_ACCESS_VIOLATION, 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 PUCHAR Name,
IN USHORT StoreAddress
)
{
ULONG RetVal;
static PUCHAR LastType;
static ULONG64 LastAddress;
FIELD_INFO flds = {Name, NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL};
SYM_DUMP_PARAM Sym = {
sizeof (SYM_DUMP_PARAM), LastType, DBG_DUMP_NO_PRINT, LastAddress,
NULL, NULL, NULL, 1, &flds
};
if (StoreAddress) {
LastAddress = TypeAddress;
LastType = Name;
return GetTypeSize(LastType); // non-zero on success
}
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)
//
// 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 PUCHAR Type,
IN ULONG64 Address,
IN USHORT ListByFieldAddress,
IN PUCHAR NextPointer,
IN PVOID Context,
IN PSYM_DUMP_FIELD_CALLBACK CallbackRoutine
)
{
//
// Number of elements to list limited to 30
//
FIELD_INFO flds = {NextPointer, NULL, 30, 0, 0, NULL};
SYM_DUMP_PARAM Sym = {
sizeof (SYM_DUMP_PARAM), 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 );
}
#endif // defined(KDEXT_64BIT)
__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
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;
}
#endif
#ifdef __cplusplus
}
#endif
#endif // _WDBGEXTS_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -