大数跨境
0
0

劫持MSVC编译器编译过程(VS2019 VS2022) 利用思路

劫持MSVC编译器编译过程(VS2019 VS2022) 利用思路 看雪学苑
2025-11-29
2
导读:看雪论坛作者ID:TeddyBe4r

今天为大家带来一个基于Dll劫持的MSVC编译过程劫持思路,我本来是想要研究下MSVC编译器想通过注入的方式劫持编译流,然后通过得出逆向出微软编译器的IR格式,最后通过自己的Pass实现原生的Windows下驱动混淆方案(又或者 编译期代码植入)。

我目前用的方案是自己写的LLVM替换编译工具链的方式来对驱动进行混淆的,但是该方案每次我改动LLVM的时候就需要重新编译LLVM,非常的麻烦。所以我就想着能不能通过注入的方式去做,结果在研究的过程中发现可以通过劫持的方式去做(微软偷懒没有对PASS 相关的DLL进行鉴权导致我们可以利用这个机制进行植入)换句话说这个也是一个代码植入的APT思路,虽然我们已经可以用譬如:

1.替换C库文件

2.替换静态库文件


等等方式使其编译带毒感染,但是总归都不如通过直接劫持编译器来的快。

影响版本

更早的没有测过了,至少新版本是可以的

◆VS2019

◆VS2017

◆VS2022


先看效果

图片描述

利用方式

通过替换Dll即可实现。路径如下:

1.Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\Hostx86\x86

2.Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\Hostx86\x64

3.Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x86

4.Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x64

这些路径下的c1.dllc2.dll都可以劫持,微软完全没有对该部分dll的加载进行任何签名校验,问题是这些dll目录一般是在Path中的所以在微软的漏洞定义里面不属于漏洞(Hijack本来也不算),因为是管理员权限,但是我还是觉得微软应该做一下鉴权毕竟也不是经常更新的东西,这个组件c1.dll同时还承担了一些编译前端的工作,在加载C/C++项目的时候也会加载(估计是做代码提示分析这一类的),编译的时候也会加载(Pass嘛)。


分析 cl.exe

如下所示,有两个地方都可以加载Dll并且没有做任何的校验


.text:00426C20 ; int __fastcall execute(intint, const WCHAR *lpLibFileName, wchar_t *Name, _DWORD *)
.text:00426C20 ?execute@@YAHW4driver_phases@@PAUpassinfo_t@@PBG2PAPAG@Z proc near in this methods this line
.text:00426E16 call ds:__imp__LoadLibraryExW@12 ; LoadLibraryExW(x,x,x)
they call the loadlibraryExW without check and after that
.text:00426E1C mov ebx, eax
.text:00426E1E test ebx, ebx
.text:00426E20 jz short loc_426E5A
.text:00426E22 push offset aInvokecompiler_0 ; "_InvokeCompilerPassW@16"
.text:00426E27 push ebx ; hModule
.text:00426E28 mov esi, ds:__imp__GetProcAddress@8 ; GetProcAddress(x,x)
.text:00426E2call esi ; GetProcAddress(x,x) ; GetProcAddress(x,x)
.text:00426E30 mov [ebp+var_28], eax
.text:00426E33 push offset aAbortcompilerp_0 ; "_AbortCompilerPass@4"
.text:00426E38 push ebx ; hModule
.text:00426E39 call esi ; GetProcAddress(x,x) ; GetProcAddress(x,x).text:00426E1C mov ebx, eax (pollute _AbortCompilerPass)
.text:00426E1E test ebx, ebx
.text:00426E20 jz short loc_426E5A
.text:00426E22 push offset aInvokecompiler_0 ; "_InvokeCompilerPassW@16"
.text:00426E27 push ebx ; hModule
.text:00426E28 mov esi, ds:__imp__GetProcAddress@8 ; GetProcAddress(x,x)
.text:00426E2call esi ; GetProcAddress(x,x) ; GetProcAddress(x,x)
pollute _InvokeCompilerPassW
.text:00426E30 mov [ebp+var_28], eax
.text:00426E33 push offset aAbortcompilerp_0 ; "_AbortCompilerPass@4"
.text:00426E38 push ebx ; hModule
.text:00426E39 call esi ; GetProcAddress(x,x) ; GetProcAddress(x,x)

分析c1.dll的利用方式

首先,我们根据cl.exe的名称可以看到他载入后调用了_InvokeCompilerPassW@16我们可以在IDA里面搜索这个签名。

图片描述

找到该函数后进入Trap_callMain进入编译流程

图片描述

继续进入CallMain

图片描述

继续进入Trap_main_complie这里稍微还原以下如果大家是F5看的话应该最后是


return Trap_main_complie()


图片描述

他里面还包了一层main_compile继续

图片描述

这个非常大的函数就是编译的逻辑了,这里我给出一些大概的东西大家具体可以自己分析。

FileMap句柄(可以通过这个去写文件)

这里可以看到句柄位置

图片描述

可以通过如下类方法去研究

图片描述

然后IR的一些格式和操作需要结合cl.exe的方法才能分析出来,这部分内容我就不写了目前暂不公开,通过如上的句柄已经可以进行劫持了,修改c1.dll通过特征或者PDB获取到句柄后在编译的时候识别标准的__crt_main函数的特征码或者__init_term等等的点都可以注入一些意想不到的东西。我给出c1的主要CFG。


InvokeCompilerPassW -> Trap_CallMain -> CallMain -> Trap_main_compile ->main_compile(核心编译函数)


该方法挺通用的很多版本都可以用,具体更多用法等大家自己去开发,关于IR的一些研究我就不发了。






看雪ID:TeddyBe4r

https://bbs.kanxue.com/user-home-983513.htm

*本文为看雪论坛优秀文章,由 TeddyBe4r 原创,转载请注明来自看雪社区

# 往期推荐

Hyper-V平台IUM进程调试工具及通用TPM漏洞CVE-2025-2884分析与复现

第八届强网拟态防御国际精英挑战赛 - WIN!致敬mt 复现

VmProtect.3.9.4分析之虚拟机流程

极路由远程命令执行漏洞-漏洞分析

一道CTF题目animals:变异MD5加密分析

图片

球分享

球点赞

球在看


点击阅读原文查看更多

【声明】内容源于网络
0
0
看雪学苑
致力于移动与安全研究的开发者社区,看雪学院(kanxue.com)官方微信公众帐号。
内容 6594
粉丝 0
看雪学苑 致力于移动与安全研究的开发者社区,看雪学院(kanxue.com)官方微信公众帐号。
总阅读406
粉丝0
内容6.6k