简介

用于记录 LLVM 和 OLLVM的安装使用

参考自:https://blog.his.cat/a/vs_obfuscation.cat


一个踩坑人的自白

如果能用linux编译就用linux编译! VS的坑太多,
只要OLLVM 编译出来的 exe和lib能在Windows下边跑, 就行了, 无所谓什么编译器的.


LLVM - 一个编译框架


说明

一开始我以为需要单独编译LLVM, 然后用LLVM去整OLLVM.
所以一开始看的都是LLVM相关编译的资料, 最后发现, OLLVM是基于LLVM的修改, 然后OLLVM已经里边自带了LLVM.
因为我目前的目标: 不是学习OLLVM, 而是先使用上OLLVM的功能
所以以下仅针对OLLVM进行记录


OLLVM 编译

库 (基于Ollvm5.0)

基于库: https://github.com/qtfreet00/llvm-obfuscator
缓存: https://github.com/cryzlasm/llvm-obfuscator

工作环境

此工作环境为: 仅安装VS2015的虚拟机环境

CMake下载列表: https://cmake.org/files/v3.9/

CMake 3.9.0-rc4_X64 https://cmake.org/files/v3.9/cmake-3.9.0-rc4-win64-x64.msi
VS VS2015_Update3 自行安装VS2015
Python 2.7.15.amd64 官网自行下载Python2

编译 - CMake命令

  1. cmake -DCMAKE_BUILD_TYPE=Release -Thost=x64 -G"Visual Studio 14 2015 Win64" C:/ollvm/
  2. cmake -DCMAKE_BUILD_TYPE=Release -Thost=x64 -G"Visual Studio 15 2017 Win64" C:/ollvm/
-D CMAKE_BUILD_TYPE 生成 Release
-T host 针对目标工作平台
-G 生成针对某个IDE的工程

关于编译中无限暂停的情况

编译过程中, 会出现停止的状况, 此时 CPU 无占用, cmake 不输出, 工作一度进入假死状态.

最后发现是因为启动了一个进程 cvtres.exe 结束此进程, 可重启工作流程.
直至编译结束, 暂未发现生成的工程会出现不可预知的错误.

LLVM - OLLVM - 图1

临时替换

在编译过程中 依然会出现编译卡住的情况, 还是 cvtres.exe 卡住,
使用 VC\BIN 目录下的程序替换到运行时工作目录 VC\BIN\Amd64

  1. C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\cvtres.exe
  1. C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\cvtres.exe

VS工程编译

编译时, 会出现 "Unknown endianness of the compilation platform, check this header aes_encrypt.h" 提示缺少 aes.h

出现此提示时, 在 LLVMipoLLVMObfuscation 工程中定义一个宏 ENDIAN_LITTLE .

如果提示缺少 CryptoUtils.cppCryptoUtils.h 则参考此文章, 在GIT中获得 https://blog.csdn.net/rrrfff/article/details/78105905


集成VS编译环境

自行修改了 VS2015

TestObfuscation.zip

我个人的目录:

  1. C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Platforms

