首页
社区
课程
招聘
[原创] 初世纪解题过程
2018-12-1 18:09 4892

[原创] 初世纪解题过程

2018-12-1 18:09
4892

0x00 分析工具

x64dbg
IDA 7.0
Stud_PE

0x01 解题过程

这道题是64位的程序,而且开启了重定位。开启地址随机化的程序在调试过程中配合IDA查找对应的函数地址会很麻烦,所以我用stdu_pe这个工具先修改PE文件的Option Header中的Dll Characteristics,把这个的数据置为0,然后载入到调试器中之后就首地址就会和IDA中一样。
修改重定位

 

然后将程序载入到x64dbg中运行,然后再check按钮上设置消息断点。
消息断点

 

在输入框中随意输入一些数据后,点击check按钮。程序会断在ntdll中,这时用快捷键alt+m(和OD中一样)。然后在初世纪.exeTEXT段设置断点(F2)。
消息断点

 

然后让程序继续执行就会自动断在程序判断序列号的位置了,这个函数的首地址就是0x0000000140001340。然后再IDA中跳转到这个位置以后,使用F5快捷键查看程序的伪C代码。

INT_PTR __fastcall checkserino(HWND a1, int a2, unsigned __int16 a3)
{
  int v3; // ebx
  unsigned __int16 v4; // si
  HWND v5; // rdi
  int v6; // ebx
  int v7; // ebx
  UINT v9; // ebx
  CHAR *v10; // rdx
  HICON v11; // rax
  HWND v12; // rax
  CHAR String2[16]; // [rsp+30h] [rbp-D0h]
  int v14; // [rsp+40h] [rbp-C0h]
  __int16 v15; // [rsp+44h] [rbp-BCh]
  char v16; // [rsp+46h] [rbp-BAh]
  __int64 v17; // [rsp+48h] [rbp-B8h]
  int v18; // [rsp+50h] [rbp-B0h]
  __int16 v19; // [rsp+54h] [rbp-ACh]
  char v20; // [rsp+56h] [rbp-AAh]
  CHAR Dst; // [rsp+60h] [rbp-A0h]
  char v22; // [rsp+61h] [rbp-9Fh]
  char v23; // [rsp+62h] [rbp-9Eh]
  char v24; // [rsp+63h] [rbp-9Dh]
  char v25; // [rsp+64h] [rbp-9Ch]
  char v26; // [rsp+65h] [rbp-9Bh]
  CHAR String; // [rsp+D0h] [rbp-30h]

  v3 = a2;
  v4 = a3;
  v5 = a1;
  memset(&String, 0, 80ui64);
  memset(&Dst, 0, 100ui64);
  v18 = 2797193651;
  v19 = 0xA1A3u;
  v20 = 0;
  v14 = 0xCEB4BBD2;
  v17 = 0xA1A3E3C4B2CFA7B9i64;
  v15 = 0xA1A3u;
  v16 = 0;
  *(_OWORD *)String2 = xmmword_1400453C0;
  v6 = v3 - 16;
  if ( !v6 )
  {
    DestroyWindow(v5);
    return 0i64;
  }
  v7 = v6 - 256;
  if ( !v7 )
  {
    v11 = LoadIconA(hInstance, (LPCSTR)0x70);
    SendMessageA(v5, 0x80u, 1ui64, (LPARAM)v11);
    SendDlgItemMessageA(v5, 1000, 0xC5u, 0x50ui64, 0i64);
    v12 = GetDlgItem(v5, 1000);
    SetFocus(v12);
    return 0i64;
  }
  if ( v7 != 1 )
    return 0i64;
  if ( v4 == 1002 )
  {
    SendMessageA(v5, 0x10u, 0i64, 0i64);
    return 1i64;
  }
  if ( v4 != 1013 )
  {
    if ( v4 == 1014 || v4 == 40002 )
    {
      DialogBoxParamA(hInstance, (LPCSTR)0x67, v5, (DLGPROC)DialogFunc, 0i64);
      return 1i64;
    }
    return 1i64;
  }
  v9 = GetDlgItemTextA(v5, 1000, &String, 81);
  GetDlgItemTextA(v5, 1000, &Dst, 101);
  if ( v9 != 6 || Dst != '6' || v22 != 'E' || v23 != 'w' || v24 != 'i' || v25 != '9' || v26 != 'H' )
    v10 = String2;
  else
    v10 = (CHAR *)&v17;
  lstrcpyA((LPSTR)&String1, v10);
  DialogBoxParamA(hInstance, (LPCSTR)0x79, v5, (DLGPROC)sub_1400012E0, 0i64);
  return 1i64;
}

在这段程序的最后我们可以看到v9 = GetDlgItemTextA(v5, 1000, &String, 81);,这里就是程序获取输入内容的位置,v9存储的是输入序列号的长度。在下边有一个if判断(if ( v9 != 6 || Dst != '6' || v22 != 'E' || v23 != 'w' || v24 != 'i' || v25 != '9' || v26 != 'H' ))。这里首先判断序列号的长度是否为6,然后又判断了序列号的从第一位开始的每一位是否正确。在这里我们就能拼凑出正确的序列号6Ewi9H

 

最后只需要提交FLAG即可。


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

收藏
点赞0
打赏
分享
最新回复 (2)
雪    币: 19
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
包子QAQ 2019-7-28 16:51
2
0
直接查找窗口过程在x64dbg中怎么掉出来啊?
雪    币: 1622
活跃值: (208)
能力值: ( LV8,RANK:135 )
在线值:
发帖
回帖
粉丝
DickBoomSky 2019-8-6 15:05
3
0
包子QAQ 直接查找窗口过程在x64dbg中怎么掉出来啊?
在句柄那个窗口的中间就能看到窗口了,需要右键刷新一下。
游客
登录 | 注册 方可回帖
返回