<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    在 Windows下搭建LLVM 使用環境

    VSole2023-04-04 09:36:31

    一、目的

    搭建一個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 10

    https://github.com/llvm/llvm-project/releases/tag/llvmorg-12.0.0

    CMake (https://cmake.org/download/)

    VS 2019 16.11.10

    MSYS2

    Python

    Git

    三、安裝步驟

    1、安裝cmake,https://cmake.org/download/ ,下載對應windows安裝包安裝即可。

    PS: 安裝時選擇添加環境變量給所有用戶使用。

    2、安裝MSYS2。

    PS: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工具鏈

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

    3、在VS 2019 中安裝clang cmake 等工具。

    4、下載llvm 12.0.0源碼,只需要下載clang和llvm文件夾即可,其他的編譯pass用不到。

    https://github.com/llvm/llvm-project/releases/tag/llvmorg-12.0.0

    5、將源碼解壓,文件樹如下:

    PS:其中build* 文件夾是我運行bat文件后產生的目錄,lld 可以不用下載,是之前踩坑的產物。

    6、編譯源碼:

    x64_gcc_build.bat 文件內容

    cd C:\Users\admin\Documents\llvmProject12set PATH=%PATH%;C:\msys64\mingw64\bingcc --versioncmake -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=ONcmake --build ./build_dyn_x64 -j 4cmake -DCMAKE_INSTALL_PREFIX="C:\Program Files\LLVM\llvm12\llvm12_dyn_x64" -P .\build_dyn_x64\cmake_install.cmake
    

    x86_gcc_build.bat 文件內容

    cd C:\Users\admin\Documents\llvmProject12set PATH=%PATH%;C:\msys64\mingw32\bingcc --versioncmake -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=ONcmake --build ./build_dyn_x32 -j 4cmake -DCMAKE_INSTALL_PREFIX="C:\Program Files\LLVM\llvm12\llvm12_dyn_x32" -P .\build_dyn_x32\cmake_install.cmake
    

    運行 bat 文件即可編譯對應的 llvm。

    7、編譯安裝完成之后可以在下面兩個目錄中找到編譯好的clang 文件。

    C:\Program Files\LLVM\llvm12\llvm12_dyn_x64C:\Program Files\LLVM\llvm12\llvm12_dyn_x32
    

    8、安裝后,我們已經可以用clang 編譯hello world的cpp文件,但是編譯正常的項目文件時,我們需要去解決動態鏈接庫缺失和靜態庫的問題。

    缺失的動態庫可以去C:\msys64\mingw64\bin去尋找,并且復制到C:\Program Files\LLVM\llvm12\llvm12_dyn_x64\bin 中。

    libstdc++-6.dlllibgcc_s_seh-1.dlllibwinpthread-1.dllzlib1.dll
    

    缺失的動態庫可以去C:\msys64\mingw32\bin去尋找,并且復制到C:\Program Files\LLVM\llvm12\llvm12_dyn_x32\bin 中。

    libstdc++-6.dlllibgcc_s_dw2-1.dll (這個庫名稱不一樣)libwinpthread-1.dllzlib1.dll
    

    靜態庫則可以去對應的C:\Users\admin\Documents\llvmProject12\build_dyn_x32\lib 或者C:\Users\admin\Documents\llvmProject12\build_dyn_x64\lib中,將所有a文件添加到對應目錄下。

    四、測試使用

    1、搭建測試的Pass文件和 測試程序源碼,測試的文件樹如下:

    Transforms 文件夾里存放pass文件,TestProgram是項目源碼文件夾。

    2、其中 CMakeLists.txt 文件內容如下:

    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 pathif (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}) # Debugmessage(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的即可):

    cd C:\Users\admin\Documents\llvmProject\ollvm++:: Set MSYS2 envset PATH=%PATH%;C:\msys64\mingw64\bin :: Set LLVM_HOMEset LLVM_HOME=%PROGRAMFILES%/LLVM/llvm12/llvm12_dyn_x64set CC=%LLVM_HOME%/bin/clang.exeset CXX=%LLVM_HOME%/bin/clang++.exeset OPT=%LLVM_HOME%/bin/opt.exeset LLC=%LLVM_HOME%/bin/llc.exe rd /Q /S .\Build :: Build release versioncmake -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  projectcmake --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逆向題:

    #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 <= 1){        return 0;    }    strcpy(input,_argv[1]);    printf("Please input your flag: %s",input);    unsigned char dest[100] = {0};    encrypt(dest, input);    bool result = strlen(input) == 22 && !memcmp(dest, enc, 22);    if(result){         printf("Congratulations~");    }else{         printf("Sorry try again.");    }}
    

    5、配置好之后,直接運行bat文件就能編譯測試:

    集成到Visual Studio 中

    1、我使用的是vs 2019,在之前下載了llvm 12.0 ,并且我們編譯替換成自己的,做好準備工作之后,只需要在命令行選項中加入調用語句即可。

    -Xclang -load -Xclang "C:\\Users\\admin\\Desktop\\Work\\ollvm++\\Build\\libmypass.dll"
    

    2、使用前還需要將平臺工具集先改了。

    編譯程序llvm
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    源碼分析1、LLVM編譯器簡介LLVM 命名最早源自于底層虛擬機的縮寫,由于命名帶來的混亂,LLVM就是該項目的全稱。LLVM 核心庫提供了與編譯器相關的支持,可以作為多種語言編譯器的后臺來使用。自那時以來,已經成長為LLVM的主干項目,由不同的子項目組成,其中許多是正在生產中使用的各種 商業和開源的項目,以及被廣泛用于學術研究。
    LLVM PASS類pwn題入門
    2022-06-30 16:46:54
    同時IR也是一個編譯器組件接口。LLVM的IR有三種表示形式:內存格式,只保存在內存中,人無法看到。不可讀的IR,被稱作bitcode,文件后綴為bc。可讀的IR,介于高級語言和匯編代碼之間,文件后綴為ll。而LLVM PASS就是去處理IR文件,通過opt利用寫好的so庫優化已有的IR,形成新的IR。而LLVM PASS類的pwn就是利用這一過程中可能會出現的漏洞。
    使用AFL++復現歷史CVE
    2022-08-12 17:36:45
    安裝調試目標從github等途徑下載并解壓。從網上找現成的樣本sample。
    假如想在x86平臺運行arm程序,稱arm為source ISA, 而x86為target ISA, 在虛擬化的角度來說arm就是Guest, x86為Host。這種問題被稱為Code-Discovery Problem。每個體系結構對應的helper函數在target/xxx/helper.h頭文件中定義。
    常規調試下watchpoint功能的受限及trace的低效是由于我們是使用軟件方式在用戶態進行操作,受到了CPU及操作系統的限制。但QEMU主要關注于仿真,對于安全分析來說并不友好。原因在于這個程序只是在控制臺打印了HelloWorld,并沒有涉及到JNI相關操作。Qiling的這種做法,以最小的成本保證了對各類各個版本的系統最大的適配性,并且也保證了程序運行狀態與真實環境差異較小。
    AFL--模糊測試使用淺析
    Ghostscript是一款Adobe PostScript語言和PDF的解釋器軟件,被諸多著名應用(如ImageMagick)所使用。 9月5日,海外安全研究員在Twitter公開Ghostscript的安全模式繞過0day,并給出ImagMgick的利用代碼,該漏洞可以造成任意命令執行,影響諸多下游應用,當天TSRC緊急對該漏洞進行復現與分析。 9月9日,Ghostscript官方發布補丁代
    美國國家安全局敦促企業和機構棄用C和C++等編程語言,并轉向內存安全的編程語言,例如C#、Rust、Go、Java、Ruby和Swift等。
    ChatGPT為快速獲得逆向工程工具的幫助增加了另一條途徑。ChatGPT的響應通常包括帶注釋的匯編代碼,這進一步提高了學習效果。一種方法是指示ChatGPT將編寫在一個指令集中的匯編代碼轉換為另一個指令集。
    然而在內核態中,堆內存的分配策略發生了變化。并把這個slab劃分為一個個object,并將這些object組成一個單向鏈表進行管理,這里需要注意slub系統把內存塊當成object看待,而不是伙伴系統中的頁。本次選擇演示的例題是2019-SUCTF的sudrv例題,查看start.sh中的信息可以發現開啟了kaslr保護與smep保護。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类