ljlVink 发表于 2021-5-22 16:39

小白c++手写cm,无壳

tips:密码无数种,但只要一种就行



求过程 谢谢大佬们

iTruth 发表于 2021-5-22 19:55

代码分析完了,但解密出来的东西对不上。我也不清楚是哪里的问题,下面是我的分析还请大佬赐教!
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax
int result; // eax
int idx_u2; // eax
signed int pwd_map_copy_len; //
signed int other_table_len; //
signed int v8; //
int n; //
signed int m; //
int l; //
int k; //
signed int other_table_idx; //
int middle_output_to_cpy_idx; //
int final_index; //
signed int j; //
int i; //
int cpy_pwd_map_index; //

__main();
v3 = time(0);
srand(v3);
std::operator<<<std::char_traits<char>>((std::ostream::sentry *)&std::cout, "password:");
std::operator>><char,std::char_traits<char>>((std::istream::sentry *)&std::cin, enter_pwd);
if ( pwd_check_and_build_other_table() == -5 )// 第一次检查密码,并构建other_table
{
    std::operator<<<std::char_traits<char>>((std::ostream::sentry *)&std::cout, "err\n");
    getchar();
    getchar();
    result = 0;
}
else
{
    cpy_pwd_map_index = 0;
    for ( i = 0; i <= 25; ++i )               // 拷贝密码表,已dump
                                                // 8311 7999 9691 1511 5701 1710 8323 3328 9111 1173 9118 1013 2991 1497 9910 7101 1003 2116 1041 0132 1129 7115 1151 1911 1114 1000
    {
      v8 = strlen(&pwd_map);
      for ( j = 0; j < v8; ++j )
      {
      idx_u2 = cpy_pwd_map_index++;
      pwd_map_copy = pwd_map;
      }
    }
    other_table_len = strlen(other_table);
    pwd_map_copy_len = strlen(pwd_map_copy);
    final_index = 0;
    middle_output_to_cpy_idx = 0;
    for ( other_table_idx = 0; other_table_idx < other_table_len; ++other_table_idx )// 遍历other_table
    {
      if ( other_table == 50 ) // 针对other_table每一个字符'2'
      {
      for ( k = final_index; final_index + 2 > k; ++k )// 遍历final_index~final_index+2,取两位pwd_map_copy
      {
          if ( k == final_index )               // 第一次进入这个for循环
            middle_output_to_cpy += 10 * (pwd_map_copy - 48);
          if ( final_index + 1 == k )         // 第二次进入这个for循环
            middle_output_to_cpy += pwd_map_copy - 48;
      }
      ++middle_output_to_cpy_idx;
      final_index += 2;
      }
      if ( other_table == 51 ) // 针对other_table每一个字符'3'
      {
      for ( l = final_index; final_index + 3 > l; ++l )// 遍历final_index~final_index+3,取三位pwd_map_copy
      {
          if ( l == final_index )               // 第一次进入这个for循环
            middle_output_to_cpy = 100 * (pwd_map_copy - 48);
          if ( final_index + 1 == l )         // 第二次进入这个for循环
            middle_output_to_cpy += 10 * (pwd_map_copy - 48);
          if ( final_index + 2 == l )         // 第三次进入这个for循环
            middle_output_to_cpy += pwd_map_copy - 48;
      }
      ++middle_output_to_cpy_idx;
      final_index += 3;
      }
    }
    for ( m = 0; m < pwd_map_copy_len; ++m )    // 下面就是将middle_output_to_cpy拷贝至final_output里输出
      final_output = middle_output_to_cpy;
    for ( n = 0; n <= 39; ++n )
      std::operator<<<std::char_traits<char>>((std::ostream::sentry *)&std::cout, final_output);
    std::ostream::operator<<(std::endl<char,std::char_traits<char>>);
    result = 0;
}
return result;
}
// 返回0正确,返回-5错误
int pwd_check_and_build_other_table(void)
{
int v1; // eax
int v2; // eax
int v3; // eax
char enter_pwd_idx_i; //
int j; //
int i; //
int other_table_construct_index; //

other_table_construct_index = 0;
if ( strlen(enter_pwd) != 41 )
    return -5;
for ( i = 0; i <= 96; ++i )                   // 根据enter_pwd填写other_table
{
    enter_pwd_idx_i = enter_pwd;
    if ( enter_pwd_idx_i == 94
      || enter_pwd_idx_i == 106
      || enter_pwd_idx_i == 108
      || enter_pwd_idx_i == 102
      || enter_pwd_idx_i == 110
      || enter_pwd_idx_i == 120
      || enter_pwd_idx_i == 35
      || enter_pwd_idx_i == 33
      || enter_pwd_idx_i == 37
      || enter_pwd_idx_i == 99
      || enter_pwd_idx_i == 52
      || enter_pwd_idx_i == 57
      || enter_pwd_idx_i == 103
      || enter_pwd_idx_i == 111
      || enter_pwd_idx_i == 115 )
    {
      enter_pwd = 0;
      v1 = other_table_construct_index++;
      other_table = 50;
    }
    if ( enter_pwd_idx_i == 50
      || enter_pwd_idx_i == 55
      || enter_pwd_idx_i == 97
      || enter_pwd_idx_i == 98
      || enter_pwd_idx_i == 112
      || enter_pwd_idx_i == 119
      || enter_pwd_idx_i == 113
      || enter_pwd_idx_i == 117
      || enter_pwd_idx_i == 122
      || enter_pwd_idx_i == 118
      || enter_pwd_idx_i == 104
      || enter_pwd_idx_i == 41
      || enter_pwd_idx_i == 64
      || enter_pwd_idx_i == 36
      || enter_pwd_idx_i == 47 )
    {
      enter_pwd = 0;
      v2 = other_table_construct_index++;
      other_table = 51;
    }
}
for ( j = 0; j <= 96; ++j )                   // 遍历寻找空格,找到了返回-5
{
    if ( enter_pwd == 48 )
    {
      std::ostream::operator<<(0);
      return -5;
    }
}
if ( unknown_check_with_other_table(114514) == -514049345 )// 这里应该为真,关键点1
    return 0;
v3 = unknown_check_with_other_table(114514);
std::ostream::operator<<(v3);
std::ostream::operator<<(std::endl<char,std::char_traits<char>>);
return -5;
}

