首页
社区
课程
招聘
[原创]寻找Asp1.2X的Stolen code的另一种方法
2004-7-11 21:19 9453

[原创]寻找Asp1.2X的Stolen code的另一种方法

2004-7-11 21:19
9453
Advanced WMA Workshop 2.04b简单脱壳破解

程序用asp1.24rc4加壳,并用壳的时间保护

作者:lordor
QQ:88378557
Mail:lordor#163.com
来自:www.digitalnuke.com
说明:asp1.24RC4的Stolen code的寻找方法,这个方法对于1.3以上的是否管用,还在研究中。
自由转载请保

一、寻找伪OEP
用od载入程序,设置内存不打钩,其它都 打钩,隐藏od,到如下:
AWMAWork.>PUSH AWMAWork.00632001        ==>先停在这里,看一下寄存器的值
--------------
ECX 0012FFB0
EDX 7FFE0304
EBX 7FFDF000
ESP 0012FFC4        ==>注意这个
EBP 0012FFF0        ==>
ESI 00000024
EDI 00000000
EIP 00401000 AWMAWork.<ModuleEntryPoint>
--------------

经过26个seh后,到这里的特征代码:
00CB39EC  XOR DWORD PTR DS:[EAX],EAX        ==>停在这里
00CB39EE  POP DWORD PTR FS:[0]
00CB39F5  POP EAX
00CB39F6  CMP DWORD PTR DS:[CB7EB0],0
00CB39FD  JE SHORT 00CB3A13
00CB39FF  PUSH 0C
00CB3A01  MOV ECX,0CB7EB0
00CB3A06  LEA EAX,DWORD PTR SS:[EBP-8]
00CB3A09  MOV EDX,4
00CB3A0E  CALL 00CB0B40
00CB3A13  PUSH DWORD PTR SS:[EBP-4]
00CB3A16  PUSH DWORD PTR SS:[EBP-8]
00CB3A19  MOV EAX,DWORD PTR SS:[EBP-C]
00CB3A1C  CMP DWORD PTR DS:[EAX],0
00CB3A1F  JE SHORT 00CB3A23
00CB3A21  PUSH DWORD PTR DS:[EAX]
00CB3A23  PUSH DWORD PTR SS:[EBP-10]
00CB3A26  PUSH DWORD PTR SS:[EBP-14]
00CB3A29  RETN                        ==>这里下断,shift+F9运行到这里

打开"Memory Map"窗口
在AWMAWorkshop的"code"段下“Set break-on access”(即按F2),这样当执行完壳的代码后,再执行解压后代码段的内容就会停下来。
置完后,按F9,会到这里
0047DB94  PUSH AWMAWork.0047DCEC                   ; JMP to MSVCR70._except_handler3
0047DB99  MOV EAX,DWORD PTR FS:[0]
0047DB9F  PUSH EAX
0047DBA0  MOV EAX,DWORD PTR SS:[ESP+10]
0047DBA4  MOV DWORD PTR SS:[ESP+10],EBP
0047DBA8  LEA EBP,DWORD PTR SS:[ESP+10]
0047DBAC  SUB ESP,EAX                ==>这里为stack分配局部地址,eax为压入的立即数
0047DBAE  PUSH EBX                ***
0047DBAF  PUSH ESI                ***       
0047DBB0  PUSH EDI                ***
0047DBB1  MOV EAX,DWORD PTR SS:[EBP-8]
0047DBB4  MOV DWORD PTR SS:[EBP-18],ESP
0047DBB7  PUSH EAX                ***
0047DBB8  MOV EAX,DWORD PTR SS:[EBP-4]
0047DBBB  MOV DWORD PTR SS:[EBP-4],-1
0047DBC2  MOV DWORD PTR SS:[EBP-8],EAX
0047DBC5  LEA EAX,DWORD PTR SS:[EBP-10]
0047DBC8  MOV DWORD PTR FS:[0],EAX
0047DBCE  RETN                        ==>停在这里
0047DBCF  MOV ECX,DWORD PTR SS:[EBP-10]
0047DBD2  MOV DWORD PTR FS:[0],ECX
0047DBD9  POP ECX
0047DBDA  POP EDI
0047DBDB  POP ESI
0047DBDC  POP EBX
0047DBDD  LEAVE
0047DBDE  PUSH ECX

