获取SSDT,SSSDT原始函数地址

2023-05-16

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;  
  
}SHADOWFUNC, *PSHADOWFUNC;  

SHADOWFUNC  g_ShadowFunc[827] = {0}; 

BOOL IsExist(ULONGLONG pSystemAdd)
{
	int		i = 0;
	BOOL	exist = FALSE;

	for(i = 0;i < 827; i++)
	{
		if(sssdt[i] == pSystemAdd)
		{
			exist = TRUE;
		}
	}
	return exist;
}

BOOL CALLBACK SymEnumSymbolsProc(  
                 PSYMBOL_INFO  pSymInfo,  
                 ULONG  SymbolSize,  
                 PVOID64  UserContext
                 )  
{  
		if(IsExist((ULONGLONG)pSymInfo->Address))
		{
			printf("0x%llx\t%s\n",(ULONGLONG)pSymInfo->Address,pSymInfo->Name);			
		}
  return TRUE;  
}  
 
BOOL CALLBACK SymEnumSymbolsProcForTable(  
                 PSYMBOL_INFO  pSymInfo,  
                 ULONG  SymbolSize,  
                 PVOID64  UserContext
                 )  
{  	
	if(strcmp("W32pServiceTable",pSymInfo->Name)==0)
	{
		*(PULONG64)UserContext = pSymInfo->Address;
		printf("W32pServiceTable:%llx\n",pSymInfo->Address);
	}
  return TRUE;  
}  

BOOL CALLBACK SymEnumSymbolsProcTest(  
                 PSYMBOL_INFO  pSymInfo,  
                 ULONG  SymbolSize,  
                 PVOID64  UserContext
                 )  
{  
	PULONGLONG temp = 0;
	
	if(UserContext == 0)//获取w32p
	{
		if(strcmp("W32pServiceTable",pSymInfo->Name)==0)
		{
			//printf("W32pServiceTable:%llx\n\n",pSymInfo->Address);
			g_w32pServiceTable = pSymInfo->Address;
		}
	}else
	{
		temp = (PULONGLONG)UserContext;

		for (i = 0; i < 827; i++)  
		{  
			 if ((ULONG64)*(temp + i) == (ULONG64)pSymInfo->Address)  
			 {  
				g_ShadowFunc[i].FuncAddr = (ULONG64)pSymInfo->Address;  
				lstrcpynA(g_ShadowFunc[i].FuncName, pSymInfo->Name, 100);   
				//printf("i:%d---Address:%llx,Name:%s\n",i,(ULONG64)pSymInfo->Address,&pSymInfo->Name);
			 }  
		}  
		
	}
  return TRUE;  
}  

//这个用来测试用的
void OrigFunction()
{
	  HANDLE		 hHandle = 0;  
	   
	  

	  hHandle = GetCurrentProcess(); 
	  printf("Are enumerated symbolic...\n\n");
	  SymInitialize(hHandle, NULL, TRUE);  
	  ploadImage = ImageLoad("win32k.sys", NULL);  
	  sssdt[0] = 0xFFFFF97FFF0DC4EC;
      sssdt[1] = 0xFFFFF97FFF0D5070;
	  sssdt[2] = 0xFFFFF97FFF077FA0;
	  sssdt[3] = 0xFFFFF97FFF085510;
	  ulBaseDll = SymLoadModule64(hHandle,\
								  ploadImage->hFile,\
								  "win32k.sys",\
								  "win32k.pdb",\
								  0,\
								  ploadImage->SizeOfImage);  
	  printf("SSSDTFunctionAddr\tSSSDTFunctionName\n");
	  printf("------------------\t------------------\n");
	  SymEnumSymbols(hHandle,\
					 ulBaseDll,\
					 NULL,\
					 SymEnumSymbolsProc,\
				     NULL); 
	  printf("\nEnumerations end of symbols...\n");
	  ImageUnload(ploadImage);  
	  SymCleanup(hHandle);  
	  getchar();
}

