免责声明: 文章仅用于技术分享,切勿非法测试,由于传播、利用本公众号朱厌安全团队所提供的信息而造成的后果以及损失,均由使用者本人承担,本公众号朱厌安全团队以及作者不为此承担任何责任!如有侵权烦请告知,我们会立即删除并致歉!
How to generate PE file
0X01 前言
前面一章简单的介绍了PE文件中的Section部分,下面来生成一个PE文件,去看看PE文件在内存当中是怎样的,为后面恶意软件开发奠定基础。
0x02 生成EXE文件
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
printf("RT Operator, here I come!n");
getchar();
return 0;
}
可以看到这是一段非常简单的C++代码,下面直接给他编译成可执行的文件。编译的指令如下:
cl.exe /nologo /Ox /MT /W0 /GS- /DNDEBUG /Tcimplant.cpp /link /OUT:implant.exe /SUBSYSTEM:CONSOLE /MACHINE:x64
简单解释一下这一串编译指令其中cl.exe是Visual C++ 的编译器,参数nologo是不显示编译器的版本信息,Ox是指定编译器使用最大优化级别进行编译,MT是指定使用多线程静态库,以便可将应用程序独立打包,这个是比较要重要的一个参数,他会直接影响你编译好的程序能否在其他操作系统上执行,如果不使用这个参数的话,在其他操作系统上运行话会提示少一些库,W0是指定关闭警告信息输出,GS指定关闭安全检查,即关闭缓冲区溢出检查,DNDEBUG指定定义NDEBUG宏,以便在代码中使用assert()宏进行调试,/Tcimplant.cpp指定要编译的C++源代码文件为implant.cpp,link指定使用链接器进行链接,/OUT:implant.exe:指定生成的可执行文件名称为implant.exe,/SUBSYSTEM:CONSOLE指定应用程序的子系统为控制台,/MACHINE:x64:指定生成的可执行文件为64位应用程序。
成功编译之后,可以看到代码中打印的字符,那么接下使用Process Hacker 研究一下PE文件在内存当中是什么样的,直接双击implant.exe。
可以看到Process Hacker 给了很多信息,比如文件的完整路径,PEB地址,父进程,当前路径,线程,内存,加载的dll。
以后就可以去通过查看内存属性,双击内存区域,去定位Shellcode,目前这一节只需要去了解一下这个Process Hacker,后面会亲手定位恶意软件的shellcode。
可以看到双击后能清楚的看到,这个RX内存区域内容。
0x03 生成DLL文件
通过下面给出的代码就可以生成一个DLL文件
#include <Windows.h>
#pragma comment (lib, "user32.lib")
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
extern "C" {
__declspec(dllexport) BOOL WINAPI RunME(void) {
MessageBox(
NULL,
"RT Operator, here I come!",
"RTO",
MB_OK
);
return TRUE;
}
}
简单说一下这个代码,DllMain是这个DLL的主函数,他可以在不同的情况下调用,当加载程序将DLL 加载到进程中时会调用DllMain函数,当DLL从进程中卸载的时候也会调用DllMain函数,那么他同样也适用于运行的线程和退出的线程,比如运行的线程和退出的线程导致了dll的加载和卸载都会去调用dllMain函数。
可以看到这个switch代码明确这个这种情况,当进程加载了dll将会执行,DLL_PROCESS_ATTACH的逻辑,当进程卸载DLL的时候执行,DLL_PROCESS_DETACH的逻辑,线程同理。
extern "C" {
__declspec(dllexport) BOOL WINAPI RunME(void) {
MessageBox(
NULL,
"RT Operator, here I come!",
"RTO",
MB_OK
);
return TRUE;
}
}
可以看到还写了一个函数,这个函数主要是弹出一个MesageBox,作为外部函数导出提供给进程调用。下面将源文件编译成dll文件。
cl.exe /D_USRDLL /D_WINDLL implantDLL.cpp /MT /link /DLL /OUT:implant.dll
简单的解释之前没有见过的参数,D_USRDLL指定定义USRDLL宏,以便编译器将该C++源代码文件编译为Windows DLL, D_WINDLL指定定义WINDLL宏,以便编译器将该C++源代码文件编译为Windows DLL动态链接库,DLL指定生成的库文件为Windows DLL动态链接库。
可以看到编译成功了,因为DLL不能独立运行,现在就是想办法把它加载到进程空间运行就可以了,那么Windows就给提供了一个这样程序Rundll.exe,他可以去加载任意的Dll。
可以看到成功加载了DLL,也成功的调用了导出函数。
原文始发于微信公众号(朱厌安全团队):恶意软件开发(二)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论