小菜鸟一枚 发表于 2020-2-23 09:43

一枚隐藏了中文字符串的简单CM!

本帖最后由 小菜鸟一枚 于 2020-2-23 12:47 编辑

之前有个常量初始化语句写错了,现在修改完毕!


还是vs2010编写的控制台程序,只是对中文进行了处理,OD不能直接搜索到!
代码还是都在一个cpp文件里,bug未知!



失败:程序会直接退出!
成功:输出解压密码,可以解压源码压缩包!
源码下载地址:https://www.lanzouj.com/i9lo0kj

不好意思,对不起大家,浪费了你们的时间,现在放出答案:by_52pojie
还是欢迎大家继续尝试分析!


PS:欢迎坛友们回帖分析交流,最好能贴出分析过程!{:1_893:}

iTruth 发表于 2020-2-23 11:29

用IDA稍微分析了下,给大佬一个参考.如果发现有什么地方分析的有问题请指出
int wmain()
{
FILE *v0; // eax
FILE *v1; // eax
char *v2; // eax
unsigned int username_lenth; // kr00_4
unsigned int password_lenth; // kr04_4
char *v5; // eax
unsigned int password_lenth_2; // kr08_4
unsigned int v34_lenth; // kr0C_4
char *v8; // esi
char *v9; // eax
clock_t v10; // ST34_4
char username; //
char password; //
char v14; //
char v15; //
int 破解程序累计用时_字符串; //
int v17; //
int v18; //
int v19; //
__int16 v20; //
int 输入用户名_字符串; //
int v22; //
int v23; //
__int16 v24; //
char v25; //
int 输入密码_字符串; //
int v27; //
int v28; //
char v29; //
int 破解密码_字符串; //
int v31; //
__int16 v32; //
char v33; //
char 数组_v34; //
char v35; //
char v36; //
int v37; //
int v38; //

输入用户名_字符串 = -456463417;
v22 = -1009521720;
v23 = -71063621;
v24 = -17757;
v25 = 0;
输入密码_字符串 = -456463417;
v27 = -591139896;
v28 = -1163662398;
v29 = 0;
v35 = -128;
v37 = 1869623861;
v38 = 6646122;
破解密码_字符串 = -1177427267;
v31 = -339551037;
v32 = -17757;
v33 = 0;
破解程序累计用时_字符串 = -490879290;
v17 = -221197133;
v18 = -960701504;
v19 = -1312111661;
v20 = -17757;
printf("%s\n", &输入用户名_字符串);
v0 = _iob_func();
fgets(&username, 21, v0);
printf("%s\n", &输入密码_字符串);
v1 = _iob_func();
fgets(&password, 21, v1);
if ( username )
{
    v2 = &username;
    do
    {
      *v2 = (*v2 - 28) & 0x52;
      ++v2;
    }
    while ( *v2 );                              // 将username的每一个字符都*username_chr=(*username_chr-28)&0x52;
}
username_lenth = strlen(&username);
if ( username_lenth < 0xC || username_lenth > 0x12 )// if(username_lenth<12 || username_lenth>18)
{
    ++password;                                 // password的第一个字节+1
    数组_v34 = 96;                              // v34='`'
}
else
{
    ++v14;
    数组_v34 = 98;                              // v34='b'
}
password_lenth = strlen(&password);
if ( password_lenth <= 0xC || (v36 = 95, password_lenth >= 0x12) )// if(password_lenth<= 12||(v36 = 95, password_lenth>=18))
    v36 = 93;
if ( !strcmp(&username, &password) )          // 如果username == password
{
    if ( 数组_v34 )                               // 如果v34不是空的,感觉这个if一定会成立
    {
      v5 = &数组_v34;
      do
      {
      *v5 = (*v5 - 28) & 0x52;
      ++v5;
      }
      while ( *v5 );                            // 将v34里的每一位都-28后&0x52
    }
}
else
{
    ++v15;                                    // 没用的语句?
    v35 = 127;                                  // v35 = backspace
}
if ( !strcmp(&username, &password) )
    ++v36;
else
    --v36;
password_lenth_2 = strlen(&password);
v34_lenth = strlen(&数组_v34);
if ( password_lenth_2 <= v34_lenth )          // 如果password_lenth_2 <= v34_lenth
{
    if ( password_lenth_2 < v34_lenth )
      exit(-1);                                 // 只有password_lenth_2 == v34_lenth才会继续执行
    if ( 数组_v34 )
    {
      v9 = &数组_v34;
      do
      {
      *v9 = (*v9 - 28) & 0x52;
      ++v9;
      }
      while ( *v9 );                            // 执行和上面一样的算法
    }
    printf("%s", &破解密码_字符串);
    printstr(&数组_v34);                        // 打印解密出来的字符串
}
else                                          // 否则直接打印解密出来的字符串
{
    printf("%s", &破解密码_字符串);
    if ( 数组_v34 )
    {
      v8 = &数组_v34;
      do
      printf("%c", *v8++);
      while ( *v8 );
    }
    printf("\n");
}
printf("%s", &破解程序累计用时_字符串);                  // 输入破解时间
v10 = clock();
printf("%.2f", (double)v10 / 1000.0);
printf("%c", 195);
printf("%c", 235);
printf("\n");
system("pause");
return 0;
}

