文章总结: 本文介绍利用C语言宏和switch-case技巧实现协程的方法,通过crBegin、crReturn、crFinish三个宏配合静态变量保存状态,利用__LINE__宏生成唯一case标签实现执行流跳转,达到函数暂停与恢复的效果。该技术源自达夫设备变种,展示了C语言底层编程技巧,但存在代码可读性差、依赖静态变量等局限,适合嵌入式等特定场景使用。 综合评分: 65 文章分类: 安全开发,二进制安全,其他
【赤石C++】使用宏魔法在 C 语言中实现协程
原创
crackme.net crackme.net
crackme安全实验室
2026年2月9日 04:52 河南
协程
协程(Coroutine) 可以看作是“可暂停和恢复的函数”。与普通函数只能“调用-返回”一次不同,协程可以在执行过程中多次暂停(yield)并交出控制权,之后又能从上次暂停的地方继续执行
比如:
def my_coroutine():
for i in range(3):
yield i # 暂停并返回 i
gen = my_coroutine()
print(next(gen)) # 输出 0
print(next(gen)) # 输出 1
print(next(gen)) # 输出 2
每次调用next(),协程就从上次yield的地方继续执行
C 语言实现协程
赤过“达夫设备”这篇文章的都知道,switch 语句的 case 标签可以出现在 switch 内部任意位置,甚至嵌套在另一个循环里
【赤石C++】详解达夫设备
#include <iostream>
#define crBegin static int state = 0; switch (state) { case 0:
#define crReturn(x) do { state = __LINE__; return x; case __LINE__:; } while (0)
#define crFinish }
int my_coroutine() {
staticint i;
crBegin;
for (i = 0; i < 3; ++i) {
crReturn(i);
}
crFinish;
}
int main() {
std::cout << my_coroutine() << std::endl; // 输出 0
std::cout << my_coroutine() << std::endl; // 输出 1
std::cout << my_coroutine() << std::endl; // 输出 2
}
(如果你使用 MSVC,这段代码可能需要 Release 模式才能编译)
乍一看有点魔法,我们不妨先手动将宏展开再进行分析
int my_coroutine_no_macro() {
staticint i;
/* --- crBegin; 展开开始 --- */
staticint state = 0;
switch (state) {
case0:;
/* --- crBegin; 展开结束 --- */
for (i = 0; i < 3; ++i) {
/* --- crReturn(i); 展开开始 --- */
do {
state = 23; // 假设这行是第 23 行(__LINE__ 宏展开结果)
return i;
case23:; // 这一行也是 23,我为了方便阅读手动加上回车了
} while (0);
/* --- crReturn(i); 展开结束 --- */
}
/* --- crFinish; 展开开始 --- */
};
/* --- crFinish; 展开开始 --- */
}
执行流程:
首次调用时
- • 初始时
state = 0,switch进入case 0分支 - •
case 0后面跟的是一条空语句(一个分号),所以fall-through到for循环起始处
case 0:;
/* fall through */
// 穿透到 for 循环处
for(i = 0; i < 3; ++i)
/* ...... */
- •
do { ... } while(0)不需要特别分析,这个是常用的编程技巧,本文不会涉及 - • 进入
for循环后,将state设置为23,并返回初始i = 0
再次调用时
- • 由于
state = 23,switch语句进入case 23分支 - • 同样的,
case 23后面跟的也是一条空语句,所以fall-through到for循环末尾,并进行条件判断 - • 条件判断成立时,
for循环跳转到开头再次执行,由于i是静态变量,保存了上一次调用的状态,所以返回i = 1
参考
https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html (顺带一提,这位大神还是 PuTTY 的开发者)
https://zh.wikipedia.org/wiki/%E5%8D%8F%E7%A8%8B
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:crackme安全实验室 crackme.net crackme.net《【赤石C++】使用宏魔法在 C 语言中实现协程》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。








评论