首页
社区
课程
招聘
[已解决] [求助] ntoskrnl可选头的ImageBase是怎么被设置成内核基址的? 10雪币
发表于: 7小时前 164

[已解决] [求助] ntoskrnl可选头的ImageBase是怎么被设置成内核基址的? 10雪币

7小时前
164

以前看别的大佬写的代码都是直接从内核可选头拿到内核基址,我以前写代码也学着这么写

导致我一直以为驱动或者程序被加载以后会有机制把已经被加载到内存里的可选头ImageBase改成实际的va

但是今天偶然发现好像只有ntoskrnl有这个待遇:
比如说我现在的内核基址是:fffff80697200000


lkd> dt _IMAGE_DOS_HEADER fffff80697200000
nt!_IMAGE_DOS_HEADER
(省略掉)
   +0x03c e_lfanew         : 0n280

lkd> dt _IMAGE_NT_HEADERS64 fffff80697200000+0n280
nt!_IMAGE_NT_HEADERS64
   +0x000 Signature        : 0x4550
   +0x004 FileHeader       : _IMAGE_FILE_HEADER
   +0x018 OptionalHeader   : _IMAGE_OPTIONAL_HEADER64

lkd> dx -id 0,0,ffffbd06a6731040 -r1 (*((ntkrnlmp!_IMAGE_OPTIONAL_HEADER64 *)0xfffff80697200130))(*((ntkrnlmp!_IMAGE_OPTIONAL_HEADER64 *)0xfffff80697200130))                 [Type: _IMAGE_OPTIONAL_HEADER64]
    (也略掉)
    [+0x018] ImageBase        : 0xfffff80697200000 [Type: unsigned __int64]

可以发现这里内存里的ImageBase确实是内核基址,

而且貌似完全不受kaslr的影响,哪怕开了kaslr这里边也放的是真实内核基址。。


然而我去实验了一下别的已加载驱动/内核模块(比如说hal.dll ci.dll和其他的一些驱动等等)

他们加载到内存以后这个ImageBase都和硬盘里面的原始映像一致比如说是0x140000000这样

用户态的exe我也看了几个,没有一个imagebase被改了的

 

windows internal我去翻了翻也没翻到有什么提到他的地方

网上也没搜到这个内核的可选头到底是谁改的,问ai也给不出啥可信的文档来源

本人小白一枚win引导过程不是很了解,有没有比较懂这一块的大佬给指个路,用不着太细给个方向我自己研究就行,感激不尽!!!


[内核课程]《Windows内核攻防实战》!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。

收藏
免费 0
打赏
分享
最新回复 (2)
雪    币: 3841
活跃值: (2614)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
2
winload.efi加载内核
OslpLoadAllModules -> OslLoadImage -> BlLdrLoadImage/LdrpLoadImage -> ImgpLoadPEImage
ImgpLoadPEImage里面判断条件把mov qword ptr [r15+0x30], rsi,把ImageBase改为实际地址。

具体判断条件来说,nt的地址是预申请的,OslLoadImage的ImageFlags = IMAGE_FLAGS_MEMORY_PRE_ALLOCATED,其他不是。
7小时前
1
雪    币: 58
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3

上面大佬给的点配合ai大概看明白了:

winload.efi里面


OslpLoadAllModules里面ntoskrnl被加载了两次,

第一次加载


第二次加载


关注loadflags

关键在于loadflags导致加载好的nt可选头imagebase被修改

这个flag和预分配来的基地址和大小一路顺着这些函数往下传:

OslLoadImage → BlLdrLoadImage → LdrpLoadImage → BlImgLoadPEImageEx → ImgpLoadPEImage

最终走到

ImgpLoadPEImage


关键代码:

flag 0x4不置位的时候会调用BlImgAllocateImageBuffer,第一个参数传入的时候是首选基地址也就是可选头里面的,传出的时候是实际分配到的
第一次加载的时候0x4置位了所以不走这个分支,用上面默认传进来的

设置imagebase的地方:

感谢上面的大佬,希望能帮到其他人

还有点其他不重要的小问题暂时没有搞懂明天再说吧



1小时前
0
游客
登录 | 注册 方可回帖
返回