编程技术 您所在的位置:网站首页 dyn是什么 编程技术

编程技术

#编程技术| 来源: 网络整理| 查看: 265

本文目的

搭建一个windows 下应用层能够快捷使用的 llvm 工具链,文中将会解释为什么要这么做,以及阐述其他方式可能会遇到的坑点,同时这个文章只是一个实践文,并不涉及具体原理,只为了提供一个windows 下搭建llvm的最佳实践方案。

为什么不使用 VS2019 自带的llvm进行使用?不编译的话,就无法编译生成Pass,你只能利用clang去编译生成exe,比起VS2019 自带的cl并没有明显优势,作为一个小白,并不清楚支持llvm的原因。而Pass相当于一个插件,起到中间层实际执行混淆的作用,相当于我们这个功能的核心,所以必须要它。

为什么不用 VS2019 进行项目编译?经过在12.0.1 / 12.0.0 / 15.0.6 几个版本的实践,会遇到各种问题,其中最主要的问题是,如果不使用12.0.0 ,你编译出来的llvm 集成到VS 2019中使用时,会出现各种意想不到的错误。另外用MSVC 编译llvm时,不支持开启BUILD_SHARED_LIBS 选项,但可以使用LLVM_EXPORT_SYMBOLS_FOR_PLUGINS 选项或LLVM_ENABLE_PLUGINS选项,但这样会出现一个问题,编译后的pass仅能使用new Pass语法,而且必须使用opt 进行加载插件使用,实际只有registerPipelineParsingCallback回调函数可以正常使用

既然我们需要的只是Pass,也就是一个dll文件,那么我们是否能生成12.0.0 版本的llvm pass,然后就直接用VS 2019 自带的llvm进行编译集成呢?我也尝试过,但没有成功,不是自己编译出来的llvm pass 和 自己编译出来的 llvm clang-cl 在使用时会报无法加载模块,0x7E的错误,实在不想在windows下试图调试llvm 源码找出报错原因,因为这样也许还要被折磨几周。

环境搭建

基础环境windows 10https://github.com/llvm/llvm-project/releases/tag/llvmorg-12.0.0CMake (https://cmake.org/download/)VS 2019 16.11.10MSYS2PythonGit

安装步骤 安装cmake,https://cmake.org/download/ ,下载对应windows安装包安装即可PS: 安装时选择添加环境变量给所有用户使用图片描述

