测试文件:https://buuoj.cn/files/aa4f6c7e8d5171d520b95420ee570e79/a9d22a0e-928d-4bb4-8525-e38c9481469e.rar?token=eyJ0ZWFtX2lkIjpudWxsLCJ1c2VyX2lkIjoxOTAzLCJmaWxlX2lkIjoxNTl9.XXCjMA.QBNzEL8Ujfk_QRbQYa6XZ3dYjQ4

1.准备

获得信息

  1. 32位文件

2.IDA打开

将main函数反编译为C语言代码

int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx
int v4; // edi
int v5; // esi return main_0(v3, v4, v5);
}

打开main_0函数

 __int64 __usercall main_0@<edx:eax>(int a1@<ebx>, int a2@<edi>, int a3@<esi>)
{
int v3; // eax
const char *v4; // eax
size_t v5; // eax
int v6; // edx
__int64 v7; // ST08_8
signed int j; // [esp+DCh] [ebp-ACh]
signed int i; // [esp+E8h] [ebp-A0h]
signed int v11; // [esp+E8h] [ebp-A0h]
char Dest[]; // [esp+F4h] [ebp-94h]
char Str; // [esp+160h] [ebp-28h]
char v14; // [esp+17Ch] [ebp-Ch] for ( i = ; i < ; ++i )
{
if ( (unsigned int)i >= 0x64 )
j____report_rangecheckfailure(a1, a2, a3);
Dest[i] = ;
}
sub_41132F("please enter the flag:");
sub_411375("%20s", &Str);
v3 = j_strlen(&Str);
v4 = (const char *)sub_4110BE((int)&Str, v3, (int)&v14);
strncpy(Dest, v4, 0x28u);
v11 = j_strlen(Dest);
for ( j = ; j < v11; ++j )
Dest[j] += j;
v5 = j_strlen(Dest);
if ( !strncmp(Dest, Str2, v5) )
sub_41132F("rigth flag!\n");
else
sub_41132F("wrong flag!\n");
HIDWORD(v7) = v6;
LODWORD(v7) = ;
return v7;
}

2.1代码分析

第24行代码,第27~28行代码在对Dest进行一些列变换

从第30行代码分析得到,Str2中存储的就是flag变换过后的字符串,打开Str2

.data:0041A034 ; char Str2[]
.data:0041A034 Str2 db 'e3nifIH9b_C@n@dH', ; DATA XREF: _main_0+142↑o

因此,我们只需要将Str2反向变换即可得到flag。

第27~28行代码的变换没有难度,再来看看第24行代码的函数。

 void *__cdecl sub_411AB0(char *a1, unsigned int a2, int *a3)
{
int v4; // STE0_4
int v5; // STE0_4
int v6; // STE0_4
int v7; // [esp+D4h] [ebp-38h]
signed int i; // [esp+E0h] [ebp-2Ch]
unsigned int v9; // [esp+ECh] [ebp-20h]
int v10; // [esp+ECh] [ebp-20h]
signed int v11; // [esp+ECh] [ebp-20h]
void *Dst; // [esp+F8h] [ebp-14h]
char *v13; // [esp+104h] [ebp-8h] if ( !a1 || !a2 )
return ;
v9 = a2 / ;
if ( (signed int)(a2 / ) % )
++v9;
v10 = * v9;
*a3 = v10;
Dst = malloc(v10 + );
if ( !Dst )
return ;
j_memset(Dst, , v10 + );
v13 = a1;
v11 = a2;
v7 = ;
while ( v11 > )
{
byte_41A144[] = ;
byte_41A144[] = ;
byte_41A144[] = ;
for ( i = ; i < && v11 >= ; ++i )
{
byte_41A144[i] = *v13;
--v11;
++v13;
}
if ( !i )
break;
switch ( i )
{
case :
*((_BYTE *)Dst + v7) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[] >> ];
v4 = v7 + ;
*((_BYTE *)Dst + v4++) = aAbcdefghijklmn[((byte_41A144[] & 0xF0) >> ) | * (byte_41A144[] & )];
*((_BYTE *)Dst + v4++) = aAbcdefghijklmn[];
*((_BYTE *)Dst + v4) = aAbcdefghijklmn[];
v7 = v4 + ;
break;
case :
*((_BYTE *)Dst + v7) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[] >> ];
v5 = v7 + ;
*((_BYTE *)Dst + v5++) = aAbcdefghijklmn[((byte_41A144[] & 0xF0) >> ) | * (byte_41A144[] & )];
*((_BYTE *)Dst + v5++) = aAbcdefghijklmn[((byte_41A144[] & 0xC0) >> ) | * (byte_41A144[] & 0xF)];
*((_BYTE *)Dst + v5) = aAbcdefghijklmn[];
v7 = v5 + ;
break;
case :
*((_BYTE *)Dst + v7) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[] >> ];
v6 = v7 + ;
*((_BYTE *)Dst + v6++) = aAbcdefghijklmn[((byte_41A144[] & 0xF0) >> ) | * (byte_41A144[] & )];
*((_BYTE *)Dst + v6++) = aAbcdefghijklmn[((byte_41A144[] & 0xC0) >> ) | * (byte_41A144[] & 0xF)];
*((_BYTE *)Dst + v6) = aAbcdefghijklmn[byte_41A144[] & 0x3F];
v7 = v6 + ;
break;
}
}
*((_BYTE *)Dst + v7) = ;
return Dst;
}

