HideNimMain-Hide NimMain in DLL
HideNimMain-Hide NimMain in DLL
S0cke3t序
相信很多使用nim做过开发或者免杀的师傅都遇到过这种情况,使用nim编译的dll会默认导出一个NimMain
函数,即使你没有定义该函数
对于正常开发来说,这也无可厚非。但对于使用nim来做免杀或者其他红队相关的工作,要尽可能的减少文件的特征。
注: 此工具并非新技术,仅仅是笔者对原始文章的重构与扩展
编译过程
首先nim编译器在编译时会对所有参与编译的nim源文件生成对应的c语言中间文件(取决你使用的编译标志),默认情况下如果没有使用--nimcache
编译标志指定中间文件生成位置,那么编译器会默认在%USERPROFILE%\\nimcache\\project
生成对应缓存文件,linux默认会在$HOME/.cache/nim/project
其中project
会根据编译标志-d
参数的不同有所变化,如指定-d:debug
则会生成project_d
, -d:release
则会是project_r
其中<project>
会根据编译标志-d
参数的不同有所变化,如指定-d:debug
则会生成<project>_d
, -d:release
则会是<project>_r
以此项目为例,在生成的众多文件中需要重点关注的就是@<project>.nim.c
此文件为项目主文件经由nim编译器生成的对应C语言文件
而<project>.json
则保存了所有编译及链接所需的命令
修补NimMain
首先使用nim c --noLinking:on -d=mingw --app=lib --nomain demo.nim
来生成demo对应的C文件
在生成的文件中,nim编译器自动为NimMain
使用了N_LIB_EXPORT
宏
N_LIB_EXPORT
通常用于标记需要被导出的函数或变量,这意味着使用 N_LIB_EXPORT
标记的函数或变量可以被其他模块或外部程序引用和调用。
那么我们只需要修改这个默认的宏就可以阻止NimMain
函数导出,如将其修改为N_LIB_PRIVATE
注意在修改完后,不能再使用nim编译器进行编译,这样会覆盖掉修改的宏。我们需要手动执行<project>.json
中编译和链接的操作
在参考文章中作者给出了一个修改的工具compFiddler
,但此仓库已被作者删除
根据此原理笔者重写此工具,并加入了对x86和x64的支持
运行后会在out目录下生成两个dll,<project>.dll
为原始dll,<project>-nomain.dll
为patch后的dll
代码已上传至Github
总结
此方法仅仅作为最基础的处理手段,要想运用在实际场景中还需结合其他规避手段
除了使用patch源文件的方法还可以使用加载def文件来达到相同的目的,原理类似此处不再进行赘述。