一个简单的逆向qwq
叫你输入key,给出提示信息
--
无壳
C++编写
老规矩:拖IDA
搜索fail找到了main函数
这个main流程有点复杂qwq
我们看看它的伪代码:
全代码:
1 _DWORD *__fastcall sub_401D90(_DWORD *a1, _DWORD *a2) 2 { 3 _DWORD *v2; // esi 4 _DWORD *v3; // ebx 5 int v4; // eax 6 signed int v5; // edi 7 int v6; // ecx 8 int v7; // eax 9 void (__thiscall ***v8)(_DWORD, signed int); // eax 10 bool v9; // cf 11 _BYTE *v10; // eax 12 int v11; // ecx 13 int v12; // eax 14 unsigned int v13; // edi 15 int i; // eax 16 char v15; // dl 17 unsigned int v16; // edi 18 _DWORD *v17; // eax 19 _DWORD *v18; // eax 20 int v19; // eax 21 bool v20; // zf 22 int v21; // eax 23 int v22; // ecx 24 int v24; // [esp+0h] [ebp-4Ch] 25 int v25; // [esp+4h] [ebp-48h] 26 int v26; // [esp+8h] [ebp-44h] 27 int v27; // [esp+Ch] [ebp-40h] 28 char v28; // [esp+10h] [ebp-3Ch] 29 int v29; // [esp+14h] [ebp-38h] 30 _DWORD *v30; // [esp+18h] [ebp-34h] 31 char v31; // [esp+1Ch] [ebp-30h] 32 int v32; // [esp+20h] [ebp-2Ch] 33 int v33; // [esp+24h] [ebp-28h] 34 _DWORD *v34; // [esp+28h] [ebp-24h] 35 int v35; // [esp+2Ch] [ebp-20h] 36 int v36; // [esp+30h] [ebp-1Ch] 37 int v37; // [esp+34h] [ebp-18h] 38 int v38; // [esp+38h] [ebp-14h] 39 int *v39; // [esp+3Ch] [ebp-10h] 40 int v40; // [esp+40h] [ebp-Ch] 41 int v41; // [esp+44h] [ebp-8h] 42 int v42; // [esp+48h] [ebp-4h] 43 44 v39 = &v24; 45 v2 = a2; 46 v3 = a1; 47 v34 = a1; 48 v4 = *a1; 49 v5 = 0; 50 v32 = 0; 51 HIBYTE(v38) = 0; 52 v30 = a1; 53 v6 = *(_DWORD *)((char *)a1 + *(_DWORD *)(v4 + 4) + 56); 54 if ( v6 ) 55 (*(void (**)(void))(*(_DWORD *)v6 + 4))(); 56 v42 = 0; 57 v31 = std::basic_istream<char,std::char_traits<char>>::_Ipfx(v3, 0); 58 v42 = 1; 59 if ( v31 ) 60 { 61 v7 = std::ios_base::getloc((char *)v3 + *(_DWORD *)(*v3 + 4), &v28); 62 LOBYTE(v42) = 2; 63 v33 = sub_401940(v7); 64 LOBYTE(v42) = 3; 65 if ( v29 ) 66 { 67 v8 = (void (__thiscall ***)(_DWORD, signed int))(*(int (**)(void))(*(_DWORD *)v29 + 8))(); 68 if ( v8 ) 69 (**v8)(v8, 1); 70 } 71 v9 = v2[5] < 0x10u; 72 v2[4] = 0; 73 if ( v9 ) 74 v10 = v2; 75 else 76 v10 = (_BYTE *)*v2; 77 *v10 = 0; 78 LOBYTE(v42) = 4; 79 v11 = *(_DWORD *)(*v3 + 4); 80 v12 = *(_DWORD *)((char *)v3 + v11 + 36); 81 v13 = *(_DWORD *)((char *)v3 + v11 + 32); 82 v37 = *(_DWORD *)((char *)v3 + v11 + 32); 83 if ( v12 >= 0 && (v12 > 0 || v13) && (v36 = v12, v13 < 0xFFFFFFFE) ) 84 { 85 v36 = v12; 86 } 87 else 88 { 89 v13 = -2; 90 v37 = -2; 91 } 92 for ( i = std::basic_streambuf<char,std::char_traits<char>>::sgetc(*(_DWORD *)((char *)v3 + v11 + 56)); 93 ; 94 i = std::basic_streambuf<char,std::char_traits<char>>::snextc(*(_DWORD *)((char *)v3 95 + *(_DWORD *)(v19 + 4) 96 + 56)) ) 97 { 98 v15 = i; 99 v36 = i; 100 if ( !v13 ) 101 break; 102 if ( i == -1 ) 103 { 104 v5 = 1; 105 goto LABEL_38; 106 } 107 if ( *(_BYTE *)(*(_DWORD *)(v33 + 12) + 2 * (unsigned __int8)i) & 0x48 ) 108 break; 109 if ( (unsigned int)~v2[4] <= 1 ) 110 sub_401780(); 111 v16 = v2[4] + 1; 112 if ( v2[4] == -1 ) 113 { 114 v9 = v2[5] < 0x10u; 115 v2[4] = 0; 116 if ( v9 ) 117 *(_BYTE *)v2 = 0; 118 else 119 *(_BYTE *)*v2 = 0; 120 } 121 else 122 { 123 if ( v2[5] < v16 ) 124 { 125 sub_401790(v2, v16); 126 v15 = v36; 127 } 128 if ( v2[5] < 0x10u ) 129 v17 = v2; 130 else 131 v17 = (_DWORD *)*v2; 132 *((_BYTE *)v17 + v2[4]) = v15; 133 v9 = v2[5] < 0x10u; 134 v2[4] = v16; 135 if ( v9 ) 136 v18 = v2; 137 else 138 v18 = (_DWORD *)*v2; 139 *((_BYTE *)v18 + v16) = 0; 140 } 141 v19 = *v3; 142 v13 = v37 - 1; 143 HIBYTE(v38) = 1; 144 --v37; 145 } 146 v5 = 0; 147 LABEL_38: 148 v42 = 1; 149 } 150 v20 = HIBYTE(v38) == 0; 151 v21 = *(_DWORD *)(*v3 + 4); 152 *(_DWORD *)((char *)v3 + v21 + 32) = 0; 153 *(_DWORD *)((char *)v3 + v21 + 36) = 0; 154 if ( v20 ) 155 v5 |= 2u; 156 std::basic_ios<char,std::char_traits<char>>::setstate( 157 (char *)v3 + *(_DWORD *)(*v3 + 4), 158 v5, 159 0, 160 v24, 161 v25, 162 v26, 163 v27, 164 *(_DWORD *)&v28, 165 v29, 166 v30, 167 *(_DWORD *)&v31, 168 v32, 169 v33, 170 v34, 171 v35, 172 v36, 173 v37, 174 v38, 175 v39, 176 v40, 177 v41, 178 v42); 179 v42 = 6; 180 v22 = *(_DWORD *)((char *)v30 + *(_DWORD *)(*v30 + 4) + 56); 181 if ( v22 ) 182 (*(void (**)(void))(*(_DWORD *)v22 + 8))(); 183 return v3; 184 }
简单分析一下可以看出:
sub_401D90这个函数是获取输入的(疑似有处理)
sub_401300是处理输入的
sub_401120也有点关系
后面有简单的处理与验证(暂时不管qwq)
先看看sub_401D90:
_DWORD *__fastcall sub_401D90(_DWORD *a1, _DWORD *a2) { _DWORD *v2; // esi _DWORD *v3; // ebx int v4; // eax signed int v5; // edi int v6; // ecx int v7; // eax void (__thiscall ***v8)(_DWORD, signed int); // eax bool v9; // cf _BYTE *v10; // eax int v11; // ecx int v12; // eax unsigned int v13; // edi int i; // eax char v15; // dl unsigned int v16; // edi _DWORD *v17; // eax _DWORD *v18; // eax int v19; // eax bool v20; // zf int v21; // eax int v22; // ecx int v24; // [esp+0h] [ebp-4Ch] int v25; // [esp+4h] [ebp-48h] int v26; // [esp+8h] [ebp-44h] int v27; // [esp+Ch] [ebp-40h] char v28; // [esp+10h] [ebp-3Ch] int v29; // [esp+14h] [ebp-38h] _DWORD *v30; // [esp+18h] [ebp-34h] char v31; // [esp+1Ch] [ebp-30h] int v32; // [esp+20h] [ebp-2Ch] int v33; // [esp+24h] [ebp-28h] _DWORD *v34; // [esp+28h] [ebp-24h] int v35; // [esp+2Ch] [ebp-20h] int v36; // [esp+30h] [ebp-1Ch] int v37; // [esp+34h] [ebp-18h] int v38; // [esp+38h] [ebp-14h] int *v39; // [esp+3Ch] [ebp-10h] int v40; // [esp+40h] [ebp-Ch] int v41; // [esp+44h] [ebp-8h] int v42; // [esp+48h] [ebp-4h] v39 = &v24; v2 = a2; v3 = a1; v34 = a1; v4 = *a1; v5 = 0; v32 = 0; HIBYTE(v38) = 0; v30 = a1; v6 = *(_DWORD *)((char *)a1 + *(_DWORD *)(v4 + 4) + 56); if ( v6 ) (*(void (**)(void))(*(_DWORD *)v6 + 4))(); v42 = 0; v31 = std::basic_istream<char,std::char_traits<char>>::_Ipfx(v3, 0); v42 = 1; if ( v31 ) { v7 = std::ios_base::getloc((char *)v3 + *(_DWORD *)(*v3 + 4), &v28); LOBYTE(v42) = 2; v33 = sub_401940(v7); LOBYTE(v42) = 3; if ( v29 ) { v8 = (void (__thiscall ***)(_DWORD, signed int))(*(int (**)(void))(*(_DWORD *)v29 + 8))(); if ( v8 ) (**v8)(v8, 1); } v9 = v2[5] < 0x10u; v2[4] = 0; if ( v9 ) v10 = v2; else v10 = (_BYTE *)*v2; *v10 = 0; LOBYTE(v42) = 4; v11 = *(_DWORD *)(*v3 + 4); v12 = *(_DWORD *)((char *)v3 + v11 + 36); v13 = *(_DWORD *)((char *)v3 + v11 + 32); v37 = *(_DWORD *)((char *)v3 + v11 + 32); if ( v12 >= 0 && (v12 > 0 || v13) && (v36 = v12, v13 < 0xFFFFFFFE) ) { v36 = v12; } else { v13 = -2; v37 = -2; } for ( i = std::basic_streambuf<char,std::char_traits<char>>::sgetc(*(_DWORD *)((char *)v3 + v11 + 56)); ; i = std::basic_streambuf<char,std::char_traits<char>>::snextc(*(_DWORD *)((char *)v3 + *(_DWORD *)(v19 + 4) + 56)) ) { v15 = i; v36 = i; if ( !v13 ) break; if ( i == -1 ) { v5 = 1; goto LABEL_38; } if ( *(_BYTE *)(*(_DWORD *)(v33 + 12) + 2 * (unsigned __int8)i) & 0x48 ) break; if ( (unsigned int)~v2[4] <= 1 ) sub_401780(); v16 = v2[4] + 1; if ( v2[4] == -1 ) { v9 = v2[5] < 0x10u; v2[4] = 0; if ( v9 ) *(_BYTE *)v2 = 0; else *(_BYTE *)*v2 = 0; } else { if ( v2[5] < v16 ) { sub_401790(v2, v16); v15 = v36; } if ( v2[5] < 0x10u ) v17 = v2; else v17 = (_DWORD *)*v2; *((_BYTE *)v17 + v2[4]) = v15; v9 = v2[5] < 0x10u; v2[4] = v16; if ( v9 ) v18 = v2; else v18 = (_DWORD *)*v2; *((_BYTE *)v18 + v16) = 0; } v19 = *v3; v13 = v37 - 1; HIBYTE(v38) = 1; --v37; } v5 = 0; LABEL_38: v42 = 1; } v20 = HIBYTE(v38) == 0; v21 = *(_DWORD *)(*v3 + 4); *(_DWORD *)((char *)v3 + v21 + 32) = 0; *(_DWORD *)((char *)v3 + v21 + 36) = 0; if ( v20 ) v5 |= 2u; std::basic_ios<char,std::char_traits<char>>::setstate( (char *)v3 + *(_DWORD *)(*v3 + 4), v5, 0, v24, v25, v26, v27, *(_DWORD *)&v28, v29, v30, *(_DWORD *)&v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42); v42 = 6; v22 = *(_DWORD *)((char *)v30 + *(_DWORD *)(*v30 + 4) + 56); if ( v22 ) (*(void (**)(void))(*(_DWORD *)v22 + 8))(); return v3; }
有……有点复杂
结合OD分析
【未完待续qwq】