上週日給Real World CTF 2018出了一道forensics題ccls-fringe,向解出此題的31支隊伍表達祝賀。
上一次出題已是2016年,一直沒有人教我pwn、reverse、web所以只能從平常接觸的東西裏勉強抽出要素弄成題目。
kelwya找我來出題,他說forensics也可以,阻止了我說另請高明。另外也想給自己的項目打廣告,萌生了從ccls的cache弄一道forensics的想法,因爲惰性拖了兩個星期沒有動手。之前一次LeetCode Weekly前在和一個學弟聊天,就想把他的id嵌入了flag。LeetCode第一題Leaf-Similar Trees沒有叫成same-fringe,所以我的題目就帶上fringe字樣“科普”一下吧。
下載ccls-fringe.tar.xz後解壓得到.ccls-cache/@home@flag@/fringe.cc.blob。這是存儲的cache文件。
這裏體現了ccls和cquery的一個不同點。ccls默認使用"cacheFormat":"binary"了,這個自定義的簡單序列化格式,cquery仍在使用JSON。
寫段程序讀入文件,用ccls::Derialize反序列化成IndexFile,用ToString可以轉成JSON字串,閱讀可以發現其中一個變量int b:
1 | { |
clang -fparse-all-comments會把非Doxygen註釋也嵌入AST,註釋暗示了我們應該找和它類似的變量。spell差不多表示spelling
SourceRange,第80列很奇怪。寫一段程序收集位於80列的其他單字符變量,按行號排序:
1 |
|
Makefile指定編譯選項和鏈接選項,除了LLVM只有rapidjson一個依賴了。
1 | CCLS := $(HOME)/Dev/Util/ccls |
編譯成ccls.so,讓ccls吐出flag:
1
2% LD_PRELOAD=./ccls.so ~/Dev/Util/ccls/Debug/ccls
blesswodwhoisinhk
这只是这人用的id的一个子串,他教育我要多做Codeforces,是很好玩的(可惜我依然這麼菜,嗚嗚😭😭😿😿)。
把same-fringe problem寫成coroutine形式也是爲了紀念一個去New York City的同學,他在Stanford讀研期間,給一門課當助教時曾讓我校對一個課程實驗Cooperative User-Level Threads。
1 |
|
假如你用clang trunk (>=7),ccls可以檢索macro replacement-list中的引用。某些限定條件下template instantiation得到的引用也能索引。
代碼
https://github.com/MaskRay/RealWorldCTF-2018-ccls-fringe
ccls的xref功能可以看https://github.com/MaskRay/ccls/wiki/Emacs裏的截圖。Vim/NeoVim用戶也強烈建議看看Emacs能達到什麼效果。最近也加了一個vscode-ccls,但我不用VSCode因此沒有精力維護。