Getright 5 手动脱壳和重建IAT--第一部分(图)

所属分类: 网络安全 / 加密解密 阅读数: 213
收藏 0 赞 0 分享

这是一篇Armadillo加壳软件Getright 5.01的脱壳译文,我是参照Ricardo Narvaja的“Getright 5 脱壳和重建IAT”的文章以及Bighead[DFCG][YCG]的译文,一边实践一边再次翻译的。感谢Ricardo Narvaja和Bighead[DFCG][YCG]。
Armadillo for Dummies: Getright 5 手动脱壳和重建 IAT (第一部分)
因为Armadillo实在是太复杂了,以至于人们已经不得不沿用下面这个手动的方法去脱壳armadillo,这不是我的过错,只是因为armadillo实在是太难脱壳了,然后我将会在这个文档中一步一步地去完成脱壳,同时配上很多图片,只是想让它变得尽量容易理解.我并不想写一个10兆大的参考教程,所以我把这个文档分成两部分.第一部分主要讲如何转储(dump)armadillo保护的程序,然后我会在第二部分中提及一些以前在其它任何教程中都未曾见过的东西,那就是输入表(import table)的redirection和rebuilding.
在我们开始之前,我必须声明这篇参考教程只在Windows XP上测试.请不要在 windows98或者2000中尝试.原因是只有Windows xp才拥有必要的API,能够把子进程(child)从它的父进程father那儿脱钩下来.
这次练习,我们找到的自愿者是Getright 5 final. Crusader曾经写过关于这个软件的某一个版本的参考教程,但是这篇参考教程在很多方面都不同于crusader写的那篇.
crusader写的那篇参考教程(原版)----附(1)
crusader写的那篇参考教程(FTBirthday翻译版本)----附(2)
你可以从以下连接下载GetRight 5.不管怎样我在我的ftp中保存了一个副本,所以你可以从那儿下载,就不用去管它在网上被放在哪儿了.
http://www.getright.com/
抓起你的鼠标,安装好Getright然后准备作战.Armadillo将会变得软弱无力.
如何脱壳(UNPACK)以及转储(DUMP)Getright 5
在OLLYBG中载入GETRIGHT.exe然后整装待发.我将按照以下的步骤,很容易记住的,你可以在其它任何armadillo保护软件中按部就班.
第一步:重新设置检测ISDEBUGGERPRESENT API的字节
我将要解释如何在任何电脑中去寻找这个字节.
首先从这个连接下载命令行插件:
http://dd.x-eye.net/file/cmdbar10802.zip
解压它然后复制dll到OLLYDBG文件夹.只要你运行Ollydbg你将会在调试窗口的左下角看到一个白色的输入框,在那儿你可以键入很多命令.让我们键入:
Bp IsDebuggerPresent
我们将要使用BP而不是BPX,因为BP可以直接在API上下断点,那正是我们所需要的.
我们必须准确地键入Bp IsDebuggerPresent.记住我们必须保证大小写的顺序,因为如果我们键入了任何不同于以上形式的命令,那么一个错误提示(UNKNOWN COMMAND)将在命令行的右边产生.所以正确地键入BP IsDebuggerPresent然后按回车. 如果在按回车后没有错误提示出现,那就说明这个BP已经生效.
现在按F9运行程序,它将会中断在API IsDebuggerPresent

在这张图中我们可以看到OllyDBG中断在API IsDebuggerPresent(红色), 然后按F7步进到第三行(白色)
77E52749 0FB640 02 MOVZX EAX,BYTE PTR DS:[EAX 2]
一旦到达那儿,看一下disassembly,在那儿我们可以看到如下图的内容:

