比铰经典查表 CM 算法分析和注册机编写
本帖最后由 wangwei1978 于 2015-6-9 23:13 编辑如何找关键就不说,汇编太长太乱只是大致了解一下.text:00401130 ; int __cdecl sub_401130(HWND hDlg)
.text:00401130 sub_401130 proc near ; CODE XREF: WinMain(x,x,x,x)+81p
.text:00401130
.text:00401130 MainkeyBuffer = byte ptr -51Ch
.text:00401130 nameBuffer = byte ptr -4FCh
.text:00401130 var_4FB = byte ptr -4FBh
.text:00401130 name = byte ptr -434h
.text:00401130 var_433 = byte ptr -433h
.text:00401130 reg = byte ptr -36Ch
.text:00401130 var_36B = byte ptr -36Bh
.text:00401130 Key_288 = byte ptr -2A4h
.text:00401130 var_2A3 = byte ptr -2A3h
.text:00401130 hDlg = dword ptr4
.text:00401130
.text:00401130 sub esp, 51Ch
.text:00401136 push ebx
.text:00401137 push ebp
.text:00401138 push esi
.text:00401139 push edi
.text:0040113A mov ecx, 7
.text:0040113F mov esi, offset Mainkey ; "TRADECANMAKEEVERYONEBETTEROFF"
.text:00401144 lea edi,
.text:00401148 xor eax, eax
.text:0040114A rep movsd
.text:0040114C movsw
.text:0040114E mov ecx, 31h
.text:00401153 lea edi,
.text:0040115A mov , 0
.text:00401162 mov , 0
.text:0040116A rep stosd
.text:0040116C stosw
.text:0040116E stosb
.text:0040116F mov ecx, 31h
.text:00401174 xor eax, eax
.text:00401176 lea edi,
.text:0040117D mov , 0
.text:00401185 rep stosd
.text:00401187 stosw
.text:00401189 stosb
.text:0040118A mov ecx, 0A8h
.text:0040118F xor eax, eax
.text:00401191 lea edi,
.text:00401198 mov , 0
.text:0040119D rep stosd
.text:0040119F stosw
.text:004011A1 stosb
.text:004011A2 mov ecx, 31h
.text:004011A7 xor eax, eax
.text:004011A9 lea edi,
.text:004011AD xor esi, esi
.text:004011AF rep stosd
.text:004011B1 stosw
.text:004011B3 stosb
.text:004011B4 lea edi,
.text:004011BB
.text:004011BB loc_4011BB: ; CODE XREF: sub_401130+A8j
.text:004011BB xor ecx, ecx
.text:004011BD
.text:004011BD loc_4011BD: ; CODE XREF: sub_401130+A1j
.text:004011BD lea eax,
.text:004011C0 mov ebx, 1Ah
.text:004011C5 cdq
.text:004011C6 idiv ebx
.text:004011C8 add dl, 41h
.text:004011CB mov , dl
.text:004011CE inc ecx
.text:004011CF cmp ecx, ebx
.text:004011D1 jl short loc_4011BD
.text:004011D3 inc esi
.text:004011D4 add edi, ebx
.text:004011D6 cmp esi, ebx
.text:004011D8 jl short loc_4011BB
.text:004011DA mov ebp,
.text:004011E1 lea eax,
.text:004011E8 push 0C9h ; cchMax
.text:004011ED push eax ; lpString
.text:004011EE push 3E8h ; nIDDlgItem
.text:004011F3 push ebp ; hDlg
.text:004011F4 call ds:GetDlgItemTextA
.text:004011FA mov esi, eax
.text:004011FC cmp esi, 4
.text:004011FF jl loc_401305
.text:00401205 cmp esi, 0Fh
.text:00401208 jg loc_401305
.text:0040120E lea ecx,
.text:00401215 push esi
.text:00401216 push ecx
<font size="4" color="#ff0000">.text:00401217 call sub_401320 ; 这个CALL 作用是检测是否有数字或特殊字符,有就返回0,注册失败,另一个功能,是小写转为大写</font>
.text:0040121C add esp, 8
.text:0040121F test eax, eax
.text:00401221 jz loc_401305
.text:00401227 mov eax, 1Dh
.text:0040122C cdq
.text:0040122D idiv esi
.text:0040122F test eax, eax
.text:00401231 jle short loc_40124D
.text:00401233 mov edi, ds:lstrcatA
.text:00401239 mov esi, eax
.text:0040123B
.text:0040123B loc_40123B: ; CODE XREF: sub_401130+11Bj
.text:0040123B lea edx,
.text:00401242 lea eax,
.text:00401246 push edx ; lpString2
.text:00401247 push eax ; lpString1
.text:00401248 call edi ; lstrcatA
.text:0040124A dec esi
.text:0040124B jnz short loc_40123B
.text:0040124D
.text:0040124D loc_40124D: ; CODE XREF: sub_401130+101j
.text:0040124D mov ebx, ds:lstrlenA
.text:00401253 lea ecx,
.text:00401257 push ecx ; lpString
.text:00401258 call ebx ; lstrlenA
.text:0040125A mov esi, 1Dh
.text:0040125F xor edi, edi
.text:00401261 sub esi, eax
.text:00401263 test esi, esi
.text:00401265 jle short loc_40127E
.text:00401267
.text:00401267 loc_401267: ; CODE XREF: sub_401130+14Cj
.text:00401267 lea edx,
.text:0040126B push edx ; lpString
.text:0040126C call ebx ; lstrlenA
.text:0040126E mov cl,
.text:00401275 inc edi
.text:00401276 cmp edi, esi
.text:00401278 mov , cl
.text:0040127C jl short loc_401267
.text:0040127E
.text:0040127E loc_40127E: ; CODE XREF: sub_401130+135j
.text:0040127E lea edx,
.text:00401285 push 0C9h ; cchMax
.text:0040128A push edx ; lpString
.text:0040128B push 3E9h ; nIDDlgItem
.text:00401290 push ebp ; hDlg
.text:00401291 call ds:GetDlgItemTextA
.text:00401297 cmp eax, 1Dh
.text:0040129A jnz short loc_401305
.text:0040129C push eax
.text:0040129D lea eax,
.text:004012A4 push eax
.text:004012A5 call sub_401320
.text:004012AA add esp, 8
.text:004012AD test eax, eax
.text:004012AF jz short loc_401305
.text:004012B1 xor edx, edx
.text:004012B3
.text:004012B3 loc_4012B3: ; CODE XREF: sub_401130+1C3j
.text:004012B3 mov al,
.text:004012B7 sub al, 41h
.text:004012B9 xor ecx, ecx
.text:004012BB movsx eax, al
.text:004012BE lea esi,
.text:004012C1 lea eax,
.text:004012C4 lea esi,
.text:004012CB mov al,
.text:004012D2
.text:004012D2 loc_4012D2: ; CODE XREF: sub_401130+1BDj
.text:004012D2 cmp al,
.text:004012D5 jnz short loc_4012E9
.text:004012D7 mov bl,
.text:004012DB cmp bl,
.text:004012E2 jnz short loc_401305
.text:004012E4 mov ecx, 1Dh
.text:004012E9
.text:004012E9 loc_4012E9: ; CODE XREF: sub_401130+1A5j
.text:004012E9 inc ecx
.text:004012EA cmp ecx, 1Dh
.text:004012ED jl short loc_4012D2
.text:004012EF inc edx
.text:004012F0 cmp edx, 1Dh
.text:004012F3 jl short loc_4012B3
.text:004012F5 pop edi
.text:004012F6 pop esi
.text:004012F7 pop ebp
.text:004012F8 mov eax, 1
.text:004012FD pop ebx
.text:004012FE add esp, 51Ch
.text:00401304 retn
.text:00401305 ; ---------------------------------------------------------------------------
.text:00401305
.text:00401305 loc_401305: ; CODE XREF: sub_401130+CFj
.text:00401305 ; sub_401130+D8j ...
.text:00401305 pop edi
.text:00401306 pop esi
.text:00401307 pop ebp
.text:00401308 xor eax, eax
.text:0040130A pop ebx
.text:0040130B add esp, 51Ch
.text:00401311 retn
.text:00401311 sub_401130 endp 我用F5看再整理一下看代码
int __cdecl sub_401130(HWND hDlg)
{
signed int n; // esi@1
char *Key; // edi@1
signed int i; // ecx@2
int namelen; // eax@5
signed int namelen_1; // esi@5
int m; // esi@9
int y; // edi@11
int k; // esi@11
int nameBufferlen; // eax@12
CHAR namebyte; // cl@12
signed int i_reg; // edx@15
signed int y_reg; // ecx@16
int result; // eax@22
char MainkeyBuffer; // @1
CHAR nameBuffer; // @1
char v16; // @1
__int16 v17; // @1
char v18; // @1
CHAR name; // @1
char v20; // @1
__int16 v21; // @1
char v22; // @1
CHAR reg; // @1
char v24; // @1
__int16 v25; // @1
char v26; // @1
char Key_288; // @1
char v28; // @1
__int16 v29; // @1
char v30; // @1
;把一个KEY表COPY (Mainkey db 'TRADECANMAKEEVERYONEBETTEROFF',0)进 MainkeyBuffer中
;#####################################################
qmemcpy(MainkeyBuffer, Mainkey, 0x1Eu);
name = 0;
reg = 0;
memset(&v20, 0, 196u);
v21 = 0;
v22 = 0;
Key_288 = 0;
memset(&v24, 0, 196u);
v25 = 0;
v26 = 0;
nameBuffer = 0;
memset(&v28, 0, 672u);
v29 = 0;
v30 = 0;
n = 0;
memset(&v16, 0, 0xC4u);
v17 = 0;
v18 = 0;
; 初始化堆栈
;####################################################
Key = &Key_288;
do
{
i = 0;
do
{
Key = (i + n) % 0x1A + 0x41;
++i;
}
while ( i < 0x1A );
++n;
Key += 0x1A;
}
while ( n < 0x1A );
;动态初始化另一个KEY表用于查表选岀组成注册码的字符
;####################################################
namelen = GetDlgItemTextA(hDlg, 1000, &name, 201);
namelen_1 = namelen;
if ( namelen < 4 || namelen > 0xF || !sub_401320((int)&name, namelen) )
goto error;
if ( 0x1D / namelen_1 > 0 )
{
m = 0x1D / namelen_1;
do
{
lstrcatA(&nameBuffer, &name);
--m;
}
while ( m );
}
y = 0;
k = 0x1D - lstrlenA(&nameBuffer);
if ( k > 0 )
{
do
{
nameBufferlen = lstrlenA(&nameBuffer);
namebyte = *(&name + y++);
*(&nameBuffer + nameBufferlen) = namebyte;
}
while ( y < k );
}
;判断用户名长度是否大于4小于15.在此范围,就开始拼接用户名字串, m 是注册码长度/用户名长度.并把它作
为拼接用户名的次数.不是0x1D长度的字符用用户名单字循环补足为止
;################################################################
if ( GetDlgItemTextA(hDlg, 1001, ®, 201) == 0x1D && sub_401320((int)®, 0x1D) )
{
i_reg = 0; 外循环为注册码长度
do
{
y_reg = 0;
do
{
;注册码逐位取出和从第二个KEY表(位置是用户名 - 0x41的26倍的值 )开始比较,找到后.
if ( *(® + i_reg) == *(&Key_288 + 26 * (char)(*(&nameBuffer + i_reg) - 0x41) + y_reg)
)
{
;找到注册码所在KEy表位置 y_reg ,再逐位取出第一个KEY 与第二KEY 进行匹配
if ( MainkeyBuffer != *(&Key_288 + y_reg) )
goto error;
y_reg = 0x1D;
}
++y_reg;
}
while ( y_reg < 0x1D );
++i_reg;
}
while ( i_reg < 0x1D );
;如果所有MainkeyBuffer== 第二KEY表注册成功
result = 1;
}
else
{
error:
result = 0;
}
return result;
} 大家应该可以看懂.
整理一下算法
1.首先用户名要在4 --->15之间,注册码长度为29
2.判断用户名和注册码都不能有数字和特殊字符,有直接死了,而且会把小写改成大写
3.用户名把小写改为大写后,用注册码长度除以用户名长度 得到的值用作循环把用户名字符连接的次数,循环完后不足29位,再用用户名单字符循环补齐
4.还真不好说看代码
if ( GetDlgItemTextA(hDlg, 1001, ®, 201) == 0x1D && sub_401320((int)®, 0x1D) )
{
i_reg = 0; 外循环为注册码长度
do
{
y_reg = 0;
do
{
;注册码逐位取出和从第二个KEY表(位置是用户名 - 0x41的26倍的值 )开始比较,找到后.
if ( *(® + i_reg) == *(&Key_288 + 26 * (char)(*(&nameBuffer + i_reg) - 0x41) + y_reg)
)
{
;找到注册码所在KEy表位置 y_reg ,再逐位取出第一个KEY 与第二KEY 进行匹配
if ( MainkeyBuffer != *(&Key_288 + y_reg) )
goto error;
y_reg = 0x1D;
}
++y_reg;
}
while ( y_reg < 0x1D );
++i_reg;
}
while ( i_reg < 0x1D );
;如果所有MainkeyBuffer== 第二KEY表注册成功
result = 1;
}
else
{
error:
result = 0;
}
return result;
}5.注册源码从汇编提取出看下
; =============== S U B R O U T I N E =======================================
sub_401320proc
pushad
xor eax,eax
xor edx,edx
loop1:
mov dl,byte ptr
cmp dl,0
jeexit1
cmp dl,30h
jna exit
cmp dl,39h
jnaexit
cmp dl,60h
jnalea1
sub dl,20h
lea1:
mov byte ptr,dl
inc eax
jmp loop1
exit:
popad
mov eax,0
ret
exit1:
popad
ret
sub_401320 endp
; int __cdecl sub_401130(HWND hDlg)
sub_401130 proc near ; CODE XREF: WinMain(x,x,x,x)+81p
MainkeyBuffer = byte ptr -51Ch
nameBuffer = byte ptr -4FCh
var_4FB = byte ptr -4FBh
szname = byte ptr -434h
var_433 = byte ptr -433h
reg = byte ptr -36Ch
var_36B = byte ptr -36Bh
Key_288 = byte ptr -2A4h
var_2A3 = byte ptr -2A3h
hDlg = dword ptr4
sub esp, 51Ch
push ebx
push ebp
push esi
push edi
mov ecx, 7
mov esi, offset Mainkey ; "TRADECANMAKEEVERYONEBETTEROFF"
lea edi,
xor eax, eax
rep movsd
movsw
mov ecx, 31h
lea edi,
mov , 0
mov , 0
rep stosd
stosw
stosb
mov ecx, 31h
xor eax, eax
lea edi,
mov , 0
rep stosd
stosw
stosb
mov ecx, 0A8h
xor eax, eax
lea edi,
mov , 0
rep stosd
stosw
stosb
mov ecx, 31h
xor eax, eax
lea edi,
xor esi, esi
rep stosd
stosw
stosb
lea edi,
loc_4011BB: ; CODE XREF: sub_401130+A8j
xor ecx, ecx
loc_4011BD: ; CODE XREF: sub_401130+A1j
lea eax,
mov ebx, 1Ah
cdq
idiv ebx
add dl, 41h
mov , dl
inc ecx
cmp ecx, ebx
jl short loc_4011BD
inc esi
add edi, ebx
cmp esi, ebx
jl short loc_4011BB
mov ebp,
lea eax,
push 0C9h ; cchMax
push eax ; lpString
push 1003 ; nIDDlgItem
push ebp ; hDlg
call ds:GetDlgItemTextA
mov esi, eax
cmp esi, 4
jl loc_401305
cmp esi, 0Fh
jg loc_401305
lea ecx,
; push esi
; push ecx
call sub_401320
; add esp, 8
test eax, eax
jz loc_401305
mov eax, 1Dh
cdq
idiv esi
test eax, eax
jle short loc_40124D
mov edi, ds:lstrcatA
mov esi, eax
loc_40123B: ; CODE XREF: sub_401130+11Bj
lea edx,
lea eax,
push edx ; lpString2
push eax ; lpString1
call edi ; lstrcatA
dec esi
jnz short loc_40123B
loc_40124D: ; CODE XREF: sub_401130+101j
mov ebx, ds:lstrlenA
lea ecx,
push ecx ; lpString
call ebx ; lstrlenA
mov esi, 1Dh
xor edi, edi
sub esi, eax
test esi, esi
jle short loc_40127E
loc_401267: ; CODE XREF: sub_401130+14Cj
lea edx,
push edx ; lpString
call ebx ; lstrlenA
mov cl,
inc edi
cmp edi, esi
mov , cl
jl short loc_401267
loc_40127E: ; CODE XREF: sub_401130+135j
; lea edx,
; push 0C9h ; cchMax
; push edx ; lpString
; push 3E9h ; nIDDlgItem
; push ebp ; hDlg
; call ds:GetDlgItemTextA
; cmp eax, 1Dh
; jnz short loc_401305
; push eax
; lea eax,
; push eax
; ;call sub_401320
; add esp, 8
; test eax, eax
; jz short loc_401305
xor edx, edx
loc_4012B3: ; CODE XREF: sub_401130+1C3j
mov al,
sub al, 41h
xor ecx, ecx
movsx eax, al
lea esi,
lea eax,
lea esi,
; mov al,
loc_4012D2: ; CODE XREF: sub_401130+1BDj
; cmp al,
; jnz short loc_4012E9
mov bl,
cmp bl,
jnz short loc_4012E9
mov al,
mov byte ptr,al
mov ecx, 1Dh
loc_4012E9: ; CODE XREF: sub_401130+1A5j
inc ecx
cmp ecx, 1Dh
jl short loc_4012D2
inc edx
cmp edx, 1Dh
jl short loc_4012B3
pop edi
pop esi
pop ebp
mov eax, 1
pop ebx
add esp, 51Ch
retn
; ---------------------------------------------------------------------------
loc_401305: ; CODE XREF: sub_401130+CFj
; sub_401130+D8j ...
pop edi
pop esi
pop ebp
xor eax, eax
pop ebx
add esp, 51Ch
retn
sub_401130 endp
sub_401320这个是我自已实现,功能在上面说了,为保证汇编原来的样子,无用代码并没有删除只是注释了,方便朋友对照学习。同时CM和注册机源码打包上传。请大家指点
就是那个挖了许多坑逼你静态分析的cm?{:soso_e179:} 喜欢这样的源码,利于我们初学者学习,赞一个{:soso_e179:} lucky_789 发表于 2015-6-9 23:37
就是那个挖了许多坑逼你静态分析的cm?{:soso_e179:}
不是 lucky_789 发表于 2015-6-9 23:37
就是那个挖了许多坑逼你静态分析的cm?
sub_4012C0 proc near ; CODE XREF: sub_401028j
Buffer = byte ptr -138h
n = dword ptr -0F8h
sum_1 = dword ptr -0F4h
sum = dword ptr -0F0h
var_24 = dword ptr -24h
szname = dword ptr8
push ebp
mov ebp, esp
sub esp, 138h
push ebx
push esi
push edi
lea edi,
mov ecx, 4Eh
mov eax, 0CCCCCCCCh
rep stosd
mov , 0FFFFFFF8h
mov , 0
mov , 3C6h
mov , 0
jmp short loc_40130E
; ---------------------------------------------------------------------------
loc_401305: ; CODE XREF: sub_4012C0+77j
mov eax,
add eax, 1
mov , eax
loc_40130E: ; CODE XREF: sub_4012C0+43j
mov ecx,
push ecx ; char *
call _strlen
add esp, 4
cmp , eax
jnb short loc_401339
mov edx,
add edx,
xor eax, eax
mov al,
mov ecx,
add ecx, eax
mov , ecx
jmp short loc_401305
; ---------------------------------------------------------------------------
loc_401339: ; CODE XREF: sub_4012C0+5Dj
mov , 0
jmp short loc_40134B
; ---------------------------------------------------------------------------
loc_401342: ; CODE XREF: sub_4012C0+F8j
mov edx,
add edx, 1
mov , edx
loc_40134B: ; CODE XREF: sub_4012C0+80j
mov eax,
push eax ; char *
call _strlen
add esp, 4
cmp , eax
jnb short loc_4013BA
mov ecx,
shr ecx, 8
shl ecx, 18h
shr ecx, 18h
mov edx,
add edx,
mov al,
xor al, cl
mov ecx,
add ecx,
mov , al
mov edx,
add edx,
xor eax, eax
mov al,
mov ecx,
add ecx, eax
mov , ecx
mov edx,
imul edx, 6BADh
mov , edx
mov eax,
add eax, 0C0DEh
mov , eax
jmp short loc_401342
; ---------------------------------------------------------------------------
loc_4013BA: ; CODE XREF: sub_4012C0+9Aj
mov , 0
jmp short loc_4013CC
; ---------------------------------------------------------------------------
loc_4013C3: ; CODE XREF: sub_4012C0+135j
mov ecx,
add ecx, 1
mov , ecx
loc_4013CC: ; CODE XREF: sub_4012C0+101j
mov edx,
push edx ; char *
call _strlen
add esp, 4
cmp , eax
jnb short loc_4013F7
mov eax,
add eax,
xor ecx, ecx
mov cl,
mov edx,
add edx, ecx
mov , edx
jmp short loc_4013C3
; ---------------------------------------------------------------------------
loc_4013F7: ; CODE XREF: sub_4012C0+11Bj
mov eax,
imul eax, 3E8h
add eax,
pop edi
pop esi
pop ebx
add esp, 138h
cmp ebp, esp
;call __chkesp
mov esp, ebp
pop ebp
retn
sub_4012C0 endp
坑就一个,也可以动态调试,IDA的F5更直观。只是看到反调试判断,想都没选择了一个算法模块。但忘了一件事,od可以过掉这个反调试。所以我选择分析模块是错的。上面是陷井中的算法注册机了,真的算法没有分析到{:soso_e153:}
页:
[1]