邪修 C 語言,10 段“直接勸退”的黑魔法代碼
——僅供技術(shù)獵奇,切勿上生產(chǎn)!
編譯器警告、UB(未定義行為)、UBSAN 狂怒,請自備防護(hù)眼鏡 ??
1?? 一行 main
都沒有的程序
#include <stdio.h>
void _start(){puts("邪修C");}
鏈接時(shí)加
-nostartfiles
,直接跳過 CRT,Linux 裸奔。
2?? Duff’s Device —— switch 跳進(jìn) while
void evil_memcpy(char *dst, char *src, size_t n){
switch(n & 7){
case 0: while(n--){ *dst++ = *src++;
case 7: *dst++ = *src++;
case 6: *dst++ = *src++;
case 5: *dst++ = *src++;
case 4: *dst++ = *src++;
case 3: *dst++ = *src++;
case 2: *dst++ = *src++;
case 1: *dst++ = *src++;
}break;
}
}
循環(huán)展開 + switch 套 while,上古時(shí)代“手動 SIMD”。
3?? 宏黑魔法:讓 if
變成代碼塊
#define evil_if(x) if(x);else
evil_if(0)
puts("你猜我會打印嗎?");
宏定義末尾的分號把
else
直接懸空,編譯器當(dāng)場裂開。
4?? 指針運(yùn)算玩出花
int a[5] = {1,2,3,4,5};
printf("%d\n", 3[a]); // 輸出 4
a[3]
與3[a]
等價(jià),編譯器:你們開心就好。
5?? 結(jié)構(gòu)體“零長度數(shù)組”末班車
struct msg {
int len;
char data[0]; // 邪修柔性數(shù)組
};
struct msg *m = malloc(sizeof *m + 100);
strcpy(m->data, "hello");
0 長度數(shù)組是 GNU 私貨,標(biāo)準(zhǔn) C99 請用
char data[]
。
6?? 位域重疊 + 聯(lián)合體重寫
union {
struct { unsigned a:4, b:4; } nibble;
unsigned char byte;
} u = {.byte = 0xAB};
printf("%x %x\n", u.nibble.a, u.nibble.b); // 平臺決定大小端
一步踏進(jìn) 未定義行為 的大坑。
7?? 自修改機(jī)器碼(mmap 版)
#include <sys/mman.h>
char *code = mmap(NULL, 4096, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
unsigned char payload[] = {0x48,0xC7,0xC0,0x01,0x00,0x00,0x00,0xC3}; // x86-64: mov rax,1; ret
memcpy(code, payload, sizeof payload);
int (*ret1)(void) = (int (*)(void))code;
printf("ret=%d\n", ret1());
運(yùn)行時(shí)生成 shellcode,殺毒軟件直接報(bào)警。
8?? 多重 sizeof
套娃
printf("%zu\n", sizeof sizeof sizeof "abc"); // 輸出 8(64 位指針)
連續(xù)
sizeof
把任何表達(dá)式剝成size_t
,毫無營養(yǎng)。
9?? 逗號運(yùn)算符“一行流”
int x = (printf("a\n"), printf("b\n"), 3);
printf("%d\n", x); // 依次打印 a b 3
把副作用寫進(jìn)表達(dá)式,debug 時(shí)想打人。
?? GOTO 地獄 + 標(biāo)簽運(yùn)算
int main(){
static const void *tab[] = {&&l0, &&l1, &&l2};
int i = 1;
goto *tab[i];
l0: puts("zero"); return 0;
l1: puts("one"); return 0;
l2: puts("two"); return 0;
}
用 計(jì)算型 goto(GNU C 擴(kuò)展)手寫跳轉(zhuǎn)表。
邪修口訣
“內(nèi)存隨便指,宏里藏殺機(jī),UB 當(dāng)特性,編譯器哭泣?!?/p>