acc 视频解密笔记

active player 是北京网动(http://www.iactive.com.cn/)出品的多媒体课件播放器。很好用。在国内的教育行业有较为广泛的应用。时代光华、华图网校等课件都是用这种播放器来播放的。

 
手中的课件使用了网络验证。二话不说先抓包。结果如下:
ExpandedBlockStart.gif代码

GET /verify/verify.asp?username=12345678910 &password =123456 &guid =7USC9W34-2Q90-VBG2-7A45-28UXZY9W9S1T &enc_mode =2 &enc_seed =619823 HTTP/1.1

User-Agent: ACPlayer

Host: http://www.******.net/

Cache-Control: no-cache



HTTP/1.1 200 OK

Date: Wed, 23 Dec 2009 04:24:20 GMT

Server: Microsoft-IIS/6.0

X-Powered-By: ASP.NET

Content-Length: 137

Content-Type: text/html

Cache-control: private



ID:36ca8f6009ba4d8481f13d4a77a0c41f33fe43cdaf494710a542988b38dca2990cb7d371183241019ad2d5dc167eaa89be3cfc70aacd45ddac49ed82dbdf3a58;INFO:


http 包很简单。应答包中,有一个ID字串,可能这就是 key 了。

用错误的用户名和密码试试:

ExpandedBlockStart.gif 代码
GET /verify/verify.asp?username=123213 &password =213123 &guid =7USC9W34-2Q90-VBG2-7A45-28UXZY9W9S1T &enc_mode =2 &enc_seed =1399442 HTTP/1.1

User-Agent: ACPlayer

Host: www.htexam.net

Cache-Control: no-cache

Cookie: 92o_smile=1D1D0D1; rtime=3; ltime=1259506761000; cnzz_eid=52227509-1258510252-; 92o_cookietime=2592000; ASPSESSIONIDSARSBCTD=BAIGHELANAJMNENJDHCFJPHC; xsxscdb_cookietime=2592000; DOYOO_USER_ID=c114da7eaa134aaa99fbccc26c548645; DVC_25924=1



HTTP/1.1 200 OK

Date: Wed, 23 Dec 2009 04:37:19 GMT

Server: Microsoft-IIS/6.0

X-Powered-By: ASP.NET

Content-Length: 30

Content-Type: text/html

Cache-control: private



ID:0;INFO:....................

以上,info 是一个二进制字串。其 hex值为:

d3 c3 bb a7 c3 fb bb f2 d5 df c3 dc c2 eb b4 ed ce f3 a3 a1                                         ...

共 20个字节。

对应的提示信息是 10个中文字符:

用户名或者密码错误!

故以上info的两个字节代码一个汉字字节。应该是 gbk 编码吧。

所以,关键的返回的信息应该就是id 串了。  在上面的字串中,id 是一个 128 位的字串,其字符范围是 [0-9][a-f]。估计是一些字节的 16进制视图。那么,这个id 应该是一个 64byte的二进制串。

36 ca 8f 60 09 ba 4d 84 81 f1 3d 4a 77 a0 c4 1f 33 fe 43 cd 
af 49 47 10 a5 42 98 8b 38 dc a2 99 0c b7 d3 71 18 32 41 01 
9a d2 d5 dc 16 7e aa 89 be 3c fc 70 aa cd 45 dd ac 49 ed 82 
db df 3a 58


祭出 ida。载入程序后 debug 起来:

 

CDialog::OnOK( void )    .text 0047EDEA  00000006  R . . . . . .

 

 

呵呵,看到程序中就这一个 ok 按钮。当然要在这里下断点了。
右键,"add breakpoint"。运行后,程序果然断了下来。
回到程序领空。

0044600D    .  6A  00           push      0
0044600F    .  6A  00           push      0
00446011    .   68   02000084     push      84000002
00446016    .  6A  01           push      1
00446018    .  8B85 58FFFFFF  mov      eax, dword ptr [ebp-A8]
0044601E    .   50              push     eax
0044601F    .  8B4D DC        mov      ecx, dword ptr [ebp- 24 ]
00446022    .  E8 CB8E0300    call     < jmp .&MFC42.#5207 _CInternetSession: :OpenURL>        ;   连接网络
00446027    .   8985  54FFFFFF  mov      dword ptr [ebp-AC], eax                             ;   // CHttpFile*

 

openurl 的第一个参数就是 我们上面截获的 get 串。往上查找 get 字串的组织过程:

 

ExpandedBlockStart.gif 代码
004474B5       FF15  00DD4800   call     dword ptr [<&WINMM.timeGetTime>]                  ;   WINMM.timeGetTime
......

004474E2    .   52              push     edx  ;  edx是开机到现在的秒数
004474E3    .   68  44 034A00     push      004A0344                                           ;   ASCII "%d"
004474E8    .  8D45 C8        lea      eax, dword ptr [ebp- 38 ]
004474EB    .   50              push     eax
004474EC    .  E8 7BF90300    call     < jmp .&MFC42.#2818 _CString: :Format>                ;   [ebp-38]指向开机秒数的字串
......

00447524    .   52              push     edx
00447525    .  8B85 6 0FFFFFF   mov      eax, dword ptr [ebp-A0]
0044752B    .  8B88 8C000000  mov      ecx, dword ptr [eax+8C]                           ;  [00100fb8+8c]
00447531    .   51              push     ecx                                               ;   guid
00447532    .  8B15 C0334A00  mov      edx, dword ptr [4A33C0]                           ;   用户名
00447538    .   52              push     edx
00447539    .  A1 C4334A00    mov      eax, dword ptr [4A33C4]                           ;   密码
0044753E    .   50              push     eax
0044753F    .  8B4D  08         mov      ecx, dword ptr [ebp+ 8 ]
00447542    .  E8 79DCFBFF    call      004051C0                                           ;   **[ebp+8]
00447547    .   50              push     eax                                               ;   [ebp-14] 带形参的 get字串
00447548    .  8D4D EC        lea      ecx, dword ptr [ebp- 14 ]                           ;   [ebp-14] 组织好的 get 字串
0044754B    .   51              push     ecx
0044754C    .  E8 1BF90300    call     < jmp .&MFC42.#2818 _CString: :Format>                ;   填充 get 字串中的形参

 

经过多次跟踪发现,get 串中,只有 enc_seed 字段的值是变的。而从上面的代码分析知,enc_seed 的值是首地址保存在 [ebp-38] 中的一个字串。这个字串是开机到现在的秒数的 string  表达。而其 int 值保存在了 [ebp-1c]中。

向下查看函数中与 [ebp-38] 或 [ebp-1c] 相关的代码:

 

ExpandedBlockStart.gif id 与 timegettime值的计算
0044789C    > \8B55 C4        mov      edx, dword ptr [ebp-3C]
0044789F    .   52              push     edx
004478A0    .  E8 3CFC0200    call      004774E1                                           ;   对 id 进行计算。提取到一个整数。关键算法?
004478A5    .  83C4  04         add      esp,  4
004478A8    .   8985   0CFFFFFF   mov      dword ptr [ebp-F4], eax
004478AE    .  8B85  0CFFFFFF   mov      eax, dword ptr [ebp-F4]
004478B4    .   8945  E0        mov      dword ptr [ebp- 20 ], eax                           ;   [ebp -20] ID 的运算值
004478B7    .  8B4D E0        mov      ecx, dword ptr [ebp- 20 ]
004478BA    .  334D E4        xor      ecx, dword ptr [ebp-1C]
004478BD    .  894D E0        mov      dword ptr [ebp- 20 ], ecx

 以上代码中,首地址为 edx 的 id 字串,经函数 004774e1解密后,与保存在 [ebp-1c] 中的时间函数做 xor 运算。得到一个整数值保存在 [ebp-20]中。再往下看这个函数知,函数只将 [ebp-20] 作为函数返回值返回。因为这个函数中没有涉及栈帧以外的变量来处理 id 值,所以我们推测,id 字串已经浓缩为 [ebp-20]。原字串已经不再有用。

程序从函数 返回到 acplayer.004469c6:

ExpandedBlockStart.gif acplayer.004469c6
00446D70   |.  E8  0B060000     call      00447380                                           ;   连接网络并获得返回值的摘要
00446D75   |.  8B8D 78FBFFFF  mov      ecx, dword ptr [ebp- 488 ]
00446D7B   |.   8981   18020000   mov      dword ptr [ecx+ 218 ], eax
00446D81   |.  8B95 78FBFFFF  mov      edx, dword ptr [ebp- 488 ]
00446D87   |.  83BA  18020000 > cmp      dword ptr [edx+ 218 ],  0                             ;   [00100fb8+ 218] id xor time 的值
00446D8E   |.   75  2A          jnz      short  00446DBA

 返回值保存到了栈帧以外的变量中 [00100fb8+ 218] 。这就是解密的 key 了吧?

在 00100fb8+ 218 处下内存访问断点。f9,程序一路小跑。停下来了:

 

 

004463CD    > \C745 EC 4C454> mov      dword ptr [ebp- 14 ], 524E454C                      ;   "LENR"
004463D4    .  8B85 1CFBFFFF  mov      eax, dword ptr [ebp-4E4]
004463DA    .  83B8 1C020000> cmp      dword ptr [eax+21C],  0
004463E1    .   74   12           je       short  004463F5
004463E3    .  8B8D 1CFBFFFF  mov      ecx, dword ptr [ebp-4E4]
004463E9    .  8B55 EC        mov      edx, dword ptr [ebp- 14 ]
004463EC    .   3391   18020000   xor      edx, dword ptr [ecx+ 218 ]

 

此处 [00100fb8+ 218] 的操作是:解密字串 "LENR"。

 

查找程序中所有对此处的引用。一种办法是下内存访问断点。另一种办法是使用 ida 的脚本。

祭出《加密与解密》, 124 页。

“一个简单并且有效的办法,是在整个代码里搜索访问 0xxxxxxx--0xxxxxxx 这段缓存区的 mov 指令。这时 IDA 强大就体现出来了。用IDA 打开如下脚本,就可将读取指定内存的代码列出了”。

 

书中提供了一个脚本   getasm.idc

//  filename : getasm.idc
//  code by DarkNessOut

static  getasm( from, to, range1, range2  )
{
    auto ea, cmd, fp,deta, opcode;
    fp 
=  fopen(  " c:\\code.txt " " w "  );
    
for ( ea =  from;ea  <  to; )


    {
      cmd 
=  GetMnem( ea );
        
if  ( strstr( cmd,  " mov "  )  ==   0   ||  strstr( cmd,  " lea "  )  ==   0  )
        {
           opcode 
=  Dword( NextNotTail( ea )  -   4  );
           
if  ( opcode <   0  )
           {
               opcode 
=   ~ opcode;
               opcode
++ ;
           }
           Message( 
" -> %08X %08X\n " , ea, opcode );
           
if ( opcode  >=  range1  &&  opcode  <=  range2 )
           {
               deta 
=  opcode  -  range1;
               fprintf( fp, 
" %08X %s    // + 0x%04X\n   " , ea, GetDisasm( ea ), deta );
               MakeComm( ea, form( 
"   //  +0x%04X " ,deta ) );
           }
        }
      ea = NextNotTail( ea );
    }
}


 

 用法如下:

getasm( 0x401000 , 0x4b4000 0x002027C6 0x00202846 )

其中,第一个参数和第二个参数是主程序 acplayer.exe 镜像的内存范围。后两个参数是 http 消息 id 的内存范围。
但是没有找到结果。

 

 

 

73DDEDBC  2A D2 DC  73   05  4B DA  73  F8 0D DC  73  7B  06  DC  73    * 臆sK趕 ? 躶{躶
73DDEDCC  F8 0D DC 
73   99  CC D8  73   71  D1 D8  73   35  D2 D8  73    ? 躶櫶豷q沿s5邑s
73DDEDDC  
93  B1 D4  73   65  C4 D4  73  6C C9 D8  73  FD 3D DA  73   摫詓e脑sl韶s ?
73DDEDEC  
87   39  DA  73   03   51  DA  73  CC 3D DA  73  4E 3A DA  73    ? 趕Q趕 ? 趕N:趕
73DDEDFC  
77  3B DA  73  6B FC DB  73  6B FC DB  73               w;趕ksks ?





766996DF    F3:A5           rep     movs dword ptr es:[edi], dword ptr [esi]             ; 内存断点

  F3   A5是汇编的原始二进制代码  
  rep   movs   dword   ptr   [edi],dword   ptr   [esi]是个串处理指令  
  是把esi所指向的内存中的内容复制到edi所指向的内存中  
  长度是在ecx寄存器中指定的

t
- IIS / 6.0


EAX 001E2AA0
ECX 
00000022
EDX 
00000089
EBX 
00204480
ESP 000FFFEC
EBP 0010032C
ESI 002110A3 ASCII 
49 , " D:c10f085d0b4f4217a75e17ac2c97b89e82b4b96c1546468299b140a9d89ec88cad8fe51 "
EDI 0165B8A0
EIP 766996DF WININET.766996DF
0   ES  0023  32位  0 (FFFFFFFF)
1   CS 001B 32位  0 (FFFFFFFF)
0   SS  0023  32位  0 (FFFFFFFF)
0   DS  0023  32位  0 (FFFFFFFF)
0   FS 003B 32位 7FFDF000(FFF)
0   GS  0000  NULL
0
0   LastErr ERROR_SUCCESS ( 00000000 )
EFL 
00210206  (NO,NB,NE,A,NS,PE,GE,G)
MM0 
0000   0000   0000   0000
MM1 00FF 00FF 00FF 00FF
MM2 
0000   0000   0000   0000
MM3 
0000   0000   0000   0000
MM4 A5AC 15FF FFA4 F000
MM5 A6AA AAAA AAAA A800
MM6 A5A9 7B55 54FA 
4000
MM7 
0000   0000   0000   0000


73DA3CC0    FF15 14E1E073   call    dword ptr [73E0E114]                                 ; WININET.InternetReadFile


0165B848                                3A 
31   33   34   33   33              13433
0165B858  
32   30   63   30   62   64   31   34   61   66   33   31   34   34   30   36   20c0bd14af314406
0165B868  
36   63   35   64   37   31   33   34   39   39   34   34   63   36   63   31   6c5d71349944c6c1
0165B878  
63   37   63   33   31   62   61   34   65   34   61   30   35   35   30   37   c7c31ba4e4a05507
0165B888  
61   35   34   31   39   30   38   39   38   33   39   34   33   32   34   63   a54190898394324c
0165B898  
66   38   35   66   39   36   61   34   39   34   36   61   34   65   38   32   f85f96a4946a4e82
0165B8A8  
31   64   64   37   38   66   33   33   31   39   38   66   38   30   39   30   1dd78f33198f8090
0165B8B8  
32   66   34   64   32   65   61   34   66   64   61   62   31   61   63   61   2f4d2ea4fdab1aca
0165B8C8  
31   64   37   37   62   32   37   63   32   35   39  3B  49  4E  46  4F  1d77b27c259;INFO
0165B8D8  3A                                               :

EAX 
00000089
ECX 
01651238  ASCII  " ID:1343320c0bd14af3144066c5d71349944c6c1c7c31ba4e4a05507a54190898394324cf85f96a4946a4e821dd78f33198f80902f4d2ea4fdab1aca1d77b27c259;INFO: "
EDX 
01651239  ASCII  " D:1343320c0bd14af3144066c5d71349944c6c1c7c31ba4e4a05507a54190898394324cf85f96a4946a4e821dd78f33198f80902f4d2ea4fdab1aca1d77b27c259;INFO: "
EBX 001005B8
ESP 001004B8
EBP 001004C8
ESI 016512B7 ASCII 
" c259;INFO: "
EDI 
00000080
EIP 73DA3D8B MFC42.73DA3D8B
0   ES  0023  32位  0 (FFFFFFFF)
1   CS 001B 32位  0 (FFFFFFFF)
0   SS  0023  32位  0 (FFFFFFFF)
0   DS  0023  32位  0 (FFFFFFFF)
1   FS 003B 32位 7FFDF000(FFF)
0   GS  0000  NULL
0
0   LastErr ERROR_SUCCESS ( 00000000 )
EFL 
00200286  (NO,NB,NE,A,S,PE,L,LE)
MM0 
0000   0000   0000   0000
MM1 00FF 00FF 00FF 00FF
MM2 
0000   0000   0000   0000
MM3 
0000   0000   0000   0000
MM4 
0000   0000   0000   0000
MM5 
8000   0000   0000   0000
MM6 
0000   0000   0000   0000
MM7 
0000   0000   0000   0000


004461CE   .  E8 938B0300   call    
< jmp. & MFC42.#4277_CString::Mid >


001005BC  
48   13   65   01   38  7F  65   01  D8 7F  65   01   00   16  D3  17   He 8 e ? e. ?
001005CC  
37   08   00   00  1C  52   47   00   78  B4  65   01  FF FF FF FF   7 ..RG.x磂
001005DC  
20   46  5C  00   02   00   00   00   28   11   65   01  D4  04   10   00    F\....(e ? .
001005EC  B0 0A 
10   00   18   30   48   00   07   00   00   00  BC 0A  10   00    ? .0H.... ? .
001005FC  
85   57   44   00  2C AE  49   00   00   00  BC  00  F0  01   15   00   匴D.,甀... ?? .
0010060C  
48  B8  65   01   50   06   10   00   50   06   10   00   00   06   10   00   H竐P.P...
0010061C  
58   06   10   00   58   06   10   00   00   06   10   00   60   06   10   00   X.X...`.
0010062C  
60   06   10   00   00   06   10   00   70   23   10   00   38  B3  65   01   `...p#.8砮
0010063C  
88   04   00   00   50  B8  65   01   30   74  1F  00   01   00   00   00    ? ..P竐0t....
0010064C  
50  B8  65   01  D4  86  E0  73   00   06   10   00   18   71  BC  00   P竐詥鄐..q ?
0010065C  
00   06   10   00   88  7F  65   01   00   06   10   00  D8  06   10   02   .. ? e.. ?
0010066C  E8 F8 
98  7C  00   00  BC  00   84   77   94  7C AC  06   10   00   桫榺.. ? 剋攟 ? .
0010067C  DF E5 
98  7C  00   00  BC  00   00   00   00   00   70  B3  65   01   咤榺.. ? ....p砮
0010068C  
00   00  BC  00   78  B3  65   01  A8  06   10   00  0C  07   10   00   .. ? x砮 ? ...


00444F38   .  
68  046A4400   push    00446A04
00444F3D   .  E8 A2A10300   call    
< jmp. & MFC42.#1105_AfxBeginThread >                     ;  解码完成。开始播放

00444F38   .  
68  046A4400   push    00446A04


00446016    .  6A  01          push     1



 

 

 找到音频函数:

 

00448939   .  55            push    ebp                                              ;  // 解码的关键函数。挂起此函数导致音频中断

 

 

 

EBP ==>  >/0467FF80
EBP+4    >|73DE0BBD  返回到 MFC42.73DE0BBD
EBP+8    >|00100FB8
EBP+C    >|0456FB30
EBP+10   >|00B0C270
EBP+14   >|00B0C5F0
EBP+18   >|00B0C5F0
EBP+1C   >|73E7764C  MFC42.73E7764C
EBP+20   >|00000001
EBP+24   >|00000000

 

 

转载于:https://www.cnblogs.com/diylab/archive/2009/12/23/1630179.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值