📄 ssdtdump.cpp
字号:
//////////////////////////////////////////////////////////////////////////
// SSDTDump by 李马
// http://www.titilima.cn
//////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <stdio.h>
#include "..\SYS\ioctl.h"
#include "SSDTDump.h"
#define MOV 0xb8
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
//
// MessageId: STATUS_INFO_LENGTH_MISMATCH
//
// MessageText:
//
// The specified information record length does not match the length required for the specified information class.
//
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemModuleInformation = 11
} SYSTEM_INFORMATION_CLASS;
typedef LONG NTSTATUS;
#pragma pack( push, 1 )
typedef struct _tagSSDTEntry {
BYTE byMov; // 0xb8
DWORD dwIndex;
} SSDTENTRY;
#pragma pack( pop )
typedef struct _SYSTEM_MODULE_INFORMATION {
ULONG Reserved[2];
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef struct _tagSysModuleList {
ULONG ulCount;
SYSTEM_MODULE_INFORMATION smi[1];
} SYSMODULELIST, *PSYSMODULELIST;
// NtQuerySystemInformation
typedef DWORD ( WINAPI * QSIPTR )( SYSTEM_INFORMATION_CLASS, LPVOID, DWORD, PULONG );
//////////////////////////////////////////////////////////////////////////
BOOL GetSSDT( IN HANDLE hDriver, OUT PSSDT buf )
{
if ( NULL == buf )
{
return FALSE;
}
DWORD dwReturned;
BOOL bRet = DeviceIoControl( hDriver, IOCTL_GETSSDT, NULL, 0, buf,
sizeof( SSDT ), &dwReturned, NULL );
return bRet && ERROR_SUCCESS == GetLastError();
}
BOOL GetProc( IN HANDLE hDriver, IN ULONG ulIndex, OUT PULONG buf )
{
if ( NULL == buf )
{
return FALSE;
}
DWORD dwReturned;
BOOL bRet = DeviceIoControl( hDriver, IOCTL_GETPROC, &ulIndex,
sizeof( ULONG ), buf, sizeof( ULONG ), &dwReturned, NULL );
return bRet && ERROR_SUCCESS == GetLastError();
}
//////////////////////////////////////////////////////////////////////////
PSYSMODULELIST CreateModuleList( IN HMODULE hNtDll )
{
QSIPTR NtQuerySystemInformation = (QSIPTR)GetProcAddress( hNtDll,
"NtQuerySystemInformation" );
NTSTATUS s;
ULONG nRetSize;
PSYSMODULELIST pRet = new SYSMODULELIST;
s = NtQuerySystemInformation( SystemModuleInformation, pRet,
sizeof( SYSMODULELIST ), &nRetSize );
if ( STATUS_INFO_LENGTH_MISMATCH == s )
{
// 缓冲区太小,重新分配
delete pRet;
pRet = (PSYSMODULELIST)new BYTE[nRetSize];
s = NtQuerySystemInformation( SystemModuleInformation, pRet,
nRetSize, &nRetSize );
}
if ( !NT_SUCCESS( s ) )
{
delete[] (LPBYTE)pRet;
return NULL;
}
else
{
return pRet;
}
}
void DestroyModuleList( IN PSYSMODULELIST pList )
{
delete[] (LPBYTE)pList;
}
BOOL FindModuleByAddr( IN ULONG ulAddr, IN PSYSMODULELIST pList,
OUT LPSTR buf, IN DWORD dwSize )
{
for ( ULONG i = 0; i < pList->ulCount; ++i )
{
ULONG ulBase = (ULONG)pList->smi[i].Base;
ULONG ulMax = ulBase + pList->smi[i].Size;
if ( ulBase <= ulAddr && ulAddr < ulMax )
{
// 对于路径信息,截取之
PCSTR pszModule = strrchr( pList->smi[i].ImageName, '\\' );
if ( NULL != pszModule )
{
lstrcpynA( buf, pszModule + 1, dwSize );
}
else
{
lstrcpynA( buf, pList->smi[i].ImageName, dwSize );
}
return TRUE;
}
}
return FALSE;
}
void EnumSSDT( IN HANDLE hDriver, IN HMODULE hNtDll )
{
DWORD dwOffset = (DWORD)hNtDll;
PIMAGE_EXPORT_DIRECTORY pExpDir = NULL;
int nNameCnt = 0;
LPDWORD pNameArray = NULL;
int i = 0;
// 到PE头部
dwOffset += ((PIMAGE_DOS_HEADER)hNtDll)->e_lfanew + sizeof( DWORD );
// 到第一个数据目录
dwOffset += sizeof( IMAGE_FILE_HEADER ) + sizeof( IMAGE_OPTIONAL_HEADER )
- IMAGE_NUMBEROF_DIRECTORY_ENTRIES * sizeof( IMAGE_DATA_DIRECTORY );
// 到导出表位置
dwOffset = (DWORD)hNtDll
+ ((PIMAGE_DATA_DIRECTORY)dwOffset)->VirtualAddress;
pExpDir = (PIMAGE_EXPORT_DIRECTORY)dwOffset;
nNameCnt = pExpDir->NumberOfNames;
// 到函数名RVA数组
pNameArray = (LPDWORD)( (DWORD)hNtDll + pExpDir->AddressOfNames );
// 初始化系统模块链表
PSYSMODULELIST pList = CreateModuleList( hNtDll );
// 循环查找函数名
for ( i = 0; i < nNameCnt; ++i )
{
PCSTR pszName = (PCSTR)( pNameArray[i] + (DWORD)hNtDll );
if ( 'N' == pszName[0] && 't' == pszName[1] )
{
// 找到了函数,则定位至查找表
LPWORD pOrdNameArray = (LPWORD)( (DWORD)hNtDll + pExpDir->AddressOfNameOrdinals );
// 定位至总表
LPDWORD pFuncArray = (LPDWORD)( (DWORD)hNtDll + pExpDir->AddressOfFunctions );
LPCVOID pFunc = (LPCVOID)( (DWORD)hNtDll + pFuncArray[pOrdNameArray[i]] );
// 解析函数,获取服务名
SSDTENTRY entry;
CopyMemory( &entry, pFunc, sizeof( SSDTENTRY ) );
if ( MOV == entry.byMov )
{
ULONG ulAddr = 0;
GetProc( hDriver, entry.dwIndex, &ulAddr );
CHAR strModule[MAX_PATH] = "[Unknown Module]";
FindModuleByAddr( ulAddr, pList, strModule, MAX_PATH );
printf( "0x%04X\t%s\t0x%08X\t%s\r\n", entry.dwIndex,
strModule, ulAddr, pszName );
}
}
}
DestroyModuleList( pList );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -