首页
社区
课程
招聘
1
[原创]第一题:神秘来信:(IDA+C#)
发表于: 2019-6-10 15:46 5676

[原创]第一题:神秘来信:(IDA+C#)

htg 活跃值
4
2019-6-10 15:46
5676
分析方法:采用IDA静态分析
1、IDA查看源代码F5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // esi
  unsigned int inputStrLen; // kr00_4
  unsigned int i; // ecx
  unsigned __int8 inputStr; // [esp+10h] [ebp-3Ch]
  unsigned __int8 v10; // [esp+11h] [ebp-3Bh]
  unsigned __int8 v11; // [esp+12h] [ebp-3Ah]
  char v12; // [esp+13h] [ebp-39h]
  char v13; // [esp+14h] [ebp-38h]
  char v14; // [esp+15h] [ebp-37h]
  CPPEH_RECORD ms_exc; // [esp+34h] [ebp-18h]
 
  v3 = 0;
  sprintf((int)"请输入序列号:\n");
  scanf("%s", &inputStr);
  inputStrLen = strlen((const char *)&inputStr);
  if ( inputStrLen < 7 && v14 == 0x33 && v13 == 0x35 && v12 == 0x33 && v11 + v10 + inputStr == 0x95 )// 判断语句:小于7个字符,实际需要6个字符,后三位为数字353,前面三位需要满足字节码相加为0x95(需要写代码分析)
  {
    i = 0;
    if ( inputStrLen )
    {
      do
        v3 = *(&inputStr + i++) + 16 * v3 - 0x30;// 取输入输入元素
      while ( i < inputStrLen );
    }
    ms_exc.registration.TryLevel = 0;
    sprintf((int)"error!\n");
    while ( 1 )
      ;
  }
  sprintf((int)"error\n");
  return 0;
}
通过分析,我们得出:输入6个字符,后三位为353,前几位相加为0x95;
这里面有一个坑:
需要触发除零的异常,才能正常输出结果。
关键代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
.text:0040134D                 push    eax
.text:0040134E                 call    loc_401354//执行后,跳转到401354语句,会把下一句压入堆栈401353
.text:0040134E ; ---------------------------------------------------------------------------
.text:00401353                 db 0EBh
.text:00401354 ; ---------------------------------------------------------------------------
.text:00401354
.text:00401354 loc_401354:                             ; CODE XREF: _main+EE↑j
.text:00401354                 pop     eax//弹出,eax=401353
.text:00401355                 sub     eax, 0
.text:00401358                 sub     esi, eax
.text:0040135A                 div     esi///触发esi=0,那么esi必须等于401353,esi由上面的代码累计计算
.text:0040135C                 pop     eax
ESI计算代码
1
2
3
4
5
6
7
8
.text:00401330 loc_401330:                             ; CODE XREF: _main+E0↓j
.text:00401330                 movzx   eax, [ebp+ecx+inputStr]
.text:00401335                 shl     esi, 4
.text:00401338                 add     esi, 0FFFFFFD0h
.text:0040133B                 add     esi, eax
.text:0040133D                 inc     ecx
.text:0040133E                 cmp     ecx, edx
.text:00401340                 jb      short loc_401330
//为了确保是可输入字符,我们仅选择0x20至0x7E之间的输出结果。
我们写一个C#程序,输出结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
        private StringBuilder GetKey()
        {
            StringBuilder sb = new StringBuilder();
            string str = "";
            byte[] byteA = new byte[6] { 0x00, 0x00, 0x00, 0x33, 0x35, 0x33 };
            for (int i = 1; i < 0x94; i++)
            {
                byteA[0] = (byte)i;
                for (int j = 1; j + i < 0x95; j++)
                {
                    byteA[1] = (byte)j;
                    byteA[2] = (byte)(0x95 - i - j);
                    //str.AppendLine(GetResult(byteA));
                    if (isValid(byteA, out str)) sb.AppendLine(str);
                }
            }
            return sb;
        }
        private bool isValid(byte[] tmp, out string str)
        {
            bool flag = false; str = "";
            if (tmp.Length != 6) return flag;
            uint esi = 0;
            foreach (byte b in tmp)
            {
                esi = esi << 4;
                esi = esi - 0x30;
                esi = esi + (uint)b;
            }
            if (esi == 0x401353 && isValidKey(tmp[0])&& isValidKey(tmp[1])&& isValidKey(tmp[2]))
            {
                flag = true;
                str = string.Format("Hex:{0:X2} {1:X2} {2:X2} {3:X2} {4:X2} {5:X2} Str:{6}"
                    , tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5]
                    , Encoding.ASCII.GetString(tmp)
                    );
            }
            return flag;
        }
        private bool isValidKey(byte b)
        {
            if (b < 0x20 || b > 0x7E) return false;
            return true;
        }
Hex:33 41 21 33 35 33 Str:3A!353
Hex:34 30 31 33 35 33 Str:401353

两个结果输入,均正确,看来还是有多解答。

辅以IDA分析图,会更清洗。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
赞赏记录
参与人
雪币
留言
时间
伯爵的信仰
为你点赞~
2023-9-2 13:33
最新回复 (2)
雪    币: 55943
活跃值: (21565)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
题目重新下载,修正了bug,去除了这一行:
ms_exc.registration.TryLevel = 0;
2019-6-10 16:09
0
雪    币: 5583
活跃值: (3508)
能力值: ( LV12,RANK:417 )
在线值:
发帖
回帖
粉丝
3
kanxue 题目重新下载,修正了bug,去除了这一行: ms_exc.registration.TryLevel = 0;
版主,我输入了3A!353提示正确啊。
2019-6-26 17:44
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册