小白学逆向六月份第二周笔记

题目描述:菜鸡发现Flag似乎并不一定是明文比较的

  用ida打开附件,然后F5查看伪代码

  

int __cdecl main(int argc, const char **argv, const char **envp)
{
  signed int v3; // ebx
  char v4; // al
  int result; // eax
  int v6; // [esp+0h] [ebp-70h]
  int v7; // [esp+0h] [ebp-70h]
  char v8; // [esp+12h] [ebp-5Eh]
  char v9[20]; // [esp+14h] [ebp-5Ch]
  char v10; // [esp+28h] [ebp-48h]
  __int16 v11; // [esp+48h] [ebp-28h]
  char v12; // [esp+4Ah] [ebp-26h]
  char v13; // [esp+4Ch] [ebp-24h]

  strcpy(&v13, "437261636b4d654a757374466f7246756e");//复制字符
  while ( 1 )
  {
    memset(&v10, 0, 0x20u);
    v11 = 0;
    v12 = 0;
    sub_40134B(aPleaseInputYou, v6);
    scanf(aS, v9);
    if ( strlen(v9) > 0x11 )//如果长度过长则跳出循环
      break;
    v3 = 0;
    do
    {
      v4 = v9[v3];
      if ( !v4 )
        break;
      sprintf(&v8, asc_408044, v4);
      strcat(&v10, &v8);
      ++v3;
    }//将输入的字符整成16进制,然后和v13比较 如果相同则得到答案
    while ( v3 < 17 );
    if ( !strcmp(&v10, &v13) )
      sub_40134B(aSuccess, v7);
    else
      sub_40134B(aWrong, v7);
  }
  sub_40134B(aWrong, v7);
  result = stru_408090._cnt-- - 1;
  if ( stru_408090._cnt < 0 )
    return _filbuf(&stru_408090);
  ++stru_408090._ptr;
  return result;
}

  将16进制转换为字符串

  小白学逆向六月份第二周笔记

 

   则v13的字符串解码为:CrackMeJustForFun,得到flag。

题目描述:菜鸡发现这个程序偷偷摸摸在自己的机器上搞事情,它决定一探究竟   用IDA打开附件,F5反编译为c语言代码
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v3; // al
  __int64 v5; // [rsp+0h] [rbp-40h]
  int i; // [rsp+4h] [rbp-3Ch]
  FILE *stream; // [rsp+8h] [rbp-38h]
  char filename[8]; // [rsp+10h] [rbp-30h]
  unsigned __int64 v9; // [rsp+28h] [rbp-18h]

  v9 = __readfsqword(0x28u);//变量定义初始化
  LODWORD(v5) = 0;
  while ( (signed int)v5 < strlen(s) )
  {
    if ( v5 & 1 )
      v3 = 1;
    else
      v3 = -1;
    *(&t + (signed int)v5 + 10) = s[(signed int)v5] + v3;
    LODWORD(v5) = v5 + 1;
  }//定义flag的值
  strcpy(filename, "/tmp/flag.txt");
  stream = fopen(filename, "w");
  fprintf(stream, "%s\n", u, v5);
  for ( i = 0; i < strlen(&t); ++i )
  {
    fseek(stream, p[i], 0);
    fputc(*(&t + p[i]), stream);
    fseek(stream, 0LL, 0);
    fprintf(stream, "%s\n", u);
  }//将所得的值写入文件
  fclose(stream);
  remove(filename);
  return 0;
}

  分析代码后,可以发现我们需要得到s和t的值,双击查看参数的值

.data:00000000006010A0 s               db 'c61b68366edeb7bdce3c6820314b7498',0
.data:00000000006010A0                                         ; DATA XREF: main+25↑o
.data:00000000006010A0                                         ; main+3F↑r
.data:00000000006010C1                 align 20h
.data:00000000006010E0                 public t
.data:00000000006010E0 ; char t
.data:00000000006010E0 t               db 53h                  ; DATA XREF: main+65↑w
.data:00000000006010E0                                         ; main+C9↑o ...
.data:00000000006010E1 aHarifctf       db 'harifCTF{????????????????????????????????}',0

  则s的值为‘c61b68366edeb7bdce3c6820314b7498’,t的值为“0x53H+harifCTF{???}”,则t的值为SharifCTF{???}’。

  改写中间十行生成flag的代码,输出flag即可

