惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Register - Security
The Register - Security
美团技术团队
Recent Announcements
Recent Announcements
MongoDB | Blog
MongoDB | Blog
Jina AI
Jina AI
C
Check Point Blog
aimingoo的专栏
aimingoo的专栏
I
InfoQ
S
Securelist
T
Tor Project blog
GbyAI
GbyAI
L
LINUX DO - 热门话题
V
Visual Studio Blog
AWS News Blog
AWS News Blog
The Cloudflare Blog
腾讯CDC
K
Kaspersky official blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Recorded Future
Recorded Future
李成银的技术随笔
W
WeLiveSecurity
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
M
Microsoft Research Blog - Microsoft Research
G
Google Developers Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Schneier on Security
Schneier on Security
B
Blog
IT之家
IT之家
爱范儿
爱范儿
H
Help Net Security
Simon Willison's Weblog
Simon Willison's Weblog
NISL@THU
NISL@THU
J
Java Code Geeks
博客园 - 聂微东
T
The Exploit Database - CXSecurity.com
Cyberwarzone
Cyberwarzone
博客园 - 叶小钗
MyScale Blog
MyScale Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Project Zero
Project Zero
F
Future of Privacy Forum
D
Darknet – Hacking Tools, Hacker News & Cyber Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Hacker News: Ask HN
Hacker News: Ask HN
D
Docker
Apple Machine Learning Research
Apple Machine Learning Research
B
Blog RSS Feed
V
Vulnerabilities – Threatpost

ABB00717

788. Rotated Digits 396. Rotate Function 幫耳機補血! 週刊 做過的夢(旅行) 週刊 Vol.18 週刊 Vol.17 週刊 Vol.16 做過的夢(火箭推進器和追蹤導彈) 部落格聚集地 在 Ubuntu 24.04 中安裝 python2 和 pip2 動態牆 音樂 用 miniflux 和 Cloudflare Tunnel 自架 RSS Reader 關於用了 GCC 擴充功能,而被批評不夠 Clean Code 這檔事 週記 Vol.15 Makefile GDB TwoMillion 週記 Vol.14 Hack The Box ABB00717's Blog 週記 Vol.13 1980. Find Unique Binary String 週記 Vol.12 Leetcode 在互聯網上,什麼該說,什麼又不該說? 週記 Vol.8 週記 Vol.7 天才之於一種義務 就算 LLM 能解答所有問題,你也不該放棄學習 Stack-Based Buffer Overflow 書籍 《絕佳時間》 週記 Vol.5 Linux 雜項筆記 偽深刻的自我解構 解決 Ubuntu 待機後喚醒異常的問題 將應用程式新增到 GNOME 的 Activities Overview 週記 Vol.4 Assembly Language 筆記 週記 Vol.3 文章 紀錄 資源 挑戰
週記 Vol.6
2026-01-25 · via ABB00717

不知道為什麼,這周感覺過得特別漫長 …。

音樂

這禮拜大部分聽的都是舊專輯,也沒有挖掘到想讓我大書特書的新專輯,就不寫心得了。

Hack The Box

Source

這禮拜完成了 Footprinting 模組。基本上就是針對企業內部常見服務的枚舉與嗅探大全。涵蓋了 NFS, FTP, SMB, DNS, IMAP, SNMP 等等。學會了如何掃描這些服務、尋找設定錯誤的權限,或是預設憑證來當作突破口。這部分比較偏向體力活和記憶,就是把工具指令記熟。

Quine

我還記得大二下 OOP 教授說過他以前做過 Quine(也鼓勵我們自己做一個),當時讀 Ken Thompson 的經典論文 Reflections on Trusting Trust 時,也大概理解 Quine 的邏輯,但一直沒親手實作過,直到這禮拜 Tsoding 出這隻影片 Self-Reproducing Programs

其實他的思路非常簡單,就是把程式分成「框架」和「數據」兩部分,重點在於如何用一個字串來表示程式自身,並將其格式化輸出。

char *self = "...";
 
int main() {
    print("%s", self);
}

最後就可以變成這樣:

#include <stdio.h>
#include <string.h>
 
