• [攻防世界


    先用exeinfo查一下,发现是32位程序

    运行程序,发现抛出了乱码窗口

    ida打开,反编译主函数

    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, (int)lpMem);
        ExitProcess(0xFFFFFFFF);
      }
      MessageBoxA(0, lpMem + 1, "Flag", 2u);
      HeapFree(hHeap, 0, lpMem);
      HeapDestroy(hHeap);
      ExitProcess(0);
    }
    

    阅读函数,发现在if中对lpMen进行了操作,查看函数sub_401000()

    unsigned int __fastcall sub_401000(int a1, int a2)
    {
      int v2; // esi
      unsigned int v3; // eax
      unsigned int v4; // ecx
      unsigned int result; // eax
    
      v2 = dword_409B38;
      v3 = a2 + 1 + strlen((const char *)(a2 + 1)) + 1;
      v4 = 0;
      result = ((v3 - (a2 + 2)) >> 2) + 1;
      if ( result )
      {
        do
          *(_DWORD *)(a2 + 4 * v4++) ^= v2;
        while ( v4 < result );
      }
      return result;
    }
    

    疑似加密操作,联想到lpMem = (CHAR *)HeapAlloc(hHeap, 8u, MaxCount + 1);为lpMem申请空间,猜测lpMem存储flag
    下文有MessageBoxA(),联系到打开程序时抛出的乱码窗口,猜测sub_40102A() || IsDebuggerPresent()为否,未能进入if
    Ollydbg打开程序,找到IsDebuggerPresent()所在的位置

    在此设置断点,单步调试,发现跳过了第一个MessageBoxA
    猜测IsDebuggerPresent()指令是反调试函数,观察其中的指令,发现该高亮行跳过了第一个MessageBox函数,将其修改为nop跳过

    但继续调试时发现在int3处程序强行停止,尝试将刚才的语句改为跳转到mov edx,dword ptr ss:[ebp-0xC]处,并将call后的跳转语句nop掉,运行得到

    发现窗口中输出了空语句。
    联想到伪代码中MessageBoxA(0, lpMem + 1, "Flag", 2u);,lpMem + 1说明该变量的第0位极有可能是空位符,则尝试把刚才call后的跳转语句重新定向至第二个MessageBox处

    得到flag:

    flag{reversing_is_not_that_hard!}
    

    upd on 2021/11/12
    "尝试将刚才的语句改为跳转到mov edx,dword ptr ss:[ebp-0xC]处,并将call后的跳转语句nop掉"

    这里当时做题实际上歪打正着了,call调用的函数实际上是对lpMen的加密函数,执行此函数后才能让输出不是乱码,当时做题的时候没考虑到这一点。

    在IDA里可以看到,这个加密函数是在倒数第二句话的,简单分析就可以知道他是加密函数

    (懒得重新上图了)

  • 相关阅读:
    如何向Android模拟器打电话发短信
    APK文件安装模拟器和ADB命令的使用
    android的个人代码总结
    android一些基础知识
    android常用的一些属性说明
    新的博客
    用字符进行布尔值判断,踩到的一个小坑
    通过outlook的web邮箱获取指定邮件内容的邮件
    使用win32com接口获取outlook收件箱的内容
    Python 详解命令行解析
  • 原文地址:https://www.cnblogs.com/Here-is-SG/p/15356995.html
Copyright © 2020-2023  润新知