IDA

好久没写博客了,最近在刷re,这道题是我觉得十分有意义的一道题。故AC后总结分享给大家。不足之处请指正

分析

直接导入IDA shift +F12

双击后按 ctrl + x跳转到被调用的函数中,按F5反编译,源代码如下

int func()
{int result; // eaxint v1[4]; // [esp+14h] [ebp-44h]unsigned __int8 v2; // [esp+24h] [ebp-34h] BYREFunsigned __int8 v3; // [esp+25h] [ebp-33h]unsigned __int8 v4; // [esp+26h] [ebp-32h]unsigned __int8 v5; // [esp+27h] [ebp-31h]unsigned __int8 v6; // [esp+28h] [ebp-30h]int v7; // [esp+29h] [ebp-2Fh]int v8; // [esp+2Dh] [ebp-2Bh]int v9; // [esp+31h] [ebp-27h]int v10; // [esp+35h] [ebp-23h]unsigned __int8 v11; // [esp+39h] [ebp-1Fh]char v12[29]; // [esp+3Bh] [ebp-1Dh] BYREFstrcpy(v12, "Qsw3sj_lz4_Ujw@l");printf("Please input:");scanf("%s", &v2);result = v2;if ( v2 == 65 ){result = v3;if ( v3 == 67 ){result = v4;if ( v4 == 84 ){result = v5;if ( v5 == 70 ){result = v6;if ( v6 == 123 ){result = v11;if ( v11 == 125 ){v1[0] = v7;v1[1] = v8;v1[2] = v9;v1[3] = v10;*(_DWORD *)&v12[17] = 0;while ( *(int *)&v12[17] <= 15 ){if ( *((char *)v1 + *(_DWORD *)&v12[17]) > 64 && *((char *)v1 + *(_DWORD *)&v12[17]) <= 90 )*((_BYTE *)v1 + *(_DWORD *)&v12[17]) = (*((char *)v1 + *(_DWORD *)&v12[17]) - 51) % 26 + 65;if ( *((char *)v1 + *(_DWORD *)&v12[17]) > 96 && *((char *)v1 + *(_DWORD *)&v12[17]) <= 122 )*((_BYTE *)v1 + *(_DWORD *)&v12[17]) = (*((char *)v1 + *(_DWORD *)&v12[17]) - 79) % 26 + 97;++*(_DWORD *)&v12[17];}*(_DWORD *)&v12[17] = 0;while ( *(int *)&v12[17] <= 15 ){result = (unsigned __int8)v12[*(_DWORD *)&v12[17]];if ( *((_BYTE *)v1 + *(_DWORD *)&v12[17]) != (_BYTE)result )return result;++*(_DWORD *)&v12[17];}result = printf("You are correct!");}}}}}}return result;
}

