yzslly 发表于 2006-11-14 14:07:36

**广告拦截超级助手算法分析

破解日期】 2006年11月12日
【破解作者】 yzs
【作者主页】 http://www.freewebs.com/realplayerassist/
【使用工具】 OD
【破解平台】 Win9x/NT/2000/XP
【软件名称】 realplayer广告拦截超级助手 V1.36
【下载地址】 自己网上找
【软件大小】 607KB
【加壳方式】 无(Microsoft Visual C++ 7.0 Method2)
【破解声明】 我是一只小菜鸟,第一次写破文,偶得一点心得,愿与大家分享:),写的很差,希望大家勿怪,呵呵
--------------------------------------------------------------------------------
【破解内容】
代码:
________________________________________
机器码: PKRMMSJV 用户名:yzs注册码:11111111,点注册跟踪来到:

00408000    /$83EC 14   sub esp,14
00408003    |.53      push ebx
00408004    |.33C0      xor eax,eax
00408006    |.894424 04 mov dword ptr ss:,eax
0040800A    |.55      push ebp
0040800B    |.56      push esi
0040800C    |.894424 10 mov dword ptr ss:,eax
00408010    |.57      push edi
00408011    |.8B7C24 2C mov edi,dword ptr ss:
00408015    |.894424 18 mov dword ptr ss:,eax
00408019    |.894424 1C mov dword ptr ss:,eax
0040801D    |.8BCF      mov ecx,edi
0040801F    |.33DB      xor ebx,ebx――――――――――――――――清零,准备循环
00408021    |.884424 20 mov byte ptr ss:,al
00408025    |.33F6      xor esi,esi――――――――――――――――-清零,准备循环
00408027    |.FF15 00B4>call dword ptr ds:[<&MFC71.#2902>]    ――得到注册码长度,送入EAX
0040802D    |.85C0      test eax,eax
0040802F    |.7E 2D   jle short RealOneA.0040805E――――――长度为零跳走,否则继续
00408031    |>56      /push esi
00408032    |.8BCF      |mov ecx,edi
00408034    |.FF15 BCB3>|call dword ptr ds:[<&MFC71.#865>] -----将注册码的ASC码值赋值给al
0040803A    |.3C 2D   |cmp al,2D ――――――――――判断是否输入“-”号,不知何意,呵呵
0040803C    |.74 0E   |je short RealOneA.0040804C――-只要不输入“-”号,就不会跳
0040803E    |.56      |push esi
0040803F    |.8BCF      |mov ecx,edi
00408041    |.FF15 BCB3>|call dword ptr ds:[<&MFC71.#865>]       ;MFC71.7C1894E7
00408047    |.88441C 10 |mov byte ptr ss:,al――――将注册码的ASC逐位入栈
0040804B    |.43      |inc ebx  ――――――――――――――――――计数加1
0040804C    |>83FB 10   |cmp ebx,10   ――――――――判断所取注册码是否超16位
0040804F    |.7D 0D   |jge short RealOneA.0040805E――――――是,跳走,否则继续
00408051    |.8BCF      |mov ecx,edi
00408053    |.46      |inc esi   ―――――――――――――――――计数加1
00408054    |.FF15 00B4>|call dword ptr ds:[<&MFC71.#2902>]      ;MFC71.7C146AB0
0040805A    |.3BF0      |cmp esi,eax ―――――与注册码长度相比较,看注册码是否都取完
0040805C    |.^ 7C D3   \jl short RealOneA.00408031
//////////////////////////////////////////////////////////////////////////////////////////
从这里我们可以看出注册码的有效位数最长为16位,多余位数系统是不认可的。
//////////////////////////////////////////////////////////////////////////////////////////
0040805E    |>8B6C24 28 mov ebp,dword ptr ss:
00408062    |.33FF      xor edi,edi     
00408064    |>0FBE447C >/movsx eax,byte ptr ss: ―――将注册码第一位(以后循环是取注册码的奇数位)的ASC码移至eax,记为a,
00408069    |.83E8 41   |sub eax,41――――――――减去41,记为b
0040806C    |.78 20   |js short RealOneA.0040808E――――――跳就OVER
0040806E    |.83F8 1A   |cmp eax,1A―――――――比较b与1A大小
00408071    |.7D 1B   |jge short RealOneA.0040808E――――――――跳就OVER
///////////////////////////////////////////////////////////////////////////////////////////
到这里,我们可以判断得出,注册码的ASC必须大于41,小于(41+1A),即输入的注册码必须为大写字母,长度为16位,重新输入注册码:ABABABABABABABAB
//////////////////////////////////////////////////////////////////////////////////////////
00408073    |.8A98 6CCE>|mov bl,byte ptr ds:
///////////////////////////////////////////////////////////////////////////////////////////
该命令是根据上面b值,在 “UEKXWHNFQLGVYIAPJSCRDBMZOT”找出相应字符的ASC码赋值给bl,我们刚刚输入是A,经过上面计算后b=0,所以此时bl=55,即“U”
//////////////////////////////////////////////////////////////////////////////////////////
00408079    |.8A447C 11 |mov al,byte ptr ss:―――――――将注册码的第二位(以后循环是取注册码的偶数位)的ASC码赋值给al
0040807D    |.33F6      |xor esi,esi
0040807F    |.90      |nop
///////////////////////////////////////////////////////////////////////////////////////
00408080    |>3A86 88CE>|/cmp al,byte ptr ds:
00408086    |.74 12   ||je short RealOneA.0040809A
00408088    |.46      ||inc esi
00408089    |.83FE 24   ||cmp esi,24
0040808C    |.^ 7C F2   |\jl short RealOneA.00408080
上面这个小循环是判断注册码的偶数位是否能在“S4X5DQMHIYV6NP80B2LE91J3UKGF7ATWZRCO”这36位字符中找到,如不能找到,注册失败,如能找到,记录ESI的值,刚刚我们输入的是B,所以此时ESI=10,即是字符窜的第16位。
//////////////////////////////////////////////////////////////////////////////////////
0040808E    |>5F      |pop edi
0040808F    |.5E      |pop esi
00408090    |.5D      |pop ebp
00408091    |.33C0      |xor eax,eax
00408093    |.5B      |pop ebx
00408094    |.83C4 14   |add esp,14
00408097    |.C2 0800   |retn 8
0040809A    |>83FE 24   |cmp esi,24――――――前面条件都满足后,跳到这里
0040809D    |.^ 7D EF   |jge short RealOneA.0040808E――――条件满足这里自然就不跳
0040809F    |.57      |push edi
004080A0    |.8BCD      |mov ecx,ebp
004080A2    |.FF15 BCB3>|call dword ptr ds:[<&MFC71.#865>]――应该是将机器码移送al
004080A8    |.0FBED3    |movsx edx,bl――――――将bl的值给EDX,此时EDX=55
004080AB    |.0FBEC8    |movsx ecx,al―――――将第一位机器码的ASC码赋值给ECX,ECX=50(P)
004080AE    |.33D6      |xor edx,esi――――――对EDX和刚刚得到ESI进行XOR运算
004080B0    |.3BCA      |cmp ecx,edx――――――然后与机器码的ASC值相比较
004080B2    |.^ 75 DA   |jnz short RealOneA.0040808E――――跳就OVER
004080B4    |.47      |inc edi
004080B5    |.83FF 08   |cmp edi,8――――――――判断8位机器码是否比较完,这里我们也可看到注册码是必需为16位的。
004080B8    |.^ 7C AA   \jl short RealOneA.00408064―――没判断完,跳回再循环,过程一样,就不多写了。
004080BA    |.5F      pop edi
004080BB    |.5E      pop esi
004080BC    |.5D      pop ebp
004080BD    |.B8 010000>mov eax,1―――――标志位赋值
004080C2    |.5B      pop ebx
004080C3    |.83C4 14   add esp,14
004080C6    \.C2 0800   retn 8
/////////////////////////////////////////////////////////////////////
这里就可以收工了,呵呵
算法小结:

1) 注册码必需是大写字母,且必需是16位。
1) 取注册码的奇数位的ASC值减41后,在UEKXWHNFQLGVYIAPJSCRDBMZOT查出相应字符的ASC,记为A
2) 取注册码的偶数位,在“S4X5DQMHIYV6NP80B2LE91J3UKGF7ATWZRCO”这36位字符中找到,记下位置为B
3) 对A和B进行XOR运算得出C
4) 将C与机器码的ASC值逐位比较,全部相等注册成功
////////////////////////////////////////////////////////////////////
返回
004069C2   .50      push eax
004069C3   .B9 380141>mov ecx,RealOneA.00410138               煳@
004069C8   .899C24 B8>mov dword ptr ss:,ebx
004069CF   .E8 CC1700>call RealOneA.004081A0----产生机器码,有兴趣自己去跟
004069D4   .68 640141>push RealOneA.00410164            
004069D9   .8D4C24 10 lea ecx,dword ptr ss:      
004069DD   .51      push ecx                           
004069DE   .B9 380141>mov ecx,RealOneA.00410138         
004069E3   .E8 181600>call RealOneA.00408000
004069E8   .85C0      test eax,eax―――――――――――返回这里
004069EA   .0F95C0    setne al―――――――――――――爆破点
004069ED   .3AC3      cmp al,bl
004069EF   .A2 440141>mov byte ptr ds:,al――――标志位赋值
004069F4   .0F85 6402>jnz RealOneA.00406C5E ―――跳就over
004069FA   .B9 380141>mov ecx,RealOneA.00410138            煳@
004069FF   .E8 7C1900>call RealOneA.00408380
00406A04   .8D5424 14 lea edx,dword ptr ss:

////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////


________________________________________

--------------------------------------------------------------------------------
【破解总结】
本身这个程序的注册验证相对简单,而眀由于程序对注册码的偶数位检测只是简单判断,因此注册码并不是一一对应,而是一对多,这可能是作者没注意到,也是这个算法失败的一个地方。
给出一个注册码,注册码与用户无关
机器码: PKRMMSJV 用户名:yzs注册码:PSCSTSWSWSRSQSLS

cha23 发表于 2006-11-15 10:12:03

学习了:hug:

Nisy 发表于 2006-12-16 11:33:43

强 软件看了半天也没弄懂 在兄弟这学习了~~

playboysen 发表于 2008-6-1 16:49:25

算法没看懂,呵呵,我把他爆破了:loveliness:
页: [1]
查看完整版本: **广告拦截超级助手算法分析