今天这个CM非常漂亮!很多地方可圈可点啊~今天拿几个地方出来自我欣赏欣赏~
One:
Two:
00401420 8B4C24 04 mov ecx, dword ptr [esp+4]
00401424 F7C1 03000000 test ecx, 3 ; 3
0040142A 74 14 je short 00401440
0040142C 8A01 mov al, byte ptr [ecx]
0040142E 41 inc ecx
0040142F 84C0 test al, al
00401431 74 40 je short 00401473
00401433 F7C1 03000000 test ecx, 3
00401439 ^ 75 F1 jnz short 0040142C
0040143B 05 00000000 add eax, 0
00401440 8B01 mov eax, dword ptr [ecx]
00401442 BA FFFEFE7E mov edx, 7EFEFEFF ; 0x7EFEFEFF
00401447 03D0 add edx, eax ; ++
00401449 83F0 FF xor eax, FFFFFFFF
0040144C 33C2 xor eax, edx
0040144E 83C1 04 add ecx, 4
00401451 A9 00010181 test eax, 81010100
00401456 ^ 74 E8 je short 00401440
00401458 8B41 FC mov eax, dword ptr [ecx-4]
0040145B 84C0 test al, al
0040145D 74 32 je short 00401491
0040145F 84E4 test ah, ah
00401461 74 24 je short 00401487
00401463 A9 0000FF00 test eax, 0FF0000
00401468 74 13 je short 0040147D
0040146A A9 000000FF test eax, FF000000
/*这段代码扯了那么多 好像很复杂,其实目的就一个 就是获取NameLen
和我之前发表的一篇关于获取NameLen的简短Asm无调用代码的长度简直是天壤之别!
也可能是我反的东西太少 这中方式也许不是CODER的意图 而是编译器的意图~
抛开这谁谁导致这种获取方式的,我们光对比两张方式 就会发现今天这种方式是多么的漂亮~起码让人提起十分精神*/
0040146F 74 02 je short 00401473
00401471 ^ EB CD jmp short 00401440
00401473 8D41 FF lea eax, dword ptr [ecx-1]
00401476 8B4C24 04 mov ecx, dword ptr [esp+4]
0040147A 2BC1 sub eax, ecx
0040147C C3 retn
0040147D 8D41 FE lea eax, dword ptr [ecx-2]
00401480 8B4C24 04 mov ecx, dword ptr [esp+4]
00401484 2BC1 sub eax, ecx
00401486 C3 retn
00401487 8D41 FD lea eax, dword ptr [ecx-3]
0040148A 8B4C24 04 mov ecx, dword ptr [esp+4]
0040148E 2BC1 sub eax, ecx ; 取NameLen
00401490 C3 retn; 终于啰嗦完了 End
/*看了三个retn就知道上面那段长长的代码在啰嗦什么了,我们且认为是作者刻意的编码,这方式非常哈皮啊
虽然我汇编编程也不多 经验也不足 但是看到这类代码顿时愉悦无比*/
/*********************************************************/
最后是注册机编写过程中遇到的问题,这应该说是属于数学问题了…把错误的地方拿出来看看:
A:
/*for (;szMin<=0xFFFD;szMin++)
{
for (szUn=szMin+1;szUn<=0xFFFE;szUn++)
{
for (szMax=szUn+1;szMax<=0xFFFF;szMax++)
{
if (szMax==szSum2%szUn || szSum2%szUn==0)
{
if (szUn==szSum2%szMin || szSum2%szMin==0)
{
wsprintf(szLine,”%X-%X-%X”,szMax,szUn,szMin);
}
}
}
}
}*/
B:
/*for (szMax=0x1003;szMax<=0xFFFF;szMax++)
{
for (szUn=0x1002;szUn<szMax;szUn++)
{
for (szMin=0x1001;szMin<szUn;szMin++)
{
if (szMax==szSum2%szUn || szSum2%szUn==0)
{
if (szUn==szSum2%szMin || szSum2%szMin==0)
{
wsprintf(szLine,”%.4X-%.4X-%.4X”,szMax,szUn,szMin);
}
}
}
}
}*/
C:
szMax=0xFFFF;
szUn=szSum2%szMax;
szMin=szSum2%szUn;
wsprintf(szLine,”%.4X-%.4X-%.4X”,szMax,szUn,szMin);
/********************************************************************/
ABC 其实都是涉及一个函数求值的问题,a b c 三个参数, szSum2一个已知数,x,y两个变量,用数学的方式表达就是:
a=szSum2-xb
b=szSum2-yb
求符合x,y为正整数时候的a.b.c…A B C三种方法都OK 但是只有C是可行的~为嘛呢 翻翻高中数学书和CTRL+C编译下就知道了
其实说白了这就是个函数求值问题 这函数有多组解 也就是说 这个crackme每个用户名对应的注册码不是唯一的~
/*******************************************************************/
呃 初学反汇编 初学汇编 可能会有诸多个人谬误
一组可用KEY:
ShadowKong
FFFF-2B8B-2278
这个注册机并不完美~但是可以应付大部分用户名了~