这儿我们可以看到在我的机器中偏移是7ffdf002,包含了值01.这个地址在其它机器中可能会不同. 值01意味着调试器被检测到了,所以写下这个地址,在任何时候我们在ollydbg中运行程序,都必须把它修改为00,从而避免被packer检测到.记住在ollydbg中运行或重运行程序的任何时候修改此值为00.
我们将以重启ollydbg (ctrl F2)来结束第一步,到转储窗口(DUMP)单击右键选择"前往 表达" 7ffdf002或者其它任何先前你记下的地址,然后把它的值从01修改为00.


把它改为00.

第二步:BP WAITFORDEBUGEVENT
这一步并非必要,但却是一个好的选择,当它停止时在转储(DUMP)区看到report.让我们看看该怎样做.
首先我们需要在命令行输入BP WaitForDebugEvent,和我们输入IsDebuggerPresent的方法是相同的.
现在运行它,当它停下时我们可以在堆栈窗口(Stack window)看到关于这个API的所有参数信息.

看一下第二行.那儿我们可以看到它将在哪儿显示report,所以到转储窗口(dump window), 右键选择 "前往 表达"= 12EFF8.注意这个值在一些机器上可能会不同,所以前往你的机器显示的值.

我们在上面的图中看到的是我们将要称之为"API report"的东西.主程序(让我们把它称为Father)通过那里得知secondary program(让我们把它称为son)发生了什么.
现在我们可以很容易地通过在命令行输入BC WaitForDebugEvent来删除这个断点.
所有的操作都是为了在转储窗口(dump window)看到report,在这个report中我们可以看到入口点OEP(entry point).
第三步: BP WRITEPROCESSMEMORY

像图中一样设置这个断点然后点击"运行".也许你会在一些例外(exceptions)处停下,但是你可以通过按SHIFT F9很容易地走过.一旦我们停在了WriteProcessMemory API不要做任何事情,看下图:
正如我们在下图中看到的, father将要复制给son的第一个块(block)的所有信息,都可以在堆栈窗口(STACK window)看到.

FTBirthday:由经验,我觉得很难走到这一步,但是我知道是在005F949E处call了WriteProcessMemory如图:

我通过一遍遍试验,得出了最好的方法:等到前两次在别处call了WriteProcessMemory后,左手一直按住shift, 右手连续按F9大约31次,就可以顺利到达.
这些信息被保存在父进程的一个缓冲区从3B8FB0开始,然后它会复制给子进程一个从538000开始的 1000 bytes (BYTES TO WRITE)的块(block),所以如果我们到了这一步,我们可以很容易理解child的第一个section是完全空的,所以当它试图执行到OEP时,它报告一个error因为那儿没有任何东西,所以 father得到了通知正如我们可以在father的report中看到的,所以它停止了运行,复制必要的数据块,然后继续运行直到下一个error.被复制的数据块的大小是1000 bytes,所以当程序试图执行任何超过这个大小的block外的指令时, 另一个error将会发生,然后这个error会被通知给father, father会复制另外1000 bytes的块block然后继续.
顺便说一下,我们可以假设第一个error发生是因为son (坏小子)call了它的入口点OEP,它的值应该就在 report上.显然OEP的值必定在第一个block,father复制过去来解决son报告的error.
这个块从538000开始知道538fff.OEP值必定在这些值中. 让我们看一下REPORT.看转储窗口(DUMP window) 我们先前已经知道了指向report的指针12EFF8.

太好了!在那儿我们至少看到了三次这个值: 538540.数学课告诉我538540比538000大,比538fff小 (那些是father试图拷贝给son的那个块的起止值)所以我可以确信538540就是child的OEP.
让我们从API WriteProcessMemory来改变断点的性质.知道哪个块被拷贝不是很好吗.可以通过下面的方法做到.首先选择bpx所在的行,按F2移除bpx.
右击选择"断点/条件记录".现在在对话框中准确地填入如图所示的值.这样做的目的是使我们在记录窗口中看到所有被father decrypts并拷贝给son的blocks.

