一个简单的逆向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】
