实验四:使用UPX加壳与脱壳

一、实验目的

    了解程序加壳、脱壳原理 掌握PE文件结构 学习利用UPX Shell、LoardPE、IDA等工具完成软件的加、脱壳操作

二、实验题目

    UPX加壳:对crackme加上UPX壳,用 LordPE 或 PEiD 工具查看加壳前后的变化 UPX脱壳:用UPX Unpacker对已加壳的 crackme.exe 程序进行脱壳 手动脱壳:使用ESP定律和Ollydbg工具对crackme.exe进行手工脱壳 IDA静态分析:用 IDA 的 F5 反汇编功能查看脱壳前后的程序伪代码,获取运行crackme后屏幕提示的输入口令

三、实验环境

    Windows 7系统或以上、连接Internet的主机 可能会用到的软件:upxshell、LordPE、PEiD、upx unpacker、IDA、OllyDBG 手动脱壳实例参考:https://www.52pojie.cn/thread-727090-1-1.html ESP定律学习参考:https://www.52pojie.cn/thread-394116-1-1.html

四、实验步骤及结果

4.1 UPX加壳

首先查看未加壳前的应用程序

现在使用UPX Shell对壳进行加载

检查发现已经加壳成功

4.2 UPX脱壳

用UPX Unpacker对已加壳的 crackme.exe 程序进行脱壳

4.3 手动脱壳

根据ESP定律先找到PUSHAD下使得ESP变红的内存地址

然后在数据窗口中追踪

然后使用断点 --> 硬件访问 --> Word

然后使用F9直接运行到

然后再F8运行到OEP

然后删除硬件断点

然后使用Ollydbg脱壳工具进行脱壳

可以发现dump出来的文件脱壳成功

4.4 IDA静态分析

使用IDA打开脱壳后的文件可以看到main函数源代码

// write access to const memory has been detected, the output may be wrong!
int main_0()
{
          
   
  int v0; // ST14_4
  int v1; // edx
  int result; // eax
  int v3; // ST14_4
  int v4; // edx
  unsigned int i; // [esp+50h] [ebp-2Ch]
  char v6; // [esp+54h] [ebp-28h]
  char v7; // [esp+55h] [ebp-27h]
  char v8; // [esp+56h] [ebp-26h]
  char v9; // [esp+57h] [ebp-25h]
  char v10; // [esp+58h] [ebp-24h]
  char v11; // [esp+59h] [ebp-23h]
  char v12; // [esp+5Ah] [ebp-22h]
  char v13; // [esp+5Bh] [ebp-21h]
  char v14; // [esp+5Ch] [ebp-20h]
  char v15; // [esp+5Dh] [ebp-1Fh]
  char v16; // [esp+5Eh] [ebp-1Eh]
  char v17; // [esp+5Fh] [ebp-1Dh]
  int v18; // [esp+60h] [ebp-1Ch]
  int v19; // [esp+64h] [ebp-18h]
  char v20[20]; // [esp+68h] [ebp-14h]

  v6 = r;
  v7 = o;
  v8 = i;
  v9 = s;
  v10 = 2;
  v11 = 0;
  v12 = 1;
  v13 = 4;
  v14 = r;
  v15 = o;
  v16 = i;
  v17 = s;
  v18 = ;
  v19 = ;
  printf("password:");
  scanf("%s", v20);
  if ( strlen(v20) == 12 )
  {
          
   
    for ( i = 0; i < 0xC && *(&v6 + i) == v20[i]; ++i )
      ;
    if ( i == 12 )
      printf("good job!
the key is your input!
");
    else
      printf("try again!
");
    if ( --stru_437180._cnt < 0 )
    {
          
   
      _filbuf(&stru_437180);
    }
    else
    {
          
   
      v3 = (unsigned __int8)*stru_437180._ptr;
      ++stru_437180._ptr;
    }
    if ( --stru_437180._cnt < 0 )
    {
          
   
      _filbuf(&stru_437180);
    }
    else
    {
          
   
      v4 = (unsigned __int8)*stru_437180._ptr;
      ++stru_437180._ptr;
    }
    result = 0;
  }
  else
  {
          
   
    printf("try again!!
");
    if ( --stru_437180._cnt < 0 )
    {
          
   
      _filbuf(&stru_437180);
    }
    else
    {
          
   
      v0 = (unsigned __int8)*stru_437180._ptr;
      ++stru_437180._ptr;
    }
    if ( --stru_437180._cnt < 0 )
    {
          
   
      _filbuf(&stru_437180);
    }
    else
    {
          
   
      v1 = (unsigned __int8)*stru_437180._ptr;
      ++stru_437180._ptr;
    }
    result = 0;
  }
  return result;
}

程序是在与字符串rois2014rois进行比较,所以密码就是rois2014rois,测试成功

经验分享 程序员 微信小程序 职场和发展