看着眼花,慢慢来讲
int8的v2-v6本质上就是字符,因为int8就是一个字节和char长度相等,
int32才是我们常说的四个字节
v2-v6和v11其实就是 ACTF{},中间的字符才是关键,也就是v7 v8 v9 v10这四个int32的变量,也就是4*4=16 个ascii字符
v7-v10赋值给了v1[0-3],后面其实就是v1和v12之间的比较,但是这个*((char *) 等指针看的眼花缭乱,下面慢慢理。

记住以下几点:
*((char *) 一个字节
*((_BYTE *) 一个字节
*(_DWORD *) 四个字节 相当于int32

我们分别看看 v1 和 v12的内存视图
v1 : 00 00 00 00 | 00 00 00 00 | 00 00 00 00 | 00 00 00 00
v12 : Qsw3sj_lz4_Ujw@l 0 | 0000 0000 0000
先看v1因为 int v1[4],所以v1有4个int32,分开来看,一个00代表了1字节数据(4个字节正好 1 int)
v1数组可以存4个int32位的整型,也可以看作4*4=16 个ascii字符。把如上反编译代码简化以下得到

int func()
{int result; // eaxint v1[4]; // [esp+14h] [ebp-44h]unsigned __int8 v2; // [esp+24h] [ebp-34h] BYREFunsigned __int8 v3; // [esp+25h] [ebp-33h]unsigned __int8 v4; // [esp+26h] [ebp-32h]unsigned __int8 v5; // [esp+27h] [ebp-31h]unsigned __int8 v6; // [esp+28h] [ebp-30h]int v7; // [esp+29h] [ebp-2Fh]int v8; // [esp+2Dh] [ebp-2Bh]int v9; // [esp+31h] [ebp-27h]int v10; // [esp+35h] [ebp-23h]unsigned __int8 v11; // [esp+39h] [ebp-1Fh]char v12[29]; // [esp+3Bh] [ebp-1Dh] BYREFstrcpy(v12, "Qsw3sj_lz4_Ujw@l");printf("Please input:");scanf("%s", &v2);result = v2;if ( v2 == 65 ){result = v3;if ( v3 == 67 ){result = v4;if ( v4 == 84 ){result = v5;if ( v5 == 70 ){result = v6;if ( v6 == 123 ){result = v11;if ( v11 == 125 ){v1[0] = v7;v1[1] = v8;v1[2] = v9;v1[3] = v10;point = 0; // \*(&v12+17) int point//char v12[29] = "Qsw3sj_lz4_Ujw@l";while ( point <= 15 ){if ( *((char *)v1 + point) > 65 && *((char *)v1 + point) <= 90 )*((_BYTE *)v1 + point) = (*((char *)v1 + point) - 51) % 26 + 65;/*如果为大写字母a = (a - 51) % 26 + 65*/if ( *((char *)v1 + point) > 96 && *((char *)v1 + point) <= 122 )*((_BYTE *)v1 + point) = (*((char *)v1 + point) - 79) % 26 + 97;/*如果为小写字母a = (a - 79) % 26 + 97*/++point;}point = 0;while ( point <= 15 ){result = (unsigned __int8)v12[point];if ( *((_BYTE *)v1 + point) != (_BYTE)result )return result;++point;}result = printf("You are correct!");
}

说明一:题目把v12后面没有用到的空间作为一个int整型存数字(虽然不够4个字节?这部分不是很懂,但不影响做题)即上面加粗的部分。

说明二:v1明明是一个int类型的数组,但是题目却使用了char类型指针,说明其实v1数字存放的是ascii字符。我们就应该把v1的内存分开来看,所以我在上面分开了。正好v12字符串的长度和v1的长度相等,v1其实就是我们要找的flag{}中间的那16个未知字符。每一个00 对应了一个字母。

说明三:*(_DWORD *)&v12[17]可以把他看成一个int整型的point,就是计算地址用的,就像数组中a[114]或者*a+114 这个形式

说明四:_BYTE就是char,无需在意。为什么留着这个没有简化?是因为让读者知道这时的v1不能简单地看作int类型数组。

说明五:point 从0到15长度为16,正好与v12字符串长度相等,也和我们flag长度相等。

解题

由简化后的代码可知:输入的字符经过了变换 -> 大小写字母有一个位移变换,其他字符不变。
那么我们把密码本反向构造好flag就直接出来了。

#[ACTF新生赛2020]rome1
# Author me 2023.6.6 22:03
dic = {}
'''
分别构造大小写密码本
'''
for key in range(65,90+1):value = ( key - 51) % 26 + 65dic[chr(value)] = chr(key)for key in range(97,122+1):value = ( key - 79) % 26 + 97dic[chr(value)] = chr(key)s = 'Qsw3sj_lz4_Ujw@l'
ans = ""
for i in s:if i in dic: # 是字母直接转换ans += dic[i]else:        # 不是字母的照旧ans += i
print(ans) # Cae3ar_th4_Gre@t
# 加上ACTF{}就得到 You are correct!

[BUUOJ] [RE] [ACTF新生赛2020] rome1相关推荐

  1. [SUCTF2018]babyre [ACTF新生赛2020]fungame

    文章目录 [SUCTF2018]babyre 惯用思维 常人思维 GAMEOVER [ACTF新生赛2020]fungame int __cdecl sub_401340(int a1) int __ ...

  2. BUU [ACTF新生赛2020]Universe_final_answer

    [ACTF新生赛2020]Universe_final_answer 首先查壳, 64bit 无壳 ida64位打开 main() __int64 __fastcall main(int a1, ch ...

  3. BUUCTF Misc 穿越时空的思念 [ACTF新生赛2020]outguess [HBNIS2018]excel破解 [HBNIS2018]来题中等的吧

    目录 穿越时空的思念 [ACTF新生赛2020]outguess [HBNIS2018]excel破解 [HBNIS2018]来题中等的吧 穿越时空的思念 下载文件 使用Audacity打开 点击图示 ...

  4. BUUCTF-MISC-[BJDCTF2020]你猜我是个啥~[ACTF新生赛2020]outguess

    文章目录 1.[BJDCTF2020]你猜我是个啥 2.秘密文件 3.[SWPU2019]神奇的二维码 4.[BJDCTF2020]一叶障目 5.[BJDCTF2020]just_a_rar 6.[B ...

  5. re学习笔记(59)BUUCTF - re - [ACTF新生赛2020]Oruga

    新手一枚,如有错误(不足)请指正,谢谢!! 题目链接:[ACTF新生赛2020]Oruga IDA64位载入,进入main函数 进入sub_78A()函数 类似于象棋里面的'车'吧,不过这个要走到障碍 ...

  6. BUUCTF——[ACTF新生赛2020]SoulLike——使用angr解

    64位无壳.IDApro打开,查看main函数 逻辑很简单,我们来查看sub_83A函数.点进去,toobig 看了其他博客. 我们需要将ida /ctg目录下的hexrays.cfg文件中的MAX_ ...

  7. [ACTF新生赛2020]fungame

    32位无壳 简单异或,解出来是 Re_1s_So0_funny but没有那么简单,这里只有16字节.继续分析: 这里出现了栈溢出: 4013BA函数的参数source 也就是v4(我们的flag) ...

  8. [ACTF新生赛2020]easyre

    脱壳 使用exeinfo查看文件,发现有upx,使用upxshell解压缩.之后放进IDA中. 查看程序 很明显V4和v16都是个数组.可以看出是将v4的每个值(一共12个),去和data的那个数组去 ...

  9. BUU_re_[ACTF新生赛2020]rome

    拖进IDA,查看main函数 int func() {int result; // eaxint v1; // [esp+14h] [ebp-44h]int v2; // [esp+18h] [ebp ...

最新文章

  1. selenium 获取请求返回内容的解决方案
  2. java简单通讯录的实现02person类_Java中Math类的简单介绍
  3. ubuntu下安装vim失败
  4. Longest Palindromic Substring
  5. 唐敏豪:我给MSU评测打9分
  6. 我的Google Analytics(分析)正式通知升级到新版本
  7. matlab读取excel第一列,读取excel中的数据把第一列相同的所有行数据输出成一个excel...
  8. python编程从入门到实战抛出异常_文件和异常——python从编程入门到实践
  9. Spring框架的本质:4那些高曝光率的Annotation
  10. python读取excel绘制柱状图_python读取excel制作柱状图和词云图片
  11. Nav2极简笔记03-启动文件launch
  12. 初探Java设计模式4:JDK中的设计模式
  13. 数据结构考研复习(详细指导)(持续更新中)
  14. 志愿者积分兑换小程序开发制作
  15. centOs7 安装docker 镜像
  16. 写的一个网页登录注册模板(css+js),注册成功后把账号保存到MySQL数据库,登录时从数据库查找进行验证(jsp+javabean)
  17. 基于矩阵分解模型的协同过滤理论概述(涉及到SVD,SVD++,TimeSVD++)
  18. IDEA插件系列(77):Spec Math symbols插件——数学符号
  19. w10计算机运行特别卡,Win10电脑运行卡死怎么办?Win10电脑卡死的解决方法
  20. Win32绘图总结篇(点、直线、折线、贝塞尔曲线、矩形、椭圆、圆弧、弓形、扇形、多边形等)

热门文章

  1. linux qgis源码编译,ubuntu安装QGIS(一)
  2. 浅谈驱动中强制结束进程的3种方法
  3. linux终端教程,Linux终端命令
  4. 需要使用cacti检测一台linux,部署cacti监控windows linux
  5. 4D毫米波雷达:成像距离超百米,成本仅为LiDAR十分之一
  6. 软考常考知识点整理-项目进度计划与项目进度管理计划
  7. 使用Python批量拼接图片
  8. Nutch和CasperJS的区别
  9. Python爬虫百度
  10. 使用JMeter测试Go WebSocket服务的并发