ADworld reverse wp easyre-153

逆向分析

做逆向题先查壳, 就像做pwn先checksec一样
ADworld reverse wp easyre-153_第1张图片

用PEid查不出来, 用Exeinfo PE可以查出ELF文件的壳
用工具直接脱upx壳, kali自带的工具或者手动安装一个windows的upx工具

脱壳之后拖入IDA32

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int pipedes[2]; // [esp+18h] [ebp-38h] BYREF
  __pid_t v5; // [esp+20h] [ebp-30h]
  int v6; // [esp+24h] [ebp-2Ch] BYREF
  char buf[30]; // [esp+2Eh] [ebp-22h] BYREF
  unsigned int v8; // [esp+4Ch] [ebp-4h]

  v8 = __readgsdword(0x14u);
  pipe(pipedes);
  v5 = fork();                                  // subprocess fpid
  if ( !v5 )                                    // if subprocess then execute
  {
    puts("\nOMG!!!! I forgot kid's id");
    write(pipedes[1], "69800876143568214356928753", 0x1Du);
    puts("Ready to exit     ");
    exit(0);
  }
  read(pipedes[0], buf, 0x1Du);                 // subprocess input 69800876143568214356928753
  __isoc99_scanf("%d", &v6);
  if ( v6 == v5 )
  {
    if ( (unsigned __int8)*(_DWORD *)((char *)lol + 3) == 204 )
    {
      puts(":D");
      exit(1);
    }
    printf("\nYou got the key\n ");
    lol(buf);
  }
  wait(0);
  return 0;
}

这是一个linux系统编程的逆向, 需要fork和进程间通信的知识, 系统编程和软件开发是做逆向的基本功, 所以需要补这方面的知识, 就不多说了 (面向搜索引擎做逆向也是基本功, 什么不懂现场学就完了

首先fork()是返回创建的子进程的进程id, 子进程fpid是0, 父进程则保存子进程的fpid, 所以下面的代码只有子进程会执行

  if ( !v5 )                                    // if subprocess then execute
  {
    puts("\nOMG!!!! I forgot kid's id");
    write(pipedes[1], "69800876143568214356928753", 0x1Du);
    puts("Ready to exit     ");
    exit(0);
  }

pipe(pipedes);是创建父子进程之间的通信管道, pipedes[0]是读, pipedes[1]是写
read(pipedes[0], buf, 0x1Du);即父进程从管道读取0x1D的数据到buf缓冲区
write(pipedes[1], "69800876143568214356928753", 0x1Du);是子进程将"69800876143568214356928753"写入管道, 所以父进程读出来的就是这一串

跟如lol()函数发现反编译和汇编代码不一致, 这里就是涉及IDA反汇编的优化操作, 如果一段汇编代码被强制跳转略过, 根本不会被执行, 那么IDA的F5就不会反编译这段汇编代码, 所以看到的伪代码就是一行printf
用IDApython nop掉0x080486B0地址的汇编指令, 这里如果是IDA7.5+版本, 因为API改了, 所以需要加一句from idc_bc695 import *
ADworld reverse wp easyre-153_第2张图片
再F5即可反编译完整汇编

int __cdecl lol(_BYTE *buf)
{
  int result; // eax
  char flag[7]; // [esp+15h] [ebp-13h] BYREF
  int v3; // [esp+1Ch] [ebp-Ch]

  flag[0] = 2 * buf[1];
  flag[1] = buf[4] + buf[5];
  flag[2] = buf[8] + buf[9];
  flag[3] = 2 * buf[12];
  flag[4] = buf[18] + buf[17];
  flag[5] = buf[10] + buf[21];
  flag[6] = buf[9] + buf[25];
  if ( v3 == 1 )
    result = printf("%s", flag);
  else
    result = printf("flag_is_not_here");
  return result;
}

破解

阅读F5出来的伪代码, 即可知道flag就是69800876143568214356928753处理出来的7字节串, 直接用cpp写逆

#include 
#include 
using namespace std;

int main () {
    string flag(7, '0');
    string buf = "69800876143568214356928753";
    flag[0] = 2 * buf[1];
    flag[1] = buf[4] + buf[5];
    flag[2] = buf[8] + buf[9];
    flag[3] = 2 * buf[12];
    flag[4] = buf[18] + buf[17];
    flag[5] = buf[10] + buf[21];
    flag[6] = buf[9] + buf[25];

    cout << "RCTF{" << flag << '}' << endl;
}

搞定~

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