BUUCTF [FlareOn6]Overlong

两种思路

第一种 修改程序使MessageBox输出完整flag

image
(这是修改后的版本)
查看 byte_402008
image
很长一串
而修改前 sub_401160只处理了28个字符
所以我们将28改为0xaf 这里由于Ollydbg打开地址偏移很难定位 直接用WinHex
找到对应的 6A 1C (push命令)
修改为 6A AF 即可
image
然后运行exe就可以得到flag了
image

另一种思路:

利用给出的 byte_402008 顺着程序思路写代码破解28位后的也行
只是这里有些 像_BYTE 这种的处理有点麻烦
先贴一份:

#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
int __cdecl sub_401000(unsigned __int8 *a1, unsigned char *a2)
{
  int v3; // [esp+0h] [ebp-8h]
  unsigned __int8 v4; // [esp+4h] [ebp-4h]

  if ( (int)(unsigned __int8)*a2 >> 3 == 30 )
  {
    v4 = a2[3] & 0x3F | ((a2[2] & 0x3F) << 6);
    v3 = 4;
  }
  else if ( (int)(unsigned __int8)*a2 >> 4 == 14 )
  {
    v4 = a2[2] & 0x3F | ((a2[1] & 0x3F) << 6);
    v3 = 3;
  }
  else if ( (int)(unsigned __int8)*a2 >> 5 == 6 )
  {
    v4 = a2[1] & 0x3F | ((*a2 & 0x1F) << 6);
    v3 = 2;
  }
  else
  {
    v4 = *a2;
    v3 = 1;
  }
  *a1 = v4;
  return v3;
}
unsigned int __cdecl sub_401160(TBYTE *a1,unsigned char *a2, unsigned int a3)
{
  unsigned int i; // [esp+4h] [ebp-4h]

  for ( i = 0; i < a3; ++i )
  {
    a2 += sub_401000(a1, a2);
    if ( !*a1++ )
      break;
  }
  cout<<a2<<"\n\n\n";
  return i;
}

signed main(){
	unsigned char byte_402008[] = {
		0xE0,0x81,0x89,0xC0,0xA0,0xC1,0xAE,0xE0,0x81,0xA5,
		0xC1,0xB6,0xF0,0x80,0x81,0xA5,0xE0,0x81,0xB2,0xF0,0x80,
		0x80,0xA0,0xE0,0x81,0xA2,0x72,0x6F,0xC1,0xAB,0x65,0xE0,
		0x80,0xA0,0xE0,0x81,0xB4,0xE0,0x81,0xA8,0xC1,0xA5,0x20,
		0xC1,0xA5,0xE0,0x81,0xAE,0x63,0xC1,0xAF,0xE0,0x81,0xA4,
		0xF0,0x80,0x81,0xA9,0x6E,0xC1,0xA7,0xC0,0xBA,0x20,0x49,
		0xF0,0x80,0x81,0x9F,0xC1,0xA1,0xC1,0x9F,0xC1,0x8D,0xE0,
		0x81,0x9F,0xC1,0xB4,0xF0,0x80,0x81,0x9F,0xF0,0x80,0x81,
		0xA8,0xC1,0x9F,0xF0,0x80,0x81,0xA5,0xE0,0x81,0x9F,0xC1,
		0xA5,0xE0,0x81,0x9F,0xF0,0x80,0x81,0xAE,0xC1,0x9F,0xF0,
		0x80,0x81,0x83,0xC1,0x9F,0xE0,0x81,0xAF,0xE0,0x81,0x9F,
		0xC1,0x84,0x5F,0xE0,0x81,0xA9,0xF0,0x80,0x81,0x9F,0x6E,
		0xE0,0x81,0x9F,0xE0,0x81,0xA7,0xE0,0x81,0x80,0xF0,0x80,
		0x81,0xA6,0xF0,0x80,0x81,0xAC,0xE0,0x81,0xA1,0xC1,0xB2,
		0xC1,0xA5,0xF0,0x80,0x80,0xAD,0xF0,0x80,0x81,0xAF,0x6E,
		0xC0,0xAE,0xF0,0x80,0x81,0xA3,0x6F,0xF0,0x80,0x81,0xAD,0x00
	};
	unsigned char *text = new (unsigned char );
	int a3 = strlen((char *)byte_402008);
	unsigned char* a2 = byte_402008;
	unsigned char* d = text;
	for(int i=0;i<a3;i++){
		a2 += sub_401000(d,a2);
		int v3 = *d;
		d++;
		if(!v3)break;
	}
//	sub_401160()
	cout<<text;
}

由于 C++好像没有_BYTE(试试TBYTE说不定可以) 所以这些转来转去真的特别特别特别麻烦...
有空多研究研究吧...
这里还有个要特别注意的点
用unsigned char!!!
不然
image
超出范围了会报错 所以以后都用 unsigned char
然后用 unsigned char 修饰byte_402008后 strlen的时候又要将其转为char类型...
好的 现在发现也可以直接在IDA原来函数的基础上修改

