您的当前位置:首页正文

我以为面试官在第二层,没想到他在第5层(dll注入:系统kernel32.dll为什么在每个进程中的基址相同)

2024-11-27 来源:个人技术集锦

在漫长的春招过程中,身为一个大三找实习的弱鸡,免不了被面试官捶打。
昨天被问到一个dll注入的问题,当时心想,正中我的下怀,唉,我就叽里呱啦把远程线程注入的实现过程讲了一下:

当然这是第一层,我知道面试肯定没有这么简单,我在第二层等着面试官。

果不其然,面试官问道:“唉,那么问题来了,你在不同的进程调用loadlibrary(),是怎么调用的?”

我以为到第二层就已经结束了。

没想到面试官非常兴奋地问道:“那么问题又来了,为什么dll在每个进程中默认加载机制一样?”

心里一惊 Σ(っ °Д °;)っ

硬着头皮回答道:“Windows默认系统dll在所有进程的加载基址不变,是因为所有进程公用一个内核空间,在内核空间对这里做了规定,所以加载基址一样。”
当然回答的时候,我知道这应该是不对的,所以一直用疑问的语气尝试让面试官给出结果。

这时候,我才意识到,原来面试官是在第5层。

然后我陷入了思考…

首先下面这句话,无疑是正确的。

Windows默认的是同一个系统中dll的文件加载位置是固定的。

然后下面这段话,无疑也是正确的。

那么当它们俩撞在了一起,就让我想起了矛盾相争的故事。“啊,我的茅牛逼,没有扎不破的盾,我的盾也牛逼,没有茅能扎破它”。

”每次加载基址变化的话,那么就绪要重定位,但是重定位的位置在每个进程中,不一定一样啊。”

面试官:“嗯,对,那你再想想,他是在什么时候进行处理的呢?”

我当时想的是,每次系统开启之后就不变了,那么我就赌一手:“每次系统开启的过程中,会进行重定位的处理,之后就不变了。”

面试官:“嗯嗯好,那下一个问题”。

我:疑惑脸,不知道自己回答的对不对,还是面试结束后再去看一下吧。
没想到这个问题老千层饼了。

下面进入正题。

为什么在ASLR机制下,系统DLL加载基址在每个进程中相同

ASLR机制:

这里有一篇是对为什么系统DLL加载基址不变的解释:
http://www.nynaeve.net/?p=198

简单概括:

似乎好像和我回答的有点相像。但这只是规定,我们就去看一下到底是不是这么一回事。

下面是用windbg查找kernel32.dll的基址(这里只是以kernel32为例)

通过查阅MSDN,知道,这个Flink指向的具体的数据结构类型是:_LDR_DATA_TABLE_ENTRY

但是至于这样子ASLR不改变进程中系统dll的基址的原因,我们还需要继续探究。

小弟才疏学浅,还得继续研究,留待搞清楚之后补齐。

显示全文