mobile2(gctf)
这题多少有点zz,用记事本打开xtml文件

打开后发现fl4g就是flag,神人题
Easy_vb
得到一个程序先查是否有壳,发现没有直接用IDA打开

用IDA打开后,先使用string去搜索一下一些关键字符,如flag,ctf

发现MCTF就是flag,将MCTF改为flag就行

Easy_Re
先查一下是否有壳

无壳,直接用IDA打开查看,F5查看一下main函数的伪代码,发现flag

从中可以看出flag就是v5的值,就是xmmword_413E34的ASCLL值,双击查看一下xmmword_413E34的值,这里xmmword和413E34的值是分开的,且都为十六进制

将其转换伪ASCLL字符得到

发现得到的ASCLL值有点像flag的倒序,因为flag的形式伪DUTCTF{},尝试之后得到真正的flag
DUTCTF{We1c0met0DUTCTF}
peter的手机
解压后得到一个后缀名伪ipa的文件,用010打开查看了一下,发现真实文件头为zip:50 4B 03 04

将文件名改为zip后解压,找到FirstOS文件,查看后发现是64位,用IDA64打开

发现一个重要函数,btn->button(按钮),用F5查看其伪代码,

分析后发现一个验证用户输入是否等于1997019247Acf,来得到right或error,尝试一下看看是不是flag,得到flag{1997019247Acf}
树木的小秘密
先用exeinfo查看一下是否有壳

无壳,且为64位,使用了Pyinstaller打包工具,使用工具进行反编译获取pyc,得到

在对123.pyc进行反编译得到flag信息,发现flag被base64加密过

解密后得到flag{my_name_is_shumu}
入门题
先查看一下是否有壳

没壳且为64位,用IDA打开查看

分析一下main函数的伪代码得到,这是一个flag验证程序,这里定义了一个长度为30字节数组v6,并在偏移22处设置了特定的64位值,对输入的字符先进行了+3,结果与 0x5A (90 in decimal) 进行异或,再与v6进行比较。
所以我们需要对v6进行逆推来获取flag,需要先与 0x5A 异或,再减3;根据思路写出脚本
python
# 1. 构造 v6 数组
# 初始字符串
initial_str = "35>0$/2#2/,6+08*>=282>,&"
v6 = list(initial_str.encode('utf-8')) # 转换为整数列表
# 2. 处理 QWORD 覆盖 (小端序)
# 0xDA626F696F38262C
overwrite_bytes = [0x2C, 0x26, 0x38, 0x6F, 0x69, 0x6F, 0x62, 0xDA]
# 从索引 22 开始覆盖
for i in range(8):
# 注意:initial_str 只有 24 字节,我们需要扩展数组以容纳到索引 29
if 22 + i < len(v6):
v6[22 + i] = overwrite_bytes[i]
else:
v6.append(overwrite_bytes[i])
# 确保总长度为 30 (题目中 v8 = 30)
v6 = v6[:30]
# 3. 逆向解密
flag = ""
for char_code in v6:
# 逻辑: (Input + 3) ^ 0x5A = v6
# 逆向: Input = (v6 ^ 0x5A) - 3
decrypted_char = (char_code ^ 0x5A) - 3
flag += chr(decrypted_char)
print(f"Flag: {flag}")
运行后得到flag;flag{reversing_made_easy_2025}
马老师杀毒卫士
解压后得到两个文件,先查一下exe文件,看一下是否有壳

没壳,32位,用IDA打开查看

用string搜索一下有关flag的字符

发现一串特殊字符,应该是栅栏密码,直接用随波逐流得到flag

游戏过关
先查一下是否有壳

打开程序尝试从1到8逐一输入尽然得到了flag

用iDA打开string查找了一下flag

没发现什么,然后去查看了一下mian函数的伪代码

判断得到flag所在位置位sub_457AB4,查看一下其数据


得到两个数组求和,在与0x13u求与,然后就可以通过脚本来自己计算flag
python
# py -3
# coding:utf-8
array1 = [18,64,98,5,2,4,6,3,6,48,49,65,32,12,48,65,31,78,62,32,49,32,1,57,96,3,21,9,4,62,3,5,4,1,2,3,44,65,78,32,16,97,54,16,44,52,32,64,89,45,32,65,15,34,18,16,0]
array2 = [123,32,18,98,119,108,65,41,124,80,125,38,124,111,74,49,83,108,94,108,84,6,96,83,44,121,104,110,32,95,117,101,99,123,127,119,96,48,107,71,92,29,81,107,90,85,64,12,43,76,86,13,114,1,117,126,0]
flag = ''
for i in range(len(array1)):
flag+= chr(array1[i] ^ array2[i] ^ 0x13 )
print (flag)
不好用的ce
用exeinfo查了之后没有发现壳

直接用IDA打开查看

发现不能进行F5,查看时发现一些特殊字符串,用随波逐流解密后得到了flag

patch_call
先查看是否有壳,发现没有后,用IDA打开

string查找字符串,没有发现有关flag的,先去查看main函数

发现printf函数,查看一下发现有关flag

love
得到文件后先查一下是否有壳,发现没壳使用IDA打开,通过string查找flag发现

追溯一下right flag发现其出现在main函数,去查看其伪代码得

这是一个flag验证程序,想要获得flag我们需要先查找str的值,对其每个字符进行减去索引,再逆向sub_4110BE函数

因为str前面被进行了for循环,所以我们需要逆回去解出dest,写一个简单脚本就可以了

