内容简介:上周日给Real World CTF 2018出了一道forensics题ccls-fringe,向解出此题的31支队伍表达祝贺。上一次出题已是2016年,一直没有人教我pwn、reverse、web所以只能从平常接触的东西里勉强抽出要素弄成题目。kelwya找我来出题,他说forensics也可以,阻止了我说另请高明。另外也想给自己的项目打广告,萌生了从
上周日给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
:
{ "usr": 7704954053858737267, "detailed_name": "int b", "qual_name_offset": 4, "short_name_offset": 4, "short_name_size": 1, "hover": "", "comments": "flag is here", "declarations": [], "spell": "16:80-16:81|1935187987660993811|3|2", "extent": "16:76-16:81|1935187987660993811|3|0", "type": 52, "uses": [], "kind": 13, "storage": 0 },
clang -fparse-all-comments
会把非Doxygen注释也嵌入AST,注释暗示了我们应该找和它类似的变量。 spell
差不多表示spelling SourceRange,第80列很奇怪。写一段程序收集位于80列的其他单字符变量,按行号排序:
#include"indexer.h" const char blob[] = ".ccls-cache/@home@flag@/fringe.cc.blob"; __attribute__((constructor)) void solve(){ std::string content = *ReadContent(blob); auto file = ccls::Deserialize(SerializeFormat::Binary, blob, content, "", {}); std::vector<std::pair<int, char>> wod; for (auto &[usr, v] : file->usr2var) { Maybe<Use> spell = v.def.spell; if (spell) { Position start = spell->range.start; if (start.column == 79) wod.emplace_back(start.line, v.def.detailed_name[4]); } } sort(wod.begin(), wod.end()); for (auto t: wod) putchar(t.second); puts(""); exit(0); }
Makefile
指定编译选项和链接选项,除了LLVM只有rapidjson一个依赖了。
CCLS := $(HOME)/Dev/Util/ccls LLVM := $(HOME)/Dev/llvm LDFLAGS := -shared CXXFLAGS := -std=c++17 -fPIC -g CXXFLAGS += -I$(CCLS)/src -I$(CCLS)/third_party -I$(CCLS)/third_party/rapidjson/include CXXFLAGS += -I$(LLVM)/include -I$(LLVM)/Release/include CXXFLAGS += -I$(LLVM)/tools/clang/include -I$(LLVM)/Release/tools/clang/include solve.so: solve.cc $(LINK.cc) $^ -o $@
编译成 ccls.so
,让 ccls
吐出flag:
% LD_PRELOAD=./ccls.so ~/Dev/Util/ccls/Debug/ccls blesswodwhoisinhk
这只是这人用的id的一个子串,他教育我要多做Codeforces,是很好玩的(可惜我依然这么菜,呜呜:sob::sob::crying_cat_face::crying_cat_face:)。
把same-fringe problem写成coroutine形式也是为了纪念一个去New York City的同学,他在Stanford读研期间,给一门课当助教时曾让我校对一个课程实验Cooperative User-Level Threads。
#include <iostream> #include <vector> #include <ucontext.h> using namespace std; struct TreeNode { int val; TreeNode *left; TreeNode *right; }; struct Co { ucontext_t c; char stack[8192]; TreeNode *ret; Co(ucontext_t *link, void (*f)(Co *, TreeNode *), TreeNode *root) { {int b; /* flag is here */} getcontext(&c); {int l;} c.uc_stack.ss_sp = stack; {int e;} c.uc_stack.ss_size = sizeof stack; {int s;} c.uc_link = link; {int s;} makecontext(&c, (void(*)())f, 2, this, root); } void yield(TreeNode *x) { {int w;} ret = x; {int o;} swapcontext(&c, c.uc_link); {int d;} } }; void dfs(Co *c, TreeNode *x) { {int w;} if (!x) return; {int h;} if (!x->left && !x->right) c->yield(x); {int o;} dfs(c, x->left); {int i;} dfs(c, x->right); {int s;} } class Solution { public: bool leafSimilar(TreeNode *root1, TreeNode *root2) { {int i;} ucontext_t c; {int n;} Co c2(&c, dfs, root2), c1(&c2.c, dfs, root1); {int h;} do { {int k;} c1.ret = c2.ret = nullptr; swapcontext(&c, &c1.c); } while (c1.ret && c2.ret && c1.ret->val == c2.ret->val); return !c1.ret && !c2.ret; } }; void insert(TreeNode **x, TreeNode &y) { while (*x) x = y.val < (*x)->val ? &(*x)->left : &(*x)->right; *x = &y; } int main() { TreeNode xs[] = {{3},{1},{5},{0},{2},{4},{6}}; TreeNode ys[] = {{5},{3},{6},{1},{4},{0},{2}}; TreeNode zs[] = {{3},{1},{5},{0},{2},{6}}; TreeNode *tx = nullptr, *ty = nullptr, *tz = nullptr; for (auto &x: xs) insert(&tx, x); for (auto &y: ys) insert(&ty, y); for (auto &z: zs) insert(&tz, z); Solution s; cout << s.leafSimilar(tx, ty) << endl; cout << s.leafSimilar(tx, tz) << endl; }
假如你用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因此没有精力维护。 有更多精力的话可以帮我支持下 https://github.com/autozimu/LanguageClient-neovim/issues/454 。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Real World CTF 2018 rwext5命题报告
- 开源等于免费?这只是你认知里的一个伪命题
- 新京报:在区块链技术加持下 数据孤岛会是个“伪命题”
- 圆桌讨论:技术为王还是落地为王?智慧安防遇冷是伪命题吗
- 为什么管理式医疗春天即将来临、复制美国PBM是个伪命题、DRG将推动医疗改革?【VB100观点】
- 网站前端性能测试报告
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Persuasive Technology
B.J. Fogg / Morgan Kaufmann / 2002-12 / USD 39.95
Can computers change what you think and do? Can they motivate you to stop smoking, persuade you to buy insurance, or convince you to join the Army? "Yes, they can," says Dr. B.J. Fogg, directo......一起来看看 《Persuasive Technology》 这本书的介绍吧!