-
-
[原创]第六题 追凶者也
-
发表于: 2018-12-11 18:27 2914
-
s7:与前三位的7置换
首先找到注册码判断点
strcpy(Text, "try again!"); strcpy(Caption, "fail"); String = 0; v6 = 0; v7 = 0; v8 = 0; v9 = 0; v10 = 0; v11 = 0; GetDlgItemTextA(hDlg, 1001, &String, 20); v4 = 0; for ( i = 0; i < 20; ++i ) v4 += *(&String + i); if ( v4 > 0 && v4 < 4132 ) { v1 = malloc(v4); sub_401020(); j___free_base(v1); } return MessageBoxA(0, Text, Caption, 0);
但奇怪的是几乎什么都没做就直接弹出失败信息
strcpy(Text, "try again!"); strcpy(Caption, "fail"); String = 0; v6 = 0; v7 = 0; v8 = 0; v9 = 0; v10 = 0; v11 = 0; GetDlgItemTextA(hDlg, 1001, &String, 20); v4 = 0; for ( i = 0; i < 20; ++i ) v4 += *(&String + i); if ( v4 > 0 && v4 < 4132 ) { v1 = malloc(v4); sub_401020(); j___free_base(v1); } return MessageBoxA(0, Text, Caption, 0);
但奇怪的是几乎什么都没做就直接弹出失败信息
仔细分析发现原来在GetDlgItemTextA内有一处HOOK,在GetWindowTextA后直接跳转到了别的地方对注册码进行判断(程序启动时创建了一个线程对这里进行HOOK)
74F56B36 > 8BFF MOV EDI,EDI 74F56B38 55 PUSH EBP 74F56B39 8BEC MOV EBP,ESP 74F56B3B FF75 0C PUSH DWORD PTR SS:[EBP+C] 74F56B3E FF75 08 PUSH DWORD PTR SS:[EBP+8] 74F56B41 E8 7486FCFF CALL GetDlgItem 74F56B46 85C0 TEST EAX,EAX 74F56B48 74 0E JE SHORT 74F56B58 74F56B4A FF75 14 PUSH DWORD PTR SS:[EBP+14] 74F56B4D FF75 10 PUSH DWORD PTR SS:[EBP+10] 74F56B50 50 PUSH EAX 74F56B51 E8 D394FAFF CALL GetWindowTextA 74F56B56 - E9 B5AEBA8B JMP 穿甲葡萄.00B01A10 74F56B5B 007406 8B ADD BYTE PTR DS:[ESI+EAX-75],DH 74F56B5F 45 INC EBP 74F56B60 10C6 ADC DH,AL 74F56B62 0000 ADD BYTE PTR DS:[EAX],AL 74F56B64 33C0 XOR EAX,EAX 74F56B66 5D POP EBP 74F56B67 C2 1000 RETN 10
之后走到核心判断位置
bool __cdecl sub_401290(int a1, int a2) { byte_4147D0[0] = 4; byte_4147D0[1] = 1; byte_4147D0[2] = 3; byte_4147D0[3] = 7; byte_4147D0[4] = 2; byte_4147D0[5] = 5; byte_4147D0[6] = 8; byte_4147D0[7] = 6; byte_4147D0[8] = 0; return sub_4015B0(a1, a2); }
可以看到首先初始化了一个序列
04 01 03 07 02 05 08 06 00
然后经过一系列操作
bool __cdecl sub_4015B0(int a1, int a2) { int i; // [esp+0h] [ebp-Ch] int v4; // [esp+8h] [ebp-4h] v4 = -858993460; if ( a2 % 2 ) return 0; for ( i = 0; i < a2; i += 2 ) { if ( *(_BYTE *)(i + a1) == 119 ) v4 = 0; if ( *(_BYTE *)(i + a1) == 100 ) v4 = 1; if ( *(_BYTE *)(i + a1) == 115 ) v4 = 2; if ( *(_BYTE *)(i + a1) == 97 ) v4 = 3; if ( !sub_401380(v4, *(char *)(i + a1 + 1) - 48) ) return 0; } return byte_4147D0[0] == 1 && byte_4147D0[1] == 2 && byte_4147D0[2] == 3 && byte_4147D0[3] == 4 && byte_4147D0[4] == 5 && byte_4147D0[5] == 6 && byte_4147D0[6] == 7 && byte_4147D0[7] == 8 && !byte_4147D0[8]; }
使得序列变为
01 02 03 04 05 06 07 08 00
char __cdecl sub_401380(int a1, int a2) { char result; // al signed int i; // [esp+8h] [ebp-8h] signed int v4; // [esp+Ch] [ebp-4h] if ( !a2 ) return 0; v4 = 0; LABEL_4: if ( v4 >= 3 ) return 0; for ( i = 0; ; ++i ) { if ( i >= 3 ) { ++v4; goto LABEL_4; } if ( byte_4147D0[3 * v4 + i] == a2 ) break; LABEL_6: ; } switch ( a1 ) { case 0: if ( v4 ) { if ( byte_4147D0[3 * (v4 - 1) + i] ) { result = 0; } else { byte_4147D0[3 * (v4 - 1) + i] = byte_4147D0[3 * v4 + i]; byte_4147D0[3 * v4 + i] = 0; result = 1; } } else { result = 0; } break; case 1: if ( i == 2 ) { result = 0; } else if ( byte_4147D1[3 * v4 + i] ) { result = 0; } else { byte_4147D1[3 * v4 + i] = byte_4147D0[3 * v4 + i]; byte_4147D0[3 * v4 + i] = 0; result = 1; } break; case 2: if ( v4 == 2 ) { result = 0; } else if ( byte_4147D0[3 * (v4 + 1) + i] ) { result = 0; } else { byte_4147D0[3 * (v4 + 1) + i] = byte_4147D0[3 * v4 + i]; byte_4147D0[3 * v4 + i] = 0; result = 1; } break; case 3: if ( i ) { if ( byte_4147CF[3 * v4 + i] ) { result = 0; } else { byte_4147CF[3 * v4 + i] = byte_4147D0[3 * v4 + i]; byte_4147D0[3 * v4 + i] = 0; result = 1; } } else { result = 0; } break; default: goto LABEL_6; } return result; }
对上面的函数进行详细分析发现是用末尾的00对序列进行一系列的置换
注册码每两位分为一个单位,首位为操作码(w:与后三位的数置换 d:
与前一位的数置换 s:
与前三位的数置换 a:
与后一位的数置换),第二位是操作数
观察置换前后的序列不难发现其中的置换操作:
bool __cdecl sub_401290(int a1, int a2) { byte_4147D0[0] = 4; byte_4147D0[1] = 1; byte_4147D0[2] = 3; byte_4147D0[3] = 7; byte_4147D0[4] = 2; byte_4147D0[5] = 5; byte_4147D0[6] = 8; byte_4147D0[7] = 6; byte_4147D0[8] = 0; return sub_4015B0(a1, a2); }
可以看到首先初始化了一个序列
bool __cdecl sub_401290(int a1, int a2) { byte_4147D0[0] = 4; byte_4147D0[1] = 1; byte_4147D0[2] = 3; byte_4147D0[3] = 7; byte_4147D0[4] = 2; byte_4147D0[5] = 5; byte_4147D0[6] = 8; byte_4147D0[7] = 6; byte_4147D0[8] = 0; return sub_4015B0(a1, a2); }
可以看到首先初始化了一个序列
bool __cdecl sub_401290(int a1, int a2) { byte_4147D0[0] = 4; byte_4147D0[1] = 1; byte_4147D0[2] = 3; byte_4147D0[3] = 7; byte_4147D0[4] = 2; byte_4147D0[5] = 5; byte_4147D0[6] = 8; byte_4147D0[7] = 6; byte_4147D0[8] = 0; return sub_4015B0(a1, a2); }
可以看到首先初始化了一个序列
04 01 03 07 02 05 08 06 00
然后经过一系列操作
04 01 03 07 02 05 08 06 00
然后经过一系列操作
bool __cdecl sub_4015B0(int a1, int a2) { int i; // [esp+0h] [ebp-Ch] int v4; // [esp+8h] [ebp-4h] v4 = -858993460; if ( a2 % 2 ) return 0; for ( i = 0; i < a2; i += 2 ) { if ( *(_BYTE *)(i + a1) == 119 ) v4 = 0; if ( *(_BYTE *)(i + a1) == 100 ) v4 = 1; if ( *(_BYTE *)(i + a1) == 115 ) v4 = 2; if ( *(_BYTE *)(i + a1) == 97 ) v4 = 3; if ( !sub_401380(v4, *(char *)(i + a1 + 1) - 48) ) return 0; } return byte_4147D0[0] == 1 && byte_4147D0[1] == 2 && byte_4147D0[2] == 3 && byte_4147D0[3] == 4 && byte_4147D0[4] == 5 && byte_4147D0[5] == 6 && byte_4147D0[6] == 7 && byte_4147D0[7] == 8 && !byte_4147D0[8]; }
使得序列变为
bool __cdecl sub_4015B0(int a1, int a2) { int i; // [esp+0h] [ebp-Ch] int v4; // [esp+8h] [ebp-4h] v4 = -858993460; if ( a2 % 2 ) return 0; for ( i = 0; i < a2; i += 2 ) { if ( *(_BYTE *)(i + a1) == 119 ) v4 = 0; if ( *(_BYTE *)(i + a1) == 100 ) v4 = 1; if ( *(_BYTE *)(i + a1) == 115 ) v4 = 2; if ( *(_BYTE *)(i + a1) == 97 ) v4 = 3; if ( !sub_401380(v4, *(char *)(i + a1 + 1) - 48) ) return 0; } return byte_4147D0[0] == 1 && byte_4147D0[1] == 2 && byte_4147D0[2] == 3 && byte_4147D0[3] == 4 && byte_4147D0[4] == 5 && byte_4147D0[5] == 6 && byte_4147D0[6] == 7 && byte_4147D0[7] == 8 && !byte_4147D0[8]; }
使得序列变为
01 02 03 04 05 06 07 08 00
char __cdecl sub_401380(int a1, int a2) { char result; // al signed int i; // [esp+8h] [ebp-8h] signed int v4; // [esp+Ch] [ebp-4h] if ( !a2 ) return 0; v4 = 0; LABEL_4: if ( v4 >= 3 ) return 0; for ( i = 0; ; ++i ) { if ( i >= 3 ) { ++v4; goto LABEL_4; } if ( byte_4147D0[3 * v4 + i] == a2 ) break; LABEL_6: ; } switch ( a1 ) { case 0: if ( v4 ) { if ( byte_4147D0[3 * (v4 - 1) + i] ) { result = 0; } else { byte_4147D0[3 * (v4 - 1) + i] = byte_4147D0[3 * v4 + i]; byte_4147D0[3 * v4 + i] = 0; result = 1; } } else { result = 0; } break; case 1: if ( i == 2 ) { result = 0; } else if ( byte_4147D1[3 * v4 + i] ) { result = 0; } else { byte_4147D1[3 * v4 + i] = byte_4147D0[3 * v4 + i]; byte_4147D0[3 * v4 + i] = 0; result = 1; } break; case 2: if ( v4 == 2 ) { result = 0; } else if ( byte_4147D0[3 * (v4 + 1) + i] ) { result = 0; } else { byte_4147D0[3 * (v4 + 1) + i] = byte_4147D0[3 * v4 + i]; byte_4147D0[3 * v4 + i] = 0; result = 1; } break; case 3: if ( i ) { if ( byte_4147CF[3 * v4 + i] ) { result = 0; } else { byte_4147CF[3 * v4 + i] = byte_4147D0[3 * v4 + i]; byte_4147D0[3 * v4 + i] = 0; result = 1; } } else { result = 0; } break; default: goto LABEL_6; } return result; }
对上面的函数进行详细分析发现是用末尾的00对序列进行一系列的置换
注册码每两位分为一个单位,首位为操作码(w:与后三位的数置换 d:
与前一位的数置换 s:
与前三位的数置换 a:
与后一位的数置换),第二位是操作数
01 02 03 04 05 06 07 08 00
char __cdecl sub_401380(int a1, int a2) { char result; // al signed int i; // [esp+8h] [ebp-8h] signed int v4; // [esp+Ch] [ebp-4h] if ( !a2 ) return 0; v4 = 0; LABEL_4: if ( v4 >= 3 ) return 0; for ( i = 0; ; ++i ) { if ( i >= 3 ) { ++v4; goto LABEL_4; } if ( byte_4147D0[3 * v4 + i] == a2 ) break; LABEL_6: ; } switch ( a1 ) { case 0: if ( v4 ) { if ( byte_4147D0[3 * (v4 - 1) + i] ) { result = 0; } else { byte_4147D0[3 * (v4 - 1) + i] = byte_4147D0[3 * v4 + i]; byte_4147D0[3 * v4 + i] = 0; result = 1; } } else { result = 0; } break; case 1: if ( i == 2 ) { result = 0; } else if ( byte_4147D1[3 * v4 + i] ) { result = 0; } else { byte_4147D1[3 * v4 + i] = byte_4147D0[3 * v4 + i]; byte_4147D0[3 * v4 + i] = 0; result = 1; } break; case 2: if ( v4 == 2 ) { result = 0; } else if ( byte_4147D0[3 * (v4 + 1) + i] ) { result = 0; } else { byte_4147D0[3 * (v4 + 1) + i] = byte_4147D0[3 * v4 + i]; byte_4147D0[3 * v4 + i] = 0; result = 1; } break; case 3: if ( i ) { if ( byte_4147CF[3 * v4 + i] ) { result = 0; } else { byte_4147CF[3 * v4 + i] = byte_4147D0[3 * v4 + i]; byte_4147D0[3 * v4 + i] = 0; result = 1; } } else { result = 0; } break; default: goto LABEL_6; } return result; }
对上面的函数进行详细分析发现是用末尾的00对序列进行一系列的置换
注册码每两位分为一个单位,首位为操作码(w:与后三位的数置换 d:
与前一位的数置换 s:
与前三位的数置换 a:
与后一位的数置换),第二位是操作数
char __cdecl sub_401380(int a1, int a2) { char result; // al signed int i; // [esp+8h] [ebp-8h] signed int v4; // [esp+Ch] [ebp-4h] if ( !a2 ) return 0; v4 = 0; LABEL_4: if ( v4 >= 3 ) return 0; for ( i = 0; ; ++i ) { if ( i >= 3 ) { ++v4; goto LABEL_4; } if ( byte_4147D0[3 * v4 + i] == a2 ) break; LABEL_6: ; } switch ( a1 ) { case 0: if ( v4 ) { if ( byte_4147D0[3 * (v4 - 1) + i] ) { result = 0; } else { byte_4147D0[3 * (v4 - 1) + i] = byte_4147D0[3 * v4 + i]; byte_4147D0[3 * v4 + i] = 0; result = 1; } } else { result = 0; } break; case 1: if ( i == 2 ) { result = 0; } else if ( byte_4147D1[3 * v4 + i] ) { result = 0; } else { byte_4147D1[3 * v4 + i] = byte_4147D0[3 * v4 + i]; byte_4147D0[3 * v4 + i] = 0; result = 1; } break; case 2: if ( v4 == 2 ) { result = 0; } else if ( byte_4147D0[3 * (v4 + 1) + i] ) { result = 0; } else { byte_4147D0[3 * (v4 + 1) + i] = byte_4147D0[3 * v4 + i]; byte_4147D0[3 * v4 + i] = 0; result = 1; } break; case 3: if ( i ) { if ( byte_4147CF[3 * v4 + i] ) { result = 0; } else { byte_4147CF[3 * v4 + i] = byte_4147D0[3 * v4 + i]; byte_4147D0[3 * v4 + i] = 0; result = 1; } } else { result = 0; } break; default: goto LABEL_6; } return result; }
对上面的函数进行详细分析发现是用末尾的00对序列进行一系列的置换
注册码每两位分为一个单位,首位为操作码(w:与后三位的数置换 d:
与前一位的数置换 s:
与前三位的数置换 a:
与后一位的数置换),第二位是操作数
观察置换前后的序列不难发现其中的置换操作:
d6:与前一位的6置换
04 01 03 07 02 05 08 00 06
d8:与前一位的8置换
04 01 03 07 02 05 00 08 06
s7:与前三位的7置换
04 01 03 00 02 05 07 08 06
s4:与前三位的4置换
00 01 03 04 02 05 07 08 06
a1:与后一位的1置换
01 00 03 04 02 05 07 08 06
w2:与后三位的2置换
01 02 03 04 00 05 07 08 06
a5:与后一位的5置换
01 02 03 04 05 00 07 08 06
w6:与后三位的6置换
01 02 03 04 05 06 07 08 00
连起来得到注册码:d6d8s7s4a1w2a5w6
04 01 03 07 02 05 08 00 06
d8:与前一位的8置换
04 01 03 07 02 05 00 08 06
s7:与前三位的7置换
04 01 03 00 02 05 07 08 06
s4:与前三位的4置换
00 01 03 04 02 05 07 08 06
a1:与后一位的1置换
01 00 03 04 02 05 07 08 06
w2:与后三位的2置换
01 02 03 04 00 05 07 08 06
a5:与后一位的5置换
01 02 03 04 05 00 07 08 06
w6:与后三位的6置换
01 02 03 04 05 06 07 08 00
连起来得到注册码:d6d8s7s4a1w2a5w6
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
- [原创]第十题 侠义双雄 3848
- [原创]第六题 追凶者也 2915
- [原创]第五题 交响曲 2846
- [原创]第二题 半加器 2849
- [求助]读取Shadow SSDT中的函数蓝屏 6339
看原图
赞赏
雪币:
留言: