SSSDT的原始地址新的获取方法
时至今日发现我x64 下win32k.sys中W32pServiceTable是导出的... 一直没注意...
SSDT
当前函数地址 = KiSeviceTable + *(KiServiceTalbe + index * 4);TableRVA = KiSeviceTable - 内核真实加载地址 ;
ImageBase = 0x140000000;(理想加载地址)
ImageKiSeviceTable = ImageBase + TableRVA;
LoadDLLBase = LoadLibrary("内核文件");
x64下 如果内核文件是以理想地址加载(0x140000000)的话那么在KiServiceTable里面的的地址就是理想函数地址
比如:NtReadFile 它在KiServiceTable下的0x18处(index = 4) 那么这个KiserviectTable+0x18位置处存储的就是NtReadFile地址,只不过它是理想地址
思路:我们首先得到基于PE镜像基址的KiServieTalbe的RVA
我们程序直接加载内核文件到进程(LoadLibrary或者映射文件),这个时候我们得到加载到进程的内核Base
这个Base + RVA 就是进程内存中的KiServieTable的地址
我们读这个地址的值(得到了基于理想地址的函数地址) 然后减去理想加载地址就得到了函数与内核加载地址的RVA
这个RVA在跟真实的内核加载地址相加就得到了原始的函数地址
这上面是SSDT--SSSDT一致 需要注意的是相对文件偏移和相对内存偏移
我这里使用符号获取SSSDT名
关于符号解析请看我上一篇文章
代码实现 查看SSSDT原始函数地址
一次显示100个 一共有837个
#include <windows.h>
#include <stdio.h>
#include <Dbghelp.h>
#include <psapi.h>
#pragma comment(lib, "Dbghelp.lib")
#pragma comment(lib, "Imagehlp.lib")
//去除警告
PLOADED_IMAGE
IMAGEAPI
ImageLoad(
PCSTR DllName,
PCSTR DllPath
);
BOOL
IMAGEAPI
ImageUnload(
PLOADED_IMAGE LoadedImage
);
BOOL MapAndLoad(
PSTR ImageName,
PSTR DllPath,
PLOADED_IMAGE LoadedImage,
BOOL DotDll,
BOOL ReadOnly
);
BOOL UnMapAndLoad(
PLOADED_IMAGE LoadedImage
);
//SSSDT函数地址
ULONGLONG sssdt[827] = {0};
ULONGLONG g_w32pServiceTable = 0;
ULONGLONG K = 0;
ULONG64 ulBaseDll = 0;
PLOADED_IMAGE ploadImage = {0};
int i = 0;
typedef struct _SHADOWFUNC
{
CHAR FuncName[100];
ULONG64 FuncAddr;
}SHA