#include<stdio.h>
#include<string.h> 
int main()
{
  char v3; // al
  __int64 v5=0; // [rsp+0h] [rbp-40h]
  int i; // [rsp+4h] [rbp-3Ch]
  FILE *stream; // [rsp+8h] [rbp-38h]
  char filename[8]; // [rsp+10h] [rbp-30h]
  unsigned __int64 v9; // [rsp+28h] [rbp-18h]
   char s[] = "c61b68366edeb7bdce3c6820314b7498";
    char t[] = "SharifCTF{????????????????????????????????}";
  while ( (signed int)v5 < strlen(s) )
  {
    if ( v5 & 1 )
      v3 = 1;
    else
      v3 = -1;
    *(t + (signed int)v5 + 10) = s[(signed int)v5] + v3;
    v5++;
  }
  printf("%s",t);
  return 0;
} 

小白学逆向六月份第二周笔记

题目描述:菜鸡开始学习逆向工程,首先是最简单的题目   使用IDA将其打开,使用shift f12打开string窗口,找出所有字符串
小白学逆向六月份第二周笔记

 

 双击flag get进入IDA View-A图标架构,在这里查看程序的逻辑树形图。

小白学逆向六月份第二周笔记

 

 定位其中地址00413E60后使用快捷键:CTRL X引用交叉列表。

小白学逆向六月份第二周笔记

 

 F5进入伪代码后分析代码

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // eax
  __int128 v5; // [esp+0h] [ebp-44h]
  __int64 v6; // [esp+10h] [ebp-34h]
  int v7; // [esp+18h] [ebp-2Ch]
  __int16 v8; // [esp+1Ch] [ebp-28h]
  char v9; // [esp+20h] [ebp-24h]

  _mm_storeu_si128((__m128i *)&v5, _mm_loadu_si128((const __m128i *)&xmmword_413E34));
  v7 = 0;
  v6 = qword_413E44;
  v8 = 0;
  printf(&byte_413E4C);
  printf(&byte_413E60);
  printf(&byte_413E80);
  scanf("%s", &v9);
  v3 = strcmp((const char *)&v5, &v9);//v5和v9进行字符串比较,v9为随意输入的值,v5为函数xmmword_413E34赋值的,找到函数xmmword_413E34的值即可
    v3 = -(v3 < 0) | 1;
  if ( v3 )
    printf(aFlag);
  else
    printf((const char *)&unk_413E90);
  system("pause");
  return 0;
}

小白学逆向六月份第二周笔记

  双击函数后,发现其值后转为字符串,则得到flagDUTCTF{We1c0met0DUTCTF}。

题目描述:菜鸡听说有的程序运行就能拿Flag?   用IDA打开附件,F5查看伪代码
int __cdecl main(int argc, const char **argv, const char **envp)
{
  setlocale(6, &locale);
  banner();
  prompt_authentication();
  authenticate();
  return 0;
}

  对每个函数进行跟进,发现authenricate(),符合获得flag的函数。

void authenticate()
{
  wchar_t ws[8192]; // [esp+1Ch] [ebp-800Ch]
  wchar_t *s2; // [esp+801Ch] [ebp-Ch]

  s2 = (wchar_t *)decrypt(&s, &dword_8048A90);//decrypt,字面意思为加密。
  if ( fgetws(ws, 0x2000, stdin) )
  {
    ws[wcslen(ws) - 1] = 0;
    if ( !wcscmp(ws, s2) )
      wprintf(&unk_8048B44);
    else
      wprintf(&unk_8048BA4);
  }
  free(s2);
}

   在authenticate函数的第七行设置断点,进入断点后查看s2的值

小白学逆向六月份第二周笔记

 

   则可得flag: 9447{you_are_an_international_mystery}

题目描述:听说运行就能拿到Flag,不过菜鸡运行的结果不知道为什么是乱码   将程序放入IDA并在main函数下F5生成伪代码
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  int v3; // ecx
  CHAR *lpMem; // [esp+8h] [ebp-Ch]
  HANDLE hHeap; // [esp+10h] [ebp-4h]

  hHeap = HeapCreate(0x40000u, 0, 0);
  lpMem = (CHAR *)HeapAlloc(hHeap, 8u, MaxCount + 1);
  memcpy_s(lpMem, MaxCount, &unk_409B10, MaxCount);
  if ( sub_40102A() || IsDebuggerPresent() )//如果在动态调试器中就进入判断运行,如果没有就直接弹窗显示乱码
  {
    __debugbreak();
    sub_401000(v3 + 4, lpMem);
    ExitProcess(0xFFFFFFFF);
  }
  MessageBoxA(0, lpMem + 1, "Flag", 2u);
  HeapFree(hHeap, 0, lpMem);
  HeapDestroy(hHeap);
  ExitProcess(0);
}