得到dest的值为e2lfbDB2ZV95b3V9,通过对sub_4110BE函数的追溯得到dest值被进行了base64加密,密码表如下

解密后得到flag:{i_l0ve_you}
特殊的Base64
查了一下发现没壳,使用IDA打开,string一下发现特殊字符

发现这是一个简单的flag验证程序,且发现被加密的flag,加密方法为base64,且base64码表就在下面,解密后得到flag

flag{Special_Base64_By_Lich}
新年快乐
用exeinfo查看之后发现套了一个upx壳

使用脱壳工具将其进行脱壳处理

脱壳后再使用IDA打开进行分析,观察其主函数的伪代码发现这是一个简单的flag验证程序

它是将str1即输入的flag与str2进行比较,而str2的值就在上面,所以flag{HappyNewYear!}
xor
解压文件后先使用die去查看一下基本信息,发现无壳,是macos操作系统

直接用IDA打开进行分析,用F5查看一下其main函数

发现这是一个flag验证程序,但是对flag进行了异或加密,查看global的数据

得到global的数据跟据xor写个脚本解密获取flag
python
global_data = [
0x66, 0x0A, 0x6B, 0x0C, 0x77, 0x26, 0x4F, 0x2E, 0x40, 0x11,
0x78, 0x0D, 0x5A, 0x3B, 0x55, 0x11, 0x70, 0x19, 0x46, 0x1F,
0x76, 0x22, 0x4D, 0x23, 0x44, 0x0E, 0x67, 0x06, 0x68, 0x0F,
0x47, 0x32, 0x4F, 0x00
]
G = global_data[:33] # 只取前33个字节进行比较
flag_bytes = bytes([G[0]] + [G[i] ^ G[i-1] for i in range(1, 33)])
print("解密后的flag:", flag_bytes.decode())

reverse3
先使用die查看一下基本信息看看是否有壳

发现无壳使用IDA打开,查看一下main的伪代码

发现这是一个加密验证flag的程序,我们想要获取flag,需要对其进行逆推;
python
// 1. 先对输入进行某种变换
v3 = j_strlen(Str);
v4 = (const char *)sub_4110BE(Str, v3, v14);
// 2. 将变换后的结果复制到 Destination
strncpy(Destination, v4, 0x28u);
// 3. 对 Destination 进行简单的循环加法运算
v11 = j_strlen(Destination);
for ( j = 0; j < v11; ++j )
Destination[j] += j; // <--- 关键点:每个字符加上它的索引值
这里进行了一个简单的数学转换,变换后将得到Destination与str2进行比较,想要获得flag;
先查看str2的值,str2为加密后的flag

再查看sub_4110BE函数看看它对str进行那些加密

发现是一个标准的base64加密,且也给出了base64的索引表,根据逻辑我们写一个脚本来获取flag
python
import base64
# 目标字符串 (Str2)
target_str = "e3nifIH9b_C@n@dH"
# 第一步:逆向索引加法 (字符 - 索引)
decoded_str = ""
for i in range(len(target_str)):
# ord() 获取ASCII码,chr() 转回字符
original_char = chr(ord(target_str[i]) - i)
decoded_str += original_char
print(f"第一步结果 (Base64字符串): {decoded_str}")
# 第二步:Base64 解码
try:
# Base64解码通常需要填充 '=',如果长度不够需要手动补全
missing_padding = len(decoded_str) % 4
if missing_padding:
decoded_str += '=' * (4 - missing_padding)
flag = base64.b64decode(decoded_str).decode('utf-8')
print(f"最终 flag: {flag}")
except Exception as e:
print(f"解码出错: {e}")
运行脚本后得到flag

不一样的flag

查壳后发现没壳,且为32位,使用IDA打开查看;直接查看其main函数的伪代码

经过分析发现这题是一个迷宫解密,迷宫的原始数据即地图就是strcpy(v3, "*11110100001010000101111#"),字符串的长度为25,所以是一个5x5的矩阵
*1111
01000
01010
00010
1111#
从v3和v4来看,起始坐标应该为(0,0),v5为用户输入,而移动规则就是输入1 向上;输入2 向下;输入3 向左;输入4 向右;然后还有检测当前位置的字符是否等于49和35,49对应的ASCLL码为'1',35为'#';而1代表陷阱,#代表终点即通关;
根据v3,成功得到迷宫路径即得到flag:{222441144222}
SimpleRev
直接使用IDA打开查看其main函数

没发现什么重要信息,再去查看一下string

发现有关flag的信息,追溯一下Congratulation!

去查看一下Decry函数,发现这是一个自定义的维吉尼亚密码,程序逻辑是输入flag,使用密钥加密,加密进行对比

我们对其进行逆推获取flag,需要找到key和text的值,根据
text = (char *)join(key3, v9);
strcpy(key, key1);
strcat(key, src);
可以得到key和text的值,key的值等于key1加src;text的值等于key3与v9拼接
key3的值为
v9的值根据 v9[0] = 0x776F646168LL;
v9[1] = 0LL;
相对应的ASCLL值为hadow
key1的值为adsfk

scr的值根据*(_QWORD *)src = 0x534C43444ELL;得到为NDCLS(这里需要注意src的值是其ASCLL值的倒序,这里考察到小端序:在 x86/x64 架构(我们常用的电脑和服务器)中,多字节数据在内存中是低位在前,高位在后存储的。)
得到重要值后再根据加密逻辑写一个脚本获取flag

得到flag为flag{EFXKWOXZTI}


