Category Archives: unpack

wsnpoem unpack part two

本文已发表在看雪论坛, 详情可见: https://bbs.pediy.com/thread-223401.htm 承接之前写的zbot变种木马wsnpoem脱壳笔记 part 1,我们这次用另外一种方式来脱壳。并且本文还将分析另外两个恶意样本。 文中分析的程序你可以点击此处下载: wsnpoem恶意样本par2.zip, 解压密码: www.pediy.com OD重载wsnpoem-with-rootkit.exe,依然是之前的顺序,在leave处设下硬件断点后运行,让第1阶段的解密完成。然后删除设下的硬件断点,向下翻看。 不过这次我们就不会在00409EDA处的jmp eax下断了,我们再向下翻到00409F26处的mov eax, 004051B7,这句汇编代码下面是call eax,也就是说程序将要执行OEP处的代码。 我们在004051B7设下硬件执行断点,然后执行断下,程序停在了OEP处,我们删除硬件断点 那么我们接下来的步骤就跟之前一样,运行步过004051D2处的call 0040aad4导入函数表,然后将EIP重设为004051B7。 之前用Ollydump+ImportREC我们手动cut chunks来修复导入表,这样不仅枯燥费力,而且还有可能误删正确的chunks导致修复失败,这次我们使用额外一个工具 – Universial Import Fixer 1.0[Final],也就是UIF。这个工具可以为我们自动修复导入表,我们只需要将wsnpoem的进程id输入进去就可以。 在重设完EIP后,我们打开UIF,然后再通过在cmd里用tasklist命令查询到wsnpoem的pid,我的是1816,将其转为16进制,也就是0x718,填入到UIF的Process ID中,取消掉默认勾选的Fix NtDll to Kernel32,然后点击Start UIF就会帮你自动修复导入表并显示修复后的信息。这些信息我们等下用ImportREC是需要使用的,也就是下图的IAT RVA和IAT Size 既然修复好了导入表,那么我们就可以用Ollydump将程序转储出来,记得在dump时要取消勾选rebuild imports,转储文件保存为dump.exe 打开ImortREC,然后选择wsnpoem进程,输入OEP,并按照UIF修复给出的IAT RVA和IAT Size填入到ImportREC中 你可以看到导入表直接就是可用的,我们不需要手动修复导入表。我们就可以直接转储到文件就行了。IDA打开当然也是脱壳完成并且各导入函数清晰的。 … Continue reading

Posted in malware, unpack | Leave a comment

wsnpoem unpack part one

本文已发表在看雪论坛, 详情可见: https://bbs.pediy.com/thread-223393.htm wsnpoem恶意程序是zbot木马家族的变种,经过加壳保护,我们接下来就来脱壳。 文中分析的程序你可以点击此处下载: wsnpoem恶意样本par1.zip, 解压密码: www.pediy.com OD载入wsnpoem-with-rootkit.exe 这是wsnpoem解密的第一阶段,我们直接在00409D41的LEAVE处右键设下硬件执行断点,然后运行 然后我们选择菜单Debug->Hardware Breakpoint移除刚才设下的断点,向下翻到00409EDA处 我们在这行设下软件断点(F2)然后运行,停在断点处,我们取消掉这行的断点,按下Enter进入到跳转的分支去,向下翻到00412449处 在翻过了第2层解密后,00412449处所指向的004051B7便是我们的OEP,同样设下一个软件断点(F2),然后运行,停在断点处,我们取消掉这行的断点,然后步入OEP 然后向下一点,看到0040523A处,在数据窗口中转向0040FD34 可以看见,这里的这个call所调用的函数地址处是全零,这会造成程序的崩溃,因此我们可以推测在call以上的代码中有填充这个空间 我们现在边步过,边观察数据窗口中的0040FD34,看什么时候向该处填充了数据,可以很容易发现,在步过004051D2处的Call 0040AAD4后,数据窗口中填充了许多的数据 那这样看来,004051D2处的Call 0040AAD4就是将所有的函数都导入到内存空间中,而我们的0040FD34则是导入表的一部分,因此我们可以右键重新将EIP设到OEP处。 向上翻看导入表空间,貌似可能的函数地址块,也就是我们的导入表头,是从0040FB3C开始 我们也可以在ascii块中右键选择Long->Address,这样数据窗口会以地址格式进行显示,方便我们查看导入表 同样,我们向下翻看,查找导入表的结尾是在0040FEB8 这样,找到了OEP,也有导入表信息,那么我们就可以用Ollydump+ImportREC来进行脱壳,如下,点击dump保存为dump.exe 打开ImportREC,选择正在运行的wsnpoem-with-rootkit.exe,然后在OEP、RVA和SIZE处填写好我们获得的信息,然后点击Get Imports 但显然,我们的导入表函数虽然有找到,但都是无效的。所以我们需要手动修复导入表函数,因为可能在导入表内混有一些垃圾地址,所以我们需要手动进行移除,比如第一个chunk中 点击对应的shell32.dll右键显示反汇编,可以看到如下代码,显然不是一个正常的函数的代码,因此可以确定是垃圾地址。我们右键cut chunks 然后有的块显示反汇编提示read error,那么其实也是垃圾地址。依照类似的方法将所有的垃圾地址清除干净后,你就可以转储到文件,然后用IDA打开,你会发现壳已经脱干净并且导入函数也很清晰

