Search code examples
clinkerclanglibtool

Libtool/clang: let me pass arguments to compiler but not linker


I'm obfuscating many GitHub projects with o-llvm. It's a compile time linker implemented in clang. With o-llvm, I'm trying to compile/obfuscate a GitHub project that uses libtool, but the flags needed to specify the obfuscation transform mess up the linker.

The extra flags that I'm passing in are like:

/path/to/obfuscator/clang -O0 -mllvm -bcf -mllvm -boguscf-loop=1 -mllvm -ann

-bcf means apply bogus control flow transformation, -boguscf-loop limits how many times it runs per basic block and -ann indicates to annotate the basic blocks with printf statements.

At first, I tried doing this at the make step after configure:

make CC=/path/to/obfuscator/clang CFLAGS="-O0 -mllvm -bcf -mllvm -boguscf-loop=1 -mllvm -ann

But then gcc was the linker and it failed because it did not know the "-mllvm" option. Libtool also automatically removed the "-bcf" "-boguscf-loop=1" and "-ann" options

In another project, dropping back to configure and specifying CFLAGS in CC worked:

./configure CC="/path/to/obfuscator/clang -O0 -mllvm -bcf -mllvm -boguscf-loop=1 -mllvm -ann"

This makes the "linker" be clang, which recognizes the "-mllvm" option, but libtool removing the corresponding flags still messes up the invocation:

[...] -O0 -mllvm -mllvm -mllvm -Wl,-z -Wl,defs   -Wl,-soname [...]
clang: warning: argument unused during compilation: '-mllvm -bcf'
clang: warning: argument unused during compilation: '-mllvm -boguscf-loop=1'
clang: warning: argument unused during compilation: '-mllvm -ann'
clang: warning: argument unused during compilation: '-mllvm -mllvm'
clang: warning: argument unused during compilation: '-mllvm -Wl,-z'
/usr/bin/ld: error: cannot open defs: No such file or directory

I tried prepending my compiler-only arguments with -Wc,flag or -Xcompile but clang recognizes neither of those.

Is there some other way to tell Libtool or Clang to only use the obfuscation arguments for compilation and not linking?

Thank you.


Solution

  • I was trying to avoid this but I ended up modifying the libtool script to drop -mllvm like the other obfuscation options during linking.

    sed -i "s/-m\*|/-mtune=*|-march=*|-mcpu=*|-mfpmath=*|-masm=*|-mieee-fp|-mno-ieee-fp|-msoft-float|-mno-fp-ret-in-387|-mno-fancy-math-387|-malign-double|-mno-align-double|-m96bit-long-double|-m128bit-long-double|-mlarge-data-threshold=*|-mrtd|-mregparm=*|-msseregparm|-mpc32|-mpc64|-mpc80|-mstackrealign|-mpreferred-stack-boundary=*|-mincoming-stack-boundary=*|-mmmx|-mno-mmx|-msse|-mno-sse|-msse2|-mno-sse2|-msse3|-mno-sse3|-mssse3|-mno-ssse3|-msse4.1|-mno-sse4.1|-msse4.2|-mno-sse4.2|-msse4|-mno-sse4|-mavx|-mno-avx|-maes|-mno-aes|-mpclmul|-mno-pclmul|-msse4a|-mno-sse4a|-mfma4|-mno-fma4|-mxop|-mno-xop|-mlwp|-mno-lwp|-m3dnow|-mno-3dnow|-mpopcnt|-mno-popcnt|-mabm|-mno-abm|-mfused-madd|-mno-fused-madd|-mcld|-mcx16|-msahf|-mmovbe|-mcrc32|-mrecip|-mveclibabi=*|-mabi=*|-mpush-args|-mno-push-args|-maccumulate-outgoing-args|-mthreads|-mno-align-stringops|-minline-all-stringops|-minline-stringops-dynamically|-mstringop-strategy=*|-momit-leaf-frame-pointer|-mtls-direct-seg-refs|-mno-tls-direct-seg-refs|-msse2avx|-mno-sse2avx|-m32|-m64|-mno-red-zone|-mcmodel=*|-mcmodel=*|-mcmodel=*|-mcmodel=*|/g" libtool
    

    Basically, expand -m* with every possible value from the gcc manual, minus -mllvm which is solely a clang thing. Now I can automatically compile vlc with arbitrary invocations using different compilers as part of the Chimera corpus.