能力值:
( LV4,RANK:50 )
|
-
-
35 楼
偶也来献丑,同样是格雷码。
#define CODE_LENGTH 9
#define TABLE_SIZE ((1 << CODE_LENGTH) - 1)
unsigned int table[TABLE_SIZE] = {
1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6,
1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 7,
1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6,
1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 8,
1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6,
1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 7,
1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6,
1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 9,
1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6,
1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 7,
1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6,
1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 8,
1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6,
1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 7,
1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6,
1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1
};
char name[32];
char serial[TABLE_SIZE + 1];
unsigned int calc_name
(
char name[32],
unsigned int code[CODE_LENGTH]
)
{
int name_length = strlen(name);
int factor = 0x13572468;
int tmp1, tmp2;
unsigned char c;
int i;
for (i = 0; i < name_length; i++)
{
tmp1 = name[i];
tmp1 += factor;
tmp1 *= 0x03721273;
tmp1 += 0x24681357;
tmp2 = tmp1;
tmp2 <<= 0x19;
tmp1 >>= 0x07;
tmp2 |= tmp1;
factor = tmp2;
}
for (i = 1; i < CODE_LENGTH; i++)
{
tmp1= factor;
tmp1 = tmp1 >> i;
c = (unsigned char)tmp1;
c &= 0x01;
code[i - 1] = c;
}
code[8] = 1;
return (unsigned int)factor;
}
void calc_code1
(
int * a,
int * b
)
{
int i = CODE_LENGTH;
a += (CODE_LENGTH - 1);
b += (CODE_LENGTH - 1);
*b = *a;
for (i--; i > 0; i--, a--, b--)
{
*(b - 1) = (*b) ^ (*(a - 1));
}
}
int calc_code2
(
int * a
)
{
int v = 0;
int i;
i = CODE_LENGTH;
a += (CODE_LENGTH - 1);
for (; i > 0; i--, a--)
{
v = (v << 1) + (*a);
}
return v;
}
int calc(char input[32])
{
int serial_length = 0;
unsigned int name_int = 0;
unsigned int name_code[CODE_LENGTH] = {0};
int tmp[CODE_LENGTH] = {0};
int i;
name_int = calc_name(input, name_code);
calc_code1(name_code, tmp);
serial_length = calc_code2(tmp);
for (i = 0; i < serial_length; i++)
{
serial[i] = table[serial_length - i - 1] - ((name_int >> (i % 31)) % 10);
if (serial[i] < 0)
serial[i] += 10;
serial[i] += 0x30;
}
return 0;
}
|
能力值:
( LV2,RANK:10 )
|
-
-
43 楼
我的分析方法是不是北部对?
分析的速度很慢
步骤一:任意输入,用户名:aaaaa 注册码:bbbbb
我们查找getdlgitemtexta首值,找到后下硬件访问断点,点击注册我们的程序将停在这里:
00400499 |. 8D45 EC lea eax, dword ptr [ebp-14] ;《--------这里!
0040049C |. 6A 10 push 10 ; /Count = 10 (16.)
0040049E |. 50 push eax ; |Buffer
0040049F |. 68 E9030000 push 3E9 ; |ControlID = 3E9 (1001.)
004004A4 |. FF75 08 push dword ptr [ebp+8] ; |hWnd
004004A7 |. FFD6 call esi ; \GetDlgItemTextA
004004A9 |. 85C0 test eax, eax ; 字符是零吗?
004004AB |. 74 6C je short 00400519 ; 是的话就跳
004004AD |. 8D85 E8EFFFFF lea eax, dword ptr [ebp-1018] ; 否则就把地址内容放A中
004004B3 |. 68 00100000 push 1000 ; /Count = 1000 (4096.)
004004B8 |. 50 push eax ; |Buffer
004004B9 |. 68 EA030000 push 3EA ; |ControlID = 3EA (1002.)
004004BE |. FF75 08 push dword ptr [ebp+8] ; |hWnd
004004C1 |. FFD6 call esi ; \GetDlgItemTextA
004004C3 |. 85C0 test eax, eax ; 指向下一个窗口数 , ;窗口有数据吗?
004004C5 >|. 74 52 je short 00400519 ; 没有数据就跳到下一 ;个窗口
004004C7 |. 8D7D EC lea edi, dword ptr [ebp-14] ; 字符的第一个放到DI里
004004CA |. 83C9 FF or ecx, FFFFFFFF ; 对C放1
经过分析知道这是读取用户名,和用户注册码的地方
步骤二:
004004DA |> /0FBE4415 EC /movsx eax, byte ptr [ebp+edx-14] ; 把用户名转换到A寄存 ; 器里
004004DF |. |03C3 |add eax, ebx ; AB相加
004004E1 |. |69C0 73127203 |imul eax, eax, 3721273 ; 乘上3721273放到A里
004004E7 |. |05 57136824 |add eax, 24681357 ; 再加上24681357
004004EC |. |8BF0 |mov esi, eax ; 转化结果放SI里
004004EE |. |C1E6 19 |shl esi, 19 ; 左移动19位
004004F1 |. |C1F8 07 |sar eax, 7 ; 循环右移动7位
004004F4 |. |0BF0 |or esi, eax ; 结果相或
004004F6 |. |42 |inc edx ; D增加一
004004F7 |. |3BD1 |cmp edx, ecx ; 到4了吗?
004004F9 |. |8BDE |mov ebx, esi ; 把SI的结果保存到BX ; 里
004004FB |.^\7C DD \jl short 004004DA
分析可知是一个用户名的函数变换:
函数如下:
unsingned int b=0x13572468; //常数
unsingned int a=0; //中间变量1
unsingned int s=0; //中间变量2
read();//读入一个用户名
func1(){ //用户名转化函数
for(i=0;i<4;i++){
a=read();
a=(a+b)*3721273+24681357;
s=a;
s=s<<19;
a=s>>7;
s=s|a;
b=s;
}
}
====================================
//参数2的调用
004002CC /$ 55 push ebp ; 传递了两个参数,用户名,运算,和注册玛的地址
004002CD |. 8BEC mov ebp, esp ; 保护堆栈指针
004002CF |. 81EC 28010000 sub esp, 128 ; 分配堆栈
004002D5 8065 DC 00 and byte ptr [ebp-24], 0 ; 对12eab4缓冲区清零
004002D9 |. 53 push ebx ; 保存结果用户运算结果
004002DA |. 56 push esi ; 保存结果
004002DB |. 57 push edi ; 保护将要用到的寄存器
004002DC |. 33C0 xor eax, eax ; 对A清零
004002DE |. 8D7D DD lea edi, dword ptr [ebp-23] ; 地址偏移量送DI
004002E1 |. AB stos dword ptr es:[edi] ; 串操作指令,对此地址清零
004002E2 |. 80A5 D8FEFFFF>and byte ptr [ebp-128], 0 ; 对低八位清零
004002E9 |. 6A 40 push 40
004002EB |. AB stos dword ptr es:[edi] ; 保存节
004002EC |. AA stos byte ptr es:[edi] ; 保存字节
004002ED |. 59 pop ecx
004002EE |. 33C0 xor eax, eax ; 清零
004002F0 |. 8DBD D9FEFFFF lea edi, dword ptr [ebp-127] ; 对一首址放DI里
004002F6 |. 804D F4 FF or byte ptr [ebp-C], 0FF ; 对地址12edcc的低字节的内容之一
004002FA |. F3:AB rep stos dword ptr es:[edi] ; 对一个指定的区域清零
004002FC |. 804D E8 FF or byte ptr [ebp-18], 0FF ; 对底字节之一
00400300 |. 83C9 FF or ecx, FFFFFFFF
00400303 |. 66:AB stos word ptr es:[edi] ; 对双字清陵
00400305 |. AA stos byte ptr es:[edi] ; 清零
00400306 |. 8B7D 0C mov edi, dword ptr [ebp+C] ; 对注册码地址放到DI里
00400309 |. 33C0 xor eax, eax ; A清零
0040030B |. F2:AE repne scas byte ptr es:[edi] ; 把AL或AX的内容与目标串作比较,比较结果反映在标志位
0040030D |. F7D1 not ecx ; 厕得有几个字符?
00400313 |. C645 F5 63 mov byte ptr [ebp-B], 63 ; 对12EACD填充数据
00400317 |. C645 F6 FB mov byte ptr [ebp-A], 0FB
0040031B |. C645 F7 9A mov byte ptr [ebp-9], 9A
0040031F |. C645 F8 03 mov byte ptr [ebp-8], 3
00400323 |. C645 F9 A3 mov byte ptr [ebp-7], 0A3
00400327 |. C645 FA DA mov byte ptr [ebp-6], 0DA
0040032B |. C645 FB 72 mov byte ptr [ebp-5], 72
0040032F |. C645 FC FE mov byte ptr [ebp-4], 0FE
00400333 |. C645 FD C9 mov byte ptr [ebp-3], 0C9
00400337 |. C645 FE B7 mov byte ptr [ebp-2], 0B7
0040033B |. C645 E9 6A mov byte ptr [ebp-17], 6A
0040033F |. C645 EA D1 mov byte ptr [ebp-16], 0D1
00400343 |. C645 EB D2 mov byte ptr [ebp-15], 0D2
00400347 |. C645 EC 4E mov byte ptr [ebp-14], 4E
0040034B |. C645 ED 82 mov byte ptr [ebp-13], 82
0040034F |. C645 EE DA mov byte ptr [ebp-12], 0DA
00400353 |. C645 EF 72 mov byte ptr [ebp-11], 72
00400357 |. C645 F0 FE mov byte ptr [ebp-10], 0FE
0040035B |. C645 F1 C9 mov byte ptr [ebp-F], 0C9
0040035F |. C645 F2 B7 mov byte ptr [ebp-E], 0B7
===============================================
00400363 |. 8BF1 mov esi, ecx ; 保存注册字的数目
00400365 |. 8BFB mov edi, ebx ; BX到DI
00400367 |> 8B45 08 /mov eax, dword ptr [ebp+8] ; 一字节的数放A里
0040036A |. 8BCF |mov ecx, edi ; DI内容到C
0040036C |. D3E8 |shr eax, cl ; 循环右移动CL个字节
0040036E |. 22C3 |and al, bl ; A与B的低字节相与
00400370 |. 88443D DC |mov byte ptr [ebp+edi-24], al ; 把A低字节的内容放到一地址
00400374 |. 47 |inc edi
00400375 |. 83FF 09 |cmp edi, 9
00400378 |.^ 7C ED \jl short 00400367
0040037A |. 33FF xor edi, edi ; 循环9次后放DI清零
0040037C |. 885D E5 mov byte ptr [ebp-1B], bl ; 低字节送次
0040037F |. 85F6 test esi, esi ; SI是零吗?
00400381 |. 7E 6B jle short 004003EE ; 小于等于的话就跳
00400383 |> 8B45 0C /mov eax, dword ptr [ebp+C] ; 把注册码放EA内
00400386 |. 8A0407 |mov al, byte ptr [edi+eax] ; 把注册玛送BL
00400389 |. 3C 30 |cmp al, 30 ; 注册玛合30 比较,在A里是0
0040038B |. 8845 FF |mov byte ptr [ebp-1], al ; 注册码放到12EAD7内存里
0040038E |. 0F8C 97000000 |jl 0040042B ; 小于30的话,就跳
00400394 |. 3C 39 |cmp al, 39 ; 和39比较
00400396 0F8F 8F000000 jg 0040042B ; 大于39吗?大于就就跳在ASC里是是9
0040039C |. 8BC7 |mov eax, edi ; 否DI放A
0040039E |. 6A 1F |push 1F
004003A0 |. 99 |cdq ; 字扩展
004003A1 |. 59 |pop ecx
004003A2 |. F7F9 |idiv ecx
004003A4 |. 8B45 08 |mov eax, dword ptr [ebp+8] ; 送A
004003A7 |. 6A 0A |push 0A
=====================================================
就再也分析不下去了
都是动态的
|