void GetOrigSSSDTAddr()
{
	  HANDLE		 hHandle = 0;  
	  PVOID		     pDrvAddr[128*8];
	  DWORD		     dwcbNeeded=0,n=0;
	  DWORD64		 dwBaseAddr = 0;
	  CHAR           *chName=(CHAR*)malloc(260);

	  SetConsoleTitleA("GetSSSDTOriginalFunctionAddrForWin7x64R3");

	  if (EnumDeviceDrivers(pDrvAddr,sizeof(pDrvAddr),&dwcbNeeded))
	  {
		  for (n=0 ; n<(dwcbNeeded/8) ; n++)
		  {
			  GetDeviceDriverBaseNameA(pDrvAddr[n],(LPSTR)chName,MAX_PATH);
			  if(strcmp("win32k.sys",chName)==0)
			  {
				  dwBaseAddr = (DWORD64)pDrvAddr[n];
				  //printf("%s 0x%llx\n\n",chName,(DWORD64)dwBaseAddr);
				  free(chName);
				  break;
			  }
		  }
	  }


	  hHandle = GetCurrentProcess(); 
	  printf("Are enumerated symbolic...\n\n");
	  SymInitialize(hHandle, NULL, TRUE);  
	  ploadImage = ImageLoad("win32k.sys", NULL);  
	  ulBaseDll = SymLoadModule64(hHandle,\
								  ploadImage->hFile,\
								  "win32k.sys",\
								  "win32k.pdb",\
								  0,\
								  ploadImage->SizeOfImage); 
	  SymEnumSymbols(hHandle,\
					 ulBaseDll,\
					 NULL,\
					 SymEnumSymbolsProcTest,\
				     NULL); 
	  if(g_w32pServiceTable!=0)
	  {
		  printf("Index\tSSSDTFunctionAddr\t\tSSSDTFunctionName\n");
		  printf("----\t------------------\t\t------------------\n");
		  //printf("g_w32pServiceTable:%llx ------ulBaseDll:%llx-------MappedAddr:%llx\n",g_w32pServiceTable,ulBaseDll,ploadImage->MappedAddress);
		  //getchar();
		  g_w32pServiceTable = g_w32pServiceTable - (ULONG64)ulBaseDll + (ULONG64)ploadImage->MappedAddress;
		  g_w32pServiceTable = g_w32pServiceTable - (ULONG64)0xc00;//ida中是以相对内存偏移对齐(1000)--内存映射是以相对稳健偏移对齐(400)  1000-400=0xc00
		  SymEnumSymbols(hHandle,ulBaseDll,NULL,SymEnumSymbolsProcTest,(PVOID64)g_w32pServiceTable);
	  }

	  for (i = 0; i < 827; i++)  
	  {  
		  //printf("%d\t0x%llx\t\t%s\n", i, g_ShadowFunc[i].FuncAddr, g_ShadowFunc[i].FuncName); 
		  printf("%d\t0x%llx\t\t%s\n",i,g_ShadowFunc[i].FuncAddr - ulBaseDll + (ULONG64)dwBaseAddr,g_ShadowFunc[i].FuncName);
		  K++;
		  if(K==100)
		  {
			  K = 0;
			  printf("\nInput [Enter] Continue running...\n\n");
			  getchar();
		  }
		
	  } 
	  ImageUnload(ploadImage);  
	  SymCleanup(hHandle);  
	  printf("\nThe current system consists of %d functions\n\n",i);
	  printf("Input [Enter] Exit...\n");
	  getchar();
}
//运行会很慢,
//需要的符号文件
//dbghelp.pdb
//imagehlp.pdb
//kernel32.pdb
//kernelbase.pdb
//msvcr110d.amd64.pdb
//msvcrt.pdb
//ntdll.pdb
//win32k.pdb
//首次运行成功后,在同目录下sym文件中可以找到相应的pdb文件,复制到同目录即可.

