一、目的:
分析 LLVM 自帶的符號重寫Pass
二迹栓、分析執(zhí)行流程:
- LLVM原生的文件
lib/Transforms/Utils/SymbolRewriter.cpp
-
入口首先有 RewriteSymbolPass 類對象創(chuàng)建,該構(gòu)造函數(shù)內(nèi)首先解析輸入的map文件好港;
image.png -
一路跟蹤 parse 函數(shù)灿巧,可以看到解析文件內(nèi)容边酒;
image.png -
讀取內(nèi)容將對象指針存儲到容器中:
ExplicitRewriteFunctionDescriptor 表示顯示名稱替換,就是全名替換挟憔;
PatternRewriteFunctionDescriptor 表示正則名稱替換憎妙;
image.png -
文件解析完后库正,進(jìn)入 runOnModule 開始執(zhí)行;
image.png -
循環(huán)list對象 Descriptors 厘唾,棧結(jié)構(gòu)褥符;
image.png -
符號替換,看起來并不復(fù)雜抚垃,核心邏輯使用setName將source替換為Target:
Comdat組件被 rewriteComdat 提前處理喷楣,老實(shí)說,Comdat 的來源和作用并不是很理解鹤树,官網(wǎng)以及一些網(wǎng)站的解釋還是不懂铣焊,有大佬可以留言解釋一下。QAQ
image.png 兩個命令行參數(shù):
static cl::list<std::string> RewriteMapFiles("rewrite-map-file",
cl::desc("Symbol Rewrite Map"),
cl::value_desc("filename"),
cl::Hidden);
INITIALIZE_PASS(RewriteSymbolsLegacyPass, "rewrite-symbols", "Rewrite Symbols",
false, false)
rewrite-map-file 需要跟一個yaml格式的文件罕伯,顯示指明了需要重命名的符號
三曲伊、調(diào)試運(yùn)行:
-
在xcode中可以直接使用opt調(diào)試,命令行參數(shù)如下:
image.png 我這里使用llvm自帶的例子追他,參數(shù)輸入ll文件和map文件坟募,map文件的格式在cpp文件里有注釋解釋:
// Currently, the following descriptor types are supported:
//
// - function: (function rewriting)
// + Source (original name of the function)
// + Target (explicit transformation)
// + Transform (pattern transformation)
// + Naked (boolean, whether the function is undecorated)
// - global variable: (external linkage global variable rewriting)
// + Source (original name of externally visible variable)
// + Target (explicit transformation)
// + Transform (pattern transformation)
// - global alias: (global alias rewriting)
// + Source (original name of the aliased name)
// + Target (explicit transformation)
// + Transform (pattern transformation)
-
查看生成的IR:
可以看到map文件配置的函數(shù)名都被更改了,
image.png
四邑狸、示例懈糯,自己寫一個測試下:
- c文件:
#include <stdio.h>
int a = 100;
static int add(int x, int y)
{
return x + y;
}
int sub(int x, int y)
{
return x - y;
}
int main()
{
printf("%d\n", add(3, 4));
printf("%d\n", sub(5, 4));
printf("%d\n", a);
return 0;
}
生成IR:
clang -c test_symbolobf.c -o test_symbolobf.ll -emit-llvm -S
-
配置yaml文件:
image.png 使用opt:
../bin/opt -rewrite-symbols -rewrite-map-file /xxx/test_symbolobf/test_symbolobf_map.yaml /xxx/test_symbolobf/test_symbolobf.ll -o /xxx/test_symbolobf/test_symbolobf.ll.bc
bc to ll:
llvm-dis /xxx/test_symbolobf/test_symbolobf.ll.bc
-
查看新生成IR,正常:
image.png