BUUCTF [FlareOn6]Overlong
两种思路
第一种 修改程序使MessageBox输出完整flag
(这是修改后的版本)
查看 byte_402008
很长一串
而修改前 sub_401160只处理了28个字符
所以我们将28改为0xaf 这里由于Ollydbg打开地址偏移很难定位 直接用WinHex
找到对应的 6A 1C (push命令)
修改为 6A AF 即可
然后运行exe就可以得到flag了
另一种思路:
利用给出的 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!!!
不然
超出范围了会报错 所以以后都用 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...
怕是指针写炸了...学指针的时候全用数组写的
当然 这里可以直接将 text指向byte_402008就没问题了
但是不影响做题
总结
C的逆向还是要多用C编程实现 加深对 “底层的高级语言”的理解
(这种用python写的话就很难搞了...以后再加几个 LOBYTE HIBYTE...)