【文章标题】: Registry Crawler 4.0 算法分析
【文章作者】: Suyana
【作者邮箱】: Suyasha@163.com
【软件名称】: Registry Crawler 4.0
【加壳方式】: 无壳
【使用工具】: OD
【软件介绍】: 一款很好的注册表搜索软件
【作者声明】: 我只是一只小菜鸟,失误之处难免,敬望诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
软件没有加壳,用OD载入,我用的是汉化版。查找字符串"你输入的注册信息是无效的"。来到:
0040AFE1 lea ecx, [esi+3BC]
0040AFE7 call 0042D9F5 ; 获得用户名
0040AFEC push 0FF
0040AFF1 push 0045E610
0040AFF6 lea ecx, [esi+380]
0040AFFC call 0042D9F5 ; 获得注册码
0040B001 push 0045E510
0040B006 lea ecx, [esp+C]
0040B00A call 0042E405
0040B00F mov eax, [eax]
0040B011 push 00458C84 ; /trial user
0040B016 push eax ; |Arg1
0040B017 call 004196DB ; \rcrawler.004196DB
0040B01C add esp, 8 ; 比较用户名是否等于trial user
0040B01F lea ecx, [esp+8]
0040B023 test eax, eax
0040B025 sete bl
0040B028 call 0042E397
0040B02D test bl, bl
0040B02F je short 0040B040
0040B031 push 1
0040B033 mov ecx, esi
0040B035 call 0042F015
0040B03A pop esi
0040B03B pop ebx
0040B03C add esp, 8
0040B03F retn
0040B040 call 0040ACF0 ; 这就是计算注册码并判断的函数了,进入
0040B045 test eax, eax
0040B047 je 0040B0EA ; 跳到0040B0EA,即注册失败
...
0040B0EA mov ecx, esi
0040B0EC call 0040AB00
0040B0F1 test eax, eax
0040B0F3 je short 0040B10E
...
0040B10E push 30
0040B110 push 00458DA0 ; 试用用户
0040B115 push 00458C90 ; 你输入的注册信息是无效的
0040B11A mov ecx, esi
F7进入0040B040 call 0040ACF0,来到:
0040ACF0 sub esp, 24
0040ACF3 or ecx, FFFFFFFF
0040ACF6 xor eax, eax
0040ACF8 push ebp
0040ACF9 push edi
0040ACFA mov edi, 0045E510
0040ACFF repne scas byte ptr es:[edi]
0040AD01 not ecx
0040AD03 dec ecx
0040AD04 mov ebp, ecx
0040AD06 cmp ebp, 8 ; 用户名至少为8位才跳转
0040AD09 jge short 0040AD11 ; 计算注册码
...
0040AD11 push ebx
0040AD12 push esi
0040AD13 push 0045E510
0040AD18 call 00427D62 ; 处理用户名,大写字母变成小写
0040AD1D mov ecx, 7
0040AD22 xor eax, eax
0040AD24 lea edi, [esp+19]
0040AD28 mov byte ptr [esp+18], 0
0040AD2D rep stos dword ptr es:[edi]
0040AD2F stos word ptr es:[edi]
0040AD31 add esp, 4
0040AD34 stos byte ptr es:[edi]
0040AD35 lea eax, [esp+14]
0040AD39 push 00458BE4 ; /8267- ;第一部分注册码
0040AD3E push eax ; |String1
0040AD3F call [<&KERNEL32.lstrcpyA>] ; \lstrcpyA
0040AD45 xor ebx, ebx
0040AD47 /mov esi, [458AFC] ; 0123456789 算是表吧
0040AD4D |or ecx, FFFFFFFF
0040AD50 |mov edi, esi
0040AD52 |xor eax, eax
0040AD54 |repne scas byte ptr es:[edi]
0040AD56 |not ecx
0040AD58 |dec ecx
0040AD59 |mov eax, ebx
0040AD5B |xor edx, edx
0040AD5D |mov edi, esi
0040AD5F |div ecx
0040AD61 |mov eax, ebx
0040AD63 |push 1
0040AD65 |movsx ecx, byte ptr [edx+esi]
0040AD69 |xor edx, edx
0040AD6B |div ebp
0040AD6D |movsx eax, byte ptr [edx+45E510] ; 依次取用户名的ASCII,若用户名不足8
; 位,则循环获取
0040AD74 |mov edx, eax
0040AD76 |shl edx, 5 ; 左移5位
0040AD79 |add edx, eax ; 加上用户名的ASCII
0040AD7B |lea eax, [eax+edx*2] ; eax=eax+edx*2
0040AD7E |add ecx, eax ; ecx=注册码的第n位+30h
0040AD80 |mov eax, ebx \ ebx=注册码的第n位,共九位
0040AD82 |imul eax, ebx |
0040AD85 |imul eax, ebx |
0040AD88 |imul eax, ebp | ebp用户名位数
/ eax=eax*eax*eax*ebp
0040AD8B |lea edx, [eax+eax*4] ; edx=eax+eax*4
0040AD8E |lea eax, [eax+edx*2] ; eax=eax+edx*2
0040AD91 |add ecx, eax ; eax=eax+ecx
0040AD93 |xor eax, eax
0040AD95 |mov edx, ecx
0040AD97 |or ecx, FFFFFFFF
0040AD9A |repne scas byte ptr es:[edi]
0040AD9C |not ecx
0040AD9E |mov eax, edx
0040ADA0 |dec ecx
0040ADA1 |xor edx, edx
0040ADA3 |div ecx ; eax除以10,余数edx为注册码
0040ADA5 |lea eax, [esp+18]
0040ADA9 |add edx, esi
0040ADAB |push edx
0040ADAC |push eax ; 这里用查表(表:0123456789)
0040ADAD |call 004198E0 ; 得到注册码,其实根本不用
0040ADB2 |add esp, 0C ; 直接拿余数就可以了
0040ADB5 |test ebx, ebx
0040ADB7 |je short 0040ADF6
0040ADB9 |mov eax, ebx
0040ADBB |xor edx, edx
0040ADBD |mov ecx, 3
0040ADC2 |div ecx
0040ADC4 |test edx, edx
0040ADC6 |jnz short 0040ADF6
0040ADC8 |mov edi, 00458BEC ; -
0040ADCD |or ecx, FFFFFFFF
0040ADD0 |xor eax, eax
0040ADD2 |lea edx, [esp+14]
0040ADD6 |repne scas byte ptr es:[edi]
0040ADD8 |not ecx
0040ADDA |sub edi, ecx
0040ADDC |mov esi, edi
0040ADDE |mov edi, edx
0040ADE0 |mov edx, ecx
0040ADE2 |or ecx, FFFFFFFF
0040ADE5 |repne scas byte ptr es:[edi]
0040ADE7 |mov ecx, edx
0040ADE9 |dec edi
0040ADEA |shr ecx, 2
0040ADED |rep movs dword ptr es:[edi], dword >
0040ADEF |mov ecx, edx
0040ADF1 |and ecx, 3
0040ADF4 |rep movs byte ptr es:[edi], byte pt>
0040ADF6 |inc ebx ; ebx=注册码的第n位,共九位
0040ADF7 |cmp ebx, 9 ; 循环9次(注册码长度)
0040ADFA \jb 0040AD47
0040AE00 lea eax, [esp+14]
...
现在简要写一下注册码的算法:
1.取用户名ASCII -> eax,eax shl 5 -> ebx,ebx+eax -> ebx
eax=用户名ASCII
eax+ebx*2 -> eax,eax+ebp(注册码的第n位+30h) -> ecx
2.ebx=注册码的第n位,共九位
ebx -> eax,eax*eax*eax*ebp(用户名位数) -> eax
eax+eax*4 -> edx
eax+edx*2 -> eax
eax+ecx ->eax --> ecx的值看上面 1.
eax除以10(0A)余数就是注册码
注册码格式:
8267-%4d-%3d-%2d 如:
8267-3734-380-87
注册码保存在:
[HKEY_LOCAL_MACHINE\SOFTWARE\4Developers\RCrawler] - "4D"
-----------------
文章写于2007-08-11
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!