@xiangzhai
function rename其实llvm自己就有这个功能。
symbols rewriter pass
lib/Transforms/Utils/SymbolRewriter.cpp
你们看下这个pass的用法,就知道这个功能用起来有多难受。
主要是,ExternalLinkage的符号处理了,会有linking error的问题,因为你不能保证所有这个符号的使用者定义者都做对应的rename,无论如果这个问题都无法完美解决。
而非ExternalLinkage的符号,InternalLinkage/PrivateLinkage做了没意义,反正都可以strip掉。
@penguin_wwy 你是不是知乎上的名字长了不被喷,哈哈还在坚持ast方向么。
@Zhang
添加函数我们都会我的意思是看QuarksLab的意思是他们直接运行时用clang生成IR,我现在是手动构造。
为目标module添加函数,像quarkslab那样,用LLVM API比如IRBuilder是比较灵活的。我看了你的实现,手动构造IR,再load进去,这样混淆器还得带一堆prebuild ir。最好还是用LLVM API。
IR相关的api其实很少,很快就能掌握。
一个比较偷懒的学习方法。
llvm 3.7.1及以前版本,有个cpp backend。
比如你要构造一个函数定义,把它写到c文件里。用这个cpp backend能把c代码转化成LLVM API构造IR代码,抄过来就行了。上交的那个Armariris的代码,一看就是用cpp backend生成的。
1 个赞
Zhang
62
CPP Backend太老了我懒得维护两个版本的本地build(硬盘太小了装不下)
是的我们都考虑到了所以压根这玩意儿就不在正式实现里,纯粹是给新手介绍llvm体系用的
我比较熟悉API的那套理论,我就是懒
Zhang
63
quarkslab的方案是在运行时创建CompilerInstance然后cfe有个生成Module的FrontendAction,直接动态的走这一套思路来编译LLVM IR.
Zhang
64
SymbolRename一开始的思路是丢在LTO里,但是就像你说的外部无论如何都会有别的问题。
quarkslab的方案是在运行时创建CompilerInstance然后cfe有个生成Module的FrontendAction,直接动态的走这一套思路来编译LLVM IR.
那我应该跟你看的不是同一个quarkslab的实现,我只看到他用IRBuilder创建指令,IRBuilder足够了。
是的我们都考虑到了所以压根这玩意儿就不在正式实现里,纯粹是给新手介绍llvm体系用的
符号混淆,还是挺有实际意义的,折衷方案就是symbolsrewriter那样,用黑白名单机制。
说起来就是个setName的事,不过杂项问题还是不少,比如comdats处理、linkonce的符号处理等等。
这效果怎么样
Zhang
66
是。不过我自己开源的Hikari和私有的版本都着重于其他功能的一些工作。符号混淆的话我自己手上也有一些PostRun直接对二进制进行处理的工具所以LLVM层的实现似乎也并不那么迫切
那当然了,我自己symbols处理也没费太大劲。
其他功能才需要慢慢做。
改天我不忙了,可以share一点,过程内cfg混淆的思路和实现。
不过,闭源和私密性也是安全产品的价值之一,所以,泛泛的能讨论下,细节也难说太多。
你现在自由职业还是?有兴趣可以联系我。我们这边有这个方向的岗位。比你自己面的靠谱多了。
Zhang
68
你看到隔壁2500那贴了?那是他们自己找上门来的hhhh 没事我目前是本科在读编译器只是兴趣,目前投了几家国内搞LLVM的岗位,感谢机会
Zhang
71
嗯,不过我目前规划的就业前景并不在编译器这块。
另外QuarksLab我说的这个是去年年底LLVM Developer Meeting上他们提到的,他们只说了功能,上面说的流程是我自己按照他们描述的功能来逆推的实现思路
utils里的flattencfg pass,做的不是混淆概念上的平坦化。做的是分支条件合并优化。
/// Before:
/// ......
/// %cmp10 = fcmp une float %tmp1, %tmp2
/// br i1 %cmp1, label %if.then, label %lor.rhs
///
/// lor.rhs:
/// ......
/// %cmp11 = fcmp une float %tmp3, %tmp4
/// br i1 %cmp11, label %if.then, label %ifend
///
/// if.end: // the merge block
/// ......
///
/// if.then: // has two predecessors, both of them contains conditional branch.
/// ......
/// br label %if.end;
///
/// After:
/// ......
/// %cmp10 = fcmp une float %tmp1, %tmp2
/// ......
/// %cmp11 = fcmp une float %tmp3, %tmp4
/// %cmp12 = or i1 %cmp10, %cmp11 // parallel-or mode.
/// br i1 %cmp12, label %if.then, label %ifend
///
/// if.end:
/// ......
///
/// if.then:
/// ......
/// br label %if.end;