玖公子 发表于 2020-2-23 10:41

moxiaowei 发表于 2020-2-23 10:28
破解的不完美

F9运行起来都搜索不到字符串,兄弟加油,希望我用IDA反编译的结果能帮到你! if ( Buf )
{
    v5 = &Buf;
    do
    {
      *v5 = (*v5 - 28) & 0x52;
      ++v5;
    }
    while ( *v5 );
}
v6 = strlen(&Buf);
if ( v6 < 0xC || v6 > 0x12 )         //不知道是啥,大于12,小于18
{
    ++v16;
    v37 = 96;
}
else
{
    ++v17;
    v37 = 98;
}
v7 = strlen(&v16);//系统自带的取长度函数
if ( v7 <= 0xC || (v39 = 95, v7 >= 0x12) )
    v39 = 93;
if ( !strcmp(&Buf, &v16) )
{
    if ( v37 )
    {
      v8 = &v37;
      do
      {
      *v8 = (*v8 - 28) & 0x52;
      ++v8;
      }
      while ( *v8 );
    }
}
else
{
    ++v18;
    v38 = 127;
}
if ( !strcmp(&Buf, &v16) )//系统自带的比较函数
    ++v39;
else
    --v39;
v9 = strlen(&v16);
v10 = strlen(&v37);
if ( v9 <= v10 )
{
    if ( v9 < v10 )
      exit(-1);
    if ( v37 )
    {
      v12 = &v37;
      do
      {
      *v12 = (*v12 - 28) & 0x52;
      ++v12;
      }
      while ( *v12 );
    }
    printf("%s", &v33);
    sub_401310();
}
else
{
    printf("%s", &v33);
    if ( v37 )
    {
      v11 = &v37;
      do
      printf("%c", *v11++);
      while ( *v11 );
    }
    printf("\n");
}
printf("%s", &v19);
v13 = clock();//这应该是计时函数
printf("%.2f", (double)v13 / 1000.0);
printf("%c", 195);
printf("%c", 235);
printf("\n");
system("pause");

moxiaowei 发表于 2020-2-23 10:28

破解的不完美

小菜鸟一枚 发表于 2020-2-23 10:30

moxiaowei 发表于 2020-2-23 10:28
破解的不完美

你好,你这个好像不对哦,打不开源码压缩包吧,加油,建议你再试试!:handshake

坑比 发表于 2020-2-23 11:21

我能说我随便输入猜到密码了吗{:301_1010:}

moxiaowei 发表于 2020-2-23 11:22

程序有BUG?
输入9位以上就不退出,显示错误的解压密码

小菜鸟一枚 发表于 2020-2-23 11:25

moxiaowei 发表于 2020-2-23 11:22
程序有BUG?
输入9位以上就不退出,显示错误的解压密码

所有的if你选择了一个错误的跳转,解出来的就不会是真正的解压密码。当然你也可以全部改掉:lol!

小菜鸟一枚 发表于 2020-2-23 11:27

坑比 发表于 2020-2-23 11:21
我能说我随便输入猜到密码了吗

我能说你是错的吗?这可不是一个nop就能出来的,好几个if语句呢,我自己爆破都没成功,你可以追码试试。

小菜鸟一枚 发表于 2020-2-23 12:11

@moxiaowei@iTruth 有个常量初始化语句写错了,我重新修改了下,你们再试试,不好意思啊!{:1_893:}
页: [1] 2
查看完整版本: 一枚隐藏了中文字符串的简单CM!