int main() {
    // 利用 `~` 當作佔位符表示自己(`self`)
    // 推薦用魔法來複製和編輯程式骨架
    // Emacs & Vim: Could your VSCode do this?
    char *self = "#include <stdio.h>\n#include <string.h>\n\nint main() {\n    char *self = \"~\";\n    int n = strlen(self);\n\n    for (int i = 0; i < n; i++) {\n        if (self[i] == 126) {\n            for (int j = 0; j < n; j++) {\n                switch (self[j]) {\n                    case '\\n':\n                        printf(\"\\\\n\");\n                        break;\n                    case '\"':\n                        printf(\"\\\\\\\"\");\n                        break;\n                    case '\\\\':\n                        printf(\"\\\\\\\\\");\n                        break;\n                    default:\n                        printf(\"%c\", self[j]);\n                }\n            }\n        } else {\n            printf(\"%c\", self[i]);\n        }\n    }\n}\n";
    int n = strlen(self);
 
    // 透過遍歷 `self` 輸出 `main.c` 的程式框架
    for (int i = 0; i < n; i++) {
        // 當遇到 `~` 時,代表我們要一五一十的把整個字串輸出出來
        if (self[i] == 126) {
            for (int j = 0; j < n; j++) {
                switch (self[j]) {
                    // 這是最簡單的情況,遇到 \n 不能換行,而是要輸出 \n,為了輸出 \n 就必須用到逃脫字元 \
                    case '\n':
                        printf("\\n");
                        break;
                    // 這很酷。在上面 `self` 時,我們如果要表示 ",就必須用逃脫字元 \。而在這裡我們為了輸出 \ 和 ",我們必須個別為他們添上逃脫字元,也就變成了 \\\"
                    case '"':
                        printf("\\\"");
                        break;
                    // 同理!
                    case '\\':
                        printf("\\\\");
                        break;
                    default:
                        printf("%c", self[j]);
                }
            }
        } else {
            printf("%c", self[i]);
        }
    }
}

超酷的!還有其他的一些東東:

  • Wiki - Bloo:一個收藏各種語言的各種版本 Quine 實做的網站。

  • Github - Quine-Relay 一個 Ruby 程式,生成 Rust,再生成 Scala… 經歷 128 種語言後再變回原本的 Ruby 程式碼。藝術品 …

Tsoding

When I say that the programming language doesn’t matter, I hope you know where I’m coming from.

編譯器

這禮拜也看了些編譯器的東西。

總之我現在大概知道了編譯器的架構,分成前端、中端、後端。我原本對編譯器的理解只有停在詞法分析、語法分析、語義檢查的前端部份,中端和後端是最近才知道的。不過就我觀察,大部分自幹的編譯器,好像也都只專住在前端而已。

不需要分號的 C 編譯器

我好像變成 Tsoding 的 “Fanboy” 了 …。其實原理意外簡單,tinycc 的 Parser 在分析完一段 Statement 後會預期並檢查是否有分號,我們只要把那個「強制檢查」改成「可選」甚至是「略過」就好。

#include <stdio.h>
 
int main(){
    printf("Hello World\n")
    printf("Hello World\n")
    printf("Hello World\n")
    printf("Hello World\n")
    printf("Hello World\n")
 
    return 0
}
$ ./tcc no-semi.c
no-semi.c:5: error: ';' expected (got 'printf')

尋找 expected (got 是在哪裡報錯的。

ST_FUNC void skip(int c)
{
    if (tok != c) {
        char tmp[40];
        pstrcpy(tmp, sizeof tmp, get_tok_str(c, &tokc));
        tcc_error("'%s' expected (got '%s')", tmp, get_tok_str(tok, &tokc));
	}
    next();
}

所以我們需要找到哪裡呼叫了 skip(';')。透過 grep 可以發現它藏在 block 函數處理 Expression 的地方。

static void block(int flags)
{
...
                /* expression case */
            if (t != ';') {
                unget_tok(t);
    expr:
                if (flags & STMT_EXPR) {
                    vpop();
                    gexpr();
                } else {
                    gexpr();
                    vpop();
                }
                skip(';');
            }
...
}

這就是處理 Expression 的地方,把它邏輯改成「如果遇到 ; 再跳過」就可以了。

if (tok == ';') skip(';');

對於 return 也是如此。

...
    } else if (t == TOK_RETURN) {
        ...
        if (b)
            gfunc_return(&func_vt);
        if (tok == ';') skip(';');
        /* jump unless last stmt in top-level block */
        ...
    } else if (t == TOK_BREAK) {
...
$ ./tcc no-semi.c
$ ./a.out
Hello World
Hello World
Hello World
Hello World
Hello World

看!多奇妙啊!

寒假

寒假已經過了 5/9 個禮拜了天啊天啊天啊啊啊啊啊啊啊啊啊。

  • 預習編譯器、資料庫的課程,主要是把書粗略看一遍就差不多了
  • 剪輯演算法的影片,主要是動態規劃、貪婪演算法的部份(現在決定睡前剪)
  • 狂幹 HackTheBox Academy,當然希望可以直接把 CPTS Path 的所有 Modules 都看完
  • 制定專題《基於多維度漏洞挖掘之 IoT 設備安全審計與更新機制研究》的總體大綱