RE-实验吧whatamitoyou

Alikas-0x01
题目:实验吧whatamitoyou

用IDA打开,进入main函数,F5。(F5重度依赖者,菜了)

分析可知,memset语句后数据应为数组。对每组都按快捷键Y修改类型,改为char a[0x128]
[记得从后往前改(即从v5开始)]

 memset(&v5, 0, 0x128uLL);
  v5 = 2334397743343431513LL;
  v6 = 2338620985787316589LL;
  v7 = 2338323056846008934LL;
  v8 = 8583972389067452009LL;
  v9 = 199253324399LL;
  v3 = &v10;
  memset(&v10, 0, 0xD8uLL);
//修改后
  memset(v5, 0, sizeof(v5));
  strcpy(v5, "You are my best friends in the world.");//这里字符转换了,快捷键R
  v3 = &v5[40];
  memset(&v5[40], 0, 0xD8uLL);
  *(_DWORD *)&v5[288] = 3;

根据题目提示“你会唱歌吗”和题目内出现的字符串,可以搜索到一首歌My Best Friends InThe World(What Am I To You?)。对比歌词可知,题目内的歌词是乱序的。

修改类型后可看到后面的赋值语句发生变化。分析可知,该数组内,前256个字节存储歌词,后用存储三个指针,分别指向三句不同的歌词。

 *(_QWORD *)&v5[256] = &v245;
  *(_QWORD *)&v5[264] = &v237;
  *(_QWORD *)&v5[272] = &v86;
  *(_QWORD *)&v5[280] = &v214;

创建数据结构lyric,内含两个成员,一个是char a[256],储存歌词;一个是lyric *q[3],存放3个指向下一句歌词所在的数据结构的地址。[插入数据结构在IDA的Structures窗口中,插入教程就在窗口内注释部分]

00000000 ; Ins/Del : create/delete structure
00000000 ; D/A/*   : create structure member (data/ascii/array)
00000000 ; N       : rename structure or structure member
00000000 ; U       : delete structure member
00000000 ; [00000018 BYTES. COLLAPSED STRUCT Elf64_Sym. PRESS CTRL-NUMPAD+ TO EXPAND]
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 lyric           struc ; (sizeof=0x118, mappedto_6)
00000000 a               db 256 dup(?)
00000100 q               dq 3 dup(?)             ; offset
00000118 lyric           ends
00000118
00000000 ; [00000018 BYTES. COLLAPSED STRUCT Elf64_Rela. PRESS CTRL-NUMPAD+ TO EXPAND]
00000000 ; [00000010 BYTES. COLLAPSED STRUCT Elf64_Dyn. PRESS CTRL-NUMPAD+ TO EXPAND]

对数组进行再一次修改类型lyric a,修改后如下:

 memset(&v5, 0, 0x128uLL);
  strcpy(v5.a, "You are my best friends in the world.");
  v3 = &v5.a[40];
  memset(&v5.a[40], 0, 0xD8uLL);

接下来分析计算flag算法

v80 = &v41; //&41 为第一句歌词地址
 v79 = 1;
 v78 = 0; 
while ( 1 )
  {
    v77 = *a2[1];//a2即为输入的字符串
    if ( !v77 )
      break;
    if ( v79 & 1 )  
      v78 *= v79;
    else
      v78 /= v79;
    v78 += (v77 - 32) * *&v80[1].a[8]; 
    v80 = *&v80->a[8 * (v77 - 65 + 32LL)];// 根据[8*(输入的字符-65+32)]得到了下一句歌词
    ++v79;
    v3 = a2[1] + 1;
    a2[1] = v3;
  }
  if ( v80 == &v65 )//由这句猜测,将歌词从第一句开始到最后一句即可得flag
  {
    printf("Your password is tjctf{", a2, v3, a2);
    while ( v78 )
    {
      v76 = v78 % 16;
      v78 /= 16;
      putchar(v76 + 97);
    }
    puts("}");
  }
  else
  {
    puts("Nope.");
  } 

由上述分析即歌词顺序可知:

例:歌词第一句为”Everyone, Bubblegum I’m so dumb,”,下一句是”I should have just told you”,

由[8*(输入-65+32)]可知输入的第一个字符是67=‘C’。

若输入的第一个字符为A,则得到what I lost

若输入的第一个字符为B,则得到what am I to you

若输入的第一个字符为D,则得到Am I a joke,your knight,oryou brother?

依次类推,得到剩下的输入。

完整的输入为CBDABCADBCCABBABBABACBCCABDADBABABB

Linux下运行,即得flag:在这里插入图片描述
附上:歌词

你可能感兴趣的:(逆向)