• 标 题:FlashSnap 1.0的简单脱壳与算法探析
  • 作 者:txm123
  • 时 间:2003年11月30日 12:27
  • 链 接:http://bbs.pediy.com

FlashSnap 1.0的简单脱壳与算法探析
破解作者:
        yzez[DFCG][BCG][FCG]
破解对象:
    FlashSnap 1.0
软件介绍:
   FlashSnap 1.0 

软件大小:414KB
软件语言:英文
软件类别:国外软件/共享版/图像捕捉
运行环境:Win9x/Me/NT/2000/XP
加入时间:2003-11-29 9:05:57 

     目前绝大多数的动画网站都以 Flash 格式发布网站上的动画,因而 Flash 成为动画爱好人士最常
收集到的动画格式。不过虽然 Flash 是动画格式,但有时候精采的部分是在其中的某几个场景。如果你
想永久保存动画中美丽的瞬间场面,只要有了 FlashSnap 就能办到。
下载地址:
         http://www.onlinedown.net/soft/23365.htm
破解工具:
     PE-SCAN、Ollydbg1.09、ImportREC 
破解目的:
    不为破解而破解,只为技术而破解,有失误之处,请高手们指正。
破解过程:
一、简单脱壳
    用PEID竟然查不出是什么壳,用:PE-SCAN查壳是:aspack 1.07b的壳,这个壳用工具轻松脱壳,下面
的脱壳过程,是我想自己用手脱,不过这个壳实在太简单,高手不屑一顾,我等菜鸟就试一下吧!老样子,
用OD载入程序,看下面:
004170C5 >  90              NOP*******************************载入程序后我们停在这里!F8往下!
004170C6    90              NOP
004170C7    90              NOP
004170C8    75 00           JNZ     SHORT FlashSna.004170CA
004170CA  - E9 31AF0600     JMP     FlashSna.00482000*********按F7进!

00482000    60              PUSHAD****************************F7跟进后我们停在这里!
00482001    E8 00000000     CALL    FlashSna.00482006*********F8带过!
00482006    5D              POP     EBP                              
00482007    81ED 3ED94300   SUB     EBP, FlashSna.0043D93E
0048200D    B8 38D94300     MOV     EAX, FlashSna.0043D938
00482012    03C5            ADD     EAXEBP
00482014    2B85 0BDE4300   SUB     EAXDWORD PTR SS:[EBP+43DE0B]
0048201A    8985 17DE4300   MOV     DWORD PTR SS:[EBP+43DE17], EAX
00482020    80BD 01DE4300 0>CMP     BYTE PTR SS:[EBP+43DE01], 0
00482027    75 15           JNZ     SHORT FlashSna.0048203E*********不跳!
00482029    FE85 01DE4300   INC     BYTE PTR SS:[EBP+43DE01]
0048202F    E8 1D000000     CALL    FlashSna.00482051***************F8带过!
00482034    E8 79020000     CALL    FlashSna.004822B2***************F8带过!
00482039    E8 12030000     CALL    FlashSna.00482350***************F8带过!
0048203E    8B85 03DE4300   MOV     EAXDWORD PTR SS:[EBP+43DE03]
00482044    0385 17DE4300   ADD     EAXDWORD PTR SS:[EBP+43DE17]
0048204A    894424 1C       MOV     DWORD PTR SS:[ESP+1C], EAX
0048204E    61              POPAD***********************************这是福地呀!
0048204F    FFE0            JMP     EAX*****************************跳向入口!EAX的值:004029CC就是OEP!F8进!
00482051    80BD 29E04300 0>CMP     BYTE PTR SS:[EBP+43E029], 0

004029CC    68 4C2D4000     PUSH    FlashSna.00402D4C***************在这里,DUMP程序出来!
004029D1    E8 EEFFFFFF     CALL    FlashSna.004029C4                ; JMP to msvbvm50.ThunRTMain
004029D6    0000            ADD     BYTE PTR DS:[EAX], AL
004029D8    0000            ADD     BYTE PTR DS:[EAX], AL
004029DA    0000            ADD     BYTE PTR DS:[EAX], AL
004029DC    3000            XOR     BYTE PTR DS:[EAX], AL
004029DE    0000            ADD     BYTE PTR DS:[EAX], AL
004029E0    58              POP     EAX                              ; kernel32.77E5EB69
004029E1    0000            ADD     BYTE PTR DS:[EAX], AL
004029E3    0040 00         ADD     BYTE PTR DS:[EAX], AL
004029E6    0000            ADD     BYTE PTR DS:[EAX], AL
004029E8    C112 07         RCL     DWORD PTR DS:[EDX], 7
   用ImportREC修正OEP的值,试运行程序,程序正常运行!脱壳完成。
二、算法探析。
   程序是用VB编写的,用OD载入脱壳后的程序,下断:rtcMidCharVar,F9运行程序,弹出注册框后输入
