脱壳——UPX脱壳原理(脱壳helloworld)

脱壳——UPX脱壳原理(脱壳helloworld)脱壳——UPX脱壳原理脱壳步骤1找到OEP2dump(导出)内存文件3修复1找到OEP1程序运行先从壳代码运行,壳代码执行完之后会跳转到真正的OEP,也就是是说第一步,首先要找到

大家好,又见面了,我是你们的朋友全栈君。

脱壳——UPX脱壳原理

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

脱壳步骤

1 找到OEP

2 dump(导出)内存文件

3 修复

1 找到OEP

1 程序运行先从壳代码运行,壳代码执行完之后会跳转到真正的OEP,也就是是说第一步,首先要找到真正的OEP

如何找到OEP

大部分情况下,壳代码会在一个单独的区段里面,壳代码执行完一定会跳转到原来的.text段去执行,跳转之后的地址就是这个程序原始的OEP

根据OEP特征码来判断是否是原始的OEP

不同程序、不同版本编译器编译出来的程序OEP各不相同,但是大致有共同的特点:

例如:

vc6.0的OEP处的第一个API调用是GetVersion

VS2013是GetSystemTimeAsFileTime

Delphi是GetModuleHandleA

2 dump内存文件

就是把得到的新的源文件给它保存下来,可以采用从头到最后一个区段的手动复制下来,也可以用工具

3 修复

对于手动扒拉下来的内存文件,肯定还有一些问题,这里需要对PE文件进行修复

第一次脱壳

加壳程序下载链接:

https://download.csdn.net/download/weixin_43916597/18353951?spm=1001.2014.3001.5503

使用到的软件:

Peid:(吾爱激活成功教程上可以下载)

查看程序信息

首先先查看程序的信息,先了解敌人:

采用PEID来查看程序的信息:

将程序拖进PEID后:

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

这里很明显是一个UPX加壳后的程序,采用的是UPX壳代码

连接器版本6.0 也就是vc6.0的

开始脱壳

1 找到OEP

首先采用od加载exe

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

这里跟之前我们想的加壳是一样的,就是先pushad,然后再处理自己想处理的,最后popad,再跳转回到真正的OEP里面

 pushad 

//壳代码

popad

jmp xxxx

但是这里没有popad,所以需要找一下popad,在pushad执行完之后,esp指向的是栈顶的位置,popad的话会让esp移动,所以可以直接给esp打一个断点

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

这里来一个esp断点,也可以通过别的,比如在command中访问到esp的地址,然后选择,来一个硬件断点

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

需要注意的是在esp往上两个来一个硬件访问的dword断点才行

然后把这个程序跑起来,就会停在我们打的断点这里了

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

这里的话是停在了这里,这里恰好有一个popad(注:硬件访问是在这个断点运行了之后再停下来)

 

这里popad完之后就可以寻找jmp指令了,但是如何判断这个jmp是不是真正的jmp到oep呢

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

可以看到这里的jmp跳转到了非常远的距离,那么到底是不是跳转到真正的OEP呢?

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

点击od的m这个按钮来查看PE文件的各种属性

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

431B7C肯定是在这个区段里面的从这里跳转到了402680也就是上一个区段,这里就可以知道了,这里其实是跳转到了第一个区段也是加壳最常用的.text区段

然后跟入跳转到402680

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

可以看到这里的第一个api确实是GetVersion,所以这里肯定就是真正的OEP了

2 dump(导出)内存文件

需要再刚进入OEP的第一条指令就dump出来,因为不知道后面的代码逻辑是什么,万一有什么修改呢

od中可以直接调用OllyDump脱壳调试进程

手动dump:利用M按钮里面的PE文件加载情况,将主程序.exe文件的内存文件一点一点复制粘贴出来

利用010Editor创建一个hex文本类型文件

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

然后从od 的m按钮里面一块一块的复制文件过来

首先处理PE头

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

双击进入,然后修改为16进制类型

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

对整个内容进行二进制复制

然后再到010Editor中采用Ctrl+shift+v复制,不要采用Ctrl+v复制,这样才能直接复制16进制的内容进去

然后就是UPX0和UPX1还有.rsrc三个字段也复制进去

最后保存下来,随便一个文件然后以.exe结尾就好

3 修复

dump出来的exe文件不能使用的,因为还有一些PE文件的内容没有修复,这个时候再用010Editor来加载dump出来的pe文件进行修复

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

它里面就会有一些PE的提示

需要修改的信息:

区段头信息

导入表

 

