[SIZE=3]
//
打印出指定结构的元素名称及偏移[
/SIZE
]
[SIZE=3]
//
利用DbgHelp的SymGetTypeInfo函数先取得结构ID,然后取[
/SIZE
]
[SIZE=3]
//
结构元素个数,最后取得元素名称和偏移[
/SIZE
]
bool HySymPrintStructElements(DWORD64 ModBase,const char *StructName)
{
bool bRet =
false
;
PSYMBOL_INFO pSI = malloc(sizeof(SYMBOL_INFO)+MAX_SYM_NAME);
if
(!pSI) goto QUIT;
pSI->SizeOfStruct = sizeof(SYMBOL_INFO);
pSI->MaxNameLen = MAX_SYM_NAME;
pSI->ModBase = ModBase;
if
(!HySymGetTypeInfo(ModBase,StructName,pSI))
{
PRINT(
"[%s]err : Get Struct Info Failed!\n"
,__func__);
goto QUIT;
}
else
{
PRINT(
"[%s]msg Struct TypeIndex is %d\n"
,__func__,\
pSI->TypeIndex);
}
UINT ElementCount;
PVOID pData = &ElementCount;
if
(!SymGetTypeInfo(GetCurrentProcess(),\
ModBase,pSI->TypeIndex,TI_GET_CHILDRENCOUNT,pData))
{
PRINT(
"[%s]err : Get Type Element Count Failed!\n"
,\
__func__);
goto QUIT;
}
PRINT(
"[%s]msg : Element Count is %d\n"
,__func__,\
ElementCount);
TI_FINDCHILDREN_PARAMS *pCP = malloc(sizeof(ULONG)*(2+ElementCount));
if
(!pCP) goto QUIT;
memset(pCP,
'\0'
,sizeof(ULONG)*(2+ElementCount));
pCP->Count = ElementCount;
if
(!SymGetTypeInfo(GetCurrentProcess(),ModBase,\
pSI->TypeIndex,TI_FINDCHILDREN,pCP))
{
PRINT(
"[%s]err : Get Type Element Failed!\n"
,__func__);
goto QUIT;
}
WCHAR *pNameW = NULL;
for
(int i = 0;i < ElementCount;++i)
{
PRINT(
"[%02d] TypeIndex is %d\n"
,i,pCP->ChildId[i]);
if
(SymGetTypeInfo(GetCurrentProcess(),ModBase,\
pCP->ChildId[i],TI_GET_SYMNAME,&pNameW))
{
wprintf(L
"Name is %s\n"
,pNameW);
LocalFree(pNameW);
}
else
PrintErr();
}
bRet =
true
;
QUIT:
free
(pCP);
free
(pSI);
return
bRet;
}
[SIZE=3]
//
返回PE文件中指定段的文件偏移地址。
//
因为Win32k所支持的SSDTSdw表在Win32k.sys文件中的偏移地址
//
就在其数据段的文件偏移0处。(2k,xp,2k3,win7)
//
注意在某些版本的xp(sp2)下有问题,不排除第三方程序干扰的原因。[
/SIZE
]
static PVOID GetPESectionOffset(FILE *pf,const char *SectionName)
{
PVOID RetDO = NULL;
size_t SectionCount = 0;
PVOID pNTHeader;
IMAGE_NT_HEADERS ImgNTHeaders;
if
(!SectionName)
return
RetDO;
//
定位IMAGE_NT_HEADERS结构的位置信息
fseek(pf,offsetof(IMAGE_DOS_HEADER,e_lfanew),SEEK_SET);
//
读取IMAGE_NT_HEADERS的位置
fread(&pNTHeader,sizeof(long),1,pf);
//
将文件指针定位到IMAGE_NT_HEADERS的位置
fseek(pf,(long)pNTHeader,SEEK_SET);
//
读取IMAGE_NT_HEADERS结构
fread(&ImgNTHeaders,sizeof(IMAGE_NT_HEADERS),1,pf);
//
取得SECTION数目
SectionCount = ImgNTHeaders.FileHeader.NumberOfSections;
PRINT(
"[%s]msg : SectionCount is %d\n"
,__func__,SectionCount);
//
不需要显式fseek到SECTION TABLE,前面fread已经移动到正确的偏移了。
//fseek
(pf,(long)sizeof(IMAGE_NT_HEADERS),SEEK_CUR);
IMAGE_SECTION_HEADER ImgSecHeaders[SectionCount];
//
读取SECTION数组
fread(ImgSecHeaders,sizeof(ImgSecHeaders),1,pf);
for
(size_t i = 0;i<SectionCount;++i)
{
if
(strstr(ImgSecHeaders[i].Name,SectionName))
{
RetDO = (PVOID)ImgSecHeaders[i].PointerToRawData;
break
;
}
}
return
RetDO;
}
[SIZE=3]
//
从Win32k.sys中获得原始SSDTSdw表中的项目。[
/SIZE
]
static bool GetSSDTSdwOrg(PVOID buf,size_t size)
{
bool bRet =
false
;
if
(!buf || !size) goto QUIT;
FILE *pf = fopen(g_Win32kFilePath,
"rb"
);
if
(!pf) goto QUIT;
//
获取Win32k.sys中data段的文件偏移,SSDTSdw就放在该偏移。
PVOID SSDTSdwFileOffset = GetPESectionOffset(pf,
".data"
);
if
(!SSDTSdwFileOffset) goto QUIT;
fseek(pf,(long)SSDTSdwFileOffset,SEEK_SET);
fread(buf,size,1,pf);
bRet =
true
;
QUIT:
if
(pf) fclose(pf);
return
bRet;
}