好友
阅读权限40
听众
最后登录1970-1-1
|
小生我怕怕
发表于 2008-12-3 16:03
【文章标题】: 手脱Protection PLUS4.X主程序
【文章作者】: 小生我怕怕[LCG]
【作者主页】: www.52pojie.cn
【作者QQ号】: 4586631
【软件名称】: Protection PLUS
【软件大小】: 10.36M
【下载地址】: 自己搜索下载
【加壳方式】: 全保护
【编写语言】: VC++
【使用工具】: 自我修改版OD,lordPE
【操作平台】: windows xp
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
00480030 > 50 push eax //OD载入
00480031 60 pushad //壳非常简单ESP定律解决
00480032 29C0 sub eax,eax //所以在这行执行ESP定律
00480034 64:FF30 push dword ptr fs:[eax] //我们运行后会出现一个注册框
00480037 E8 00000000 call PLUS.0048003C //我们先Evaluate Protection PULS[试用的意思]
━━━━━━━━━━━━━━━━━━━━━━━━━━
图1:
━━━━━━━━━━━━━━━━━━━━━━━━━━
00C53EA2 870424 xchg dword ptr ss:[esp],eax //停在这里后我们单步一步F8走一下
00C53EA5 C3 retn //通过这个RETN我们就返回到OEP啦
00C53EA6 CC int3
00C53EA7 CC int3
━━━━━━━━━━━━━━━━━━━━━━━━━━
00419B34 55 push ebp //我们的OEP
00419B35 8BEC mov ebp,esp //运行lordPE把程序DUMP,在运行importRCE看下,有333个无效指针
00419B37 6A FF push -1 //好现在开始我们的IAT加密的处理,选中第一个无效指针双击,复制RVA
00419B39 68 B86F4300 push PLUS.00436FB8 //当前RVA==00033000
00419B3E 68 30DC4100 push PLUS.0041DC30 //打开内存看下我们的基址===00400000
00419B43 64:A1 00000000 mov eax,dword ptr fs:[0] //IAT地址等于基址+加密的RVA==00433000[加密地址]
00419B51 83EC 58 sub esp,58 //我们从载程序吧
━━━━━━━━━━━━━━━━━━━━━━━━━━
图2:
━━━━━━━━━━━━━━━━━━━━━━━━━━
00480030 > 50 push eax //从载程序,入口点
00480031 60 pushad //在命令提示行输入:d 00433000
00480032 29C0 sub eax,eax //跟踪我们的IAT的加密指针地址
00480034 64:FF30 push dword ptr fs:[eax]
00480037 E8 00000000 call PLUS.0048003C
━━━━━━━━数据窗口━━━━━━━━━━━━
00433000 9927434A //我们右键选中此句,断点---硬件访问---Dword
00433004 C0A30000 //接着我们shift+f9运行程序,直到指针初始化
00433008 107C207F
0043300C 191CEABF
00433010 FFC91F0A
━━━━━━━数据窗口━━━━━━━━━━━━━━
00433000 00000000 //当指针初始化后,同时会出现一个注册框
00433004 00000000 //我们点Evaluate Protection PULS[试用的意思]
00433008 00000000
0043300C 00000000
00433010 00000000
00433014 00000000
━━━━━━━━━━━━━━━━━━━━━━━━━━
00C51B38 8B4424 1C mov eax,dword ptr ss:[esp+1C] //停在了这里
00C51B3C 8B0B mov ecx,dword ptr ds:[ebx] //我们F8开始跟吧,跟的同时注意其他窗口的变化
00C51B3E 83C7 04 add edi,4
00C51B41 40 inc eax
00C51B42 83C6 05 add esi,5
00C51B45 3BC1 cmp eax,ecx
━━━━━━━━━━━━━━━━━━━━━━━━━━
00C51B27 55 push ebp //此句时会发现我们的IATEBP中出现,并压栈
00C51B28 52 push edx //这里压入一个加密地址
00C51B29 E8 D2000000 call 00C51C00 //这里是加密CALL
00C51B2E 85C0 test eax,eax //这里比较是否还要继续加密
00C51B30 74 65 je short 00C51B97 //如果没有需要继续加密的指针,则跳转实现
00C51B32 8B6C24 24 mov ebp,dword ptr ss:[esp+24] //这里计算出加密的地址
00C51B36 8907 mov dword ptr ds:[edi],eax //这里把我们的加密指针赋值给我们IAT地址
00C51B38 8B4424 1C mov eax,dword ptr ss:[esp+1C] //为EAX计算下一句需要处理的指针
00C51B3C 8B0B mov ecx,dword ptr ds:[ebx] //计算下一句加密地址所在地
00C51B3E 83C7 04 add edi,4 //为当前IAT指针所在地址加4处理
00C51B41 40 inc eax //EAX加1
00C51B42 83C6 05 add esi,5 //这里为加密指针地址加5处理,计算下一句需要加密
00C51B45 3BC1 cmp eax,ecx //比较是否需要加密
00C51B47 894424 1C mov dword ptr ss:[esp+1C],eax
00C51B4B ^ 72 BB jb short 00C51B08 //当这里跳转实现时,即表示下一句指针不需要进行加密处理
00C51B4D 8B03 mov eax,dword ptr ds:[ebx]
00C51B4F 8B7C24 10 mov edi,dword ptr ss:[esp+10]
00C51B53 8D0C18 lea ecx,dword ptr ds:[eax+ebx]
00C51B56 8D5C81 0C lea ebx,dword ptr ds:[ecx+eax*4+C]
00C51B5A 8B4B 04 mov ecx,dword ptr ds:[ebx+4]
00C51B5D 85C9 test ecx,ecx
00C51B5F 8D43 04 lea eax,dword ptr ds:[ebx+4]
00C51B62 ^ 0F85 5FFFFFFF jnz 00C51AC7 //当这里跳转实现时,则表示下一句指针需要加密加密处理
━━━━━━━━加密CALL━━━━━━━
00C51C00 64:A1 00000000 mov eax,dword ptr fs:[0] //我们现在来到加密CALL,看下加密指针的实现
00C51C06 6A FF push -1 //F8继续单步向下走
00C51C08 68 7B08CD00 push 0CD087B
00C51C0D 50 push eax
00C51C0E 64:8925 0000000>mov dword ptr fs:[0],esp
━━━━━━━━━━━━━━━━━━━━━━━━━━
00C51C16 55 push ebp //走到这句时发现指针准备压栈
00C51C17 56 push esi //同时压入ESI
00C51C18 57 push edi //通式压入EDI
00C51C19 68 08E6CE00 push 0CEE608 ; ASCII "kernel32.dll"//同时压入指针所属模块
00C51C1E E8 ADFFFFFF call 00C51BD0
━━━━━━━━━━━━━━━━━━━━━━━━━━
00C51C23 8B6C24 20 mov ebp,dword ptr ss:[esp+20] //计算出IAT指针正确所在地址
00C51C27 8B7C24 24 mov edi,dword ptr ss:[esp+24] //这里把我们的IAT指针赋值给当前IAT的地址
00C51C2B 3BE8 cmp ebp,eax //比较是否执行下面的加密处理
00C51C2D 0F85 90000000 jnz 00C51CC3 //当本句跳转不跳时则向下实行加密,即我们的magic jump 1
00C51C33 81FF 00000100 cmp edi,10000 ; UNICODE "ALLUSERSPROFILE=C:\Documents and Settings\All Users"
00C51C39 0F82 EA000000 jb 00C51D29 //我们继续向下看看,我们的IAT的加密实现吧
00C51C3F BE F4E5CE00 mov esi,0CEE5F4 ; ASCII "GetModuleHandleA"
00C51C44 8BC7 mov eax,edi //将加密后的指针传送给EAX
00C51C46 8A10 mov dl,byte ptr ds:[eax] //取加密指针第一位
00C51C48 8A1E mov bl,byte ptr ds:[esi] //将覆盖GetModuleHandleA第一位
━━━━━━━━━━━━━━━━━━━━━━━━━━
00C51C81 BE E4E5CE00 mov esi,0CEE5E4 ; ASCII "GetProcAddress" //和上面的加密指令一样
00C51C86 8BC7 mov eax,edi //这里把EDI加密后的指针传送EAX
00C51C88 8A10 mov dl,byte ptr ds:[eax] //取指针第一位
00C51C8A 8A1E mov bl,byte ptr ds:[esi] //取GetModuleHandleA
00C51C8C 8ACA mov cl,dl //将dl的值传送cl
00C51C8E 3AD3 cmp dl,bl //比较是否需要在加密
━━━━━━━━━━━━━━━━━━━━━━━━━━
00C51D84 /77 6B ja short 00C51DF1 //当上面执行完第一层加密后,即这里就是我们的magic jump 2
00C51D86 |FF2485 081EC500 jmp dword ptr ds:[eax*4+C51E08] //在这里执行变形处理
00C51D8D |6A 06 push 6
00C51D8F |E8 0C040000 call 00C521A0
00C51D94 |85C0 test eax,eax
00C51D96 |74 5B je short 00C51DF3
━━━━━━━━━━━━━━━━━━━━━━━━━━
00C51DA4 6A 07 push 7 //上面的JMP跳到这里完成一系列加密
00C51DA6 E8 F5030000 call 00C521A0 //这个CALL里完成我们的加密指针的完成
00C51DAB 85C0 test eax,eax //这里比较是否处理完成
00C51DAD 74 44 je short 00C51DF3 //完成则不跳走,继续下面的处理
00C51DAF C600 B8 mov byte ptr ds:[eax],0B8 //将esi的指针传送给EAX,到此加密完成
00C51DB2 8970 01 mov dword ptr ds:[eax+1],esi //下面的JMP直接跳向最后的retn返回到表层代码
00C51DB5 C640 05 50 mov byte ptr ds:[eax+5],50 //我们从载程序来一次完整的脱壳吧
00C51DB9 C640 06 C3 mov byte ptr ds:[eax+6],0C3
00C51DBD EB 30 jmp short 00C51DEF
00C51DBF 6A 05 push 5
━━━━━━━━━━━━━━━━━━━━━━━━━━
00C51C2D 0F85 90000000 jnz 00C51CC3 //改JMP使其成为我们magic jump 1
00C51D84 /77 6B ja short 00C51DF1 //改jmp使其成为我们magic jump 2
━━━━━━━━━━━━━━━━━━━━━━━━━━
00480030 > 50 push eax //在次从载程序
00480031 60 pushad //首先撤消我们一开始下的所有断点
00480032 29C0 sub eax,eax //此设置好ESP定律的断点
00480034 64:FF30 push dword ptr fs:[eax] //ctrl+g查找00C51C2D和00C51D84
00480037 E8 00000000 call PLUS.0048003C //会提示在指令地址中没有内存
0048003C 5D pop ebp //那我们设置好ESP定律后我们F8单步去找一个可以查找的地址
0048003D 83ED 3C sub ebp,3C
━━━━━━━━━━━━━━━━━━━━━━━━━━
00480107 8B85 23030000 mov eax,dword ptr ss:[ebp+323] //当我们单步到这里时需要放慢脚步啦
0048010D 50 push eax //此时寄存器里的EAX地址正好等于00C55D4D
0048010E 0385 0C000000 add eax,dword ptr ss:[ebp+C]
00480114 FFD0 call eax //这里call我们寄存器的地址,我们F7跟进
00480116 85C0 test eax,eax
00480118 75 0B jnz short PLUS.00480125
━━━━━━━━━━━━━━━━━━━━━━━━━━
00C55D4D 55 push ebp ; PLUS.00480000 //好我们可以找我们的两个magic jump啦
00C55D4E 8BEC mov ebp,esp //ctrl+g查找00C51C2D和00C51D84
00C55D50 53 push ebx //然后把两个跳转都改为JMP
00C55D51 8B5D 08 mov ebx,dword ptr ss:[ebp+8] //改好后我们shift+f9运行程序
00C55D54 56 push esi
00C55D55 8B75 0C mov esi,dword ptr ss:[ebp+C]
━━━━━━━━━━━━━━━━━━━━━━━━━━
00C53EA2 870424 xchg dword ptr ss:[esp],eax //停在了这里
00C53EA5 C3 retn //这里retn返回到我们的OEP
00C53EA6 CC int3
00C53EA7 CC int3
━━━━━━━━━━━━━━━━━━━━━━━━━━
00419B34 55 push ebp //运行lordPE把程序dump
00419B35 8BEC mov ebp,esp //dump后发现程序图标毁啦,PEID查一下,显示不是有效的PE文件[图3
00419B37 6A FF push -1 //这时很多朋友一定以为是dump时发生错误啦
00419B39 68 B86F4300 push PLUS.00436FB8 //我们用lordPE看下区段[图4],发现有区段的虚拟大小和物理大小都是0
00419B3E 68 30DC4100 push PLUS.0041DC30 //接下来我们在打开原程序看下[图5],发现原程序有大小,大小为:000E6800
00419B43 64:A1 00000000 mov eax,dword ptr fs:[0] //我们把我们脱壳后的程序也同样修改下,虚拟大小和物理大小都设置000E6800
00419B49 50 push eax //大家修改后记住保存一下
00419B4A 64:8925 0000000>mov dword ptr fs:[0],esp //现在我们打开importRCE修复一下吧,修复时会发现IAT指针全部有效
00419B51 83EC 58 sub esp,58 //到此脱壳结束程序为Microsoft Visual C++ 6.0编写
00419B54 53 push ebx
━━━━━━━━━━━━━━━━━━━━━━━━━━
图3
━━━━━━━━━━━━━━━━━━━━━━━━━━
图4
━━━━━━━━━━━━━━━━━━━━━━━━━━
图5
━━━━━━━━━━━━━━━━━━━━━━━━━━
以下为这个程序的主程序下载:
http://www.rayfile.com/files/eca ... -8b57-0019d11a795f/
--------------------------------------------------------------------------------
【经验总结】
主要是因为前次视频做得太马虎,所以今天才从做了一次,拿他的主程序玩了下,这个壳主要还是脱壳后比较忽悠人,至于
magic jump还是比较明显容易判断出来的,写得不好请大家别见笑
--------------------------------------------------------------------------------
【版权声明】: 本文原创于小生我怕怕, 转载请注明作者并保持文章的完整, 谢谢!
2008年12月03日 16:00:12
[ 本帖最后由 小生我怕怕 于 2008-12-3 16:05 编辑 ] |
免费评分
-
查看全部评分
|