第四步: NOP THE CRIPTER CALL
在先前的参考教程s中我们知道,这儿我们是在decripter call.Father为son decrypts了一个block.但是还有一个cripter call用来encrypts或者destroys已使用的blocks来避免被转储dump.现在的任务是如何找到这个call并把它nop掉.
我现在在WriteProcessMemory API,所以我打开"呼叫堆栈窗口"(Alt K)在那儿我可以看到:

在这个"呼叫堆栈窗口"越靠上面的是越最新被执行的.从CALLED FROM 我们可以看到5F949E是father calls API的地方. 如果我们向下看,我们可以看到另一个call.所以我们获得了decripter call的offset.
DECRIPTER CALL= 5F88D1
通过"前往 表达" 5F88D1跳到那儿 ,或者左键双击它.

这是好的CALL,它用来decrypts.现在去找坏的那个,稍稍向下翻屏或者右击选择"查找参考/呼叫目标" 选择出现的两个参考中的另一个.

它在这儿呢!
重新加密的call--ENCRIPTER CALL = 5F8A24

现在我们把它nop掉.我们选择这个call按空格写入nop.



第五步: 运行API并在OEP处设一个无限循环
现在到了执行WriteProcessMemory一次了. 我们有两条路可走,可以选择执行到返回它将会执行直到RET,然后按一次F7. 第二个选择是去stack第一行在那儿设一个BPX最后运行它.
在stack第一行提示程序会返回到5F94A4, 我们到那儿BPX (F2)然后运行它(F9).

现在该用PUPE了. PUPE是一个西班牙工具.你可以在www.google.com搜索一下. 通过下面几行代码我们将要在son的OEP设置一个无限循环.这会使son休眠直到我们叫醒它.
这是一张PUPE的图片.我们可以看到有两个进程, the son and the father.上面那个是son. 在右边我们可以看到进程句柄.

选择上面那个getright.exe然后右击选择"parchear".

写下出现在对话框中的original bytes然后用无限循环代码EB FE代替,如下面的对话框中所示.
最后一步就是"PARCHEAR"然后INFINITE LOOP就准备好了.

第六步: BP WAITFORDEBUGEVENT 和 NOP THE API
不要清除先前断点WriteProcessMemory,是时候写入新断点了.键入BP WaitForDebugEvent回车, 然后按F9运行

它停下时

你必须记住NEVER EVER RUN THIS API.在转储窗口"DUMP window"看一下report, 然后去堆栈窗口(STACK window).

正如我们看到的如果我们运行这个API我们应该去5F751D,所以让我们通过"前往 表达" 5F751D到主窗口.

再一次提醒不要RUN THIS API.所以右击5F751D选择"新建起源".这是跳过这个API的方法.

现在我们必须nop the call to the api以及有关的push.

所以在这些行上按空格键然后写入nop.当你完成这项工作时,将会如下图所示. 这一步结束了.



第七步:如何打入补丁
当做这一步时请注意.很多人不知道究竟该如何打补丁,所以努力试着理解我这里所作的, 然后学会在其它情况下运用.
第一步是改变跳转,

我们将要改变这个跳转为JMP 401000那是我们将要打补丁的地方, 父进程offset 401000 .

跳转设好了,现在去401000 (ctrl G)我们要开始写补丁了. 在report中我们可以看到三次entry point value.也许OEP在其它情况下会出现更多次.但是我们只需改变这三个.

father unpacks了在report中显示的block.所以我们将要欺骗father则他会相信从第一个section开始的所有blocks都存在错误, 一个接一个所有的blocks都会被unpacked.因为这一点我们需要知道第一个 section的起止点.点击"查看/内存"

这儿我们可以看到getright的sections.忽略Header section看text section,它从401000开始,结束在589000-1=588fff.
401000-588fff (第一个section的范围)
我们将要在report中用400000代替OEP的值.

正如你在图中看到的我写入了40000,然后patch会在每一个loop前加1000,所以第一个被unpack的block将在401000.
现在我们将要在401000处写下如下补丁.

