首页
社区
课程
招聘
[原创]cybricsctf-paired
发表于: 2021-7-30 21:09 10280

[原创]cybricsctf-paired

2021-7-30 21:09
10280

解包,先得到4个文件,运行app1.exe

图片描述
这几个函数不用再logic.dll里面分析,动调就可以知道是设置一个有id的储存

根据窗口类lpfnWndProc的成员根据这里找到窗口过程

这里获取edit控件字符串并检测,进入第二关

case WM_KEYDOWN(0x100):

按键要等于'ENABLE'

进入第三关

需要把消息WM_USER放入队列

这里可以加入WM_USER消息,动调查看v7函数之后,得到输入为this_is_just_some_random_string!,是fake flag,很明显不可能只分析一个文件

直接进入sub_7FF64E911210()函数分析

这里获取id==7的储存赋值给hwnd,再看前面通过第二关时

只有通过第二关,这里条件才为真, 接下来关注消息的发送, 这里所用的消息发送都将发送wparam==32的消息,执行id==64的代码,

先动调app1,进入第二关后,把断点下在第三关,然后动调app2, 运行过发送消息

v7函数, 把基地址存为id==3的储存中, 储存完成后 app2的循环停止

这里是长度检验, id==2是app1的输入框内容, 先判断不成立的情况, 这里的代码由随机数组成, srand(time(0)), 明显有很大问题

判断成立的情况

一段异或加密, 到这里

又是一段异或加密

这里有循环条件,这是其实是rbyc, id==5的由来(app1中):

输入放入id==5, 检查前面4个字节为'rbyc', 第二次异或加密

然后来到swith结构, 像极了虚拟机

然后慢慢单步走, 慢慢会发现先一直都是1, 2, 然后走5, 6, 8, 3, 8, a, 接下来就又是1, 2......., 最后, 2, 3, 4

(地址只是一个临时的值,主要怎么计算得到)

app1中的执行的代码

app1中的执行的代码

id == 7的数据换为(id==6的数据 + byte_7FF64E928A00[index + 1])

接下来会执行case 8, 将结果(1)加在 *(id==6的数据 + 8)中

这里就和app1中的加到32有点像了

这里是最后的指令, 先前的两步2, 3, 分别是把数据给到id == 7(就是每次比较的结果相加的数据)和 将id == 7与32做比较(和app1重合了), 若为真, 则id == 7 变为1

则app1中的执行的代码

这样就正确了

将id==7的数据换为(dword )(byte_7FF64E928A00 + index + 1)

app1中的执行的代码

app1中的执行的代码:

(id == 7的数据) = *(id==6的数据 + byte_7FF64E928A00[index + 1])

app2:

将 id==7 赋值给*(id == 6 + 10)

这里的1, 2指令中的其他一堆赋值貌似没什么用,主要就是每次取字符串的4个字节来加法,加数为指令3的参数(后面一个值), 结果存放在偏移量为0x10的地址中, 然后比较一下是否为32

减法解密直接python敲出来就行了

wndclass.lpfnWndProc = (WNDPROC)WndProc;
wndclass.lpfnWndProc = (WNDPROC)WndProc;
GetWindowTextA(edit_hWnd, String, 128);
    v15 = (unsigned __int8 *)&v19;
    do
    {
      v16 = v15[String - (CHAR *)&v19];
      v17 = *v15 - v16;
      if ( v17 )
        break;
      ++v15;
    }
    while ( v16 );
    if ( !v17 )
    {
      SetWindowTextW(hWnd[0], L"STAGE 2");
      pass_to_stage2 = 1;
    }
    return 0i64;
GetWindowTextA(edit_hWnd, String, 128);
    v15 = (unsigned __int8 *)&v19;
    do
    {
      v16 = v15[String - (CHAR *)&v19];
      v17 = *v15 - v16;
      if ( v17 )
        break;
      ++v15;
    }
    while ( v16 );
    if ( !v17 )
    {
      SetWindowTextW(hWnd[0], L"STAGE 2");
      pass_to_stage2 = 1;
    }
    return 0i64;
else if ( pass_to_stage2 == 1 )
     {
       j = i;
       if ( wParam != aEnable[i] )
       {
         i = 0;
         return 0i64;
       }
       ++i;
       if ( !aEnable[j + 1] )
       {
         pass_to_stage3 = 1;
         SetWindowTextW(_hwnd, L"STAGE 3...");
         add_to_storage(1i64, hWnd);
         return 0i64;
       }
     }
