【文章标题】: 大唐通讯录1.3 算法分析
【文章作者】: Flash
【作者邮箱】: amwfhv@163.com
【作者QQ号】: 239287501
【软件名称】: 大唐通讯录1.3
【下载地址】: 自己搜索下载
【加壳方式】: 无
【编写语言】: Delphi
【使用工具】: OD
【操作平台】: Win2003
【软件介绍】: 一款通讯录
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
用PEID查壳这个软件居然没有壳,那就省事了。查到是使用Delphi写的程序,直接用DEDE载入分析一下,找到
找到一窗体TFrm_Reg该窗体看名字就知道应该是注册窗体
然后查看窗体里面的事件,发现一Btn_RegClick事件地址在005D291C。
OK前期的工作做完直接进入正题用OD载入主程序分析,直接在5D291C处下断点
输入注册名和假码直接在此处断下
005D291C /. 55 push ebp //注册按钮事件
--------------------------------单步跟踪---------------------------------------
005D293F |. E8 1042EBFF call 00486B54 ; 取注册用户名
005D2944 |. 8B45 F8 mov eax, dword ptr [ebp-8] ; 此时可在堆栈中看到注册用户名
--------------------------------继续往下走------------------------------------
005D294A |. E8 ED6FE3FF call 0040993C ; 取注册名长度
005D294F |. 837D FC 00 cmp dword ptr [ebp-4], 0 ; 注册名长度
005D2953 |. 75 29 jnz short 005D297E ; 长度为0则跳到错误提示框
005D2955 |. 6A 40 push 40
005D2957 |. 68 282A5D00 push 005D2A28 ; ASCII "Warning"
005D295C |. 68 302A5D00 push 005D2A30
005D2961 |. 8BC3 mov eax, ebx
005D2963 |. E8 BCABEBFF call 0048D524
005D2968 |. 50 push eax ; |hOwner
005D2969 |. E8 3A56E3FF call <jmp.&user32.MessageBoxA> ; \提示输入注册名
--------------------------------继续往下走------------------------------------
005D2987 |. E8 C841EBFF call 00486B54 ; 取假码
005D298C |. 8B45 F0 mov eax, dword ptr [ebp-10] ; 堆栈中可看到假码
005D298F |. 8D55 F4 lea edx, dword ptr [ebp-C]
005D2992 |. E8 A56FE3FF call 0040993C ; 取注册码的长度
005D2997 |. 837D F4 00 cmp dword ptr [ebp-C], 0 ; 注册码长度不为0则跳过提示输入注册码
005D299B |. 75 29 jnz short 005D29C6
005D299D |. 6A 40 push 40
005D299F |. 68 282A5D00 push 005D2A28 ; ASCII "Warning"
005D29A4 |. 68 402A5D00 push 005D2A40
005D29A9 |. 8BC3 mov eax, ebx
005D29AB |. E8 74ABEBFF call 0048D524
005D29B0 |. 50 push eax ; |hOwner
005D29B1 |. E8 F255E3FF call <jmp.&user32.MessageBoxA> ; 提示输入注册码
005D29B6 |. 8B83 10030000 mov eax, dword ptr [ebx+310]
005D29BC |. 8B10 mov edx, dword ptr [eax]
005D29BE |. FF92 C4000000 call dword ptr [edx+C4]
005D29C4 |. EB 28 jmp short 005D29EE
005D29C6 |> 8BC3 mov eax, ebx
005D29C8 |. E8 1FFDFFFF call 005D26EC ; 这里就是关键的Call了跟进去
005D29CD |. 84C0 test al, al ; 测试al为0就会跳到注册错误
005D29CF |. 74 13 je short 005D29E4 ; 跳到注册错误
005D29D1 |. B8 582A5D00 mov eax, 005D2A58
005D29D6 |. E8 E9ACE6FF call 0043D6C4
005D29DB |. 8BC3 mov eax, ebx
005D29DD |. E8 F2FAFFFF call 005D24D4
005D29E2 |. EB 0A jmp short 005D29EE
005D29E4 |> B8 6C2A5D00 mov eax, 005D2A6C
005D29E9 |. E8 D6ACE6FF call 0043D6C4 ; 注册错误
--------------------------------005D26EC------------------------------------
005D273F |. E8 F871E3FF call 0040993C
005D2744 |. 8B55 F0 mov edx, dword ptr [ebp-10]
005D2747 |. 8D4D F4 lea ecx, dword ptr [ebp-C]
005D274A |. 8BC6 mov eax, esi
005D274C |. E8 8FFBFFFF call 005D22E0 ; 计算注册码
005D2751 |. 8B55 F4 mov edx, dword ptr [ebp-C]
005D2754 |. 58 pop eax ; 016A0F00
--------------------------------005D22E0------------------------------------
此时edx保存我的注册用户名
{
此段将输入的用户名的ASCALL码顺序相加组成一个新的字符串,这里我的注册名为Flash
此相加后的字串为
466C617368
}
------------------------------用户名的ASCALL码顺序相加----------------------
005D2327 |. BB 01000000 mov ebx, 1 ; ebx给1
005D232C |> 8D4D EC /lea ecx, dword ptr [ebp-14] ; 偏移地址入ecx 12EB34
005D232F |. 8B45 FC |mov eax, dword ptr [ebp-4] ; 用户名给eax
005D2332 |. 0FB64418 FF |movzx eax, byte ptr [eax+ebx-1] ; 取第一位
005D2337 |. 33D2 |xor edx, edx ; edx清0
005D2339 |. E8 167DE3FF |call 0040A054
005D233E |. 8B55 EC |mov edx, dword ptr [ebp-14] ; 用户名第一位给edx
005D2341 |. 8D45 F8 |lea eax, dword ptr [ebp-8]
005D2344 |. E8 5729E3FF |call 00404CA0
005D2349 |. 43 |inc ebx
005D234A |. 4E |dec esi
005D234B |.^ 75 DF \jnz short 005D232C ;
{
此段将用户名ASCALL码相加的字串顺序给倒一转跑完后字串为
863716C664
}
005D235B |. BB 01000000 mov ebx, 1
005D2360 |> 8B45 F8 /mov eax, dword ptr [ebp-8] ; 用户名相加后的字串放入eax
005D2363 |. E8 3029E3FF |call 00404C98
005D2368 |. 2BC3 |sub eax, ebx
005D236A |. 8B55 F8 |mov edx, dword ptr [ebp-8]
005D236D |. 8A1402 |mov dl, byte ptr [edx+eax]
005D2370 |. 8D45 E8 |lea eax, dword ptr [ebp-18]
005D2373 |. E8 4828E3FF |call 00404BC0
005D2378 |. 8B55 E8 |mov edx, dword ptr [ebp-18]
005D237B |. 8D45 F4 |lea eax, dword ptr [ebp-C]
005D237E |. E8 1D29E3FF |call 00404CA0
005D2383 |. 43 |inc ebx
005D2384 |. 4E |dec esi
005D2385 |.^ 75 D9 \jnz short 005D2360 ; 此段将用户名ASCALL码值倒序
//这里取用户名字串的前八位
005D238B |. B9 04000000 mov ecx, 4 ; 取几位
005D2390 |. BA 01000000 mov edx, 1 ; 从第几位取
005D2395 |. 8B45 F4 mov eax, dword ptr [ebp-C] ; 863716C664入
005D2398 |. E8 5B2BE3FF call 00404EF8 ; 取得8637
005D239D |. 8D45 F4 lea eax, dword ptr [ebp-C]
005D23A0 |. 50 push eax
005D23A1 |. B9 04000000 mov ecx, 4 ;同上面了
005D23A6 |. BA 05000000 mov edx, 5
005D23AB |. 8B45 F4 mov eax, dword ptr [ebp-C]
005D23AE |. E8 452BE3FF call 00404EF8
005D23B3 |. 8B45 F8 mov eax, dword ptr [ebp-8]
005D23BB |. 83F8 04 cmp eax, 4
005D23BE |. 7D 2F jge short 005D23EF
//此处出现一特殊字符串
005D242E |. BA B8245D00 mov edx, 005D24B8 ; ASCII "Con62bsar698"
005D243C |. B9 04000000 mov ecx, 4 ; 同上从第一位取四位
005D2441 |. BA 01000000 mov edx, 1
005D2446 |. 8B45 F0 mov eax, dword ptr [ebp-10]
005D2449 |. E8 AA2AE3FF call 00404EF8
005D245D |. B9 05000000 mov ecx, 5 ; 从第五位取5位
005D2462 |. BA 05000000 mov edx, 5
005D2467 |. 8B45 F0 mov eax, dword ptr [ebp-10]
005D246A |. E8 892AE3FF call 00404EF8
// 组合注册码
005D247A |. 8BC7 mov eax, edi
005D247C |. BA 06000000 mov edx, 6
005D2481 |. E8 D228E3FF call 00404D58 ; 调用这里组合
// 此处为组合注册码的算法
00404DAE > 8B449C 18 mov eax, dword ptr [esp+ebx*4+1>
00404DB2 . |89F2 mov edx, esi
00404DB4 . |85C0 test eax, eax
00404DB6 . |74 0A je short 00404DC2
00404DB8 . |8B48 FC mov ecx, dword ptr [eax-4]
00404DBB . |01CE add esi, ecx
00404DBD . |E8 9ADDFFFF call 00402B5C ; 调用的这里进行组合
00404DC2 > |4B dec ebx
00404DC3 .^\75 E9 jnz short 00404DAE
00404DC5 . 5A pop edx ; 016A3DA8
组合后注册码为Con6-86372bsar-16C6
********************************注册机函数Delphi版*****************************************
*****************************直接调用CreateKey传入注册用户名*******************************
function StrToStr(Value:String):string;
var
Tmp:String;
nloop:Integer;
begin
Tmp:='';
for nloop:=Length(Value) downto 1 do
Tmp:=Tmp+Value[nloop];
Result:=Tmp;
end;
function CreateKey(Name:String):String;
var
AStr:String;
UName:String;
Key:String;
nloop:Integer;
begin
AStr:='';
UName:=Trim(Name);
for nloop:=1 to Length(UName) do
AStr:=AStr+IntToHex(Ord(UName[nloop]),2);
AStr:=StrToStr(AStr);
Key:='Con6-'+Copy(AStr,1,4)+'2bsar-'+Copy(AStr,5,4);
Result:=Key;
end;
--------------------------------------------------------------------------------
【经验总结】
耐心+细心
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2008年03月05日 14:03:08
[课程]Linux pwn 探索篇!