__int64 __fastcall sub_400F8E(__int64 a1, char a2)
{
__int64 v2; // r8@1
__int64 v3; // rdx@1
__int64 v4; // rcx@1
__int64 v5; // r8@1
__int64 v6; // r9@1
signed int v7; // eax@5
char buffer[136]; // [sp+10h] [bp-B0h]@3
int v10; // [sp+98h] [bp-28h]@12
char v11; // [sp+9Fh] [bp-21h]@8
int v12; // [sp+A0h] [bp-20h]@5
unsigned __int8 v13; // [sp+A6h] [bp-1Ah]@5
char v14; // [sp+A7h] [bp-19h]@5
int v15; // [sp+A8h] [bp-18h]@5
int v16; // [sp+ACh] [bp-14h]@5
int v17; // [sp+B0h] [bp-10h]@5
int v18; // [sp+B4h] [bp-Ch]@4
int v19; // [sp+B8h] [bp-8h]@4
int i; // [sp+BCh] [bp-4h]@1
output((unsigned __int64)"Give me the password: ");
sub_4075A0((__int64)"%s", v2, a2);
for ( i = 0; buffer[i]; ++i ) // strlen
;
v19 = i == 22;
v18 = 10;
do
{
v7 = rand((__int64)"%s", (__int64)buffer, v3, v4, v5, v6);
v4 = (unsigned int)(v7 % 22);
v15 = v7 % 22;
v17 = 0;
v14 = byte_6B4270[(signed __int64)(v7 % 22)];
v13 = buffer[v7 % 22];
v12 = v7 % 22 + 1;
v16 = 0;
while ( v16 < v12 )
{
++v16;
v17 = 0x6D01788D * v17 + 12345;
}
v3 = (unsigned int)v17;
v11 = v17 ^ v13;
if ( v14 != ((unsigned __int8)v17 ^ v13) )
v19 = 0;
--v18;
}
while ( v18 );
if ( v19 )
v10 = output((unsigned __int64)"Congras\n");
else
v10 = output((unsigned __int64)"Oh no!\n");
return 0LL;
}
这道题出的很玄幻,我一直都不知道那个是个随机数生成的函数,我只是运行它发现每次都是不一样的数字,就猜测是否是随机数,没想到是的。
具体逻辑就是:输入22个字符,取10个随机数作为序号取字符进行验证即可,只要将验证反过来写就可以了
#include<cstdio>
#include<cstring>
using namespace std;
unsigned char chars[] =
{
0x5F, 0xF2, 0x5E, 0x8B, 0x4E, 0x0E, 0xA3, 0xAA, 0xC7, 0x93,
0x81, 0x3D, 0x5F, 0x74, 0xA3, 0x09, 0x91, 0x2B, 0x49, 0x28,
0x93, 0x67, 0x00
};
int main()
{
for(int i=0;i<22;i++)
{
int t=0;
for(int j=0;j<i+1;j++)
t=t*0x6D01788D+12345;
chars[i]^=t;
}
printf("%s\n",chars);
return 0;
}
个人感觉逆向还是要多猜测。。。