找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 26707|回复: 33

[求助]关于win10 x64下获取ssdt原始函数地址的问题(已解决)

 火.. [复制链接]

1

主题

7

回帖

0

精华

铜牌会员

积分
40
发表于 2018-2-28 14:35:47 | 显示全部楼层 |阅读模式
最近在学习win64下的驱动编程, 想自己写一款ARK软件
在坛主的<<WIN64驱动编程基础教程>> 中的关于SSDT UnHook获取SSDT原始函数地址的算法:
QQ截图20180228141813.png
代码是这么实现的基本就是教程里的代码,我稍微改动了一些:

获取NtosBase的函数:
  1. VOID CUtils::GetNtosBase(ULONGLONG& NtosBase, CHAR* NtosName)
  2. {
  3.         char FileName[260] = { 0 }, *FullName;
  4.         NtosBase = GetNtosBaseAndPath(FileName);
  5.         FullName = cs("C:\\Windows\\system32\", FileName);
  6.         strcpy(NtosName, FullName);
  7.         printf("NTOSKRNL base: %llx\n", NtosBase);
  8.         printf("NTOSKRNL name: %s\n", NtosName);
  9. }
复制代码


获取NtosImageBase的函数
  1. VOID CUtils::GetNtosImageBase(ULONGLONG  &NtosImageBase, char* NtosName)
  2. {
  3.         PIMAGE_NT_HEADERS64 pinths64;
  4.         PIMAGE_DOS_HEADER pdih;
  5.         char *NtosFileData = NULL;
  6.         NtosFileData = LoadDllContext(NtosName);
  7.         pdih = (PIMAGE_DOS_HEADER)NtosFileData;
  8.         pinths64 = (PIMAGE_NT_HEADERS64)(NtosFileData + pdih->e_lfanew);
  9.         NtosImageBase = pinths64->OptionalHeader.ImageBase;
  10.         printf("ImageBase: %llx\n", NtosImageBase);
  11.         free(NtosFileData);
  12. }
复制代码

最终获取原始函数地址的函数:
  1. ULONGLONG CSSDTHookView::GetFunctionOriginalAddress(DWORD index)
  2. {
  3.         //"C:\\Windows\\system32\\ntkrnlmp.exe"
  4.         if (NtosInProcess == 0)
  5.                 NtosInProcess = (ULONGLONG)LoadLibraryExA(NtosName, 0, DONT_RESOLVE_DLL_REFERENCES);  

  6.         if (KiServiceTable == 0)
  7.         {
  8.                 DWORD dwRet = 0;
  9.                 KiServiceTableAddr_INFO info;
  10.                 DriverCtrl::GetInstance()->IoControl(0x807, 0, 0, &info, sizeof(KiServiceTableAddr_INFO), &dwRet);

  11.                 if (dwRet <= 0)
  12.                 {
  13.                         MessageBox(L"获取KiServerTable地址失败", L"错误");
  14.                         return 0;
  15.                 }

  16.                 KiServiceTable = info.addr;
  17.         }

  18.         ULONGLONG RVA = KiServiceTable - NtosBase;
  19.         ULONGLONG test = (NtosInProcess + RVA + 8 * (ULONGLONG)index);
  20.         ULONGLONG temp =  *(PULONGLONG) (NtosInProcess + RVA + 8 * (ULONGLONG)index);
  21.         //IMAGE_OPTIONAL_HEADER64.ImageBase=0x140000000(这个值基本是固定的)  
  22.         ULONGLONG RVA_index = temp - NtosImageBase;
  23.         return RVA_index + NtosBase;
  24. }
复制代码


我调试看了,其中的KiServiceTable  的地址是没问题的, 这是一次我调试断点变量的值
  1. NtosInProcess   7ff6f7ff0000
  2. NtosBase   fffff800e881e000
  3. KiServiceTable  fffff800e8b6d000
  4. NtosImageBase 140000000
复制代码


好像也都没什么问题,但是计算结果还有很大误差,我本机没有开任何可能hook ssdt(修该)函数地址的软件
下面是我的程序获取到的截图
2.png

这是我的系统版本信息


6.png



这个问题困扰我好几天了, 各种百度谷歌没有找到好的解决办法, 希望路过的大牛不吝赐教,指点一下, 先谢谢了!

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2018-2-28 21:30:59 | 显示全部楼层
从WIN10某版本开始获取原始地址的方法变化了。具体公式是:
游客,如果您要查看本帖隐藏内容请回复
由于已转PHP开发,具体细节我记不清了。你应该用IDA看看。

78

主题

190

回帖

9

精华

贵宾会员

积分
15605
发表于 2018-2-28 23:39:15 | 显示全部楼层
简单说一下,win10x64th2及之前的版本,原始地址的保存方式是八字节的,每个地址是需要重定向的绝对地址,但从win10x64rs1开始,原始地址保存方式是四字节的,每个地址是不需要重定向的相对地址。
简单说公式就是
original_address=image_base+address_read_from_file
其中original_address和image_base是八字节整形,address_read_from_file是四字节整形
之前的公式是:
original_address=image_base+(address_read_from_file-file_image_base)
这四个变量都是八字节整形,括号内计算的是重定向

1

主题

7

回帖

0

精华

铜牌会员

积分
40
 楼主| 发表于 2018-3-1 11:49:47 | 显示全部楼层
Tesla.Angela 发表于 2018-2-28 21:30
从WIN10某版本开始获取原始地址的方法变化了。具体公式是:**** 本内容被作者隐藏 ****由于已转PHP开发,具 ...

嗯, 你说的新公式我试了下是可以的,谢谢

1

主题

7

回帖

0

精华

铜牌会员

积分
40
 楼主| 发表于 2018-3-1 11:55:26 | 显示全部楼层
tangptr@126.com 发表于 2018-2-28 23:39
简单说一下,win10x64th2及之前的版本,原始地址的保存方式是八字节的,每个地址是需要重定向的绝对地址, ...

嗯, 很佩服像你这样驾轻就熟的大牛,  我用ida 查看 ntosknrl.exe ,找了半天也没找到KiServerTable它初始化函数地址的地方【类似下面这张图片展示的地方】


哎。。。, 这次算是从你这里直接拿了条鱼回家吧,万分感谢。


1

主题

7

回帖

0

精华

铜牌会员

积分
40
 楼主| 发表于 2018-3-1 12:22:07 | 显示全部楼层

【分享】win10 x64通过读取ntoskrnl.exe文件获取ssdt函数原始

本帖最后由 T3Shell 于 2018-3-1 12:28 编辑

感谢Tesla.Angelatangptr 两位大大的解答

坛主在《WIN64驱动编程基础教程>》 中提到的关于SSDT UnHook获取SSDT原始函数地址的算法是这样的:
QQ截图20180228141813.png

计算ssdt原始地址的关键算法是这样写的【代码大部分都是坛主和网友写的】
  1. ULONGLONG CSSDTHookView::GetFunctionOriginalAddress(DWORD index)
  2. {
  3.         //"C:\\Windows\\system32\\ntkrnlmp.exe"
  4.         if (NtosInProcess == 0)
  5.                 NtosInProcess = (ULONGLONG)LoadLibraryExA(NtosName, 0, DONT_RESOLVE_DLL_REFERENCES);  

  6.         if (KiServiceTable == 0)
  7.         {
  8.                 DWORD dwRet = 0;
  9.                 KiServiceTableAddr_INFO info;
  10.                 DriverCtrl::GetInstance()->IoControl(0x807, 0, 0, &info, sizeof(KiServiceTableAddr_INFO), &dwRet);

  11.                 if (dwRet <= 0)
  12.                 {
  13.                         MessageBox(L"获取KiServerTable地址失败", L"错误");
  14.                         return 0;
  15.                 }

  16.                 KiServiceTable = info.addr;
  17.         }

  18.         ULONGLONG RVA = KiServiceTable - NtosBase;
  19.         ULONGLONG test = (NtosInProcess + RVA + 8 * (ULONGLONG)index);
  20.         ULONGLONG temp =  *(PULONGLONG) (NtosInProcess + RVA + 8 * (ULONGLONG)index);
  21.         //IMAGE_OPTIONAL_HEADER64.ImageBase=0x140000000(这个值基本是固定的)  
  22.         ULONGLONG RVA_index = temp - NtosImageBase;
  23.         return RVA_index + NtosBase;
  24. }
复制代码


但是最近我在测试最新的win10 x64(1709)版本的时候发现获取的地址不对,在论坛提问
原提问帖子地址: [求助]关于win10 x64下获取ssdt原始函数地址的问题
tangptrz 大大是这么说的:

简单说一下,win10x64th2及之前的版本,原始地址的保存方式是八字节的,每个地址是需要重定向的绝对地址,但从win10x64rs1开始,原始地址保存方式是四字节的,每个地址是不需要重定向的相对地址。
简单说公式就是
original_address=image_base+address_read_from_file
其中original_address和image_base是八字节整形,address_read_from_file是四字节整形
之前的公式是:
original_address=image_base+(address_read_from_file-file_image_base)
这四个变量都是八字节整形,括号内计算的是重定向


Tesla.Angela 则给出了新的计算公式

VA = KiServiceTable - NtosBase + ReloadedNtosBase;
OriAddr = getdword(VA+Index*4) + NtosBase;



我最终修正后的算法是这样的:
  1. ULONGLONG CSSDTHookView::GetFunctionOriginalAddress(DWORD index)
  2. {
  3.         //"C:\\Windows\\system32\\ntkrnlmp.exe"
  4.         if (NtosInProcess == 0)
  5.                 NtosInProcess = (ULONGLONG)LoadLibraryExA(NtosName, 0, DONT_RESOLVE_DLL_REFERENCES);  

  6.         if (KiServiceTable == 0)
  7.         {
  8.                 DWORD dwRet = 0;
  9.                 KiServiceTableAddr_INFO info;
  10.                 DriverCtrl::GetInstance()->IoControl(0x807, 0, 0, &info, sizeof(KiServiceTableAddr_INFO), &dwRet);

  11.                 if (dwRet <= 0)
  12.                 {
  13.                         MessageBox(L"获取KiServerTable地址失败", L"错误");
  14.                         return 0;
  15.                 }

  16.                 KiServiceTable = info.addr;
  17.         }

  18.         ULONGLONG RVA = KiServiceTable - NtosBase;
  19.         ULONGLONG temp =  *(PULONG) (NtosInProcess + RVA + 4 * (ULONGLONG)index);
  20.         //IMAGE_OPTIONAL_HEADER64.ImageBase=0x140000000(这个值基本是固定的)  
  21.         ULONGLONG RVA_index = temp - NtosImageBase;
  22.         return temp + NtosBase;
  23. }
复制代码



图:
1117.png

最后非常感谢论坛积极热心的朋友们的耐心解答, 希望以后能和大家一起学习交流进步

祝大家狗年大吉大利,哈哈哈

评分

参与人数 1水晶币 +10 收起 理由
Tesla.Angela + 10 淡定

查看全部评分

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2018-3-1 13:23:26 | 显示全部楼层
两条公式分别生效于不同的系统,需要区分版本号。

此外,同样的内容没必要分成两个主题帖。

0

主题

6

回帖

0

精华

初来乍到

积分
16
发表于 2018-3-1 16:48:15 | 显示全部楼层
我来看看吧

0

主题

6

回帖

0

精华

初来乍到

积分
16
发表于 2018-3-1 16:51:36 | 显示全部楼层
希望楼主发个完整的代码获取SSDT地址的 小白可以学习

78

主题

190

回帖

9

精华

贵宾会员

积分
15605
发表于 2018-3-1 22:08:57 | 显示全部楼层
T3Shell 发表于 2018-3-1 11:55
嗯, 很佩服像你这样驾轻就熟的大牛,  我用ida 查看 ntosknrl.exe ,找了半天也没找到KiServerTable它初 ...

IDA有个功能叫jump by name的,直接输入KiServiceTable就行(对窗口凭空敲键盘)。如果没有就写_KiServiceTable

0

主题

111

回帖

0

精华

银牌会员

积分
340
发表于 2018-3-1 22:35:38 | 显示全部楼层
看下 学习下,谢谢开源

0

主题

2

回帖

0

精华

铜牌会员

积分
42
发表于 2018-3-5 19:46:04 | 显示全部楼层
学习学习

0

主题

52

回帖

0

精华

铜牌会员

积分
246
发表于 2018-3-10 15:30:47 | 显示全部楼层
win10 x64下获取ssdt

1

主题

21

回帖

0

精华

初来乍到

积分
21
发表于 2018-4-22 11:45:18 | 显示全部楼层
学习一下。

6

主题

123

回帖

0

精华

初来乍到

积分
5392
发表于 2018-5-1 19:16:30 | 显示全部楼层
谢谢楼主

0

主题

44

回帖

0

精华

铜牌会员

积分
130
发表于 2019-5-20 19:35:26 | 显示全部楼层
看下!!!

0

主题

48

回帖

0

精华

铜牌会员

积分
143
发表于 2019-6-6 13:25:15 | 显示全部楼层
学习一下。。。

0

主题

103

回帖

0

精华

初来乍到

积分
3
发表于 2019-8-13 09:59:47 | 显示全部楼层
谢谢分析,看看

1

主题

57

回帖

0

精华

铜牌会员

积分
68
发表于 2019-11-7 09:24:50 | 显示全部楼层
看看什么变化。

0

主题

4

回帖

0

精华

铜牌会员

积分
34
发表于 2019-11-14 17:42:26 | 显示全部楼层
66666666666666666666

0

主题

20

回帖

0

精华

初来乍到

积分
19
发表于 2019-11-18 05:07:30 | 显示全部楼层
谢谢分享

0

主题

72

回帖

0

精华

初来乍到

积分
31
发表于 2019-11-20 20:08:57 | 显示全部楼层
看看隐藏的高级内容

0

主题

74

回帖

0

精华

铜牌会员

积分
105
发表于 2019-11-27 09:12:53 | 显示全部楼层
谢谢

0

主题

29

回帖

0

精华

初来乍到

积分
23
发表于 2019-12-7 19:11:45 | 显示全部楼层
学习一下方法

5

主题

24

回帖

0

精华

初来乍到

积分
30
发表于 2019-12-12 14:23:54 | 显示全部楼层
看看公式

0

主题

87

回帖

0

精华

金牌会员

积分
1046
发表于 2019-12-16 14:38:54 | 显示全部楼层
从哪个版本开始变的?

0

主题

1

回帖

0

精华

初来乍到

积分
11
发表于 2020-1-31 19:48:47 | 显示全部楼层
来看看回复

0

主题

24

回帖

0

精华

初来乍到

积分
33
发表于 2020-4-18 20:17:46 | 显示全部楼层
谢谢层主

0

主题

8

回帖

0

精华

初来乍到

积分
18
发表于 2020-5-5 22:09:59 | 显示全部楼层
66666666666

0

主题

12

回帖

0

精华

初来乍到

积分
20
发表于 2021-3-7 13:22:14 | 显示全部楼层
小白可以学习

0

主题

12

回帖

0

精华

初来乍到

积分
20
发表于 2021-3-10 13:07:02 | 显示全部楼层
我来看看吧

1

主题

61

回帖

0

精华

铜牌会员

积分
99
发表于 2021-11-4 14:25:03 | 显示全部楼层
巩固一下
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表