polarisctf招新赛-2026~
1.Illusion
这标着是简单题,我倒要看看是怎么样的
用detect it easy看了一下并没有加壳

开头就有个字符串验证LABEL_12有exit(0)一看就是有异常退出
所以
1 | if ( n28024[0] != 'x' ) |
可以看出来最后一个下标18为}所以猜测字符串长为19
这道题应该有反调试首先是
输入之后直接来这个沉浸在幻术之中吧,那么main函数真的是程序的主逻辑所在吗
题目名称是illusion幻觉
1 | int func(void) |
c不允许这代码,它不允许常数表达式的函数调用
c规定静态存储期变量必须用常数表达式初始化,函数调用不是常量表达式
执行main/Wmain函数前,c/c++运行时库会进行一系列初始化,

在初始化时回到用_initterm与_initterm_,按表顺序遍历并调用,批量调用前置的初始化函数
1 | _initterm(&_initterm_ptr, &_initterm_ptr_end) |
发现调用sub_7FF7ABB81000//这简单题就有inlinehook,发现以前学的还是太浅了
VirtualProtect(MessageBoxA, 0xEu, 0x40u, &flOldProtect)
为什么是0xe这个14字节,因为jmp函数在汇编中jmp指令是ff 25 00 00 00 00 +8字节
指令由操作码(opcode)与操作数组成(oprand)
接着是关键hook函数
1 | MessageBoxA = (int (__stdcall *)(HWND, LPCSTR, LPCSTR, UINT))NtCurrentPeb(); |
知道提hook在内存中是
0~2字节0x48 0xB8(mov rax, xxx)
2~10字节 sub_7FF7ABB810F0
10~12字节 0xFF 0xE0(jmp rax)
lpAddress是MessageBoxA板块执行流hook到了sub_7FF7ABB810F0函数
MessageBoxA 本身的功能
它就是 Windows 最基础的弹窗函数:
1 | int MessageBoxA( |

很明显v8对明文进行加密,下面全是对v8的检验,v8一看就是很重要,直接追进去看看究竟是什么

进去一看很明显最后是
sub_7FF7ABB819F0((__int64)v76, (__int64)v77);为AES加密
而v77就是密钥,看一眼密钥
1 | v77[0] = 0x34123412; |
刚好是16字节,128位
memset(&v9[Size + n0x10_1], (unsigned __int8)n0x10, (unsigned int)(n0x10 - n0x10_1));这个明显是PKCS#7 / PKCS#5 填充
缺了多少字节,每个填充的字节就是多少
1 | from Crypto.Cipher import AES |
题中的部分汇编指令
1.movaps [rsp+48h+var_18], xmm6
将128为的XMM6寄存器保存到栈上(movaps要求16字节对齐,栈帧要严格对其)
2.cdq
符号位拓展,将EAX的符号位复制到EDX的所有位
3.and(位与&)
4.sar r8d, 4
算数右移4(R8D = R8D >> 4(算术右移,等效除以16))
CRT初始化
程序的默认入口点是CRT提供的函数:
控制台程序:mainCRTStartup
程序窗口:WinMainCRTStartup
主要完成
1.操作系统底层对接与安全环境准备(安全环境cookie初始化)
2.操作系统参数的翻译
3.CRT本身核心组件的初始化(Heap init, I/O系统与标准流,区域设置)
4.执行C++全局/静态对象的构造
5.执行main函数
Windows的API
GetModuleHandle:获取模块句柄,获取加载DLL的及地址
GetProcAdress:获取函数地址,从指定DLL中导出函数地址
VirtualProtect:修改内存保护属性,改变一快内存的权限
1 | Bool VirtualProtect( |
[in] LPVOID lpAddres是访问保护属性的页区域的起始页的地址
[in]SIZE_T dwSize:区域的大小
[in] flNewProtect内存保护选项
- 0x01 (
PAGE_NOACCESS):完全禁止访问。 - 0x02 (
PAGE_READONLY):只允许读取。 - 0x04 (
PAGE_READWRITE):允许读写,但不可执行。 - 0x20 (
PAGE_EXECUTE_READ):允许执行和读取(大多数代码段的默认状态)。 - 0x40 (
PAGE_EXECUTE_READWRITE):允许执行、读取和写入(你用的这个)。
[out] lpfloldProtect指向变量的指针,接受第一页先前的访问保存值(备份原来的值)
inlinehook
通过修改原函数开头的汇编指令,直接跳转到指定函数
## peb
1 | typedef struct _PEB { |
BeingDebugged检测debugg是返回1
2.FunPyVM
3.ESAYFinger
好久没做题了,开始复现

解压缩出附件来,发现是bin文件,直接用ida看
先找到sub_8003498

这是stm32时钟频率计算函数
1 | if ( (MEMORY[0x40023808] & 0xC) == 4 ) |
0x40023808:这是STM32的RCC(复位与时钟控制)
在stm32标准中0x0是HSI(频率一般为16HZ),0x4是HSE(high speed external),0x8(PLL,频率不固定)
其为STmHAL标准库的 RCC_GetClocksFreq 函数
对于另一个函数
1 | if (n0x5F > 0x5F) |
先是引脚引脚校验,之后将逻辑引脚号映射到物理引擎或寄存器偏移
stm32duino(Arduino Core for STM32)的标志性函数 digitalWrite
拼接好xmctf{ RCC_GetClocksFreq_digitalWrite}
