寻找遗失的Kernal32.dll—WinDbg&汇编—手动&动态

来源:互联网 发布:淘宝买铁观音 编辑:程序博客网 时间:2024/04/30 09:43

如果你是因为标题进来的, 那么你一定在好奇, 好好的Kernal32.dll躺在我的C盘里面, 怎么会遗失呢,你一定没想到,在你打开这篇文章链接的瞬间,你的Kernal32.dll已经被我隐藏了,只有读完这篇文章,你才能找到破解的办法。

哈哈,只是开个玩笑!我还没有厉害到这个程度。

其实我这里给大家分享的是如何找到一个重要结构体, 并从这个结构体中获取有价值的数据。


这个结构体就是,铛铛铛铛:

_LDR_DATA_TABLE_ENTRY


这个名字是直接可以在WinDbg中通过dt这条命令来查看所包含元素的,客官请看:


注:浅蓝色行是输入的命令


大家也能看到,这个结构体很庞大,不过不要方,本人才疏学浅,能勉强讲给大家听的也就是本文章所涉及的元素已被标注为黄色,至于为什么是黄色微笑


首先跟着我来一起看看上面这个大大大结构体的第一个元素,结构体的第一个元素,顾名思义,直接取结构体内容即可获得其数据,那这个数据是什么呢?


我们再次使用 dt 这副照妖镜来看看这第一个元素:



啊哈,这很明显就是一个双向链表,问我为什么,老师上课教的。 另,我这么吊我妈并不知道。

    

_LDR_DATA_TABLE_ENTRY结构体中第一个元素中的第一个元素是前一个_LDR_DATA_TABLE_ENTRY结构体的地址,

嗯?有点绕,没事,先记着,看下面两个重要元素:


看图可得,这两个元素分别为模块基址和模块名称。

单纯无公害的观众到这里应该知道从这里开始可以做什么事了吧,千里之行始于足下。

思路便是:通过双向链表来遍历_LDR_DATA_TABLE_ENTRY结构体,匹配模块名称,获取模块基址。

如果你不幸跟上了我的胡诌,那么现在你想的应该是,如何获取这个结构体呢?

    

经过我上面的一些混淆措辞,我们进入正题,

我这里分别动态和手动获取一次,以便于比我更晚入门的同学理解。



先上干货,不掺水的,连寄存器环境都不带保存一下的:

  反汇编:                                    注释: WinDbg命令:

_asm
     {
          MOV EAX, FS:[0x30];    // _PEB
          MOV EAX, [EAX + 0xC];    // _PEB_LDR_DATA|   dt _PEB_LDR_DATA 77627c00
          MOV EAX, [EAX + 0xC];    // _LDR_DATA_TABLE_ENTRY[0]|   dt _LDR_DATA_TABLE_ENTRY 0x723588 
          MOV EAX, [EAX];    // _LDR_DATA_TABLE_ENTRY[-1]  |   dt _LDR_DATA_TABLE_ENTRY 0x723480 
          MOV EAX, [EAX];    // _LDR_DATA_TABLE_ENTRY[-2]  |   dt _LDR_DATA_TABLE_ENTRY 0x723958

          MOV EAX, DWORD PTR DS : [EAX + 0x18];  // DllBase :_LDR_DATA_TABLE_ENTRY[-2]+0x18|   dd 0x723970 

     }

注:WinDbg命令后面的地址以实物为准。

动态获取过程:

这里我们主要关注EAX的值,毕竟也没别的关注点。

Step1:EAX == 0x77627c00

Step2:EAX == 0x00883b18


Step3:EAX == 0x00883a10


Step4:EAX == 0x00883ee8


Step5:EAX == 0x769a0000



以防出现太长不看的评论:

Step1:EAX == 0x77627c00

Step2:EAX == 0x00883b18

Step3:EAX == 0x00883a10

Step4:EAX == 0x00883ee8

Step5:EAX == 0x769a0000


以上是动态获取下面通过手动获取来验证并详细解释:

如何验证一个用有动态基址的程序中获取的地址是否正确呢?

WinDbg->File->Attach to a process->选择你的程序`

Note:勾选Noninvasive

在内核层有一个传说中的结构体,叫做ETHREAD,它在凡间即用户层就变成了TEB线程环境块,而通过FS便能直接找到这个结构体

而它偏移0x30的位置是另一个传说在凡间的样子,那就是PEB,在座的有没有一个大胆的想法,猜猜这个结构体是谁?



MOV EAX, FS:[0x30]

没错,它就是进程环境块:

通过进程环境块的0x0C处找到下一个结构体:



在这个结构体中,终于看到一个面熟的,根据上面讲解的思路,接下来的故事就顺理成章了,忘记思路的同学,看这里:

思路便是:通过双向链表来遍历 _LDR_DATA_TABLE_ENTRY结构体,匹配模块名称,获取模块基址。

MOV EAX,[EAX+0x0C]

Step1:EAX == 0x77627c00



MOV EAX,[EAX+0x0C]

Step2:EAX == 0x00883b18



MOV EAX,[EAX]

Step3:EAX == 0x00883a10



MOV EAX,[EAX]

Step4:EAX == 0x00883ee8


Step5:EAX == 0x769a0000


那么获取到的Kernal32.dll的基址便是0x769a0000,遗失的Kernal32.dll也回家了,大家可以接着安稳地敲代码了微笑





彩蛋:

大家应该发现了,虽然思路是遍历双向链表并匹配模块名,但是代码并没有这个操作,简直是虚假广告,

请允许我做个悲伤的表情并接着忽悠,

首先,定位到的第一个_LDR_DATA_TABLE_ENTRY结构体通常为进程加载的exe模块,前一个是ntdll.dll,

再前面一个便是Kernal32.dll。

其次,师傅领进门修行靠个人,遍历和匹配字符串的代码就留给大家作为作业吧,大宝明天见!





在这个结构体中,终于看到一个面熟的

MOV EAX,[EAX+0x0C]

原创粉丝点击