要从最基础的入门级操作开始说起,我们直接选用UPX加壳的notepad.exe作为目标,使用OllyDbg 1.09d版本进行手动脱壳练习。
首先将加壳后的程序加载进OllyDbg,你会发现程序直接停在了01014110这个地址,开头是$ 60 PUSHAD——这是典型的加壳程序入口,作用是保存寄存器状态(即保存现场)。接下来我们需要找到真正的程序入口点(OEP),如何定位呢?按Ctrl+F,搜索POPAD指令。
搜索完成后,OllyDbg会自动定位到0101425E,这里确实是61 POPAD。将光标移动到1425E这一行,按F4运行到此处,然后按F8单步执行。你会看到下一步是0101425F .-E9 7C28FFFF JMP NOTEPAD.01006AE0。这个跳转指令就是关键的“电梯”——它将带我们跳转到真正的OEP。
接下来按F7单步跟入,程序终于露出了真面目:01006AE0 6A 70 PUSH 70。这就是notepad.exe原本的入口地址,至此OEP定位成功。
既然找到了OEP,就可以直接进行脱壳操作了。在OllyDbg中选择OllyDump / Dump Debug Process插件。这里有一个关键步骤:一定要去掉"Rebuild Import"复选框。为什么?因为这个壳的输入表(IAT)已经被破坏,直接让插件重建反而容易出错。我们后续会使用ImpRec来手动重建输入表,更加稳妥。直接点击Dump,生成一个脱壳后的文件。
此时,这个新生成的文件是无法正常运行的——双击运行后肯定会弹出“应用程序正常初始化(0xc0000005)失败”的提示。原因很简单,输入表尚未重建,程序无法找到正确的系统API地址。
接下来请出Import REConstructor 1.6 Final。同时,需要将刚才那个加壳的原程序也重新运行起来(保持它在内存中)。在ImpRec的进程列表中找到加壳程序,注意它的IAT Infos里显示的OEP是00014110——这个值是壳伪造的,并非真实入口。
我们需要输入真正的OEP:0006AE0。注意,这个值是RVA(相对虚拟地址),由实际地址减去Image Base 01000000计算得出。输入后,点击IAT AutoSearch,ImpRec会提示Fond address,确认即可。然后点击Get Imports,你会看到Imported Functions Found下方,所有的输入表函数都显示为valid。这说明地址正确,函数解析成功。
最后,点击Fix Dump,选择之前用OllyDbg导出的dump文件。ImpRec会自动重建输入表并修补文件。现在再次运行这个修补后的程序,你会发现——它可以正常打开了。脱壳完成。
