首页
社区
课程
招聘
[原创]第三题wp
发表于: 2017-10-30 01:59 2989

[原创]第三题wp

2017-10-30 01:59
2989

程序OD载入后,点击验证,程序直接退出,看来有AntiDebug。但是程序不防IDA,IDA载入后发现无壳无花,F5能直接看程序源码。

根据获取输入字符API:GetDlgItemTextA来到消息处理过程:
int __stdcall WindowMsgProc(HWND hDlg, int a2, int arg8, int a4)
{
  memset(&v14, 0xCCu, 0x1A40u);
  v31 = (unsigned int)&savedregs ^ dword_49B344;
  v30 = 0;
  v28 = 0;
  myMemSet((int)&v29, 0, 1023);
  v14 = a2;
  if ( a2 == 0x10 )
    ExitProcess(0);
  if ( v14 == 0x110 )
  {
    v30 = sub_42D4F1();
    if ( v30 == 1 )
      ExitProcess(0);
    v30 = 0;
    v30 = sub_42E428();
    if ( v30 == 1 )
      ExitProcess(0);
    v30 = 0;
    v30 = sub_42D825();
    if ( v30 == 1 )
      ExitProcess(0);
    j_setWindowCenter(hDlg, 1);
  }
  else if ( v14 == 0x111 )
  {
    v14 = (unsigned __int16)arg8;
    if ( (unsigned __int16)arg8 == 1002 )
    {
      String = 0;
      myMemSet((int)&v26, 0, 1023);
      a3 = 0;
      myMemSet((int)&v24, 0, 1023);
      v4 = GetDlgItemTextA(hDlg, 1001, &String, 1025);
      v27 = myCheckException(&v11 == &v11, v4);
      v21 = 0;
      myMemSet((int)&v22, 0, 1023);
      j_myBase64Decode((BYTE *)&String, 0x400u, &a3);
      v19 = 0;
      myMemSet((int)&v20, 0, 1023);
      j_myBase64Decode(&a3, 0x400u, &v21);
      j_myCodeToString((int)&v21, (int)&v19, 1024);
      v18 = 3;
      j_mySM3calc((int)&v21, 3, (int)v17);
      for ( i = 0; i < 32; ++i )
        sprintf(&v16[2 * i], "%02x", (unsigned __int8)v17[i]);
      v5 = myStrLen((int)v16);
      v6 = &String + myStrLen((int)&String);
      v7 = myStrLen((int)v16);
      if ( !myStrCmp((int)v16, (int)&v6[-v7], v5) )
      {
        sub_42D0B4(v11, v12, v13);
        if ( (unsigned __int8)j_myRunPuzzle((int)&a1, (int)&v19) == 1 )
        {
          v8 = MessageBoxA(0, "ok", "CrackMe", 0);
          myCheckException(&v11 == &v11, v8);
        }
      }
    }
  }
  sub_42D65E(&savedregs, &dword_435250);
  v9 = sub_42D1E5((unsigned int)&savedregs ^ v31);
  return myCheckException(1, v9);
}
可以看到程序处理了3个消息:0x10是退出,0x110是启动并居中显示窗口,0x111就是按钮点击处理过程了。花了四五个小时的时间把大部分函数的功能标出来了,流程还是比较清晰的:输入字符key经过2次BASE64解码,得到一串字符代码key1,再用myCodeToString()把代码转换为字符key2,然后验证key1的hash值是否与key最后0x40位相同;最后用key2去跑一个迷宫,返回1时弹出"ok"的成功提示。
先总结一下分析函数功能的方法:其实主要是靠经验和运气,比如BASE64算法,刚开始没往这方面想,完全不理解这二次字符处理是干什么的,后来看到解码过程中验证字符为0x3D即"="时停止解码,而且解码后的字符长度会缩短一点,突然想到这不就是BASE64解码的特征吗,直接用一串BASE64码验证一下,果然是BASE64算法。估计有经验的人一眼就看出这算法了。另一个SM3算法比较好找,初始化数据时用了一串常数,百度一下其中一个常数0x7380166F就直接出SM3算法了。还有一个字符替换函数,这个比较复杂,但是把其中3个子函数功能分析出来了就简单了,那3个子函数分别是把字符替换为数字,把字符替换为小写字母,把字符替换为符号。替换表如下。
num:0-9
-----
.----
..---
...--
....-
.....
-....
--...
---..
----.
sign:
.-.-.-*.
---...*:
--..--*,
-.-.-.*;
..--..*?
-...-**=
.----.*'
-..-.**/
-.-.--*!
-....-*-
..--.-*_
.-..-.*"
-.--.**(
-.--.-*)
...-..-$
.-...**&
.--.-.*@
str:a-z
.-**
-...
-.-.
-..*
.***
..-.
--.*
....
..**
.---

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

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