可以看到这个是VC7的第一个call的代码,看一下寄存器的值,并注意***上面压入了几句(这里只有四句),后面会用到:
------------
ECX 0012FFB0
EDX 7FFE0304
EBX 7FFDF000
ESP 0012FF30        ==>注意这里
EBP 0012FFC0       
ESI 00000000
EDI 00000000
EIP 0047DBCE AWMAWork.0047DBCE

------------
F8一步,到这里
0047D8C5  RETN 10
0047D8C8  ADD BYTE PTR DS:[EAX],AL
0047D8CA  ADD BYTE PTR DS:[EAX],AL
0047D8CC  ADD BYTE PTR DS:[EAX],AL
0047D8CE  NOP                                ==>花指令,nop掉
0047D8CF  CALL AWMAWork.0047DB94
0047D8D4  XOR EBX,EBX                        ===>到这里,伪OEP,可以看到上一个call(0047DB94)已经在壳中运行了
0047D8D6  PUSH EBX
0047D8D7  MOV EDI,DWORD PTR DS:[4820FC]
0047D8DD  CALL EDI
0047D8DF  CMP WORD PTR DS:[EAX],5A4D
0047D8E4  JNZ SHORT AWMAWork.0047D905
0047D8E6  MOV ECX,DWORD PTR DS:[EAX+3C]
0047D8E9  ADD ECX,EAX

二、寻找STOLEN CODE,并DUMP程序

可以看到0047D8C8  ADD BYTE PTR DS:[EAX],AL处就是真正的OEP了,那里已经抽掉两句代码了,
可能你会问,我是怎么知道的?
找回抽掉的代码的方法一般有:
1、TC跟踪得到
2、tDasm老兄介绍的还原stolen code的分析法
3、FLY老兄介绍的cdi猜测法,这个我还是未明白
4、blowfish老兄介绍的建立stack法,这个方法非常好。

我的方法是在blowfish方法的基础上再加上:参照同类编译器生成的入口代码。

