看到论坛上的那么多的大牛都能分析出算法,深感惭愧啊~只能分析这么简单的CM,还是多年以前的CM~~大牛千万别笑啊!
好了开工,载入OD进行分析:
004013A0 >/$ 55 push ebp
004013A1 |. 8BEC mov ebp, esp
004013A3 |. 6A FF push -1
004013A5 |. 68 D0404000 push 004040D0
004013AA |. 68 D41E4000 push 00401ED4 ; SE 处理程序安装
004013AF |. 64:A1 0000000>mov eax, dword ptr fs:[0]
004013B5 |. 50 push eax
004013B6 |. 64:8925 00000>mov dword ptr fs:[0], esp
004013BD |. 83EC 58 sub esp, 58
004013C0 |. 53 push ebx
004013C1 |. 56 push esi
004013C2 |. 57 push edi
004013C3 |. 8965 E8 mov dword ptr [ebp-18], esp
004013C6 |. FF15 44404000 call dword ptr [<&KERNEL32.GetVersion>; kernel32.GetVersion
没有加壳,F9运行,输入用户名,注册码,肯定不正确,提示“序列号错误,再来一次!”
F12暂停,打开堆栈,跟踪到关键部分:
0040119C > \8BB424 000100>mov esi, dword ptr [esp+100] ; Case 3F5 of switch 0040115E
004011A3 . 8B3D A0404000 mov edi, dword ptr [<&USER32.GetDlgI>; USER32.GetDlgItemTextA
004011A9 . 53 push ebx
004011AA . 8D4424 4C lea eax, dword ptr [esp+4C]
004011AE . 6A 51 push 51 ; /Count = 51 (81.)
004011B0 . 50 push eax ; |Buffer
004011B1 . 6A 6E push 6E ; |ControlID = 6E (110.)
004011B3 . 56 push esi ; |hWnd
004011B4 . FFD7 call edi ; \获取用户名
继续
004011B6 . 8D8C24 9C0000>lea ecx, dword ptr [esp+9C]
004011BD . 6A 65 push 65 ; /Count = 65 (101.)
004011BF . 51 push ecx ; |Buffer
004011C0 . 68 E8030000 push 3E8 ; |ControlID = 3E8 (1000.)
004011C5 . 56 push esi ; |hWnd
004011C6 . 8BD8 mov ebx, eax ; |
004011C8 . FFD7 call edi ; \获取注册码
004011CA . 8A4424 4C mov al, byte ptr [esp+4C] ; 取用户名第一位
004011CE . 84C0 test al, al
004011D0 . 74 76 je short 00401248
004011D2 . 83FB 05 cmp ebx, 5 ; ebx=用户名长度
004011D5 . 7C 71 jl short 00401248 ; 小于5跳走
004011D7 . 8D5424 4C lea edx, dword ptr [esp+4C] ; edx保存用户名地址
004011DB . 53 push ebx
004011DC . 8D8424 A00000>lea eax, dword ptr [esp+A0] ; eax保存注册码地址
004011E3 . 52 push edx
004011E4 . 50 push eax
004011E5 . E8 56010000 call 00401340 ; 关键call跟进
004011EA . 8B3D BC404000 mov edi, dword ptr [<&USER32.GetDlgI>; USER32.GetDlgItem
004011F0 . 83C4 0C add esp, 0C
004011F3 . 85C0 test eax, eax
004011F5 . 74 37 je short 0040122E ; 爆破点了~~~~
关键call跟进:
00401340 /$ 55 push ebp
00401341 |. 8B6C24 0C mov ebp, dword ptr [esp+C] ; 取用户名
00401345 |. 56 push esi
00401346 |. 57 push edi
00401347 |. 8B7C24 18 mov edi, dword ptr [esp+18] ; 用户名长度
0040134B |. B9 03000000 mov ecx, 3
00401350 |. 33F6 xor esi, esi
00401352 |. 33C0 xor eax, eax
00401354 |. 3BF9 cmp edi, ecx
00401356 |. 7E 21 jle short 00401379 ; 用户名长度小于3跳走
00401358 |. 53 push ebx
00401359 |> 83F8 07 /cmp eax, 7
0040135C |. 7E 02 |jle short 00401360
0040135E |. 33C0 |xor eax, eax
00401360 |> 33D2 |xor edx, edx
00401362 |. 33DB |xor ebx, ebx
00401364 |. 8A1429 |mov dl, byte ptr [ecx+ebp] ; 从用户名第三位开始
00401367 |. 8A98 30504000 |mov bl, byte ptr [eax+405030] ; 地址405030处保存的值 :00405030 0C 0A 13 09 0C 0B 0A 08
0040136D |. 0FAFD3 |imul edx, ebx ; EDX保存乘积
00401370 |. 03F2 |add esi, edx ; ESI保存累加值
00401372 |. 41 |inc ecx
00401373 |. 40 |inc eax
00401374 |. 3BCF |cmp ecx, edi
00401376 |.^ 7C E1 \jl short 00401359
00401378 |. 5B pop ebx
00401379 |> 56 push esi ; /<%ld>
0040137A |. 68 78504000 push 00405078 ; |Format = "%ld"
0040137F |. 55 push ebp ; |s
00401380 |. FF15 9C404000 call dword ptr [<&USER32.wsprintfA>] ; \wsprintfA
00401386 |. 8B4424 1C mov eax, dword ptr [esp+1C] ; 取注册码
0040138A |. 83C4 0C add esp, 0C
0040138D |. 55 push ebp ; /ESI值(真正的注册码值)
0040138E |. 50 push eax ; |假码
0040138F |. FF15 04404000 call dword ptr [<&KERNEL32.lstrcmpA>] ; \lstrcmpA
00401395 |. F7D8 neg eax
00401397 |. 1BC0 sbb eax, eax
00401399 |. 5F pop edi
0040139A |. 5E pop esi
0040139B |. 40 inc eax
0040139C |. 5D pop ebp
0040139D \. C3 retn
简单的注册机
#include<stdio.h>
#include<string.h>
int main()
{
char name[20];
int num[]={12,10,19,9,12,11,10,8};//固定值
scanf("%s",name);
int esi=0,i,j=0;
for(i=3;i<=strlen(name);i++)
{
esi+=name[i]*num[j++];
}
printf("\n%d",esi);
return 0;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)