2021.牛转乾坤.CTF公测赛-REVESE-wp

首先吐槽一下红客训练营得到赛题居然没有pwn,只能去试试Reverse了

CrackMe

  1. 例行检查,无壳儿,32位程序
    在这里插入图片描述
  2. 运行一下程序,看看大概的情况
    在这里插入图片描述
  3. 32位ida打开,我想检索字符串FALSE,找到关键函数,但是好像在字符串窗口找不到,去rdata段(资源数据段,程序用到什么资源数据都在这里)和data段(这个段存放程序的全局数据、全局常量等)找找看,最后让我在rdata段找到了‘FALSE’
    在这里插入图片描述
    ctrl+x找到引用它的函数
int __thiscall sub_401730(CWnd *this)
{
    
    
  int v2; // edi
  HMODULE v3; // eax
  int v4; // edx
  struct CWnd *v5; // eax
  int v6; // esi
  int i; // eax
  int v8; // eax
  CWnd *v9; // eax
  char v11[4]; // [esp+10h] [ebp-1D0h] BYREF
  int v12; // [esp+14h] [ebp-1CCh]
  int v13; // [esp+18h] [ebp-1C8h]
  int v14; // [esp+1Ch] [ebp-1C4h] BYREF
  int v15; // [esp+20h] [ebp-1C0h]
  char v16[396]; // [esp+24h] [ebp-1BCh] BYREF
  int v17[8]; // [esp+1B0h] [ebp-30h]
  int v18; // [esp+1DCh] [ebp-4h]

  v17[0] = 0xE;       #初始化的数据
  v17[1] = 0x28;
  v17[2] = 0xC;
  v17[3] = 0x39;
  v17[4] = 6;
  v17[5] = 5;
  v17[6] = 0x20;
  v17[7] = 0x1F;
  ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&v14);
  v2 = 0;
  v18 = 0;
  ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(v11);
  LOBYTE(v18) = 1;
  v3 = GetModuleHandleW(0);
  v4 = *((unsigned __int8 *)v3 + 1);
  v12 = *(_BYTE *)v3;
  v13 = v4;
  CWnd::UpdateData(this, 1);
  v5 = CWnd::GetDlgItem(this, 1000);
  CWnd::GetWindowTextW(v5);
  v6 = *(_DWORD *)(v14 - 12);
  v15 = 0;
  memset(v16, 0, sizeof(v16));
  if ( v6 > 0 )
  {
    
    
    do
    {
    
    
      *(&v15 + v2) = (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&v14, v2);
      ++v2;
    }
    while ( v2 < v6 );
  }
  for ( i = 0; i < v6; ++i )
  {
    
    
    if ( (i & 1) != 0 )
      *(&v15 + i) ^= v13;
    else
      *(&v15 + i) ^= v12;
  }
  v8 = 0;
  if ( v6 <= 0 )
    goto LABEL_14;
  do
  {
    
    
    if ( *(&v15 + v8) != v17[v8] )
      break;
    ++v8;
  }
  while ( v8 < v6 );
  if ( v8 == 8 && v6 == 8 )
  {
    
    
    MessageBoxW(0, L"TRUE", &Caption, 0);
  }
  else
  {
    
    
LABEL_14:
    MessageBoxW(0, L"FALSE", &word_4037A8, 0);
    ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::operator=(&v14, &unk_4037C0);
    v9 = CWnd::GetDlgItem(this, 1000);
    CWnd::SetWindowTextW(v9);
  }
  ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(v11);
  return ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::~CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&v14);
}

大概就是一开始给我们初始化了一个数据,计算一下i&1,发现然是错位跟v13和v12进行异或操作,所以说这题的主要逻辑是将我们输入的数据错位跟v13和v12进行异或操作,最后得到初始化的那个数组。只要将初始化的那个数组跟v13还有v12异或一下,就能得到正确的输入值
在这里插入图片描述
v13和v12的值来自这里

v3 = GetModuleHandleW(0);
v4 = *((unsigned __int8 *)v3 + 1);
v12 = *(_BYTE *)v3;
v13 = v4;

百度百科关于GetModuleHandleW(0)函数的解释,看字面意思没太理解,当时就卡在这里了,用od调试了半天,没找到v13和v12的值
在这里插入图片描述
比赛结束后用ida调试,根据初始化数组的长度为8,所以我们输入的数据长度也是8,动调的时候随便输入长度为8的字符串即可
找到了他们的值,赋值语句主要在这边,在locals窗口找到了v12和v13
在这里插入图片描述
在这里插入图片描述
得到了v12和v13的值,就可以写个脚本算一下正确的注册码了

a=[0x0e,0x28,0x0c,0x39,6,5,0x20,0x1f]

v12=0x4d
v13=0x5a

string=""

for i in range(8):
    if (i&1)!=0:
        string+=chr(a[i]^v13)
    else:
        string+=chr(a[i]^v12)

print(string)

在这里插入图片描述
在这里插入图片描述
应该是由于我不熟悉汇编,所以相比od,ida我用的更顺手些。

Antidebug

  1. 例行检查,32位程序,无壳儿
    在这里插入图片描述
  2. 运行一下程序,看看大概的情况
    在这里插入图片描述
  3. 由于是对话框的输入,首先用Resource Hacker来寻找一下输入框的位置,看到key的控件标识是1000
    在这里插入图片描述
    在ida中alt+i,调出搜索立即数框,搜索1000
    在这里插入图片描述
    找到调用的地方
    在这里插入图片描述
    双击来到关键函数处,发现有jz 和 jnz跳转到相同位置,初步怀疑这里有花指令影响了ida的正常运行,nop(key path -> Fill range ,pathc为nop)掉
    在这里插入图片描述
    他们跳转到的local_401524,注意 00401524是个多字节指令,先使用快捷键d转为数据,然后将它nop掉,再将后边的使用快捷键c转为代码
    修改后如图
    在这里插入图片描述
    在找到函数开始的位置push ebp的地方,右键 create function,然后就能f5查看伪代码了
    在这里插入图片描述
    在这里插入图片描述
    逻辑很简单,当输入的值等于2882395322的时候提示正确
    在这里插入图片描述
    这题主要是考察了一个去花指令

猜你喜欢

转载自blog.csdn.net/mcmuyanga/article/details/113745699