0%

如何使用LLVM编译Windows驱动(混淆&Asm)

前言


总所周知 世界上最好的IDE Viusal studio 所用的msvc编译器无法使用x64的内联汇编
当然我们可以选择intel 的编译器 这里我们提供一个选择
llvm对vs兼容性没有 intel 编译器好 但是他还有个功能是intel没有的 就是混淆

混淆效果&内联汇编


混淆前代码

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
#include "DriverEntry.h"

static VOID DriverUnload(_In_ PDRIVER_OBJECT DriverObject)
{
UNREFERENCED_PARAMETER(DriverObject);
return;
}
EXTERN_C NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObj, IN PUNICODE_STRING pRegistryString)
{
UNREFERENCED_PARAMETER(pRegistryString);
ULONG64 _Rax = 0;

for (size_t i = 0; i < 10; i++)
{
DPRINT("Test\n");

}
__asm
{
mov _Rax, rax
}
DPRINT("Rax = %x\n", _Rax);

pDriverObj->DriverUnload = DriverUnload;

return STATUS_UNSUCCESSFUL;
}

混淆后IDA F5
图 1
图 2
这里我们使用的是 goron

如何实现

1.下载安装官方版本LLVM

这一步其实自己设置环境变量

1
LLVM_DIR

LLVM 官方下载地址:LLVM

2.安装LLVM插件

Vs2019 插件下载地址:llvm2019
Vs2017 插件下载地址:LLVM Compiler Toolchain
2017以下不支持

3.修改WDK配置
1.打开PlatformToolsets目录

我的:

1
D:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Platforms\x64\PlatformToolsets
2.复制WindowsKernelModeDriver10.0并重命名

如下
图 3

3.修改WindowsKernelModeDriver10.0_LLVM中的配置
  • Toolset.props

    1
    2
    <ClangPropsFile>$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\llvm\Toolset.props</ClangPropsFile>
    <Import Condition="Exists('$(ClangPropsFile)')" Project="$(ClangPropsFile)" />

    图 4

  • Toolset.targets

    1
    2
    <ClangTargetsFile>$(VCTargetsPath)\Platforms\$(Platform)\PlatformToolsets\llvm\Toolset.targets</ClangTargetsFile>
    <Import Condition="Exists('$(ClangTargetsFile)')" Project="$(ClangTargetsFile)" />

图 5

4.配置项目
  • 平台工具集 选择 WindowsKernelModeDriver10.0_LLVM

图 6

  • 选择了我们上面修改的工具及 这里就会出现 LLVM 选项 我们这里只需要 Clang-cl 其他全选(vs2017 有三个选项)
    图 7
  • 关闭Qspectre 缓解
    图 8
  • c/c++ 命令行 从父级或项目默认设置继承 取消勾选
5. 可选
  • 使用带混淆的llvm 比如 ollvm 或者 goron 等其他可以在
    c/c++ 命令行 其他选项 添加混淆选项 以下是goron的混淆选项
    1
    -mllvm -irobf-cse -mllvm -irobf-indbr -mllvm -irobf-icall -mllvm -irobf-indgv -mllvm -irobf-cff 
    图 10
    6. 项目地址
  • 里面包括修改好的项目 以及 修改好的编译器配置
    项目地址