**广告拦截超级助手算法分析
破解日期】 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 学习了:hug: 强 软件看了半天也没弄懂 在兄弟这学习了~~ 算法没看懂,呵呵,我把他爆破了:loveliness:
页:
[1]