int __cdecl unknown_check_with_other_table(int arg_114514)
{
signed int other_table_len_1; //
signed int i; //
int return_value; //

return_value = 0;
other_table_len_1 = strlen(other_table);
for ( i = 0; i < other_table_len_1; ++i )
    return_value = (arg_114514 * return_value + other_table) % 1000000007;
return return_value;
}

ljlVink 发表于 2021-5-24 12:57

#include<bits/stdc++.h>
using namespace std;
int asfdvgare;
const int DF98D=1e9+7;
char S98HBFG;
char DFHSV5Y;
charRTGDFTHR;
char R0fjd={"8311","7999","9691","1511","5701","1710","8323","3328","9111","1173","9118","1013","2991","1497","9910","7101","1003","2116","1041","0132","1129","7115","1151","1911","1114","100"};
char I89fhga;
int Hsdfgsd23=282829919;
int Yksgbas235(int sed) {
        int res=0;
        int len=strlen(I89fhga);;
        for(int i=0;i<len;++i){
                res=(long long)(res*sed+I89fhga)%DF98D;
        }
        return res;
}
int rdfhfd5546(){
        int cs1=0;
        int lenpsw=strlen(S98HBFG);
        if(lenpsw!=41){
                return -5;
        }
        for(int i=0;i<97;i++){
                char pd=S98HBFG;
                if(pd=='^'||pd=='j'||pd=='l'||pd=='f'||pd=='n'||pd=='x'||pd=='#'||pd=='!'||pd=='%'||pd=='c'||pd=='4'||pd=='9'||pd=='g'||pd=='o'||pd=='s'){
                        S98HBFG=0;
                        I89fhga='2';
                }
                if(pd=='2'||pd=='7'||pd=='a'||pd=='b'||pd=='p'||pd=='w'||pd=='q'||pd=='u'||pd=='z'||pd=='v'||pd=='h'||pd==')'||pd=='@'||pd=='$'||pd=='/'){
                        S98HBFG=0;
                        I89fhga='3';
                }
        }
        for(int i=0;i<97;i++){
                if(S98HBFG=='0'){
            cout<<0;
                        return -5;
                }
        }/*
        if(Yksgbas235(114514)!=-514049345){
      cout<<Yksgbas235(114514)<<endl;;
                return -5;
        }*///hash写挂了,自行编译吧,不好意思
        return 0;
}
int main(int argc,char* argv[]){
        srand(time(0));
    cout<<"password:";
    cin>>S98HBFG;
    if(rdfhfd5546()==-5){
      cout<<"err\n";
      getchar();
      getchar();
      return 0;
    }
       
        int pin=0;
        for(int i=0;i<26;i++){
                int llen=strlen(R0fjd);
                for(int j=0;j<llen;j++){
                        RTGDFTHR=R0fjd;
                }
        }
        int U89ywht=strlen(I89fhga);
        int len=strlen(RTGDFTHR);
        int OOihdd34=0;
        int cnt1=0;
        for(int i=0;i<U89ywht;i++){
                if(I89fhga=='2'){
                        for(int j=OOihdd34;j<OOihdd34+2;j++){
                                if(j==OOihdd34){
                                        asfdvgare+=(RTGDFTHR-'0')*10;
                                }
                                if(j==OOihdd34+1){
                                        asfdvgare+=RTGDFTHR-'0';
                                }
                        }
                        cnt1++;
                        OOihdd34+=2;
                }
                if(I89fhga=='3'){
                        for(int j=OOihdd34;j<OOihdd34+3;j++){
                                if(j==OOihdd34){
                                        asfdvgare=(RTGDFTHR-'0')*100;
                                }
                                if(j==OOihdd34+1){
                                        asfdvgare+=(RTGDFTHR-'0')*10;
                                }
                                if(j==OOihdd34+2){
                                        asfdvgare+=RTGDFTHR-'0';
                                }
                        }
                        cnt1++;
                        OOihdd34+=3;
                }
        }
        for(int i=0;i<len;i++){
                DFHSV5Y=char(asfdvgare);
        }
        for(int i=0;i<40;i++){
                cout<<DFHSV5Y;
        }
        cout<<endl;
    return 0;
}