安装MSYS2PS:llvm 是支持 VS 2019直接去生成llvm的,不用安装这些东西,官方有相关文章(https://llvm.org/docs/GettingStartedVS.html),编译很快,但编出来不会写相关Pass并利用,这里用gcc + vs2019 构造工具链,欢迎踩完坑后分享~官网:https://www.msys2.org/详细安装步骤:https://bbs.kanxue.com/thread-272346.htm#msg_header_h3_1安装后安装gcc工具链

1 pacman - S - - needed base - devel mingw - w64 - x86_64 - toolchain mingw - w64 - i686 - toolchain cmake

在VS 2019 中安装clang cmake 等工具图片描述

下载llvm 12.0.0源码,只需要下载clang和llvm文件夹即可,其他的编译pass用不到https://github.com/llvm/llvm-project/releases/tag/llvmorg-12.0.0图片描述

将源码解压,文件树如下:PS:其中build* 文件夹是我运行bat文件后产生的目录,lld 可以不用下载,是之前踩坑的产物图片描述

编译源码:x64_gcc_build.bat 文件内容

1 2 3 4 5 6 7 8 9 10 cd C:\Users\admin\Documents\llvmProject12 set PATH = % PATH % ;C:\msys64\mingw64\ bin gcc - - version cmake - G "MinGW Makefiles" - S . / llvm - B . / build_dyn_x64  ^ - DCMAKE_BUILD_TYPE = Release - DLLVM_ENABLE_PROJECTS = "clang;" ^ - DLLVM_TARGETS_TO_BUILD = "X86" - DBUILD_SHARED_LIBS = ON ^ - DLLVM_INCLUDE_TESTS = OFF - DLLVM_BUILD_TESTS = OFF ^ - DLLVM_INCLUDE_BENCHMARKS = OFF - DLLVM_BUILD_BENCHMARKS = OFF - DLLVM_ENABLE_DUMP = ON cmake - - build . / build_dyn_x64 - j 4 cmake - DCMAKE_INSTALL_PREFIX = "C:\Program Files\LLVM\llvm12\llvm12_dyn_x64" - P .\build_dyn_x64\cmake_install.cmake

x86_gcc_build.bat 文件内容

1 2 3 4 5 6 7 8 9 10 cd C:\Users\admin\Documents\llvmProject12 set PATH = % PATH % ;C:\msys64\mingw32\ bin gcc - - version cmake - G "MinGW Makefiles" - S . / llvm - B . / build_dyn_x32  ^ - DCMAKE_BUILD_TYPE = Release - DLLVM_ENABLE_PROJECTS = "clang;" ^ - DLLVM_TARGETS_TO_BUILD = "X86" - DBUILD_SHARED_LIBS = ON ^ - DLLVM_INCLUDE_TESTS = OFF - DLLVM_BUILD_TESTS = OFF ^ - DLLVM_INCLUDE_BENCHMARKS = OFF - DLLVM_BUILD_BENCHMARKS = OFF - DLLVM_ENABLE_DUMP = ON cmake - - build . / build_dyn_x32 - j 4 cmake - DCMAKE_INSTALL_PREFIX = "C:\Program Files\LLVM\llvm12\llvm12_dyn_x32" - P .\build_dyn_x32\cmake_install.cmake

运行 bat 文件即可编译对应的 llvm图片描述

编译安装完成之后可以在下面两个目录中找到编译好的clang 文件

1 2 C:\Program Files\LLVM\llvm12\llvm12_dyn_x64 C:\Program Files\LLVM\llvm12\llvm12_dyn_x32

图片描述

安装后,我们已经可以用clang 编译hello world的cpp文件,但是编译正常的项目文件时,我们需要去解决动态链接库缺失和静态库的问题。缺失的动态库可以去C:\msys64\mingw64\bin去寻找,并且复制到C:\Program Files\LLVM\llvm12\llvm12_dyn_x64\bin 中 1 2 3 4 libstdc + + - 6.dll libgcc_s_seh - 1.dll libwinpthread - 1.dll zlib1.dll 缺失的动态库可以去C:\msys64\mingw32\bin去寻找,并且复制到C:\Program Files\LLVM\llvm12\llvm12_dyn_x32\bin 中 1 2 3 4 libstdc + + - 6.dll libgcc_s_dw2 - 1.dll (这个库名称不一样) libwinpthread - 1.dll zlib1.dll 静态库则可以去对应的C:\Users\admin\Documents\llvmProject12\build_dyn_x32\lib 或者C:\Users\admin\Documents\llvmProject12\build_dyn_x64\lib中,将所有a文件添加到对应目录下。 测试使用 搭建测试的Pass文件和 测试程序源码,测试的文件树如下:Transforms 文件夹里存放pass文件,TestProgram是项目源码文件夹图片描述 其中 CMakeLists.txt 文件内容如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 project(mydemo) cmake_minimum_required(VERSION 3.10 )   if (NOT DEFINED ENV{LLVM_HOME})      # User must define the LLVM_HOME environment that point to the root installation dir of llvm      message(FATAL_ERROR "Environment variable $LLVM_HOME is not defined, user should define it before running cmake!" ) endif()   message(STATUS "LLVM_HOME = [$ENV{LLVM_HOME}]" )   if (NOT DEFINED ENV{LLVM_DIR})      # Default llvm config file path      set (ENV{LLVM_DIR} $ENV{LLVM_HOME} / lib / cmake / llvm) endif()   # Check the path if (NOT EXISTS $ENV{LLVM_DIR})      message(STATUS "Path ($ENV{LLVM_DIR}) not found!" )        # If default llvm config path not found, try this one,      # which is config with [-DLLVM_LIBDIR_SUFFIX=64] before building llvm      set (ENV{LLVM_DIR} $ENV{LLVM_HOME} / lib64 / cmake / llvm)      if (NOT EXISTS $ENV{LLVM_DIR})          message(FATAL_ERROR "Path ($ENV{LLVM_DIR}) not found!" )      else ()          message(STATUS "Path ($ENV{LLVM_DIR}) found!" )      endif() else ()      message(STATUS "Path ($ENV{LLVM_DIR}) found!" ) endif()   # Enable verbose output for debug, # Same as: cmake -D CMAKE_VERBOSE_MAKEFILE=ON or make VERBOSE=1 # set(CMAKE_VERBOSE_MAKEFILE on)   find_package(LLVM REQUIRED CONFIG) add_definitions(${LLVM_DEFINITIONS}) include_directories(${LLVM_INCLUDE_DIRS}) link_directories(${LLVM_LIBRARY_DIRS})   # Debug message(STATUS "LLVM_DEFINITIONS  : ${LLVM_DEFINITIONS}" ) message(STATUS "LLVM_INCLUDE_DIRS : ${LLVM_INCLUDE_DIRS}" ) message(STATUS "LLVM_LIBRARY_DIRS : ${LLVM_LIBRARY_DIRS}" )   add_library(mydemo SHARED      # Add your source file here, header file is not neccessary      . / src / mydemo.cpp )   # Use C++11 to compile your pass (i.e., supply -std=c++11). target_compile_features(mydemo PRIVATE cxx_range_for cxx_auto_type)   include_directories(. / include)   # LLVM is (typically) built with no C++ RTTI. We need to match that; # otherwise, we'll get linker errors about missing RTTI data. set_target_properties(mydemo PROPERTIES COMPILE_FLAGS "-fno-rtti" )   # Get proper shared-library behavior (where symbols are not necessarily # resolved when the shared library is linked) on OS X. if (APPLE)      set_target_properties(mydemo PROPERTIES LINK_FLAGS "-undefined dynamic_lookup" ) endif(APPLE)   target_link_libraries(mydemo        libLLVMCore.dll.a      libLLVMSupport.dll.a      libLLVMipo.dll.a        libLLVMDemangle.dll.a      libLLVMTransformUtils.dll.a      libLLVMAnalysis.dll.a      libpthread.a )

3 . bat文件的内容如下(x86 就是将前面的环境设置为x86的即可):

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 cd C:\Users\admin\Documents\llvmProject\ollvm + + :: Set MSYS2 env set PATH = % PATH % ;C:\msys64\mingw64\ bin   :: Set LLVM_HOME set LLVM_HOME = % PROGRAMFILES % / LLVM / llvm12 / llvm12_dyn_x64 set CC = % LLVM_HOME % / bin / clang.exe set CXX = % LLVM_HOME % / bin / clang + + .exe set OPT = % LLVM_HOME % / bin / opt.exe set LLC = % LLVM_HOME % / bin / llc.exe   rd / Q / S .\Build   :: Build release version cmake - S . / Transforms - B . / Build - DCMAKE_BUILD_TYPE = Release - DLLVM_ENABLE_ASSERTIONS = ON  - G "MinGW Makefiles"   :: Build debug version :: cmake - S . / Transforms - B . / Build - DCMAKE_BUILD_TYPE = Debug - DLLVM_ENABLE_ASSERTIONS = ON   :: Build  project cmake - - build . / Build - j 4   copy .\Build\libmypass.dll .\ Bin \libmypassx64.dll   "%CC%" - Xclang - load - Xclang .\ Bin \libmypassx64.dll .\TestProgram\TestProgram.cpp - o .\TestProgram\ Bin \TestProgram.exe   :: / D LLVM  - mrdrnd - Xclang - load - Xclang "C:\\Users\\admin\\Desktop\\Work\\ollvm++\\Build\\libmypass.dll" .\TestProgram\ Bin \TestProgram.exe flag{s1mpl3_11vm_d3m0}

4 . TestProgram.cpp的内容,是一道简单的re逆向题:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include #include   char input [ 100 ] = { 0 }; char enc[ 100 ] = "\x86\x8a\x7d\x87\x93\x8b\x4d\x81\x80\x8a\ \x43\x7f\x49\x49\x86\x71\x7f\x62\x53\x69\x28\x9d";   void encrypt(unsigned char * dest, char * src){      int len = strlen(src);      for ( int i = 0 ;i < len ;i + + ){           dest[i] = (src[i] + ( 32 - i)) ^ i;      } }   / / flag{s1mpl3_11vm_d3m0} int main( int _argc, char * _argv[]){      / / scanf( "%s" , input );      if (_argc


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有