toolset.props:

  1. <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  2. <Import Project="$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\v140\Microsoft.Cpp.$(Platform).v140.props" Condition="Exists('$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\v140\Microsoft.Cpp.$(Platform).v140.props')"/>
  3. <Import Project="$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\v140\Toolset.props" Condition="Exists('$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\v140\Toolset.props')"/>
  4. <PropertyGroup>
  5. <LLVMInstallDir>$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\LLVM\LLVM)</LLVMInstallDir>
  6. <LLVMInstallDir Condition="'$(LLVMInstallDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\LLVM\LLVM)</LLVMInstallDir>
  7. <LLVMInstallDir Condition="'$(LLVMInstallDir)' == ''">C:\ollvm</LLVMInstallDir>
  8. <ExecutablePath>$(LLVMInstallDir)\msbuild-bin;$(ExecutablePath)</ExecutablePath>
  9. <LibraryPath>$(LLVMInstallDir)\lib;$(LibraryPath)</LibraryPath>
  10. <IncludePath>$(LLVMInstallDir)\include;$(IncludePath)</IncludePath>
  11. </PropertyGroup>
  12. <ItemDefinitionGroup>
  13. <ClCompile>
  14. <!-- Set the value of _MSC_VER to claim for compatibility -->
  15. <ObfsOptions>-mllvm -bcf -mllvm -bcf_loop=4 -mllvm -bcf_prob=100 -mllvm -sub -mllvm -sub_loop=2</ObfsOptions>
  16. <AdditionalOptions>-m32 -fmsc-version=1900 %(ObfsOptions)</AdditionalOptions>
  17. </ClCompile>
  18. </ItemDefinitionGroup>
  19. </Project>

主要需要替换 <LLVMInstallDir Condition="'$(LLVMInstallDir)' == ''">C:\ollvm</LLVMInstallDir> 此行数据, 用于查找 LLVM 的编译器


附录

如何确定 VS 编译器版本


_MSC_VERMSVC 编译器的内置宏,定义了编译器的版本,_MSC_VER 值对应版本关系

  1. MSVC++ 11.0 _MSC_VER = 1700 (Visual Studio 2012)
  2. MSVC++ 10.0 _MSC_VER = 1600 (Visual Studio 2010)
  3. MSVC++ 9.0 _MSC_VER = 1500 (Visual Studio 2008)
  4. MSVC++ 8.0 _MSC_VER = 1400 (Visual Studio 2005)
  5. MSVC++ 7.1 _MSC_VER = 1310 (Visual Studio 2003)
  6. MSVC++ 7.0 _MSC_VER = 1300 (Visual Studio 2002)
  7. MSVC++ 6.0 _MSC_VER = 1200
  8. MSVC++ 5.0 _MSC_VER = 1100



example:

  1. #if (_MSC_VER == 1300) //vc7
  2. #import "acax16ENU.tlb" no_implementation raw_interfaces_only named_guids
  3. #elif (_MSC_VER == 1200) //vc6
  4. #import "acad.tlb" no_implementation raw_interfaces_only named_guids
  5. #elif (_MSC_VER == 1400) //vc8
  6. #import "acax17ENU.tlb" no_implementation raw_interfaces_only named_guids
  7. #elif (_MSC_VER == 1500) //vc9
  8. #import "acax18ENU.tlb" no_implementation raw_interfaces_only named_guids
  9. #endif



在程序中加入_MSC_VER 宏可以根据编译器版本让编译器选择性地编译一段程序。例如一个版本编译器产生的 lib 文件可能不能被另一个版

本的编译器调用,那么在开发应用程序的时候,在该程序的 lib 调用库中放入多个版本编译器产生的 lib 文件。在程序中加入_MSC_VER 宏 ,编译器就能够在调用的时根据其版本自动选择可以链接的 lib 库版本,如下所示。

  1. #if _MSC_VER >= 1400 // for vc8, or vc9
  2. #ifdef _DEBUG
  3. #pragma comment(lib, "SomeLib-vc8-d.lib")
  4. #else if
  5. #pragma comment(lib, "SomeLib-vc8-r.lib")
  6. #endif
  7. #else if _MSC_VER >= 1310 // for vc71
  8. #ifdef _DEBUG
  9. #pragma comment(lib, "SomeLib-vc71-d.lib")
  10. #else if
  11. #pragma comment(lib, "SomeLib-vc71-r.lib")
  12. #endif
  13. #else if _MSC_VER >=1200 // for vc6
  14. #ifdef _DEBUG
  15. #pragma comment(lib, "SomeLib-vc6-d.lib")
  16. #else if
  17. #pragma comment(lib, "SomeLib-vc6-r.lib")
  18. #endif
  19. #endif