在代码的下部分,可以看到Dst会经过aAbcdefghijklmn[]数组的变换,打开此处

.rdata:00417B30 aAbcdefghijklmn db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
.rdata:00417B30 ; DATA XREF: .text:004117E8↑o
.rdata:00417B30 ; .text:↑o ...
.rdata:00417B30 db
.rdata:00417B72 align

从'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='可以看出,这个函数应该是base64的加密函数,因此只需要解密即可。

3.脚本获取flag

import base64

str1 = 'e3nifIH9b_C@n@dH'
x = ''
flag = '' for j in range(0, len(str1)):
x += chr(ord(str1[j]) - j) flag = base64.b64decode(x)
flag = flag.decode('ASCII')
print(flag)

4.get flag!

flag{i_l0ve_you}

最新文章

  1. 【神器】vimum在浏览器中键盘操作选择、复制、粘贴,键盘党的最爱
  2. js中几种常用的输出方式
  3. li 前面的缩进怎么去除?
  4. java 的SPI机制
  5. macbook安装win7
  6. Qt label加边框
  7. 微信支付(APP)集成时碰到的问题(.net提示“无权限”、iOS跳转到微信支付页面中间只有一个“确定”按钮)
  8. 对大一新生开始学习C语言课程谈几点看法
  9. linux命令 chattr超级权限控件
  10. 利用Sambaserver在Ubuntu系统和Win7系统间共享目录
  11. data Mining with Weka: Trailer More Data Mining with Weka 用weka 进行数据挖掘 Weka 用weka 进行更多数据挖掘
  12. ReactJS入门:展示数据
  13. VS2013+MFC串口控件的简单上位机
  14. 交换排序—快速排序(Quick Sort)
  15. 三消游戏FSM状态机设计图
  16. linux之Ubuntu学习
  17. 首页背景图片在PC端有显示,在手机端不显示的解决方法
  18. MySQL数据库排序选择的作用和该如何选择编码格式
  19. STM32 一个定时器产生4路 独立调频率,占中比可调,脉冲个数可以统计。
  20. cdh 安装系列1-- manager 6.01 安装

热门文章

  1. NtQuerySystemInformation
  2. java并发学习第五章--线程中的锁
  3. alert(1) to win 3
  4. PHP Session 序列化及反序列化处理器设置使用不当带来的安全隐患(转)
  5. java int整数相乘溢出
  6. java基础复习(四)
  7. VR和AR
  8. python-zx笔记11-测试压力管理
  9. HTTP请求时候总是设置的两个参数ConnectionTimeOut和SocketTimeOut
  10. linux之yum源的RPM软件包管理