//这个是传入地址给出名称
void GetImageW32pSeviceTable(PULONG64 pW32SeviceTableAddr)
{
	  HANDLE		 hHandle = 0;  
	  ULONG64		 ulBaseDll = 0;  
	  PLOADED_IMAGE  ploadImage = {0}; 

	  hHandle = GetCurrentProcess(); 
	  printf("Are enumerated symbolic...\n\n");
	  SymInitialize(hHandle, NULL, TRUE);  
	  ploadImage = ImageLoad("win32k.sys", NULL);  
	  ulBaseDll = SymLoadModule64(hHandle,\
								  ploadImage->hFile,\
								  "win32k.sys",\
								  "win32k.pdb",\
								  0,\
								  ploadImage->SizeOfImage);  
	  SymEnumSymbols(hHandle,\
					 ulBaseDll,\
					 NULL,\
					 SymEnumSymbolsProcForTable,\
					 pW32SeviceTableAddr); 
	  printf("\nEnumerations end of symbols...\n");
	  ImageUnload(ploadImage);  
	  SymCleanup(hHandle);  
}


void main()  
{  
	  GetOrigSSSDTAddr();
	  return;
}


我在测试中并没有将

dbghelp.dll   symsrv.dll 放到exe目录

如果不能正常输出,可以到windbg目录下复制过来

如果还不没有效果,检测了自己网络没有问题后

添加环境变量

变量名:_NT_SYMBOL_PATH
变量值:SRV*{$Path}*http://msdl.microsoft.com/download/symbols/
将“{$Path}”替换为要存储pdb符号表文件的路径,比如:C:\PDB,在线的符号下载。

参考:http://www.cnblogs.com/lanrenxinxin/p/4513464.html