修复区段头

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

这里里面很多区段头的信息都没有,因为这里应该是PE文件来处理的,但是我们是dump复制出来的,所以这里我们需要自己添加没有的信息

Name不用改

Misc表示未对齐的真实内存中的大小也不用改

VirtualAddress内存中的一个rva也不用改

SizeOfRawData文件中的对齐大小这个由于我们是从加载到内存中再Dump出来的,所以文件和内存已经没有必要区分开了,直接和Msic值一样就好

PointerToRawData表示foa,这里也直接用rva就好了

后面的可以不用处理

这样把三个区段头都修改好

修复好了三个区段头后,可以很清楚得看到程序的变化

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

图标回来了!虽然这个时候还无法运行

修复导入表

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

 

上面修复了PE文件的区段头,但是由于导入表没有修复还是无法使用,这里用LordPE查看该exe的导入表就可以看到dll的导入表是错的

正常的导入表是通过操作系统对字符串来处理然后得到该字符串的函数名称对应的函数地址变成地址给exe使用

但是这里由于我们是把exedump出来了,所以就是把操作系统变成的函数地址给弄了出来,而不是函数名称字符串,所以这里还需要修复,把地址修复改成函数名称

手动修复导入表:从od里面把原来的导入表地址函数名称全部提出来,然后再在dump出来的exe里面开辟一个字段来存储导入表,再把PE文件里面的导入表指向指到开辟的导入表里面就好了

在硬编码里面,有几种对于call函数的编码,但是如果编码的开始是FF15 xxx的就表明是对导入表里面的函数调用

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

这里可以很明显的看出来

然后再进入到FF15的call的地址里面查看

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

可以很明显得看到各种各种的导入表函数,拿到之后再按照前面的方式添加进去就好了

根据导入表的性质来修复

这里采用一个工具来处理

https://down.52pojie.cn/Tools/PEtools/ImportREConstructor%201.7e.zip 解压密码:www.52pojie.cn

 

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

添加进程,修改OEP和大小,然后获取导入表,同时还需要进入OD用刚刚的办法查看是否把所有的dll都包含了,这里是确实只有两个dll,如果没有可以尝试修改大小来处理

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

然后使用转存到我们刚刚弄的.exe文件就好了,正常的话下面会出现一个保存成功

这次再查看导入表

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

就是很正常的了

再查看它的区段

<span role="heading" aria-level="2">脱壳——UPX脱壳原理(脱壳helloworld)

 

 

可以看到多了个区段,和我们前面想的一样手动添加了一个区段来专门修复导入表.

 

总结 UPX脱壳

首先采取找到OEP,然后呢对整个PE文件进行dump出来,然后再修复,修复需要修复PE的区段头和导入表

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/154864.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • ubuntu kill命令_killall命令

    ubuntu kill命令_killall命令Linux中的kill命令用来终止指定的进程(terminate a process)的运行,是Linux下进程管理的常用命令。通常,终止一个前台进程可以使用Ctrl+C键,但是,对于一个后台进程就须用kill命令来终止,我们就需要先使用ps/pidof/pstree/top等工具获取进程PID,然后使用kill命令来杀掉该进程。kill命令是通过向进程发送指定的信号来结束相应进程的。在默认情况下…

    2022年10月30日
  • 补码的表示 以及+-0的问题「建议收藏」

    补码的表示 以及+-0的问题「建议收藏」正数的补码是其本身,也就是原码.负数的补码是各位取反后加1.也就是其反码加1.+0的补码就是其原码,也就是说是00000000而已(对于8位来说)-0的补码是其反码加1,其反码是11111111,当然,其反码加1后就是溢出一个进位后,仍然是00000000.问题出现在(+0)和(-0)上,在人们的计算概念中零是没有正负之分的。于是就引入了补码概念。负数的补码就是对反码加一,而正数不…

  • SingleTask启动模式与HOME键问题

    SingleTask启动模式与HOME键问题Android中Activity启动模式SingleTask时点击Home键问题:http://blog.csdn.net/java201159416/article/details/51992249

  • SQL Server 2008 还原数据库

    SQL Server 2008 还原数据库

  • mysql 自己一些平时用不到的函数

    mysql 自己一些平时用不到的函数

  • Centos7部署mysql5.7

    Centos7部署mysql5.7下载mysql源安装包wgethttp://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm如果官网下载地址有问题也可以使用博客地址下载,下载后上传至服务器即可https://download.csdn.net/download/wu2700222/10460468安装mysql源yumlocalinstall…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号