加了一些混淆代码,但是从成功信息部分反推就能剔除“花代码”了。
void __noreturn checker(void)
{
if ( ++g_flag_ZERO == 1 && !g_flag2_ZERO ) // 两个值必须都等于 0
{
gTable2[1] = getNum(1);
if ( (unsigned int)getNum(3) == 16 && gTable2[1] == '`' )
{
printf("[i] You are ");
Num = getNum(5); // 'w'
printf("%c", Num);
v7 = getNum(6); // 'i'
printf("%c", v7);
v8 = getNum(7); // 'n'
printf("%c", v8);
v9 = getNum(7); // 'n'
printf("%c", v9);
printf("er\n");
g_flag_ZERO = 1001;
}
}
反推回去:
__int64 __fastcall handler(char *name, char *passwd)
{
i = 0i64;
while ( 1 )
{
// 对用户名进行变形
v5 = name[i];
if ( (unsigned __int8)(name[i] - 0x61) <= 0xFu )
v6 = gTable1[v5 - 0x60];
else
v6 = gTable1[v5 % 16];
v7 = i + v6;
if ( (i & 1) != 0 )
v7 = gTable2[v7 % 16];
else
LOBYTE(v7) = gTable1[v7 % 16];
v8 = v7 - 0x7C - gTable1[0];
final_key = v8 - 0x16;
if ( ((v8 - 0x57) & 0xDFu) > 0x19 )
final_key = gTable1[final_key % 16]; // 有用的代码到这里就结束了
// final_key 为对应位置的序列号字符
printf(&byte_140013044, (unsigned int)final_key);
// ... 省略一部分 ...
if ( passwd[i] != final_key ) // 必须相等,不成立
break;
if ( ++i == 16 ) // 循环结束,开始检测
{
// 省略部分代码
checker();
}
}
}
算法注册机:
#include <cstdint>
#include <cstring>
#include <iostream>
#include <string>
uint8_t gTable1[] = {0x78, 0x6D, 0x6E, 0x75, 0x6C, 0x4F, 0x6F, 0x30, 0x5A, 0x7A, 0x69, 0x6A, 0x4E, 0x55, 0x58, 0x4D};
uint32_t gTable2[] = {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f};
std::string generate_key(const char *name)
{
std::string result{};
if (strlen(name) != 16)
{
return "err: strlen(name) is not 16";
}
for (int i = 0; i < 16; i++)
{
uint8_t c = name[i];
if ('a' <= c && c <= 'f') {
c -= 'a' - 1;
} else {
c &= 15;
}
c = gTable1[c] + i;
c = (i & 1) ? gTable2[c % 16] : gTable1[c % 16];
c = c - 0x7C - gTable1[0];
char s = static_cast<char>(c) - 0x16;
if (((c - 0x57) & 0xDF) > 0x19) {
s = gTable1[s % 16];
}
result += s;
}
return result;
}
int main()
{
char name[17] = "0123456789abcdef";
auto serial = generate_key(name);
std::cout << serial << std::endl;
return 0;
}
用算出来的序列号输入进去:
[#] Crack me for C language. 52pojie--zunmx
[i] Press your auth name [16 words]:0123456789abcdef
[i] Press your auth key [16 words]:PdnXnZEUdYoMcMKd
[i] You are winner```