01--AFCTF--re2(SMC)

SMC(self-Modifying Code) 自修改代码,程序在执行某段代码的过程中会对程序的代码进行修改,只有在修改后的代码才是可汇编,可执行的。在程序未对该段代码进行修改之前,在静态分析状态下,均是不可读的字节码。调试时遇到的一个问题在使用IDA进行调试的过程中可能会遇到Create Process Fail这个错误,这是因为被调试程序的路径不是全英文的。ID...
摘要由CSDN通过智能技术生成

SMC(self-Modifying Code)

自修改代码,程序在执行某段代码的过程中会对程序的代码进行修改,只有在修改后的代码才是可汇编,可执行的。在程序未对该段代码进行修改之前,在静态分析状态下,均是不可读的字节码。

调试时遇到的一个问题

在使用IDA进行调试的过程中可能会遇到Create Process Fail这个错误,这是因为被调试程序的路径不是全英文的。

IDA调试常用快捷键

  • F2:在选中位置下断点
  • F4:选中某条指令,按下F4,程序会执行到该处。如果对某条指令按F4,实际上执行了下面一系列操作:在该处设置硬件断点—>启动程序使之运行到该处暂停—>删除该处的硬件断点。
  • F5:反编译成伪C代码
  • F7:单步执行,遇到函数调用跟进函数内部
  • CTRL+F7:运行至返回。继续执行当前函数,知道该函数返回或者遇到一个断点时停止。
  • F8:单步执行,遇到函数调用不跟进
  • F9:执行代码,遇到断点则停

解题过程

选择动态调试。
这里写图片描述
选择 Local Windows debugger。
这里写图片描述
在主函数的第一条指令下一个断点。
这里写图片描述
点击开始调试图标进行调试
这里写图片描述
此时程序停在主函数第一条指令上面,按F5反编译成伪C代码,如下:

int wmain()
{
  char *v0; // eax
  int v1; // ST24_4
  __int16 v2; // ST28_2
  char v4; // [esp+1Ch] [ebp-40h]
  char v5; // [esp+36h] [ebp-26h]
  int v6; // [esp+38h] [ebp-24h]
  __int16 v7; // [esp+3Ch] [ebp-20h]
  int v8; // [esp+40h] [ebp-1Ch]
  __int16 v9; // [esp+44h] [ebp-18h]
  int v10; // [esp+48h] [ebp-14h]
  char *v11; // [esp+4Ch] [ebp-10h]
  int i; // [esp+50h] [ebp-Ch]
  int v13; // [esp+54h] [ebp-8h]
  __int16 v14; // [esp+58h] [ebp-4h]

  i = 0;
  printf("Welcome to AFCTF,I hope you have a good time!\n");
  scanf("%s", &v4);
  if ( strlen(&v4) == 27 )
  {
    if ( !strncmp(&v4, "afctf{", 6u) && v5 == 125 )
    {
      v5 = 0;
      v0 = strtok(&v4, "_");
      v11 = v0;
      v0 += 6;
      v8 = *(_DWORD *)v0;
      v9 = *((_WORD *)v0 + 2);
      v13 = *(_DWORD *)(v11 + 6);
      v14 = *((_WORD *)v11 + 5);
      v11 = strtok(0, "_");
      v6 = *(_DWORD *)v11;
      v7 = *((_WORD *)v11 + 2);
      v11 = strtok(0, "_");
      v1 = *(_DWORD *)v11;
      v2 = *((_WORD *)v11 + 2);
      dword_122EF70 = (int)dword_1237F50;
      if ( ((int (__cdecl *)(int *))dword_1237F50[0])(&v8) )
      {
        v10 = SHIBYTE(v14) ^ (char)v13 ^ (char)v14 ^ SHIBYTE(v13) ^ SBYTE2(v13) ^ SBYTE1(v13);
        for ( i = 256; i < 496; ++i )
          byte_1238048[i] = v10 ^ *(_BYTE *)(i + 19103816);
        JUMPOUT(__CS__, &byte_1238048[256]);
      }
      printf("Wrong\n");
    }
    else
    {
      printf("Wrong\n");
    }
  }
  else
  {
    printf("Wrong\n");
  }
  return 0;
}

这段代码的意思是:首先判断输入的flag长度是否为27、开头6个字母是否为“afctff{”、结尾字符是否为“}”;接下来将afctf{……}中间的内容取出来,以’_’为分界符将其分成三段,每段6个字节。然后进入if判断。
在39行下一个断点,按F9执行到这里,在终端随便输入一个符合格式的字符串:afctf{123456_123456_123456},按下F7跟进验证函数。
这里写图片描述
接下来看到汇编代码如下:

.data:01237F50 add     esi, 43AEF761h
.data:01237F56 call    $+5
.data:01237F5B pop     esi
.data:01237F5C push    edi
.data:01237F5D xor     edi, edi
.data:01237F5F
.data:01237F5F loc_1237F5F:                            ; CODE XREF: .data:01237F75↓j
.data:01237F5F cmp     edi, 0C0h
.data:01237F65 jg      short loc_1237F7B
.data:01237F67 mov     bl, [esi+edi+25h]
.data:01237F6B xor     bl, 73h
.data:01237F6E mov     [esi+edi+25h], bl
.data:01237F72 add     edi, 1
.data:01237F75 jmp     short loc_1237F5F
.data:01237F75 ; ---------------------------------------------------------------------------
.data:01237F77 db  65h ; e
.
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值