re1
nop一下
改eip到
import re
# 输入文本(假设已经复制到剪贴板或保存在文件中)
text = """
Ooooooooookkkkkkkay, thank you for waiting me for such a long time, here are the 1th char of flag... Z
............................................................
Ooooooooookkkkkkkay, thank you for waiting me for such a long time, here are the 2th char of flag... J
............................................................
Ooooooooookkkkkkkay, thank you for waiting me for such a long time, here are the 3th char of flag... N
............................................................
Ooooooooookkkkkkkay, thank you for waiting me for such a long time, here are the 4th char of flag... U
。。。。。。。。。。。。。。。。。。。。。。。
............................................................
Ooooooooookkkkkkkay, thank you for waiting me for such a long time, here are the 113th char of flag... G
............................................................
Ooooooooookkkkkkkay, thank you for waiting me for such a long time, here are the 114th char of flag... }
............................................................
2025-04-06 12:37:28 [2] Closing connection from 127.0.0.1...
"""
# 使用正则表达式提取所有 flag 字符
pattern = r"here are the \d+th char of flag... (.)"
matches = re.findall(pattern, text)
# 拼接所有字符
flag = "".join(matches)
print("提取的 flag 是:")
print(flag)
#submit ZJNUCTF{wOw_y0u_ARE_tHe_7lme_maSTeR_@Nd_y0u_Wi1I_Kn0w_The_TrUTH_i_H#pE_yoU_GO7_7h1S_Fl4G_wI7h0Ut_wA1Tin6_7o0_L#nG}
re2
改了delta,记得转端序
#include <stdio.h>
#include <stdint.h>
void decrypt(uint32_t* v, uint32_t* k) {
uint32_t v0 = v[0], v1 = v[1], sum = 0x11451419 *32, i; //这里的sum是0x9e3779b9*32后截取32位的结果,截取很重要。//这里的数据类型可能会有符号,可以尝试改为int
uint32_t delta = 0x11451419;
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
for (i = 0; i < 32; i++) {
v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
sum -= delta;
}
v[0] = v0; v[1] = v1;
}
int main()
{
uint32_t v[8] = { 0x25B0D6B1, 0xE4CC934B, 0xB088C228, 0x3B7C4A5F, 0x84C1227A, 0x28A3FF7C },
k[4] = { 0x736E3161,0x6C65775F,0x656D6F63,0x756F795F }; //若有多组数据,可以每两个进行加密。
for (int i = 0; i < 6; i += 2) {
decrypt(&v[i], k);
}
for (int i = 0; i < 40; i++) {
printf("%c", *((char*)v + i));
}
return 0;
}
re3
程序藏在脱壳代码中,而不是内部程序。
有花指令
push全面的全是花指令全部nop掉,下面有一段smc,data就是上面那段函数,注意只有132位,记得计算。
i =0
data[i++] ^= 0xcc
i>132 -->jmp
解密后恢复函数
v10为我们的输入,从上面的start的rdi寄存器可以看出来
加密逻辑
for ( j = 0LL; *(&word_9B1E + j) == ((((j ^ *(v10 + j) ^ 0x66) >> 4) | (16 * (j ^ *(v10 + j) ^ 0x66))) ^ 0x55); ++j )
解密脚本
#include<stdio.h>
#include<stdint.h>
int main()
{
unsigned char data[] = {
0x96, 0x87, 0xF7, 0x56, 0x47, 0x26, 0x37, 0xF4, 0xC6, 0x57, 0xE4, 0x76, 0x66, 0xD1, 0x84, 0x36,
0x54, 0xE4, 0xF4, 0x46, 0x87, 0xB4, 0x04, 0xB7, 0xE5, 0xA7, 0x17, 0x77, 0x64, 0xD7, 0x27, 0xA6,
0x66, 0xC5, 0xF7, 0x94, 0x84, 0xA7, 0xA5, 0xD5, 0x44, 0xA5, 0x77, 0xC7, 0x04, 0x67, 0xE3, 0xB6,
0xC5, 0x64, 0x03, 0x46, 0x85, 0xF5, 0xA6, 0x15, 0x45, 0xC6, 0x56, 0x64, 0xB6, 0x37
};
for (int i = 0; i < 62; i++) {
data[i] ^= 0x55;
data[i] = (data[i] << 4) | (data[i] >> 4);
data[i] ^= 0x66;
data[i] ^= i;
printf("%c", data[i]);
}
}
re4
第一处的逻辑
vqtbl1q_s8(*(int8x16_t *)&StringUTFChars_1[16 * i], t)对应汇编代码 TBL V0.16B, {V0.16B}, V1.16B;即以v1为索引,在表v0中查找值,放入v0中,这里是128位为一组进行操作,每次操作都是以byte为单位,逻辑大概是
for i in range(16):
data[i] = input[table[i]
#逆
for i in range(16):
res[table[i]] = data[i]
再对表进行异或修改,用修改后的表继续下一组操作,一共3组128位数据共48字节。一起的逻辑是
for j in range(3):
for i in range(16):
data[i + j*16] = input[table[i]+ j*16]
table[i] ^= j
下面有个循环位移,后面还有个换表base64解密就行
#include<stdio.h>
#include<stdint.h>
#include"base64.h"
#include <string.h>
int main()
{
int table[] = { 0xD, 0xE, 0xF, 0xC, 0xB, 0xA, 9, 8, 6, 7, 5, 4, 2 ,3, 1, 0 };
//abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ3456780129+/
unsigned char data[100] = "KJn0QBi+7Zba70HhyITl3Rv1c0K77QrGKIWWI08jStDTK1DLw1fPc1DNk1zRg09P";
decodeBase64((char*)data, sizeof(data));
//unsigned char data[] = { 0x92,0x33,0x7a,0xa9,0xb2,0x3e,0xe3,0x30,0x40,0xe3,0xa8,0x47,0x62,0x2b,0x4b,0xd2,0xb5,0x7b,0x0b,0xa9,0x38,0xe2,0xa4,0x60,0x92,0x2c,0x30,0x8b,0xae,0x49,0xb1,0x37,0x6d,0x93,0xb7,0x65,0x5b,0xb1,0x69,0x0b,0xb7,0x67,0x2b,0xb6,0x6b,0x1b,0xaf,0x69 };
unsigned char mm[100],res[100];
for (int j = 0; j <= 47; j += 3)
{
data[j] = ((unsigned __int8)data[j] << 5) | (data[j]>>3);
data[j + 1] = ((unsigned __int8)data[j + 1] << 1) | (data[j + 1] >> 7);
data[j + 2] = data[j + 2];
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 16; j++) {
data[j+i*16] ^= table[j];
}
for (int j = 0; j < 16; j++) {
res[table[j] + i * 16] = data[j + i * 16];
table[j] ^= i;
}
}
}