好,那么我们打开一个VC7的程序,看一下入口的代码
Service.<>PUSH 74               
0040270F  PUSH Service.00403BF8
00402714  CALL Service.0040290C
00402719  XOR EBX,EBX                        ==>这里以下都是相同的语句
0040271B  MOV DWORD PTR SS:[EBP-20],EBX
0040271E  PUSH EBX                                 ; /pModule => NULL
0040271F  MOV EDI,DWORD PTR DS:[<&KERNEL32.GetModu>; |kernel32.GetModuleHandleA
00402725  CALL EDI                                 ; \GetModuleHandleA
00402727  CMP WORD PTR DS:[EAX],5A4D
0040272C  JNZ SHORT Service.0040274D
0040272E  MOV ECX,DWORD PTR DS:[EAX+3C]
00402731  ADD ECX,EAX
00402733  CMP DWORD PTR DS:[ECX],4550
00402739  JNZ SHORT Service.0040274D

所以关键就是想方法补上抽掉的两句代码。首先可以推测一下这两句的形式:
push 立即数
push 地址

那么如何那个立即数及地址呢?

这里就要查看STACK的内容来确定了。

先看一载入程序时的ESP==0012FFC4,EBP=0012FFF0,
再看一下到伪OEP后的STACK的内容:
0012FF34   00000000        ==>现在的esp
0012FF38   00000000
0012FF3C   7FFDF000
0012FF40   00CA0000
0012FF44   00C80000
0012FF48   0000000C
0012FF4C   00CD1F70
0012FF50   0012FF60
0012FF54   00CCDD95  RETURN to 00CCDD95 from 00CCDDA0
0012FF58   00CCDDF3  RETURN to 00CCDDF3 from 00CCDDFD
0012FF5C   00CCDDD6  RETURN to 00CCDDD6 from 00CCDDE8
0012FF60   00400000  AWMAWork.00400000
0012FF64   C0F1DD1F
0012FF68   0012FFA4
0012FF6C   00CA0000
0012FF70   00C80000
0012FF74   00CB4138
0012FF78   00CD1DA0
0012FF7C   00CCDD50
0012FF80   00400000  AWMAWork.00400000
0012FF84   00632880  AWMAWork.00632880
0012FF88   00CCDE87  RETURN to 00CCDE87 from 00CCDE93
0012FF8C   5FCEDFF7
0012FF90   00000369
0012FF94   0080FD60
0012FF98   FDC7616E
0012FF9C   0012FFF0
0012FFA0   0012FFB0
0012FFA4   00000000
0012FFA8   0012FF34
0012FFAC   0012FFE0
0012FFB0   0012FFE0  Pointer to next SEH record
0012FFB4   0047DCEC  SE handler
0012FFB8   0049E9C0  AWMAWork.0049E9C0
0012FFBC   FFFFFFFF
0012FFC0   0012FFF0        ==>注意这里
0012FFC4   77E5EB69  RETURN to kernel32.77E5EB69

其中(0012FFB8   0049E9C0  AWMAWork.0049E9C0)的0049E9C0即为第二句抽掉的的push,
现在来确定那个立即数
0012FFC0-0012FF34=8c,这个是我们要找的立即数吗?不是,还要减掉4*4个字节(注意上面所说的),即
8c-4*4=7C,这个就是立即数。

所以总结抽掉的代码如下:
push 7C
push 0049E9C0
注:这可不是常见的push ebp什么的啊

这两句补完后,长度刚好相等
0047D8C8  PUSH 7C
0047D8CA  PUSH AWMAWork.0049E9C0
0047D8CF  CALL AWMAWork.0047DB94
0047D8D4  XOR EBX,EBX
0047D8D6  PUSH EBX

把入口修正为47D8C8后dump这个程序。

三、修复输入表

运行AsprDbgr_build_106程序,一路确定,在提示伪OEP后,运行ImportREC1.6修复输入表,在OEP中输入7d8c8,会找到全部的api,Fixdump即可
脱完壳后,程序的nag提示都没有了

lordor总结:
寻找OEP及修复输入表,都是极简单,可以用秒杀,但在修复Stolen code时我花了不少时间,参考很多文章,对blowfish老兄的方法觉得更有

价值,但操作很烦,后来我想到根据入口代码的情况,对照相应编译器未加壳的程序来寻找Stolen code,这个方法更简单实用。

By lordor 04.7.11

[培训]《安卓高级研修班(网课)》月薪三万计划,掌 握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞7
打赏
分享
最新回复 (21)
雪    币: 214
活跃值: (70)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Arucuied 2004-7-11 21:26
2
0
1.3的会麻烦一些:p
秒杀不大可能;)
雪    币: 299
活跃值: (300)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
clide2000 7 2004-7-11 22:18
3
0
学习,对于Stolen code,我一直很头痛,希望能来个Stolen code方法大集合就更好了
雪    币: 6073
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
forgot 26 2004-7-11 22:49
4
0
支持.不过1.2x好象不太流行的说,
雪    币: 279
活跃值: (375)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
lordor 6 2004-7-11 23:18
5
0
不知这个方法是不是有通用性,正在研究asp1.3等
雪    币: 303
活跃值: (461)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
liuyilin 2004-7-12 00:07
6
0
最初由 lordor 发布
不知这个方法是不是有通用性,正在研究asp1.3等

支持一下的 !
雪    币: 896
活跃值: (4039)
能力值: ( LV9,RANK:3410 )
在线值:
发帖
回帖
粉丝
fly 85 2004-7-12 00:42
7
0
最初由 Arucuied 发布
1.3的会麻烦一些:p
秒杀不大可能;)


1.3以上的新版脱壳比较麻烦
雪    币: 223
活跃值: (106)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
temerata 1 2004-7-12 08:30
8
0
最初由 lordor 发布
push 7C
push 0049E9C0


怎么我跟得的是push 70,push 0049E9C0?究竟是push 70还是push 7C?
雪    币: 279
活跃值: (375)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
lordor 6 2004-7-12 09:21
9
0
最初由 temerata 发布


怎么我跟得的是push 70,push 0049E9C0?究竟是push 70还是push 7C?


