本帖最后由 梦游枪手 于 2019-10-5 12:47 编辑
IDA载入,一进来就是main函数
[C] 纯文本查看 复制代码 signed int wmain()
{
void *username; // [esp+Ch] [ebp-8h]
void *password; // [esp+10h] [ebp-4h]
username = malloc(0x64u);
password = malloc(0x64u);
printf("请输入用户名:", username);
scanf("%s", username);
sub_401140();
printf("请输入登录密码:", password);
scanf("%s", password);
sub_401140();
if ( check((const char **)&username, (const char **)&password) )// check返回1则成功
MessageBoxW(0, L"恭喜你,快使用密码打开我的压缩包查看源码吧!", L"玖公子", 0);
else
MessageBoxW(0, L"你是密码错了还是改了本公子的程序???", L"玖公子", 0);
system("pause");
return 1;
}
查看check函数
[C] 纯文本查看 复制代码 signed int __cdecl check(const char **username, const char **password)
{
char *v2; // edx
const char *v3; // edi
_BYTE *v4; // ecx
const char *v5; // esi
int v6; // ebx
unsigned int v7; // eax
signed int result; // eax
void *passwordbak; // [esp+10h] [ebp-8h]
const char *v10; // [esp+14h] [ebp-4h]
v2 = (char *)malloc(0x64u);
v3 = *password;
passwordbak = v2;
v10 = *password;
if ( &(*password)[strlen(*password) + 1] != *password + 1 )// 复制password,可以不管
{
v4 = v2 + 1;
v5 = *password;
v6 = -1 - (_DWORD)v2;
do
{
*(v4 - 1) = *v5;
*v4 = 0;
++v5;
++v4;
v7 = strlen(v3);
v3 = v10;
}
while ( (unsigned int)&v4[v6] < v7 );
}
*username;
if ( strlen(*username) < 6 || (*username, strlen(*username) > 0x10) )// username长度应为6位到16位
{
if ( !strcmp(*username, v3) )
printf("com");
else
printf("om");
MessageBoxW(0, L"成功了,压缩包密码看命令行窗口!", L"玖公子", 0);
printf(".52p");
result = 0;
}
else
{
printf("go");
*password;
if ( strlen(*password) == 16 )
{
printf("ng");
encrypt(username); // 加密username
if ( !strcmp((const char *)passwordbak, *password) )// 比较备份的password和原本的password是否一致
{
printf("ebx");
str_cmp(password, username); // 此时username为真密码
free(passwordbak);
result = 1; // 返回1,说明是正确流程
}
else
{
printf("eax");
sub_401460(password, username);
result = 0;
}
}
else
{
if ( !strcmp(*username, *password) )
printf("com");
else
printf("om");
MessageBoxW(0, L"成功了,压缩包密码看命令行窗口!", L"玖公子", 0);
printf("ojie");
result = 0;
}
}
return result;
}
可以在str_cmp处看到真密码,破解到这里就结束了。算法方面,encrypt函数将username补齐16位后再将奇数位字符减1,偶数位字符加1。补齐的代码如下。
[C] 纯文本查看 复制代码 for(int i = 0; i<16; i++)
{
if( i>= strlen(username))
{
username[i]='H'+i;
username[i+1]='\0';
}
}
附图
|