UPX脱壳全程分析(转)
【文章标题】: UPX脱壳全程分析
004629D0 > 60 pushad //保存现场(pushad 相当于 push 所有的寄存器)
004629D1 BE 00F04300 mov esi, 0043F000 //把代码段放到esi寄存器
004629D6 8DBE 0020FCFF lea edi, dword ptr [esi+FFFC2000] //得到基址
004629DC C787 9CC00400 7> mov dword ptr [edi+4C09C], 46CD167B //将第一个函数的地址放到[edi+ 4C09C]
004629E6 57 push edi //将基址压栈
004629E7 83CD FF or ebp, FFFFFFFF //将0012FFC0与 FFFFFFFF或
004629EA EB 0E jmp short 004629FA
004629EC 90 nop
004629ED 90 nop
004629EE 90 nop
004629EF 90 nop
004629F0 8A06 mov al, byte ptr [esi] //取出0043F004的一个字节
004629F2 46 inc esi //指向下一个字节
004629F3 8807 mov byte ptr [edi], al //从00401000开始,开始还原代码
004629F5 47 inc edi //指向下一个地址
004629F6 01DB add ebx, ebx //ebx + ebx,当ebx不等于零的时候跳转,下面的adc如果为,就取出下一个地址,并放到ebx中
004629F8 75 07 jnz short 00462A01
004629FA 8B1E mov ebx, dword ptr [esi] //将0043F000放到ebx中
004629FC 83EE FC sub esi, -4 //0043F000加4
004629FF 11DB adc ebx, ebx //进位加法器
00462A01 ^ 72 ED jb short 004629F0 // 向上跳转,ebx做为是否回跳的标志,循环处理代码
00462A03 B8 01000000 mov eax, 1 // eax = 1
00462A08 01DB add ebx, ebx // ebx依然作为循环的标志
00462A0A 75 07 jnz short 00462A13
00462A0C 8B1E mov ebx, dword ptr [esi] //esi指向的地址放到ebx里面
00462A0E 83EE FC sub esi, -4 //esi + 4
00462A11 11DB adc ebx, ebx //进位加法
00462A13 11C0 adc eax, eax //进位加法
00462A15 01DB add ebx, ebx //ebx + ebx
00462A17 73 0B jnb short 00462A24
00462A19 75 28 jnz short 00462A43 //跳到下面
00462A95 81FD 00FBFFFF cmp ebp, -500 //迷惑指令
00462A9B 83D1 02 adc ecx, 2 //进位加法
00462A9E 8D142F lea edx, dword ptr [edi+ebp] //edi + ebp的地址装载到edx,即原来的代码段的地址
00462AA1 83FD FC cmp ebp, -4 //判断跳转标志,EBP小于等于-4就跳
00462AA4 76 0E jbe short 00462AB4
00462AA6 8A02 mov al, byte ptr [edx] //取出代码段的一字节
00462AA8 42 inc edx //指向下一个地址
00462AA9 8807 mov byte ptr [edi], al //取出的代码放到edi里面
00462AAB 47 inc edi //指向下一个代码
00462AAC 49 dec ecx //计数器
00462AAD ^ 75 F7 jnz short 00462AA6 //关于计数器(ecx)的跳转
00462AAF ^ E9 42FFFFFF jmp 004629F6 //向上面跳,跳到add ebx,ebx
00462AB4 8B02 mov eax, dword ptr [edx] //处理输入表
00462AB6 83C2 04 add edx, 4 //edx + 4,指向下一个地址
00462AB9 8907 mov dword ptr [edi], eax //将代码放到edi
00462ABB 83C7 04 add edi, 4 // edi + 4, 存放代码的地址
00462AC3 01CF add edi, ecx //edi + ecx,指向接收代码的地址的最后一个字节
00462AC5 ^ E9 2CFFFFFF jmp 004629F6 //跳到 add ebx,ebx
00462AD2 8A07 mov al, byte ptr [edi] //指向我们原来代码段的代码,取出到AL里面
00462AD4 47 inc edi //指向下一个字节
00462AD5 2C E8 sub al, 0E8 //处理CALL
00462AD7 3C 01 cmp al, 1 //判断al是否大于1
00462AD9 ^ 77 F7 ja short 00462AD2 //循环,到下一个CALL的第一个字节为止
00462AE0 8B07 mov eax, dword ptr [edi] //取出里面的地址,里面的地址是定位CALL的绝对地址要用到的
00462AE2 8A5F 04 mov bl, byte ptr [edi+4] //得到下条地址的开始字节放到AL里面,CALL绝对地址就是下条指令开始+刚才上面取出的那个数字
00462AE5 66:C1E8 08 shr ax, 8 //ax右移8位
00462AE9 C1C0 10 rol eax, 10 //eax算术左移 8位
00462AEC 86C4 xchg ah, al //交换内容
00462AEE 29F8 sub eax, edi //eax - edi
00462AF0 80EB E8 sub bl, 0E8 //再减去E8
00462AF3 01F0 add eax, esi //eax + esi,其中 esi是代码段开始的地方
00462AF5 8907 mov dword ptr [edi], eax //这里处理CALL的地址,算出CALL的偏移到EDI里面
00462AF7 83C7 05 add edi, 5 //edi + 5,指向call的后面
00462AFA 88D8 mov al, bl //bl的内容放到al中
00462AFC ^ E2 D9 loopd short 00462AD7 //循环处理CALL,其中ecx作为计数器
00462AFE 8DBE 00F00500 lea edi, dword ptr [esi+5F000] //代码段的起始地址 + 5F000
00462B04 8B07 mov eax, dword ptr [edi] //现在EDI指向我们的代码的输入表
00462B06 09C0 or eax, eax //eax 或 eax ,判断eax是否为零
00462B0A 8B5F 04 mov ebx, dword ptr [edi+4] //取得这个地址的数据放到ebx
00462B0D 8D8430 AC2D0600 lea eax, dword ptr [eax+esi+62DAC] // 取得外壳段的KERNEL32.DLL的地址放eax
00462B14 01F3 add ebx, esi //我们代码段的起始地址加上刚才取出的那个数据
00462B16 50 push eax //kernel32.dll的地址
00462B17 83C7 08 add edi, 8 //edi + 8
00462B1A FF96 4C2E0600 call dword ptr [esi+62E4C] //装载kernel32.dll
00462B20 95 xchg eax, ebp //交换数据,即eax指向kernel32.dll的地址
00462B21 8A07 mov al, byte ptr [edi] //取得现在的EDI的地址指向的数据放到AL
00462B23 47 inc edi //指向下一个函数
00462B24 08C0 or al, al //al 或 al,判断al是否为零
00462B26 ^ 74 DC je short 00462B04
00462B28 89F9 mov ecx, edi //取出的函数的名字放到ecx里面
00462B2A 57 push edi //函数名字压栈
00462B2B 48 dec eax //eax - 1
00462B2C F2:AE repne scas byte ptr es:[edi]
00462B2E 55 push ebp //kernel32.dll的基址
00462B2F FF96 502E0600 call dword ptr [esi+62E50] //外壳的GetProcaddress
00462B35 09C0 or eax, eax //eax或eax,得到函数的地址
00462B37 74 07 je short 00462B40
00462B39 8903 mov dword ptr [ebx], eax //处理输入表
00462B3B 83C3 04 add ebx, 4 //ebx + 4,指向下一个输入表的地址
00462B46 8BAE 542E0600 mov ebp, dword ptr [esi+62E54] //VirtualProtect的地址放到ebp
00462B4C 8DBE 00F0FFFF lea edi, dword ptr [esi-1000] //指向PE头,即映像基址
00462B52 BB 00100000 mov ebx, 1000 //把1000放到ebx,即ebx = 1000
00462B5D FFD5 call ebp //改变属性
00462B5F 8D87 1F020000 lea eax, dword ptr [edi+21F] //现在eax指向PE头中区段的偏移起始位置
00462B65 8020 7F and byte ptr [eax], 7F //改写区段名字
00462B68 8060 28 7F and byte ptr [eax+28], 7F //改写区块属性第一个区块的属性
00462B75 61 popad //恢复现场
00462B76 8D4424 80 lea eax, dword ptr [esp-80]
00462B7A 6A 00 push 0
00462B7C 39C4 cmp esp, eax
00462B7E ^ 75 FA jnz short 00462B7A
00462B80 83EC 80 sub esp, -80
00462B83 ^ E9 109FFEFF jmp 0044CA98 //跨区段的转移,跳到OEP
提供一份附件,看起来可能更直观:
http://www.2cto.com/uploadfile/2012/1202/20121202072155254.zip
UPX脱壳全程分析(转)的更多相关文章
- android 脱壳 之 dvmDexFileOpenPartial断点脱壳原理分析
android 脱壳 之 dvmDexFileOpenPartial断点脱壳原理分析 导语: 笔者主要研究方向是网络通信协议的加密解密, 对应用程序加固脱壳技术很少研究, 脱壳壳经历更是经历少之甚少. ...
- 脱壳——UPX脱壳原理(脱壳helloworld)
脱壳--UPX脱壳原理 脱壳步骤 1 找到OEP 2 dump(导出)内存文件 3 修复 1 找到OEP 1 程序运行先从壳代码运行,壳代码执行完之后会跳转到真正的OEP,也就是是说第一步,首先要找到 ...
- DexHunter在ART虚拟机模式下的脱壳原理分析
本文博客地址: http://blog.csdn.net/qq1084283172/article/details/78494620 DexHunter脱壳工具在Dalvik虚拟机模式下的脱壳原理分析 ...
- UPX源码分析——加壳篇
0x00 前言 UPX作为一个跨平台的著名开源压缩壳,随着Android的兴起,许多开发者和公司将其和其变种应用在.so库的加密防护中.虽然针对UPX及其变种的使用和脱壳都有教程可查,但是至少在中文网 ...
- DexHunter脱壳神器分析
0x00 这篇文章我们分析Android脱壳神器DexHunter的源码. DexHunter作者也写了一篇介绍它的文章从Android执行时出发.打造我们的脱壳神器.DexHunter源码位于htt ...
- 安卓脱壳&&协议分析&&burp辅助分析插件编写
前言 本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274 前言 本文以一个 app 为例,演示对 app脱壳,然后分析其 协 ...
- DexHunter在Dalvik虚拟机模式下的脱壳原理分析
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/78494671 在前面的博客<DexHunter的原理分析和使用说明(一)&g ...
- UPX压缩
什么是UPX UPX (the Ultimate Packer for eXecutables)是一款先进的可执行程序文件压缩器,压缩过的可执行文件体积缩小50%-70% ,这样减少了磁盘占用空间.网 ...
- LoardPe与Import REC X64dbg脚本 脱壳 Upx
目录 LoardPe与Import REC X64dbg脚本 脱壳 Upx 一丶X64dbg调试器与脚本 1.1 起因 1.2 脚本的调试 1.3 Upx脱壳脚本 二丶LoardPe 内存Dump与I ...
随机推荐
- 6.1-uC/OS-III软件定时器
1.软件定时器是 uC/OS 操作系统的一个内核对象,软件定时器是基于时钟节拍和系统管理创建的软件性定时器,理论上可以创建无限多个,但精准度肯定比硬件定时稍逊一筹. 2.软件定时器启动之后是由软件定时 ...
- Oracle单行函数
一.尽管各个数据库都是支持sql语句的.可是每一个数据库也有每一个数据库所支持的操作函数,这些就是单行函数.假设想进行数据库开发的话.除了要回使用sql语句外,就是要多学习函数. 1.单行函数的分类: ...
- javaweb(2)之Servlet入门
Hello Servlet 方式一 1.新建 web 工程,编写一个类,实现 javax.servlet.Servlet 接口: package com.zze.servlet; import jav ...
- GDB查看堆栈局部变量
GDB查看堆栈局部变量 “参数从右到左入栈”,“局部变量在栈上分配空间”,听的耳朵都起茧子了.最近做项目涉及C和汇编互相调用,写代码的时候才发现没真正弄明白.自己写了个最简单的函数,用gdb跟踪了调用 ...
- 建立请求号 request
1:获取TR号(一般由团队的负责人创建,发出) 2:进入 i7p系统 3:点击process 4:输入tr号 5:选中 正确的请求号,右键> process item> add task ...
- [js]js中事件的3要素
js中事件的3要素 事件源 事件 事件处理程序 <!DOCTYPE html> <html> <head lang="en"> <meta ...
- C#:特性
#define IsText//添加一个宏,接触注释 using System; using System.Collections.Generic; using System.Diagnostics; ...
- [PHP] swoole在daemonize模式下,chdir失效问题
swoole version: 1.9.6 其实跟swoole的版本无关,因为原代码体系,fpm模式下,在启动的时候,是使用 chdir 函数改变了当前目录的,而其它代码在做类的自动加载的时候,都是写 ...
- hdu4777 树状数组
题意:给了n个数,然后又m次查询,询问[L,R] 内有多少个数与其他的数不互质. 解: 我们首先可以通过处理得出每个数的有效区间,LR 就是 左边L位置上的数 和他不互质, 右边R位置上的数和不互质, ...
- Vue基础进阶 之 自定义指令
自定义指令-----钩子函数 自定义指令 除了内置指令,Vue也允许用户自定义指令: 注册指令:通过全局API Vue.directive可以注册自定义指令: 自定义指令的钩子函数: bind: in ...