注册信息:Serial Number:234567765432;Your full name:yzez;Your company:[DFCG][BCG][FCG],点注册,
程序被断在下面:
7406306E >  PUSH    EBP*************************点注册确定后我们断在这里!
7406306F    MOV     EBPESP
74063071    SUB     ESP, 10
74063074    CMP     DWORD PTR DS:[7412F064], 0
7406307B    PUSH    ESI
7406307C    PUSH    EDI
7406307D    JNZ     msvbvm50.7409D80F
74063083    MOV     ESIDWORD PTR DS:[7412F06C]
74063089    ADD     ESI, 50
7406308C    PUSH    ESI
7406308D    PUSH    DWORD PTR SS:[EBP+C]
74063090    CALL    msvbvm50.7402B82C**********取出试验码的前4位:2345送入EAX!
74063095    CMP     EAX, -1********************比较EAX的值是不是-1
74063098    JE      msvbvm50.7409D836*********相等就跳!
7406309E    PUSH    DWORD PTR SS:[EBP+14]
740630A1    PUSH    DWORD PTR SS:[EBP+10]
************************************省略一部分代码!****************************
740630CC    MOV     ESPEBP
740630CE    POP     EBP                              ; unpack_.00442D8F
740630CF    RETN    10************************返回指令!

00442D8F   MOV     EAXDWORD PTR SS:[EBP-20]**返回到这里!
00442D92   MOV     DWORD PTR SS:[EBP-120], EAX****EAX的值是1,保存,即取出试验码的第一位!
00442D98   CMP     DWORD PTR SS:[EBP-120], 100
********************************省略一部分代码!*****************************
00442E2D   PUSH    EAX
00442E2E   CALL    <JMP.&msvbvm50.rtcAnsiValueBstr>
00442E33   MOVSX   EAXAX******************第一位试验码的值:2,取其ASCII码值:32扩展到EAX
00442E36   MOV     ECXDWORD PTR SS:[EBP-20]**取出的试验码的位数1,把位数送入ECX
00442E39   IMUL    ECXECX, 2*****************相乘!ECX=ECX*2=2
00442E3C   JO      unpack_.004431F3************溢出转移!
00442E42   ADD     ECX, 6**********************ECX=ECX+6=8
00442E45   JO      unpack_.004431F3
00442E4B   IMUL    EAXECX********************EAX=ECX*ECX=32*8=190
00442E4E   JO      unpack_.004431F3
00442E54   MOV     ECXDWORD PTR SS:[EBP-20]**位数1移入ECX
00442E57   IMUL    ECXECX, 8*****************ECX=ECX*8=8
00442E5A   JO      unpack_.004431F3
00442E60   XOR     EAXECX********************EAX=EAC XOR ECX=190 XOR 8=198
00442E62   MOV     DWORD PTR SS:[EBP-9C], EAX**保存EAX的值!
00442E68   MOV     DWORD PTR SS:[EBP-A4], 3
************************************省略一部分代码!**********************
00442EC7   PUSH    EAX
00442EC8   CALL    <JMP.&msvbvm50.__vbaStrVarMove>**把上面运算的值198转化成十进制值:408,放EAX
00442ECD   MOV     EDXEAX*************************408再移入EDX中
00442ECF   LEA     ECXDWORD PTR SS:[EBP-94]
00442ED5   CALL    <JMP.&msvbvm50.__vbaStrMove>
00442EDA   MOV     EDXEAX
**********************************省略一部分代码!************************************
00442F42   CALL    <JMP.&msvbvm50.__vbaGenerateBoun>
00442F47   MOV     DWORD PTR SS:[EBP-144], EAX
00442F4D   PUSH    DWORD PTR SS:[EBP-24]**************上一次运算的结果入栈!
00442F50   MOV     EAXDWORD PTR SS:[EBP-120]
00442F56   MOV     ECXDWORD PTR SS:[EBP-80]
00442F59   PUSH    DWORD PTR DS:[ECX+EAX*4]
00442F5C   CALL    <JMP.&msvbvm50.__vbaStrCat>********把运算的结果联结起来:408494616710
00442F61   .  8985 64FFFFFF MOV     DWORD PTR SS:[EBP-9C], EAX
00442F67   .  C785 5CFFFFFF>MOV     DWORD PTR SS:[EBP-A4], 8
00442F71   .  8D85 5CFFFFFF LEA     EAXDWORD PTR SS:[EBP-A4]
00442F77   .  50            PUSH    EAX
00442F78   .  8D85 4CFFFFFF LEA     EAXDWORD PTR SS:[EBP-B4]
00442F7E   .  50            PUSH    EAX
00442F7F   .  E8 9AF7FBFF   CALL    <JMP.&msvbvm50.rtcTrimVar>
00442F84   .  8D85 4CFFFFFF LEA     EAXDWORD PTR SS:[EBP-B4]
00442F8A   .  50            PUSH    EAX
00442F8B   .  E8 DCF7FBFF   CALL    <JMP.&msvbvm50.__vbaStrVarMove>
00442F90   .  8BD0          MOV     EDXEAX
00442F92   .  8D4D DC       LEA     ECXDWORD PTR SS:[EBP-24]
00442F95   .  E8 4EF7FBFF   CALL    <JMP.&msvbvm50.__vbaStrMove>
00442F9A   .  8D85 4CFFFFFF LEA     EAXDWORD PTR SS:[EBP-B4]
00442FA0   .  50            PUSH    EAX
00442FA1   .  8D85 5CFFFFFF LEA     EAXDWORD PTR SS:[EBP-A4]
00442FA7   .  50            PUSH    EAX
00442FA8   .  6A 02         PUSH    2
00442FAA   .  E8 FDF6FBFF   CALL    <JMP.&msvbvm50.__vbaFreeVarList>
00442FAF   .  83C4 0C       ADD     ESP, 0C
00442FB2   .  8B45 E0       MOV     EAXDWORD PTR SS:[EBP-20]
00442FB5   .  40            INC     EAX
00442FB6   .  0F80 37020000 JO      unpack_.004431F3
00442FBC   MOV     DWORD PTR SS:[EBP-20], EAX
00442FBF   JMP     unpack_.00442D1D*************************跳回!循环,直到取出的4位试验码计算完毕!
00442FC4   PUSH    DWORD PTR SS:[EBP-24]
00442FC7   CALL    <JMP.&msvbvm50.__vbaLenBstr>
00442FCC   CMP     EAX, 4***********************************EAX的值是上述运算的结果的位数:C(即12)位!
00442FCF   JLE     unpack_.00443075*************************小于等于就跳!
00442FD5   PUSH    DWORD PTR SS:[EBP-24]********************计算的值408494616710入栈!
00442FD8   CALL    <JMP.&msvbvm50.__vbaLenBstr>
00442FDD   SUB     EAX, 5***********************************位数C再减去5,EAX=C-5=7
00442FE0   JO      unpack_.004431F3
00442FE6   MOV     DWORD PTR SS:[EBP-9C], EAX***************把运算的结果:7保存!
00442FEC   MOV     DWORD PTR SS:[EBP-A4], 3
00442FF6   LEA     EAXDWORD PTR SS:[EBP-A4]
00442FFC   PUSH    EAX
00442FFD   PUSH    4
00442FFF   PUSH    DWORD PTR SS:[EBP-24]********************计算的值408494616710入栈!
00443002   CALL    <JMP.&msvbvm50.rtcMidCharBstr>***********此CALL对上述结果再计算,计算是这样:把前3位去掉,
*************************************************再反后两位去掉,得到中间的7位值是:4946167!
00443007   MOV     EDXEAX**********************把这个值移入EDX中!
00443009   LEA     ECXDWORD PTR SS:[EBP-70]
0044300C   CALL    <JMP.&msvbvm50.__vbaStrMove>
00443011   LEA     ECXDWORD PTR SS:[EBP-A4]
00443017   CALL    <JMP.&msvbvm50.__vbaFreeVar>
0044301C   PUSH    DWORD PTR SS:[EBP-5C]*********把试验码的前4位:2345入栈!
0044301F   PUSH    DWORD PTR SS:[EBP-70]*********上述结果:4946167入栈!
00443022   CALL    <JMP.&msvbvm50.__vbaStrCat>***把两个值连起来:23454946167,放EAX
00443027   MOV     EDXEAX**********************把这个值移入EDX
00443029   LEA     ECXDWORD PTR SS:[EBP-90]
0044302F   CALL    <JMP.&msvbvm50.__vbaStrMove>
00443034   PUSH    EAX
00443035   MOV     EAXDWORD PTR SS:[EBP+8]*****23454946167入EAX
00443038   PUSH    DWORD PTR DS:[EAX]************试验码:234567765432入栈!             
0044303A   PUSH    0
0044303C   CALL    <JMP.&msvbvm50.__vbaStrComp>**比较试验码:234567765432与23454946167
00443041   NEG     AX****************************不相等赋AX的值为FFFF
00443044   SBB     EAXEAX
00443046   NEG     EAX
00443048   NEG     EAX
0044304A   MOV     WORD PTR SS:[EBP-120], AX
00443051   LEA     ECXDWORD PTR SS:[EBP-90]
00443057   CALL    <JMP.&msvbvm50.__vbaFreeStr>
0044305C   MOVSX   EAXWORD PTR SS:[EBP-120]
00443063   TEST    EAXEAX*********************测试EAX的值是否是0
00443065   JE      SHORT unpack_.0044306E*******相等就跳,一跳就成功!
00443067   AND     WORD PTR SS:[EBP-3C], 0
0044306C   JMP     SHORT unpack_.00443073

   算法小结:
   这个软件的注册算法有点怪,没有用用户名或者用户单位计算注册码,而是用试验码的前4位经过计算
后得到后7位注册码,再把前4位试验码和后7位得到的注册码联接起来就是软件的注册码!
其计算过程是这样:
   取前4位试验码,设取出的试验码的位数是X,取出的试验码的ASCII码值是Y,则
   (X*2+6)*Y^(X*8),再把它转化成十进制值,联接起来得到一组12位的新值,这个新值去掉前3位,再去掉
后两位,得到中间的7位数值,它的前面再加上前4位试验码就是注册码!
   一组可用的注册码:
   Serial Number:23454946167
   Your full name:yzez
   Your company:[DFCG][BCG][FCG]