Posted in malware, unpack | Leave a comment

yoda’s protector unpack

本文已发表在看雪论坛, 详情可见: https://bbs.pediy.com/thread-223371.htm yoda’s protector主要有两个需要注意的反调试保护:阻塞设备输入和枚举进程pid并终止调试器 文中分析的程序你可以点击此处下载: yoda_unpack.zip 阻塞设备输入 yoda 使用user32.dll中的BlockInput来屏蔽所有的输入设备的消息,比如鼠标键盘。当设备被屏蔽时你无法进行任何操作,只有阻塞设备的线程或进程可以使用相同的API填入不同的参数来解锁它 yoda protector会在使用api阻塞设备后转向脱壳/解密的进程并执行一些反调试的技巧,在脱壳结束并且所有检查通过时,yoda才会解锁设备。 一个非常简单的方法可以解除阻塞,那就是patch掉BlockInput,让它什么都不做就返回。 当我们用od载入unpackme,我们可以看到内存中只载入了两个dll 为了patch掉BlockInput,我们需要让user32.dll载入内存,在od选项中我们设置断在新的dll上 然后我们继续F9,让user32.dll导入到内存 随后我们就可以取消掉之前断在新dll的选项,然后跳到BlockInput的入口代码处 BlockInput的api就是上图的灰色代码,retn 4就是结尾,我们只需要将所有这些代码填充为nop就行 这样,api就不会进行任何操作,我们的输入设备也不会被阻塞 枚举进程并终止调试器 yoda使用CreateToolhelp32Snapshot来获取所有正在运行的进程,然后yoda会搜索启动unpackme的进程是否和unpackme自己的进程PID是否相同,如果不同,那么yoda就会终止掉该进程(如od)。如果我们像先前一样patch掉CreateToolhelp32Snapshot,程序则会产生句柄非法(Invalid_Handle)异常。这里有另外一种方式来绕过保护。yoda使用GetCurrentProcessId来获取PID,因此我们可以控制返回的PID的值来迷惑保护代码。 比如我们启动unpackme的进程是Ollydbg.exe,我们就要让GetCurrentProcessId返回Ollydbg.exe的PID,这样检查就不会出现问题(而不是unpackme的PID)。 首先我们必须知道ollydbg.exe的PID,这点我们可以启动LordPE来轻松获得 这里ollydbg.exe的PID是0x4B4,而unpackme的PID是0x1CC,我们要做的就是使得GetCurrentProcessId的返回结果是0x4B4 像之前一样,来到api的入口代码处 函数通过eax返回值,我们只需要修改eax即可 这样也就完成了。 在patch完后,还需要使用插件来隐藏Ollydbg(用HideOD等插件,避免IsDebuggerPresent的检查),之后的关键就是找OEP了。 OEP查找 oep的查找我们可以使用最后一次异常法来跟踪,按下shift+F9的最后一次异常,在堆栈窗口中出现的SE Handler,本例中是00413F50,我们跟踪进去,在00413F50设下断点,然后按下Shift+F9到达断点处。我们要记得开启HideDebugger或类似插件的反IsDebuggerPresent的选项,否则在使用最后一次异常法时会退出OD和unpackme并且无法再点击任务栏和图标。 然后在00413F79处的00404000就是我们的OEP了,dump出来修复IAT即可