ljlVink 发表于 2021-5-22 16:40

暴力的话,还是得暴力挺长一段时间的

fnv1c 发表于 2021-5-22 21:42

本帖最后由 fnv1c 于 2021-5-22 21:44 编辑

iTruth 发表于 2021-5-22 19:55
代码分析完了,但解密出来的东西对不上。我也不清楚是哪里的问题,下面是我的分析还请大佬赐教!

主要这问题很可能不可解,或者说没有一个比暴力更优秀的解法

fnv1c 发表于 2021-5-22 21:46

z3跑了一分多钟跑不出来结果,感觉不是算法逆向题,是一个简单的密码学题...

iTruth 发表于 2021-5-22 22:03

fnv1c 发表于 2021-5-22 21:46
z3跑了一分多钟跑不出来结果,感觉不是算法逆向题,是一个简单的密码学题...

你说的对,密码的后三位似乎是无解的。至少我不知道怎么解

fnv1c 发表于 2021-5-22 22:04

one possible version

{:301_982:}

iTruth 发表于 2021-5-22 22:05

fnv1c 发表于 2021-5-22 21:46
z3跑了一分多钟跑不出来结果,感觉不是算法逆向题,是一个简单的密码学题...

前38位已经被破译了,后面三位就像是偏移一般,最终运算结果要等于-514049345。我的数学太差了不知道怎么解。。

fnv1c 发表于 2021-5-22 22:05

iTruth 发表于 2021-5-22 22:03
你说的对,密码的后三位似乎是无解的。至少我不知道怎么解

可以直接根据密文和明文对应关系分析的,他那个114514 hash不可解。

fnv1c 发表于 2021-5-22 22:06

iTruth 发表于 2021-5-22 22:05
前38位已经被破译了,后面三位就像是偏移一般,最终运算结果要等于-514049345。我的数学太差了不知道怎么 ...

如果是三位,随便找个解方程工具就能解了。或者人工枚举
页: [1] 2 3 4
查看完整版本: 小白c++手写cm,无壳