00401000 8105 10F01200 0>picture1/add DWORD PTR DS:[12F010],1000
0040100A 8105 1CF01200 0>picture1/add DWORD PTR DS:[12F01C],1000
00401014 8105 20F01200 0>picture1/add DWORD PTR DS:[12F020],1000
这些行将我们先前在转储窗口(dump window)写的值增加1000.那些蓝色的值在不同的机器上可能会不同,所以修改为你在转储窗口(dump window)看到的实际值. 再次提醒,证实在转储窗口(dump window)写入了00 00 40 .最容易犯的错误就是在补丁(蓝色的)中的offset和转储窗口(dump window)的offset不匹配.
下一行该这样写:
0040101E 813D 20F01200 0>CMP DWORD PTR DS:[12F020],getright.00589000
比较是为了让我们知道何时所有的块都被unpacked了.
然后我们必须写下:
00401028 - 0F85 F6341F00 JNZ getright.005F7524
如果比较为假,则返回called loop的地方.然后我们需要在最后写下NOP,在那儿我们将要设下一个BP. 当它完成转储时,它将会停在那儿.

这儿我们可以看到完整的补丁代码
我们可以跟踪第一个循环,来检测report中的each entry是否每次都增加1000.
第八步: UNPACK
按F9运行程序然后等待它停在我们先前在补丁中设下nop的bpx处.如果没有错误发生,当我们停止时,看view-LOG我们将要看到所有的unpacked blocks.
这是假设的所有unpacked blocks的LOG.我没有完整的给出因为地方不够但是你可以在你的日志窗口中查看.
所以现在从401000到589000(包括588fff)的所有blocks都被unpacked了,然后dump已经就绪.
第九步:把CHILD从FATHER那儿脱钩
一旦我们停在NOP,让我们写下下面几行.
PUSH (child的handle )
Call DebugActiveProcessStop
如果handle由字母开始,你需要在它前面键入一个0,因为不这样做的话olly不会认出. 想知道son的handle只需看一下pupe, 记住child的handle是在两个进程中的上面的那个.你一样可以通过opening file attach来获得son的handle.那儿你可以看到两个名称相同的进程. 红的是father,黑的是son.在此情况下我得到的是B78 所以我将要写下0B78.记住handle在每次运行程序时都会改变.


在图示的nop处下断点,然后运行程序.看registers window,如果当程序停止时,EAX=1那意味着son已经从father处脱钩了,我们可以关闭OLLY.如果EAX=0 那么你要检查那几行代码,因为你可能犯了写错误(也许是写错了handle).
现在关闭OLLYDBG,然后再次打开他.不要载入任何东西.前往"文件/附加"然后找son,附加它(我们搞定它的father了:X).
一旦附加成功,程序将在INFINITE LOOP中 RUNNING ,需要按F12 to pause the去暂停程序,但是等一下,在做这个之前,我们先得把 EB FE改回原始值(那些我叫你记下的值,你有记下吗?) 55 8B,然后我们将停在OEP,已经准备好dump了.


我们已经准备好dump了,所以打开LORD PE然后找Getright.exe

选择Getright.exe进程然后选择INTELLIDUMP然后点击DUMP FULL, 保存后启动PEEDITOR (从www.google.com上搜索它)然后写入正确的ENTRY POINT值.
在这儿不要填写538540,而写入文件偏移,就像这样: 538540-400000 = 138540.

那就是full dump.在本参考教程的第二部分我们会学习怎样去找magic jump从而完成import table, 修复IAT,使程序运行,因为它设下了一些陷阱来避免被unpack.
现在我们保存转储(dump)文件(我把它命名为tute.exe),和原始的一样,只是IAT不同.
第二部分再见.
Ricardo Narvaja
翻译(西班牙语翻译为英语)DEGETE和Tenshin,(英语翻译为中文)FTBirthday.自由传播,但是请保留作者的姓名.

更多精彩内容其他人还在看