测试图:


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获取SSDT,SSSDT原始函数地址 的相关文章

  • Windows 远程桌面登录蓝屏、不显示桌面问题解决方法

    远程桌面登录蓝屏 不显示桌面问题解决方法 有时候的不当操作 xff0c 可以使Windows服务器或vps远程桌面出现蓝屏或者黑屏 xff01 遇到此问题 xff0c 不要急急忙忙的让机房值班给你重启机器 xff0c 因为此时除了远程连接不
  • 【5G核心网】5GC核心网之网元UPF

    UPF xff08 User Plane Function xff0c 用户面功能 xff09 xff1a ts 29 244 23 501 5 8 1 UPF User Plane Function 用户平面功能 用于RAT内 RAT间移
  • 玩转ADB命令(ADB命令使用大全)

    此文章内容整合自网络 xff0c 欢迎转载 我相信做Android开发的朋友都用过ADB命令 xff0c 但是也只是限于安装应用push文件和设备重启相关 xff0c 更深的就不知道了 xff0c 其实我们完全可以了解多一点 xff0c 有
  • Ubuntu12.04操作系统安装时,出现的问题及解决方案

    问题一 Windows 下用 putty 连接不上虚拟机上的 Ubuntu12 04 解决方案 预探索 问题可能的原因 A 先确定你能不能ping通远程的ubuntu或者虚拟机 B 如果还不能登录 xff0c 分析原因是大多数没有真正开启s
  • 获取镜像源来搭建本地Ubuntu14.04源

    针对公司的网络限制 xff0c 可以在局域网内搭建一台本地的ubuntu源 1 修改源配置 换成搜狐源 默认的ubuntu源不如某些国内的源速度快 vi etc apt source list deb http mirrors sohu c
  • Ubuntu Desktop 16 配置ssh远程登录

    文章目录 环境介绍1 安装openssh server2 允许用户登录 xff1b 编辑配置文件3 重启sshd服务并检查状态4 查看Ubuntu主机的IP5 远程登录Ubuntu6 退出远程登录参考文献英语好的同学请忽略 环境介绍 主机系
  • 关闭Linux防火墙

    文章目录 查看防火墙状态临时关闭防火墙禁止开机启动防火墙开启防火墙允许开机启动防火墙关闭防火墙的步骤 查看防火墙状态 CentOS 6 service iptables status CentOS 7 firewall cmd state
  • ubuntu挂载sd卡到分区目录+修改docker镜像存储位置

    ubuntu挂载sd卡到分区目录 43 修改docker镜像存储位置 一 挂载SD卡到 data 1 查看Linux硬盘信息 lsblk 或 fdisk l lsblk 新的硬盘 xff0c 最好删除之前的分区 xff0c 再新建分区 de
  • xRDP "Password failed, error - problem connecting"

    Add this in sesman ini under Xvnc solved my problem param8 61 SecurityTypes param9 61 None This solved my problum sudo n
  • 如何远程公司 上班族必选大集合

    老张是我们销售部的经理 xff0c 为人随和 xff0c 一点架子也没有 xff0c 和我们关系搞的都很好 xff0c 也很袒护我们 xff0c 由于疫情的原因 xff0c 不得已要居家办公了 xff0c 这让同事们都很不适应 xff0c
  • C语言排序算法之简单交换法排序,直接选择排序,冒泡排序

    C语言排序算法之简单交换法排序 xff0c 直接选择排序 xff0c 冒泡排序 xff0c 最近考试要用到 xff0c 网上也有很多例子 xff0c 我觉得还是自己写的看得懂一些 简单交换法排序 1 简单交换法 排序 2 根据序列中两个记录
  • Centos7 防火墙开放端口,查看状态,查看开放端口

    CentOS7 端口的开放关闭查看都是用防火墙来控制的 xff0c 具体命令如下 xff1a 查看防火墙状态 xff1a xff08 active running 即是开启状态 xff09 root 64 WSS bin systemctl
  • C标准库源码解剖(13):输入输出函数stdio.h

    C标准中的I O库是一个比较庞大的库 xff0c 实现也比较复杂 显然I O库的实现是依赖于操作系统的 xff0c 不同的系统上I O库的实现机理是不一样的 glibc中 xff0c I O库的核心实现在libio目录下 有4个头文件lib
  • 开源的多媒体播放器MPV

    最近在网上找到了一个很好用的开源多媒体播放器MPV 它功能强大 免费开源 支持多平台的极简播放器 底层采用了 MPlayer mplayer2 和 FFmpeg 等开源项目 xff0c 支持多种音视频格式 高清视频 GPU 解码 自定义等功
  • 计算机自动更新变灰色,无法修改解决方法。

    第一种办法 xff1a 使用本地组策略配置自动更新 1 单击 开始 xff0c 然后单击 运行 2 键入 gpedit msc xff0c 然后单击确定 3 展开 计算机配置 4 右键单击 管理模板 xff0c 然后单击 添加 删除模板 5
  • vscode 安装go环境无法安装gopls等插件,响应超时、失去连接等问题的简单解决方案

    看错误提示就大概明白 xff0c 是国内无法连接到 golang org 尝试下载了镜像网站 github com golang 里面的 tools 也不靠谱 因为安装时总会缺少非常多的插件 xff0c 导致无法简单地执行 go insta
  • UIImageView的图片居中问题

    我们都知道在ios中 xff0c 每一个UIImageView都有他的frame大小 xff0c 但是如果图片的大小和这个frame的大小不符合的时候会怎么样呢 xff1f 在默认情况 xff0c 图片会被压缩或者拉伸以填满整个区域 通过查
  • mysqld.exe 占了400M内存的问题

    最近遇到了服务器总是停机的问题 xff0c 虽然它自己只有2G的内存 xff0c 不过实际部署的应用访问量非常小 xff0c 也不至于2G就不够用 xff0c 所以开始了给服务器瘦身的计划 看着任务管理器里面的各个进程 xff0c 发现吃内
  • mysql对外数据连接出现1356错误,1130错误!!!

    问题描述 xff1a 供别的电脑连接本机的数据库 xff0c 总是连接不上 报1356错误 最后查阅相关资料说是 xff1a 连接账户没有远程连接权限 xff0c 只能在本机登录 需要更改mysql数据库里面user表格里的host项把lo
  • Python-docx 读写 Word 文档:读取正文、表格文本信息、段落格式、字体格式等

    Python docx 模块读写 Word 文档基础 xff08 三 xff09 xff1a 读取文档文本信息 表格信息 段落格式 字体格式等 前言 xff1a 1 获取文档章节信息 xff1a 2 获取段落文字信息 xff1a 3 获取文

随机推荐