hackme 攻防世界RE

__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
#include
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;
}

个人感觉逆向还是要多猜测。。。

你可能感兴趣的:(CTF)