Llvm “防”反向 pass

@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 个赞

CPP Backend太老了我懒得维护两个版本的本地build(硬盘太小了装不下)

是的我们都考虑到了所以压根这玩意儿就不在正式实现里,纯粹是给新手介绍llvm体系用的

我比较熟悉API的那套理论,我就是懒

quarkslab的方案是在运行时创建CompilerInstance然后cfe有个生成Module的FrontendAction,直接动态的走这一套思路来编译LLVM IR.

SymbolRename一开始的思路是丢在LTO里,但是就像你说的外部无论如何都会有别的问题。

quarkslab的方案是在运行时创建CompilerInstance然后cfe有个生成Module的FrontendAction,直接动态的走这一套思路来编译LLVM IR.

那我应该跟你看的不是同一个quarkslab的实现,我只看到他用IRBuilder创建指令,IRBuilder足够了。

是的我们都考虑到了所以压根这玩意儿就不在正式实现里,纯粹是给新手介绍llvm体系用的

符号混淆,还是挺有实际意义的,折衷方案就是symbolsrewriter那样,用黑白名单机制。
说起来就是个setName的事,不过杂项问题还是不少,比如comdats处理、linkonce的符号处理等等。

这效果怎么样

是。不过我自己开源的Hikari和私有的版本都着重于其他功能的一些工作。符号混淆的话我自己手上也有一些PostRun直接对二进制进行处理的工具所以LLVM层的实现似乎也并不那么迫切

那当然了,我自己symbols处理也没费太大劲。
其他功能才需要慢慢做。

改天我不忙了,可以share一点,过程内cfg混淆的思路和实现。
不过,闭源和私密性也是安全产品的价值之一,所以,泛泛的能讨论下,细节也难说太多。
你现在自由职业还是?有兴趣可以联系我。我们这边有这个方向的岗位。比你自己面的靠谱多了。

你看到隔壁2500那贴了?那是他们自己找上门来的hhhh 没事我目前是本科在读编译器只是兴趣,目前投了几家国内搞LLVM的岗位,感谢机会

哦还在读啊 实习岗位也有的

嗯,不过我目前规划的就业前景并不在编译器这块。
另外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;

嗯我后来看了下源码搞懂了