小白学逆向六月份第二周笔记

 

 对比IDA,则可以看出mov edx,[ebp+lpMem]对应的汇编指令地址,单步运行F8

小白学逆向六月份第二周笔记

 

 则已经执行了mov指令,接下来调用call,F8继续执行,执行完,edx存的就是flag的地址

 小白学逆向六月份第二周笔记

   则flag是:flag{reversing_is_not_that_hard!}

题目描述:菜鸡想要走出菜狗设计的迷宫   用IDA打开附件,F5查看伪代码
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  const char *v3; // rsi
  signed __int64 v4; // rbx
  signed int v5; // eax
  char v6; // bp
  char v7; // al
  const char *v8; // rdi
  __int64 v10; // [rsp+0h] [rbp-28h]

  v10 = 0LL;
  puts("Input flag:");
  scanf("%s", &s1, 0LL);
  if ( strlen(&s1) != 24 || (v3 = "nctf{", strncmp(&s1, "nctf{", 5uLL)) || *(&byte_6010BF + 24) != 125 )//进行判断,如果以nctf{开头则继续进行
  {
LABEL_22:
    puts("Wrong flag!");
    exit(-1);
  }
  v4 = 5LL;
  if ( strlen(&s1) - 1 > 5 )
  {
    while ( 1 )
    {
      v5 = *(&s1 + v4);
      v6 = 0;
      if ( v5 > 78 )
      {
        v5 = (unsigned __int8)v5;
        if ( (unsigned __int8)v5 == 79 )
        {
          v7 = sub_400650((char *)&v10 + 4, v3);
          goto LABEL_14;
        }
        if ( v5 == 111 )
        {
          v7 = sub_400660((char *)&v10 + 4, v3);
          goto LABEL_14;
        }
      }
      else
      {
        v5 = (unsigned __int8)v5;
        if ( (unsigned __int8)v5 == 46 )
        {
          v7 = sub_400670(&v10, v3);
          goto LABEL_14;
        }
        if ( v5 == 48 )
        {
          v7 = sub_400680(&v10, v3);//进行了四个判断,进入了四个函数
LABEL_14:
          v6 = v7;
          goto LABEL_15;
        }
      }
LABEL_15:
      v3 = (const char *)HIDWORD(v10);
      if ( !(unsigned __int8)sub_400690(asc_601060, HIDWORD(v10), (unsigned int)v10) )
        goto LABEL_22;
      if ( ++v4 >= strlen(&s1) - 1 )
      {
        if ( v6 )
          break;
LABEL_20:
        v8 = "Wrong flag!";
        goto LABEL_21;
      }
    }
  }
  if ( asc_601060[8 * (signed int)v10 + SHIDWORD(v10)] != 35 )
    goto LABEL_20;
  v8 = "Congratulations!";
LABEL_21:
  puts(v8);
  return 0LL;
}
bool __fastcall sub_400650(_DWORD *a1)
{
  int v1; // eax

  v1 = (*a1)--;
  return v1 > 0;
}
bool __fastcall sub_400660(int *a1)
{
  int v1; // eax

  v1 = *a1 + 1;
  *a1 = v1;
  return v1 < 8;
}
bool __fastcall sub_400670(_DWORD *a1)
{
  int v1; // eax

  v1 = (*a1)--;
  return v1 > 0;
}
bool __fastcall sub_400680(int *a1)
{
  int v1; // eax

  v1 = *a1 + 1;
  *a1 = v1;
  return v1 < 8;
}

我们输入的应该是'.','0','o','O',并以此来确定上下左右移动

从上往下以此追踪,可以发现这些函数会跳到lable15的位置,然后,对lable15分析,发现特殊的字符串

小白学逆向六月份第二周笔记

 

 则其可能为一个8*8的迷宫

小白学逆向六月份第二周笔记

 

 根据迷宫最后得到的flag: nctf{o0oo00O000oooo..OO}

上一篇:C语言笔记——番外篇 函数栈帧的创建


下一篇:你不知道的JavaScript(五)内置对象模版