参考:
https://bbs.ichunqiu.com/thread-30717-1-1.html
ida通过字符串定位到该函数
静态分析第一部分
int sub_4042A8()
{
int v0; // esi
int name_len; // ebx
char *v2; // eax
int v3; // eax
unsigned int v4; // esi
int password_len; // ebx
char *v6; // eax
unsigned int v8; // [esp-14h] [ebp-1Ch]
void *v9; // [esp-10h] [ebp-18h]
int *v10; // [esp-Ch] [ebp-14h]
char *v11; // [esp+0h] [ebp-8h]
char *v12; // [esp+4h] [ebp-4h]
int savedregs; // [esp+8h] [ebp+0h]
v12 = 0;
v11 = 0;
v10 = &savedregs;
v9 = &loc_4043D5;
v8 = __readfsdword(0);
__writefsdword(0, (unsigned int)&v8);
sub_402DE8(&v12); //动调,没什么变化
v0 = GetWindowTextLengthA(hWnd); // 可通过输入长度不同并动调判断是哪个hwnd,动调结果为Name
name_len = v0;
if ( v0 > 0 )
{
do
{
sub_402ED8((int *)&v12, (int)dword_4043EC);// dword[3]数组固定,应该是做运算后赋值给&v12,动调发现值和Name长度有关,且大小为int
--name_len;
}
while ( name_len );
}
v2 = sub_402FA0(v12); // 动调前静态分析是v2 = v13地址,动调后发现是v2 = *(int*)&v12
GetWindowTextA(hWnd, v2, 50); // Name的输入放入了地址为v2的值的地方
总结一下就是根据Name的长度指定一块空间来存Name
静态分析第二部分
if ( v0 >= 5 )
{
sub_402F1C((int *)&v12, (int)"DiKeN", (int)v12);// 动调,发现在输入前加了DiKeN
v3 = sub_402ED0((int)v12); // 动调,发现是len('DiKeN')+len(Name)
v4 = CRC_check(&v12, v3); // CRC_check
sub_402DE8(&v11); // 同上
password_len = GetWindowTextLengthA(dword_40652C);
if ( password_len > 0 )
{
do
{
sub_402ED8((int *)&v11, (int)dword_4043EC);// 同上
--password_len;
}
while ( password_len );
}
v6 = sub_402FA0(v11); // 同上
GetWindowTextA(dword_40652C, v6, 32); // 同上
sub_402F1C((int *)&v11, (int)&dword_404408, (int)v11);// 动调,在前面加了个0
if ( sub_404224((int)v11) ^ v4 ) // sub_404224 str转int,异或为0,两者相等
MessageBoxA_0(dword_406504, "错误的注册码", "错误", 0);
else
MessageBoxA_0(dword_406504, "正确的注册码", "恭喜", 0);
str转int
unsigned calc_code(char *c,int len){
unsigned i,j=0;
for(i=0;c!='\0';i++){
j=j*10;
j=j+(int)c-0x30;
}
printf("%x,\n",j);
return j;
}
CRC_check原代码
unsigned CRC32(char *c,int len){
unsigned i,j;
unsigned crc_i=0xFFFFFFFF;
for(i=0;c!='\0';i++){
j=(crc_i&0xFF) ^ (int)c;
crc_i=(crc_i>>8)^crc32_table[j%256];
}
crc_i=crc_i^0xFFFFFFFF;
return crc_i;
}
题目中的CRC_check
int __usercall CRC_check@<eax>(_BYTE **a1@<eax>, int len@<edx>)
{
_BYTE *v2; // esi
unsigned int v3; // eax
v2 = *a1;
v3 = -1; // 0xFFFFFFFF
do
{
LOBYTE(v3) = *v2 ^ v3;
//注意到表的第一个元素是0对应有效数据为0,元素个数为256个刚好对应8bit有效数据的所有情况
v3 = *(_DWORD *)&word_403E1A[2 * (unsigned __int8)v3] ^ (v3 >> 8);
++v2;
--len;
}
while ( len );
return ~v3;
}
Name CRC_check(CRC32加密)的结果等于password经str转Int的值
解题脚本
import zlib
s = b'DiKeNq1uTruth'
print(zlib.crc32(s))
print(hex(zlib.crc32(s)))
#1894268809
#0x70e83f89
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/88364.html