Darkctf部分re题目

1.so_much

ida打开得到从main()函数发现一个get_flag()函数。

get_flag函数:

void __usercall get_flag(__int64 a1@<rcx>, __int64 a2@<rbp>, __int64 *a3@<rdi>, __int64 *a4@<rsi>)
{
  signed int i; // [rsp-5Ch] [rbp-5Ch]
  __int64 v5; // [rsp-58h] [rbp-58h]
  __int64 v6; // [rsp-50h] [rbp-50h]
  __int64 v7; // [rsp-48h] [rbp-48h]
  int v8; // [rsp-40h] [rbp-40h]
  __int16 v9; // [rsp-3Ch] [rbp-3Ch]
  __int64 v10; // [rsp-38h] [rbp-38h]
  __int64 v11; // [rsp-30h] [rbp-30h]
  __int64 v12; // [rsp-28h] [rbp-28h]
  __int64 v13; // [rsp-20h] [rbp-20h]
  __int64 v14; // [rsp-18h] [rbp-18h]
  unsigned __int64 v15; // [rsp-10h] [rbp-10h]
  __int64 v16; // [rsp-8h] [rbp-8h]

  __asm { endbr64 }
  v16 = a2;
  v15 = __readfsqword(0x28u);
  v5 = 0LL;
  v6 = 0LL;
  v7 = 0LL;
  v8 = 0;
  v9 = 0;
  for ( i = 7; i <= 29; ++i )
  {
    v11 = 0LL;
    v12 = 0LL;
    v13 = 0LL;
    v14 = 0LL;
    v10 = flag_48(&v16, i);
    sub_10D0();
  }
  *a3 = &v5;
  if ( __readfsqword(0x28u) != v15 )
    sub_10A0();
}

可以看到有一个循环,i从7开始猜测v10每次循环的值为flag的内容。

用gdb调试可以得到flag,而钱7位为darkCTF。最终的flag为:darkCTF{w0w_s0_m4ny_funct10ns}

2.strings

在main()函数有这样的字符串

"Use this as ur input:  %s\n", "!8u)05/>!#,.W/%H-G"

按照提示输入相应的字符串。

*dest = 0LL;
  v7 = 0LL;
  v8 = 0;
  v9 = 0;
  v26 = 0;
  for ( n = 8; n >= 0; --n )
  {
    strncat(dest, &v12 + v26, 1uLL);
    strncat(dest, &v10 + n, 1uLL);
    ++v26;
  }

其中v12,v10为输入的字符串经过变化后的字符串,所以调试的时候观察*dest的内存就能得到flag:darkCTF{wah_howdu_found_me}。

3.HelloWrold

两种解法,一种是下断点查看比较的字符串是什么,另一种是改代码逻辑。

1.下断点

在0x555555555595,0x555555555607,下断点。这两个位置是调用strcmp()函数,然后在运行到断点的地方查看rdi寄存器地址的内容就得到要比较的字符串"H3ll0","W0rld"。输入即可得到flag。

check函数

__int64 __usercall check@<rax>(__int64 a1@<rbp>, _BYTE *a2@<rdi>, int a3@<esi>)
{
  __int64 result; // rax
  double v4; // xmm0_8
  double v5; // xmm0_8
  signed int i; // [rsp-50h] [rbp-50h]
  signed int j; // [rsp-4Ch] [rbp-4Ch]
  signed int v8; // [rsp-48h] [rbp-48h]
  signed int v9; // [rsp-44h] [rbp-44h]
  signed int v10; // [rsp-40h] [rbp-40h]
  signed int v11; // [rsp-3Ch] [rbp-3Ch]
  signed int v12; // [rsp-38h] [rbp-38h]
  signed int v13; // [rsp-34h] [rbp-34h]
  signed int v14; // [rsp-30h] [rbp-30h]
  signed int v15; // [rsp-2Ch] [rbp-2Ch]
  signed int v16; // [rsp-28h] [rbp-28h]
  signed int v17; // [rsp-24h] [rbp-24h]
  unsigned __int64 v18; // [rsp-10h] [rbp-10h]
  __int64 v19; // [rsp-8h] [rbp-8h]

  __asm { endbr64 }
  v19 = a1;
  v18 = __readfsqword(0x28u);
  result = 0LL;
  v8 = 5184;
  v9 = 2601;
  v10 = 11664;
  v11 = 11664;
  v12 = 2304;
  v13 = 7569;
  v14 = 2304;
  v15 = 12996;
  v16 = 11664;
  v17 = 10000;
  if ( a3 == 1 )
  {
    for ( i = 0; i <= 4; ++i )
    {
      v4 = *(&v19 + i - 16);
      sub_10D0();
      sub_1110();
    }
    result = sub_1100();
  }
  else if ( a3 == 2 )
  {
    for ( j = 0; j <= 4; ++j )
    {
      v5 = *(&v19 + j + 5 - 16);
      sub_10D0();
      sub_1110();
    }
    result = sub_1100();
  }
  if ( __readfsqword(0x28u) != v18 )
    result = sub_10E0();
  return result;
}

其中这里比较坑的地方就是sub_1100()这个函数,在运行的时候这个就是strcmp函数。

2.改代码逻辑

在地址0x55555555524A,0x555555555266的地方是jnz指令,直接改成jz,然后随便输入2个参数运行即可得到flag。

posted @ 2020-10-03 17:40  mio_yy  阅读(197)  评论(0)    收藏  举报