【工具】:OD IDA DeDe
【环境】:xp sp3
-------------------------------------------------------------------------------------------
发现加壳处理,脱之,分析。
发现为delphi编写,下断,单击注册按钮,断下代码如下:
0048F644 /. 55 push ebp
0048F645 |. 8BEC mov ebp, esp
0048F647 |. 83C4 D4 add esp, -2C
0048F64A |. 53 push ebx
0048F64B |. 56 push esi
0048F64C |. 33C9 xor ecx, ecx
0048F64E |. 894D D4 mov [local.11], ecx
0048F651 |. 894D FC mov [local.1], ecx
0048F654 |. 8BD8 mov ebx, eax
0048F656 |. 33C0 xor eax, eax
0048F658 |. 55 push ebp
0048F659 |. 68 BAF74800 push 0048F7BA
0048F65E |. 64:FF30 push dword ptr fs:[eax]
0048F661 |. 64:8920 mov dword ptr fs:[eax], esp
0048F664 |. 8D45 FC lea eax, [local.1]
0048F667 |. BA D0F74800 mov edx, 0048F7D0 ; 00000000
0048F66C |. E8 7F51F7FF call 004047F0 ; StrLAsg
0048F671 |. 8D4D FC lea ecx, [local.1] ; 12fbf0
0048F674 |. BA E4F74800 mov edx, 0048F7E4 ; 请输入软件注册号
0048F679 |. B8 08F84800 mov eax, 0048F808 ; 登记注册
0048F67E |. E8 2150FAFF call 004346A4 ; InPutQuery
0048F683 |. 3C 01 cmp al, 1 ; 判断输入是否为空
0048F685 |. 0F85 11010000 jnz 0048F79C
0048F68B |. 8D55 D4 lea edx, [local.11] ; 0
0048F68E |. 8B45 FC mov eax, [local.1] ; [12fbf0]=9cde24输入的序列号(AnsiString动态字符串)
0048F691 |. E8 4694F7FF call 00408ADC ; TRIM将字符串中的空格去掉。Trim
0048F696 |. 8B45 D4 mov eax, [local.11] ; 输入的序列号,这个是一个int64类型的字符串
0048F699 |. E8 1297F7FF call 00408DB0 ; StrToInt64()确定了只能用数字做注册码,同时位数也有限制
0048F69E |. 8945 F0 mov [local.4], eax ; 499602D2 eax 为转换后的值
0048F6A1 |. 8955 F4 mov [local.3], edx ; 有位数限制,不大于的话,edx =0
0048F6A4 |. 6A 00 push 0
0048F6A6 |. 6A 49 push 49
0048F6A8 |. 8B45 F0 mov eax, [local.4] ; 499602d2 值
0048F6AB |. 8B55 F4 mov edx, [local.3] ; 0
0048F6AE |. E8 9D60F7FF call 00405750 ; System.@_lldiv;eax 发生变化 long IDIV
0048F6B3 |. 8945 F0 mov [local.4], eax ; eax = 1020E10 注意eax
0048F6B6 |. 8955 F4 mov [local.3], edx ; 0
0048F6B9 |. 8B45 F0 mov eax, [local.4] ; 1020E10
0048F6BC |. 8B55 F4 mov edx, [local.3] ; 0
0048F6BF |. 2D E3C30B00 sub eax, 0BC3E3 ; 1020E10 eax-bc3e3 = f64a2d
0048F6C4 |. 83DA 00 sbb edx, 0
0048F6C7 |. 8945 F0 mov [local.4], eax ; f64a2d
0048F6CA |. 8955 F4 mov [local.3], edx ; 0
0048F6CD |. 8D45 D8 lea eax, [local.10] ; 【12fbcc】= 77D28FE1
0048F6D0 |. E8 5FF0FFFF call 0048E734 ; cupid edx变化
{
0048E734 /$ 53 push ebx ; 9c1d14
0048E735 |. 57 push edi ; c?
0048E736 |. 89C7 mov edi, eax ; 12fbcc
0048E738 |. B8 01000000 mov eax, 1 ; eax = 1
0048E73D |. 0FA2 cpuid ; cpuid 获得cpu信息
0048E73F |. AB stos dword ptr es:[edi] ; 20fc2 EDI = 12FBD0 cpuid[1]
0048E740 |. 89D8 mov eax, ebx ; 800
0048E742 |. AB stos dword ptr es:[edi] ; [12FBD0]= 43b679 cpuid[2]
0048E743 |. 89C8 mov eax, ecx ; 1
0048E745 |. AB stos dword ptr es:[edi] ; [12FBD4] = 110566
cpuid[3] 307BC
0048E746 |. 89D0 mov eax, edx ; 78BFBFF
0048E748 |. AB stos dword ptr es:[edi] ; [12FBD8] = 12FBE8
cpuid[4]
0048E749 |. 5F pop edi
0048E74A |. 5B pop ebx
0048E74B \. C3 retn
}
0048F6D5 |. 8B45 D8 mov eax, [local.10] ; [12FBCC]=20FC2
0048F6D8 |. 99 cdq ; 设置edx 000000
0048F6D9 |. 8945 E8 mov [local.6], eax ; 20fc2
0048F6DC |. 8955 EC mov [local.5], edx ; 0
0048F6DF |. 8B45 F0 mov eax, [local.4] ; f64a2d 变化
0048F6E2 |. 8B55 F4 mov edx, [local.3] ; local.3
0048F6E5 |. 3B55 EC cmp edx, [local.5] ; 位数限制
0048F6E8 |. 0F85 99000000 jnz 0048F787 ; 跳转到错误----------
0048F6EE |. 3B45 E8 cmp eax, [local.6] ; 比较eax和20fc2比较,通过计算转换输入的注册码的数值 和 经过cpuid 函数获得的值进行比较
0048F6F1 |. 0F85 90000000 jnz 0048F787 ; 不相等的话,跳转到错误
0048F6F7 |. B2 01 mov dl, 1
0048F6F9 |. A1 98FF4500 mov eax, dword ptr ds:[45FF98]
0048F6FE |. E8 9509FDFF call 00460098 ; Reg.Create 注册表操作
0048F703 |. 8BF0 mov esi, eax
0048F705 |. BA 02000080 mov edx, 80000002
0048F70A |. 8BC6 mov eax, esi
0048F70C |. E8 270AFDFF call 00460138 ; SetRootKey
0048F711 |. B1 01 mov cl, 1
0048F713 |. BA 1CF84800 mov edx, 0048F81C ;
0048F718 |. 8BC6 mov eax, esi
0048F71A |. E8 7D0AFDFF call 0046019C ; WriteReg
0048F71F |. 84C0 test al, al
0048F721 |. 74 0E je short 0048F731
0048F723 |. 33C9 xor ecx, ecx
0048F725 |. BA 68F84800 mov edx, 0048F868 ; gc_id
0048F72A |. 8BC6 mov eax, esi
0048F72C |. E8 DF0BFDFF call 00460310
0048F731 |> 8BC6 mov eax, esi
0048F733 |. E8 D009FDFF call 00460108 ; 关闭注册表
0048F738 |. 8BC6 mov eax, esi
0048F73A |. E8 2942F7FF call 00403968 ; free
0048F73F |. 6A 00 push 0
0048F741 |. 66:8B0D 70F84>mov cx, word ptr ds:[48F870]
0048F748 |. B2 02 mov dl, 2
0048F74A |. B8 7CF84800 mov eax, 0048F87C ; 软件登记注册成功!
0048F74F |. E8 344EFAFF call 00434588
0048F754 |. 33D2 xor edx, edx
0048F756 |. 8B83 08030000 mov eax, dword ptr ds:[ebx+308]
0048F75C |. 8B08 mov ecx, dword ptr ds:[eax]
0048F75E |. FF51 64 call dword ptr ds:[ecx+64]
0048F761 |. A1 142D4900 mov eax, dword ptr ds:[492D14]
0048F766 |. 8B00 mov eax, dword ptr ds:[eax]
0048F768 |. 8B80 04030000 mov eax, dword ptr ds:[eax+304]
0048F76E |. BA 98F84800 mov edx, 0048F898 ; 已注册版本
0048F773 |. E8 64BAFAFF call 0043B1DC ; 对话框
0048F778 |. 8B83 58030000 mov eax, dword ptr ds:[ebx+358]
0048F77E |. C740 0C 08000>mov dword ptr ds:[eax+C], 8
0048F785 |. EB 15 jmp short 0048F79C
0048F787 |> 6A 00 push 0
0048F789 |. 66:8B0D 70F84>mov cx, word ptr ds:[48F870]
0048F790 |. B2 01 mov dl, 1
0048F792 |. B8 ACF84800 mov eax, 0048F8AC ; 软件注册号错误!
0048F797 |. E8 EC4DFAFF call 00434588
0048F79C |> 33C0 xor eax, eax
0048F79E |. 5A pop edx
0048F79F |. 59 pop ecx
0048F7A0 |. 59 pop ecx
0048F7A1 |. 64:8910 mov dword ptr fs:[eax], edx
0048F7A4 |. 68 C1F74800 push 0048F7C1
0048F7A9 |> 8D45 D4 lea eax, [local.11]
0048F7AC |. E8 A74FF7FF call 00404758
0048F7B1 |> 8D45 FC lea eax, [local.1]
0048F7B4 |. E8 9F4FF7FF call 00404758
0048F7B9 \. C3 retn
【注册算法分析】
Delphi现学现用,包涵
计算流程为
获得输入的注册码 A
判断是否为空,空则提示
调用trim 将输入 的A空格去掉
StrToInt64()同时位数超过限制则跳走
A := A/49 ;
A = A – 0xBC3E3
比较 转换后的值与cpuid[0]进行比较,相等则写入注册表,作为一个注册过的标记,供下次读入。
此时,我们就可以计算出我电脑的注册码了 66148877 ,注册成功 !
48E734翻译过来的delphi代码就是
function GetCPUID : TCPUID; assembler; register;
asm
PUSH EBX {Save affected register}
PUSH EDI
MOV EDI,EAX {@Resukt}
MOV EAX,1
DW $A20F {CPUID Command}
STOSD {CPUID[1]}
MOV EAX,EBX
STOSD {CPUID[2]}
MOV EAX,ECX
STOSD {CPUID[3]}
MOV EAX,EDX
STOSD {CPUID[4]}
POP EDI {Restore registers}
POP EBX
end;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!