else if ( pass_to_stage2 == 1 )
     {
       j = i;
       if ( wParam != aEnable[i] )
       {
         i = 0;
         return 0i64;
       }
       ++i;
       if ( !aEnable[j + 1] )
       {
         pass_to_stage3 = 1;
         SetWindowTextW(_hwnd, L"STAGE 3...");
         add_to_storage(1i64, hWnd);
         return 0i64;
       }
     }
 
case 0x400u:                                // WM_USER
      if ( !get_flag )
      {
        GetWindowTextA(edit_hWnd, String, 128);
        add_to_storage(2i64, String);
        get_flag = 1;
      }
      v7 = VirtualAlloc(0i64, 0x200ui64, 0x1000u, 0x40u);
      get_data_from_storage((unsigned int)(_wParam + 32), v7, 128i64);
      v19 = 0i64;
      v20 = 0i64;
      v21 = 0i64;
      v22 = 0i64;
      v23 = 0i64;
      v24 = 0i64;
      v25 = 0i64;
      v26 = 0i64;
      get_data_from_storage(2i64, &v19, 128i64);
      success += ((__int64 (__fastcall *)(_QWORD, __int128 *))v7)((unsigned int)_wParam, &v19);
      if ( success == 32 )
      {
        MessageBoxA(0i64, "Well done!", "WINNER!", 0);
        return 0i64;
      }
case 0x400u:                                // WM_USER
      if ( !get_flag )
      {
        GetWindowTextA(edit_hWnd, String, 128);
        add_to_storage(2i64, String);
        get_flag = 1;
      }
      v7 = VirtualAlloc(0i64, 0x200ui64, 0x1000u, 0x40u);
      get_data_from_storage((unsigned int)(_wParam + 32), v7, 128i64);
      v19 = 0i64;
      v20 = 0i64;
      v21 = 0i64;
      v22 = 0i64;
      v23 = 0i64;
      v24 = 0i64;
      v25 = 0i64;
      v26 = 0i64;
      get_data_from_storage(2i64, &v19, 128i64);
      success += ((__int64 (__fastcall *)(_QWORD, __int128 *))v7)((unsigned int)_wParam, &v19);
      if ( success == 32 )
      {
        MessageBoxA(0i64, "Well done!", "WINNER!", 0);
        return 0i64;
      }
if ( pass_to_stage3 )
      {
        if ( wParam == 'F' )                    // fake
        {
          v11 = 0i64;
          v12 = 32i64;
          while ( 1 )
          {
            PostMessageA(_hwnd, 0x400u, v11++, 0i64);
            if ( !--v12 )
              break;
            _hwnd = hWnd[0];
          }
        }
      }
if ( pass_to_stage3 )
      {
        if ( wParam == 'F' )                    // fake
        {
          v11 = 0i64;
          v12 = 32i64;
          while ( 1 )
          {
            PostMessageA(_hwnd, 0x400u, v11++, 0i64);
            if ( !--v12 )
              break;
            _hwnd = hWnd[0];
          }
        }
      }
hWnd = HWND_MESSAGE|0x2;
  LODWORD(l) = get_data_from_storage(1i64, &hWnd);
  v1 = hWnd;
  if ( hWnd != HWND_MESSAGE|0x2 )
hWnd = HWND_MESSAGE|0x2;
  LODWORD(l) = get_data_from_storage(1i64, &hWnd);
  v1 = hWnd;
  if ( hWnd != HWND_MESSAGE|0x2 )
add_to_storage(1i64, hWnd);
add_to_storage(1i64, hWnd);
PostMessageA(v1, 0x400u, 0x20ui64, 0i64);
for ( i = -1i64; i == -1; get_data_from_storage(3i64, &i) );
PostMessageA(v1, 0x400u, 0x20ui64, 0i64);
for ( i = -1i64; i == -1; get_data_from_storage(3i64, &i) );
((void (__fastcall *)(__int64, void **, __int64))logic_dll_add_to_storage)(3i64, &retaddr, 8i64);
((void (__fastcall *)(__int64, void **, __int64))logic_dll_add_to_storage)(3i64, &retaddr, 8i64);
get_data_from_storage(2i64, v61);
   v3 = -1i64;
   do
     ++v3;
   while ( v61[v3] );
   if ( (_DWORD)v3 == 32 )
get_data_from_storage(2i64, v61);
   v3 = -1i64;
   do
     ++v3;
   while ( v61[v3] );

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//