Llvm “防”反向 pass


#53

Zhang大已经深入到《编译原理》的第6章 中间代码(IR)生成、第8章 代码生成(CodeGen),大大的赞!

为什么说IR层重要,是因为LLVM项目的历史,在一开始LLVM工具链并没有FrontEnd,用的是llvm-gcc 以及后来的DragonEgg 都是直接使用GCC FrontEnd,不是因为Chris Lattner那时撸不出Clang,而是因为《编译原理》的“精华”在第9章 在IR层的Target无关优化,对应到LLVM就是lib/Transform 第10、11章 指令级并行和优化 https://www.zhihu.com/question/21823699/answer/292683540 我还需要向大神们学习 orz 通过实战来提高“精华”能力!


#54

感觉后端最难啊


#55

给上游报Clang的BUG的时候可以Cc给我lesliezhai@llvm.org.cn 我会负责的!


#56

共勉:君子不器(没有局限)越过山丘(挑战困难)


#57

哈哈,主要Printer这块没啥人用,据说以前给clang报过bug,写过邮件,大半年没动静也就不了了之了,我们自己维护了


#58

方案都是有利有弊嘛,没有完美的


#59

dalao给LLVM上流丢个pull呗。
BasicBlock默认的FindInsertpt是不是应该考虑到EH的LandingPad之类的


#60

LLVM使用SVN进行版本控制,LLVM的开发流程是这样的:如果发现了BUG,欢迎PR https://bugs.llvm.org/ 如果有新需求,欢迎ML http://lists.llvm.org/pipermail/llvm-dev/ 如果希望patch被合并进入上游SVN仓库,欢迎code review https://reviews.llvm.org/ 获得LGTM后,会由maintainer(成为GCC maintainer有多难)合并到上游仓库,当然会留下作者你的名字 如果你贡献的patch多了,并严格遵守LLVM开发者政治,坚决不破坏开发流程,Chris Lattner就会给你SVN仓库的提交权限,能力越大责任越大,依然遵守LLVM开发流程,当patch获得LGTM后,再提交到SVN仓库 :slight_smile:


#61

@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生成的。


#62

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

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

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


#63

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


#64

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


#65

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

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

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

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

这效果怎么样


#66

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


#67

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

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


#68

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


#70

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


#71

嗯,不过我目前规划的就业前景并不在编译器这块。
另外QuarksLab我说的这个是去年年底LLVM Developer Meeting上他们提到的,他们只说了功能,上面说的流程是我自己按照他们描述的功能来逆推的实现思路


#72

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;

#73

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