Posted in unpack | Leave a comment

UPX 3.07 (Unpacking + DLL + Overlay)

Upx作为入门级的简单压缩壳,脱壳方法其实很简单。这里主要介绍的是使用ImportREC手动脱壳以及Dll脱壳。 ImportREC手动脱壳 我们常用的ImportREC脱壳是使用的软件自带的IAT auto search,但是如果我们要手动查找IAT的地址并dump出来,又该怎么操作呢? 首先使用ESP定律,可以很快地跳转到OEP: 00401110。 我们右键点击,选择查找->所有模块间的调用 显示出调用的函数列表,我们双击其中的某个函数(注意这里要双击的应该是程序的函数而不是系统函数) 我们来到了函数调用处 右键点击跟随,进入函数 然后再右键点击数据窗口中跟随->内存地址 这里因为显示是十六进制值,不方便查看,我们可以在数据窗口点击右键选择长型->地址,就可以显示函数名 注意我们要向上翻到IAT表的起始位置,可以看到最开始的函数地址是004050D8的kernel.AddAtomA, 我们向下找到最后一个函数,也就是user32.MessageBoxA函数,计算一下整个IAT表的大小。在OD的最下方有显示块大小:0x7C,所以我们整个IAT块大小就是0x7C 打开ImportREC,选择我们正在调试的这个程序,然后分别输入OEP:1110, RVA:50D8, SIZE:7C,然后点击获取输入表 这里在输入表窗口中右键选择高级命令->选择代码块。 然后会弹出窗口,选择完整转储,保存为dump.exe文件 dump完成后,选择转储到文件,这里选择修复我们刚刚dump出的dump.exe,得到一个dump_.exe。这时整个脱壳就完成了 DLL脱壳 为什么要谈到上面的ImportREC手动脱壳呢?因为Dll脱壳需要这一步骤。Dll脱壳的最关键的步骤在于LordPE修改其Dll的标志,用LordPE打开UnpackMe.dll,然后在特征值那里点击…,然后取消勾选DLL标志,保存后,那么系统就会将该文件视作一个可执行文件。 我们将UnpackMe.dll后缀名改成UnpackMe.exe,然后用OD载入。 一般在入口点,程序都会保存一些信息,这里就很简单,只作了一个cmp。要注意的一点是,这里的jnz跳转直接就跳到了Unpack的末尾,因此我们需要修改寄存器的z标志来使得跳转失效。同时在unpack的末尾设下一个断点以避免脱壳完直接运行。 Dll脱壳的基本步骤跟exe文件脱壳一样,只是要注意,在脱壳完dump后,要记得用LordPE把DLL标志恢复过来。

Posted in unpack | Leave a comment

!EP(EXE Pack)v1.2 unpack

典型的ESP定律脱壳+ImportREC修复导入表,PEiD的查壳结果是AHpack 0.1 -> FEUERRADER ESP定律脱壳 OD载入程序,第一行汇编指令就是popad,因此采用ESP定律脱壳。 我们F8运行popad这条指令,然后对ESP寄存器右键选择HW break[ESP]设下断点然后运行 然后运行程序 我们继续向下运行,执行到RETN返回,我们可以发现我们就到达了OEP(0x000271B0) 然后选中这些OD没能正确识别的汇编码,然后右键选择[分析]->[从模块中删除分析]。就可以看到OEP正确代码 我们再继续右键,选择[用OllyDump脱壳调试进程],然后选择确定,保存为dump文件后,我们可以运行,发现程序无法正常运行,因此我们需要修复dump文件。这里要使用ImportREC来修复函数的导入表 打开ImportREC,我们首先在最上方选择“活动进程”为我们正在用OD调试的这个程序,然后在右侧的OEP中填入我们找到的OEP: 0x271B0(注意0x00400000是程序的载入基址,不是OEP) 选择“自动查找IAT”完成后继续选择获取输入表,我们就能看到ImportREC找到了IAT中各导入函数的地址。 最后,我们选择“转储到文件”,然后选择我们之前用OllyDump导出的dump文件,确定后,ImportREC就会生成一个修复好的文件dump_.exe 我们运行dump_.exe就可以发现程序已经正常运行了。脱壳也就完整结束

Posted in unpack | Leave a comment