黑客教你破解Email账号的三种方法

电子邮件并不是安全的,在邮件的发送、传送和接收整个过程中的每个环节都可能存在薄弱环节,恶意用户如果利用其漏洞,就能够轻易的破解出账号,获得邮件内容。   一、利用邮件服务器操作系统的漏洞   邮件服务器软件是运行在特定的操作系统上的,如Linux、Windo
收藏 0 赞 0 分享

WINDOWS XP登陆来破解pubwin EP 5.0的方法

这边的网吧都用pubwin EP 5.000000069****(忘记勒^_^)的网络管理系统,操作系统用WINDOWS XP,另外还装了还原精灵,呵呵。BIOS、系统、还原精灵、pubwin EP都设置了不同的密码。 我搜索并尝试了网上所谓的破解方法,结果如下: (1)
收藏 0 赞 0 分享

密码破解以及抗击手段

密码与用户帐户的有效利用是网络安全性的最大问题之一。在本文中,Rob Shimonski将研究密码破解:如何以及为何进行密码破解。Rob将只说明渗透网络是多么简单,攻击者如何进入网络、他们使用的工具以及抗击它的方法。   对公司或组织的计算机系统进行的攻击有各种形式
收藏 0 赞 0 分享

加密解密教程:NTFS文件加密初探

我们知道NTFS文件格式可以实现对文件夹的加密,增强了文件的安全性,但因NTFS涉及的细节内容比较复杂,所以用NTFS加密后的文件由于我们的操作不当经常会出现一些问题,比如用户名丢失后、文件密码丢失了等等,都会带来不小的麻烦。今天,我们就来共同探讨一下这方面的问题
收藏 0 赞 0 分享

黑客教你十招学会软件破解大揭密

下面谈到了一些在学习解密过程中经常遇到的问题,本人根据自己的经验简单给大家谈一谈。这些问题对于初学者来说常常是很需要搞明白的,根据我自己的学习经历,如果你直接照着很多破解教程去学习的话,多半都会把自己搞得满头的雾水,因为有很多的概念要么自己不是很清楚,
收藏 0 赞 0 分享

Windows 2000/XP/2003登录密码轻松破解

当你在使用电脑时,不小心将管理员登录密码忘记了,怎么办呢?虽然网上和各IT杂志介绍了很多种破解管理员登录密码的方法,但操作起来都比较麻烦,并且针对不同的系统须要用不同的破解方法。例如,用破解Winodws 2000的方法,来破解Windows XP和Windows 2003就不行
收藏 0 赞 0 分享

安全利刃 EFS的加密方法和解密必知

经常看到对文件和文件夹加密的文章,大多是安装各种软件来实现的,如果你的系统是WinXP/Win2003/2000,就没有必要如此兴师动众地加密了,既不需要你安装软件,也不需要繁琐的操作,因为Windows本身就集成了EFS(Encryption File System-EFS)加
收藏 0 赞 0 分享

防止离职员工带走客户、防止内部员工泄密、避免华为员工泄密事件的发生

这篇文章为大家详细介绍了如何才能防止离职员工带走客户、防止内部员工泄密、避免华为员工泄密事件的发生,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

彻底防止计算机泄密、重要涉密人员离职泄密、涉密人员离岗离职前防范举措

近些年企业商业机密泄漏的事件屡有发生,这篇文章主要教大家如何彻底防止计算机泄密、重要涉密人员离职泄密、告诉大家涉密人员离岗离职前的防范举措,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

无需攻击lsass进程即可解密系统管理员密码

Lsass.exe是Windows系统中必不可少的一个进程,属于微软Windows系统中安全机制相关进程。lsass.exe进程主要用于本地安全和登陆策略,同时也管理IP相关安全信息。对lsass.exe进程进行攻击,造成相应的缓冲区溢出,从而解密Windows系统中相关密码的方
收藏 0 赞 0 分享
查看更多