分类 逆向 下的文章

Windows中ShellCode动态寻API(1)

当写shellcode的时候往往会遇到这么一个问题,如何使用汇编准确的定位到想要调用DLL中API的内存地址。

因操作系统版本以及安全补丁可能会修改DLL加载的基址,所以使用硬编码的API入口地址可能会使shellcode失效。在不同的Windows系统环境中如何动态寻址就是shellcode的Writer需要关心的问题了。

在Windows中动态寻址可以通过FS段来实现。

什么是FS段?

FS段是用来存放当前线程的线程环境块(TEB[Thread Environment Block])的一个段,FS寄存器本身的值指向的是全局段描述表(GDT)里面相应的一条索引。

FS段如何工作?

线程环境块保存了当前线程的各种信息,该结构的具体内容不同的系统也有区别,这个结构体的具体内容可以使用Windbg的dt ntdll!_TEB命令来查看重要的是该结构里面保存了我们想要的DLL的信息。
TEB的起始部分也就是fs:[0]的部分是叫做线程信息块(TIB[Thread Information Block])的结构,这个结构TIB中slef的值保存了TEB的起始值,当然了在GDT中也是可以获取这个值的。当fs寄存器知道了fs段开始的位置之后,它根据相应的偏移量(0x030)找到进程环境块(PEB[Process Environment Block])在Windbg中可以用!peb命令来查看进程环境块的内容。

07A3B5D0-D45F-44B1-8111-68302D637465.png

以上具体的内容可以去看以下书本中的相关知识:
《软件调试》(50-54页 && 713-714页)
《逆向工程核心原理》(第46章)
《0Day安全:软件漏洞分析技术》(87-97页)

可以在图中清楚的看到我们需要的DLL的基址了。当我们找到DLL的基址之后,众所周知DLL在Windows中也具有PE头,也有相应的EAT,这时候只要找到相应的函数在EAT里面的指针就大功告成了。

当然实际上可能还会碰到很多其他问题,例如让人头疼的空字节截断shellcode的问题,下一篇写一个具体利用

超级easy的U盘监控器破解

今天是美好的星期一啊,把<<Windows PE权威指南>>看掉一半就去看权利的游戏去:neckbeard:

龙妈称霸世界:sunglasses:

这个破解是<<Windows PE权威指南>>里的一个小例子,首先打开这个软件.

1E8C3E59-31C1-48C1-8F69-9870318D7DE5.png

这个界面做的真是难看....还加了弹窗广告,我呸...

随便输入123

099FA62A-B2A4-4486-BB39-4F8DF6F43093.png

注册失败了

83461D70-D029-4B9E-8EFE-B6441C7FFF04.png

可以看见失败的弹框里面有注册失败几个字.

把程序丢进OD里面
B66FD8CB-023D-4B01-825A-BB5B1F23B4A8.png

OD已经定到入口点了,再用WinHex把程序打开来看字节码

994AC89F-FE85-46D6-A4B5-66BDA7E0AED4.png

98997F5E-7B59-49CE-BAD1-2E6C52DC8B87.png

WTF!激活码直接就出来了!233333

不过用改程序流程的方法会好玩一点

可以看到注册失败这个字符串offset是81A79

VA = ImageBase + RVA

VA = 400000 + 81A79

程序在装载入程序后这段字符串的虚拟地址是0x481A79

35867F9A-B024-4E22-82EC-777A1770B358.png

查看谁用到了0x481A79这个地址,在OD的指令及指令解释区搜索常量0x481A79,可以看到0x405D2D这个地方push了0x481A79

FB9A73AA-63B1-4F94-87CE-1DF214246CD3.png

往上拉一拉在0x405D11的地方是由0F8F的地方跳转过来的,用的是jg指令,只要把jg指令改成jl指令,再用nop填充就随便输入什么字符串都能注册成功了:)

2B1A9901-39D7-4D7B-85FE-B239DA78D748.png

66848E75-CFC7-4FC7-A8D3-F6C340E4B167.png