ZwQuerySystemInformation列舉核心模組及簡單應用

Max Woods發表於2014-08-12

簡單說,即呼叫第11號功能,列舉一下核心中已載入的模組。
部分程式碼如下:
//功能號為11,先獲取所需的緩衝區大小
ZwQuerySystemInformation(SystemModuleInformation,NULL,0,&needlen);
//申請記憶體
ZwAllocateVirtualMemory(NtCurrentProcess(),(PVOID*)&pBuf,0,&needlen,MEM_COMMIT,PAGE_READWRITE);
//再次呼叫
ZwQuerySystemInformation(SystemModuleInformation,(PVOID)pBuf,truelen,&needlen);
......
//最後,釋放記憶體
ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&pBuf,&needlen,MEM_RELEASE);

突出過程,省略了錯誤判斷,和呼叫其它的功能時操作並沒有什麼區別。
關鍵在返回的內容中,緩衝區pBuf的前四個位元組是已載入的模組總數,記為ModuleCnt,接下來就是共有ModuleCnt個元素的模組資訊陣列了。
該結構如下:

typedef struct _SYSTEM_MODULE_INFORMATION {
ULONG Count;
SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

模組詳細資訊結構如下:

typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY {
HANDLE Section;
PVOID MappedBase;
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT PathLength;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;

一個for迴圈,迴圈ModuleCnt次就OK了。
基於此,寫了三個簡單的函式。

void ShowAllModules(char *pBuf)
{
//函式功能:輸出所有模組資訊
//引數pBuf:ZwQuerySystemInformation返回的緩衝區首址
PSYSTEM_MODULE_INFORMATION_ENTRY pSysModuleInfo;
DWORD Modcnt=0;
Modcnt=*(DWORD*)pBuf;
pSysModuleInfo=(PSYSTEM_MODULE_INFORMATION_ENTRY)(pBuf+sizeof(DWORD));
for (DWORD i=0;i<Modcnt;i++)
{
   printf("%d\t0x%08X 0x%08X %s\n",pSysModuleInfo->LoadOrderIndex,pSysModuleInfo->Base,pSysModuleInfo->Size,pSysModuleInfo->ImageName);
   pSysModuleInfo++;
}

}
void GetOSKrnlInfo(char *pBuf,DWORD *KernelBase,char *szKrnlPath)
{
//函式功能:返回系統核心(ntoskrnl.exe或ntkrnlpa.exe)的基址和路徑
//引數pBuf:ZwQuerySystemInformation返回的緩衝區首址
//引數KernelBase:接收返回的系統核心的基址
//引數szKrnlPath:接收返回的核心檔案的路徑
PSYSTEM_MODULE_INFORMATION_ENTRY pSysModuleInfo;
DWORD Modcnt=0;
*KernelBase=0;
Modcnt=*(DWORD*)pBuf;
pSysModuleInfo=(PSYSTEM_MODULE_INFORMATION_ENTRY)(pBuf+sizeof(DWORD));
//其實第一個模組就是了,還是驗證一下吧
if (strstr((strlwr(pSysModuleInfo->ImageName),pSysModuleInfo->ImageName),"nt"))
{
   *KernelBase=(DWORD)pSysModuleInfo->Base;
   GetSystemDirectory(szKrnlPath,MAX_PATH);
   lstrcat(szKrnlPath,strrchr(pSysModuleInfo->ImageName,'\\'));
}
}


void DetectModule(char *pBuf,DWORD dwAddress,char *ModulePath)
{
//函式功能:找出給定地址所在的模組
//引數pBuf:緩衝區地址,同上
//引數dwAddress:要查詢的核心地址
//引數ModulePath:接收返回的模組路徑
PSYSTEM_MODULE_INFORMATION_ENTRY pSysModuleInfo;
DWORD Modcnt=0;
Modcnt=*(DWORD*)pBuf;
pSysModuleInfo=(PSYSTEM_MODULE_INFORMATION_ENTRY)(pBuf+sizeof(DWORD));
for (DWORD i=0;i<Modcnt;i++)
{
   if ((dwAddress>=(DWORD)pSysModuleInfo->Base)&&(dwAddress<(DWORD)pSysModuleInfo->Base+pSysModuleInfo->Size))
   {
    lstrcpy(ModulePath,pSysModuleInfo->ImageName);
   }
   pSysModuleInfo++;
}

 

相關文章