可能准确一点是78,程序开始时分配的这部分空间只要大点就可以了,并不会影响程序运行
雪    币: 323
活跃值: (579)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
springkang[DFCG 11 2004-7-12 17:37
10
0
请问loader大侠,为什么还要减掉4*4个字节?为什么要减去ebx,esi,edi,eax四个寄存器的大小呢?
是不是因为已经执行了CALL AWMAWork.0047DB94,所以要减去呢?
雪    币: 279
活跃值: (375)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
lordor 6 2004-7-12 22:12
11
0
最初由 springkang[DFCG 发布
请问loader大侠,为什么还要减掉4*4个字节?为什么要减去ebx,esi,edi,eax四个寄存器的大小呢?
是不是因为已经执行了CALL AWMAWork.0047DB94,所以要减去呢?


对,在这个call中初始化stack,你找一下VC7的程序跟一下入口代码就明白啦
雪    币: 323
活跃值: (579)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
springkang[DFCG 11 2004-7-13 09:27
12
0
谢谢loador大侠的指点,已经脱掉了这个壳!脱了之后无任何限制,看来光靠壳来保护软件也有很大的不足!!
只是为什么要这么做还是不很理解,还有如何断定0049E9C0
就是必须补的代码呢?
雪    币: 279
活跃值: (375)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
lordor 6 2004-7-13 10:47
13
0
最初由 springkang[DFCG 发布
谢谢loador大侠的指点,已经脱掉了这个壳!脱了之后无任何限制,看来光靠壳来保护软件也有很大的不足!!
只是为什么要这么做还是不很理解,还有如何断定0049E9C0
就是必须补的代码呢?


写错我的名字啦。
基本思想是参考当类软件的入口代码,你找一个vc7的程序看看,再参考一个stack相关的数据,很好理解
雪    币: 323
活跃值: (579)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
springkang[DFCG 11 2004-7-13 16:27
14
0
最初由 lordor 发布


写错我的名字啦。
基本思想是参考当类软件的入口代码,你找一个vc7的程序看看,再参考一个stack相关的数据,很好理解


:) 不好意思写错了。
再次多谢指点!!
雪    币: 411
活跃值: (1160)
能力值: ( LV9,RANK:810 )
在线值:
发帖
回帖
粉丝
David 20 2004-12-4 14:34
15
0
:(

我照做无法运行



一、Pre-Dip:用自己的名字注册

就无NAG,但关于菜单还是无法显示注册给你,仍然是评估版本,请指教。
雪    币: 223
活跃值: (106)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
temerata 1 2004-12-4 14:58
16
0
最初由 David 发布
:(

我照做无法运行


........


没有注册码的原因吧,至少它变成了蓝色了。:D
雪    币: 411
活跃值: (1160)
能力值: ( LV9,RANK:810 )
在线值:
发帖
回帖
粉丝
David 20 2004-12-4 17:26
17
0
更正一下

外壳入口

00401000 A>  68 01206300         push AWMAWork.00632001

ESP=12FFC4

伪入口

0047D8D4     33DB                xor ebx,ebx

ESP=12FF34

故立即数算法应是

12FF34-12FFC4=70

所以总结抽掉的代码如下:

push 7C  应该纠正为 push 70

实际跟踪也是push 70

没有注册码的原因吧,至少它变成了蓝色了。

有注册码还脱壳干什么?老兄何必说风凉话。
雪    币: 223
活跃值: (106)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
temerata 1 2004-12-4 18:11
18
0
我可没说风凉话。我意思是说可能它显示注册名的代码需要注册码才会解压。仅可能而已。:o

例如Aha-soft出的那几个软件就是这样,连NAG都还在的,也不会显示注册。
雪    币: 896
活跃值: (4039)
能力值: ( LV9,RANK:3410 )
在线值:
发帖
回帖
粉丝
fly 85 2004-12-4 18:44
19
0
RSA代码锁定是很厉害的
1、Key解码
2、根据以前的完整版本(无锁定)猜测
雪    币: 78
活跃值: (115)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
采臣·宁 1 2004-12-4 18:48
20
0
和和.不远的将来将有自动修复被抽代码的工具出现了.
雪    币: 61
活跃值: (160)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
pendan2001 4 2004-12-4 20:08
21
0
学习中:D :D :D :D
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Benki 2004-12-4 20:30
22
0
我也学学~~~
游客
登录 | 注册 方可回帖
返回