玖公子 发表于 2019-10-5 09:58

非常简单的CM程序,欢迎分析

新手们,快来尝试这个简单的程序,给自己的学习增加一份自信吧!
程序介绍:
使用C语言编写的VS2010控制台程序,三无程序,可搜索字符串!
输入用户名,对用户名进行加减运算,然后和用户输入的密码做比较,成功则会输出正确压缩包密码,如下图


破解成功后,控制台上的那一串就是源码压缩包密码!
欢迎大家留下破解思路,如果能留下算法分析过程就更好了,谢谢!

PS:不要嫌弃我水平低,只会加减乘除,字符串不知道怎么藏,只好做了几个一样的干扰字符串!
程序和源码链接地址:https://www.lanzouj.com/b00n4kgod 密码:8str
因楼主初学C语言,水平有限,程序BUG较多,自行摸索哈!{:301_978:}

梦游枪手 发表于 2019-10-5 12:46

本帖最后由 梦游枪手 于 2019-10-5 12:47 编辑

IDA载入,一进来就是main函数
signed int wmain()
{
void *username; //
void *password; //

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函数
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; //
const char *v10; //

v2 = (char *)malloc(0x64u);
v3 = *password;
passwordbak = v2;
v10 = *password;
if ( &(*password) != *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 < 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。补齐的代码如下。
for(int i = 0; i<16; i++)
{
      if( i>= strlen(username))
      {
                username='H'+i;
                username='\0';
      }
}
附图

hezimu 发表于 2019-10-5 10:10

你变了   !

玖公子 发表于 2019-10-5 10:15

hezimu 发表于 2019-10-5 10:10
你变了   !

四个干扰字符串,四个MessageBox就找出来那哪个是真的,不行你单步都能找到答案。
就是一个个找会花点时间,应该不难!

iflower 发表于 2019-10-5 10:17

秀,你变的那么窈窕了

夏南离 发表于 2019-10-5 10:18

玖公子 发表于 2019-10-5 10:19

xiaosay 发表于 2019-10-5 10:17
秀,你变的那么窈窕了

呃,什么鬼?没听明白

玖公子 发表于 2019-10-5 10:19

夏南离 发表于 2019-10-5 10:18
tui,我还以为貼的是我帖子的链接
来了,就顺便瞧一瞧嘛{:301_997:}

iflower 发表于 2019-10-5 10:26

玖公子 发表于 2019-10-5 10:19
呃,什么鬼?没听明白

网络名词,找度娘问问,估计度娘会喜欢上你的

yuehanoo 发表于 2019-10-5 10:37

谢谢分享,支持支持。

旻娢 发表于 2019-10-5 11:12

我还以为是水区{:301_995:}
页: [1] 2
查看完整版本: 非常简单的CM程序,欢迎分析