#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
int __cdecl sub_401000(unsigned __int8 *a1, unsigned char *a2)
{
  int v3; // [esp+0h] [ebp-8h]
  unsigned __int8 v4; // [esp+4h] [ebp-4h]

  if ( (int)(unsigned __int8)*a2 >> 3 == 30 )
  {
    v4 = a2[3] & 0x3F | ((a2[2] & 0x3F) << 6);
    v3 = 4;
  }
  else if ( (int)(unsigned __int8)*a2 >> 4 == 14 )
  {
    v4 = a2[2] & 0x3F | ((a2[1] & 0x3F) << 6);
    v3 = 3;
  }
  else if ( (int)(unsigned __int8)*a2 >> 5 == 6 )
  {
    v4 = a2[1] & 0x3F | ((*a2 & 0x1F) << 6);
    v3 = 2;
  }
  else
  {
    v4 = *a2;
    v3 = 1;
  }
  *a1 = v4;
  return v3;
}
unsigned int __cdecl sub_401160(TBYTE *a1,unsigned char *a2, unsigned int a3)
{
  unsigned int i; // [esp+4h] [ebp-4h]

  for ( i = 0; i < a3; ++i )
  {
    a2 += sub_401000(a1, a2);
    if ( !*a1++ )
      break;
  }
//  cout<<a2<<"\n\n\n";
  return i;
}

signed main(){
	unsigned char byte_402008[] = {
		0xE0,0x81,0x89,0xC0,0xA0,0xC1,0xAE,0xE0,0x81,0xA5,
		0xC1,0xB6,0xF0,0x80,0x81,0xA5,0xE0,0x81,0xB2,0xF0,0x80,
		0x80,0xA0,0xE0,0x81,0xA2,0x72,0x6F,0xC1,0xAB,0x65,0xE0,
		0x80,0xA0,0xE0,0x81,0xB4,0xE0,0x81,0xA8,0xC1,0xA5,0x20,
		0xC1,0xA5,0xE0,0x81,0xAE,0x63,0xC1,0xAF,0xE0,0x81,0xA4,
		0xF0,0x80,0x81,0xA9,0x6E,0xC1,0xA7,0xC0,0xBA,0x20,0x49,
		0xF0,0x80,0x81,0x9F,0xC1,0xA1,0xC1,0x9F,0xC1,0x8D,0xE0,
		0x81,0x9F,0xC1,0xB4,0xF0,0x80,0x81,0x9F,0xF0,0x80,0x81,
		0xA8,0xC1,0x9F,0xF0,0x80,0x81,0xA5,0xE0,0x81,0x9F,0xC1,
		0xA5,0xE0,0x81,0x9F,0xF0,0x80,0x81,0xAE,0xC1,0x9F,0xF0,
		0x80,0x81,0x83,0xC1,0x9F,0xE0,0x81,0xAF,0xE0,0x81,0x9F,
		0xC1,0x84,0x5F,0xE0,0x81,0xA9,0xF0,0x80,0x81,0x9F,0x6E,
		0xE0,0x81,0x9F,0xE0,0x81,0xA7,0xE0,0x81,0x80,0xF0,0x80,
		0x81,0xA6,0xF0,0x80,0x81,0xAC,0xE0,0x81,0xA1,0xC1,0xB2,
		0xC1,0xA5,0xF0,0x80,0x80,0xAD,0xF0,0x80,0x81,0xAF,0x6E,
		0xC0,0xAE,0xF0,0x80,0x81,0xA3,0x6F,0xF0,0x80,0x81,0xAD,0x00
	};
	unsigned char *text = new (unsigned char );
	int a3 = strlen((char *)byte_402008);
//	unsigned char* a2 = byte_402008;
//	unsigned char* d = text;
//	for(int i=0;i<a3;i++){
//		a2 += sub_401000(d,a2);
//		int v3 = *d;
//		d++;
//		if(!v3)break;
//	}
	sub_401160(text,byte_402008,a3);
	cout<<text;
}

主要就是将 _BYTE改为TBYTE char全部改为unsigned char
好像C可以将unsigned char 和TBYTE自动类型转换
只是我这个程序好像有bug...image
怕是指针写炸了...学指针的时候全用数组写的
当然 这里可以直接将 text指向byte_402008就没问题了
但是不影响做题

总结

C的逆向还是要多用C编程实现 加深对 “底层的高级语言”的理解
(这种用python写的话就很难搞了...以后再加几个 LOBYTE HIBYTE...)

posted @ 2023-09-30 21:25  N0zoM1z0  阅读(26)  评论(0编辑  收藏  举报