Windows黑客编程技术
文章目录
第一章 开发环境
开发环境采用VS 2017,主要讲的一些配置方面的问题,
比如控制台程序和DLL程序的编译设置(兼容性设置,运行库),MFC程序编译设置。
Debug模式和Release模式
Debug通常被称为调试版本,而Release通常称为发布版本。
Debug模式和Release模式唯一的区别就是在VS开发环境里编译选项的区别。
假如在Debug模式下运行正常,代码肯定是没问题的,而在Release模式下编译通过,运行出错,是由于一些编译问题导致的,这时候就要在运行库选项里进行相应的更改。
第二章 基础技术
本章主要讲的是病毒木马中一些较为常见、基础的技术。
2.1 单一实例(进程互斥)
CreateMutex()函数
HANDLE WINAPI CreateMutex(
_In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes, //指向SECURITY_ATTRIBUTES结构的指针。若此参数为NULL,则该句柄不能由子进程继承。
_In_ BOOL bInitialOwner, //此值为TRUE并创建互斥锁,则线程获得所有权
_In_opt_LPCTSTR lpName // 如果有重名对象,则会返回错误ERROR_ALREADY_EXISTS(GetLastError函数获取)。
);//该函数成功创建时,返回一个互斥对象的句柄,如果已经重复运行返回存在对象句柄。
简单来说,该函数主要用来降低暴露的风险,保证只运行一个恶意进程。通过该函数来创建一个互斥对象,来判断系统中是否重复运行着进程(对象成功创建,则被认为是首次运行,返回错误则被认为是重复执行)
2.2 DLL延迟加载
可执行程序可以先加载执行,所依赖DLL在正式调用时在加载进来。
这样做可以将DLL以资源文件的形式插入到程序里,在正式调用必须DLL之前,程序都可以正常运行。
在这段时间里,再把DLL释放到本地,保证DLL正确的执行,这样程序只需要exe文件,而不需要DLL文件。
2.3 资源释放
如何把DLL文件释放到本地?
FindResource()函数
HRSRC FindResource(
HMODULE hModule, //包含所需资源的模块句柄,如果是程序本身,可以置为NULL
LPCWSTR lpName, //可以是资源名称或资源ID
LPCWSTR lpType //资源类型,在这里也就是我们自己指定的资源类型
);
SizeofResource()函数
HRSRC SizeofResource(
HMODULE hModule, //模块句柄,同上
HRSRC hResInfo //需要加载的资源句柄,这里也就是FindResource的返回值
);
LoadResource()函数
HGLOBAL LoadResource(
HMODULE hModule, //模块句柄,同上
HRSRC hResInfo //需要加载的资源句柄,这里也就是FindResource的返回值
);
LockResource()函数
HGLOBAL LoadResource(
HGLOBAL hResData //指向内存中要锁定的资源数据块,这里也就是LoadResource的返回值
);
- 先通过FindResource()函数,定位资源,获取资源信息块句柄
- 利用得到的句柄,通过SizeofResource()函数确定大小
- 通过LoadResource()函数加载到程序内存
- 通过LockResource()函数锁定内存,返回资源的起始地址
- 通过起始地址和大小,定位资源,释放到本地
补充
句柄,SECURITY_ATTRIBUTES,GetModuleHandle
第三章 注入技术
为了方便伪装,病毒和木马需要将要执行的ShellCode或DLL注入到目标进程,其中DLL注入最为普遍。
只要其注入成功,则DLL已经成功加载到目标进程空间,简单易用。
3.1 全局钩子
Windows中大部分应用程序都是基于消息机制的,钩子则是用来钩住这些消息的。
HHOOK SetWindowsHookEx(
int idHook, // 钩子程序的类型
HOOKPROC lpfn, // 指向钩子程序的指针
HINSTANCE hMod, // DLL句柄
DWORD dwThreadId // 相关线程标识符,若为0,则与所有线程相关
);
如果创建的是全局钩子,那么钩子函数需要依赖于DLL,这样在对应事件发生时,DLL会被加载到事件的进程地址空间,实现DLL注入。
LRESULT WINAPI CallNextHookEx(
_In_opt_ HHOOK hhk, //保存的钩子过程,也就是SetWindowsHookEx返回值.
_In_ int nCode, //根据SetWindowsHookEx设置的钩子回调而产生的不同的nCode代码. 什么意思? 意思就是如果设置的钩子类型是鼠标消息.那么那个nCode就是鼠标消息.如果是键盘这是键盘
_In_ WPARAM wParam, //同2参数一样.附加参数. 根据钩子回调类型.附加参数有不同的意义.比如如果是鼠标.那么这个有可能代表的就是鼠标的x位置.键盘就可能是键代码
_In_ LPARAM lParam //同3参数一样.附加参数.
);
而CallNextHookEx()函数表示将当前钩子传递给钩子链的下一个钩子。
BOOL WINAPI UnhookWindowsHookEx(
_In_ HHOOK hhk //参数一是 SetWindowHookEx的返回值.也就是钩子过程句柄.
);
而当钩子不再使用时,便对钩子进行卸载。
全局钩子的设置,回调,卸载都需要钩子句柄作为参数,将其传递给其他进程,可以采用共享内存的方法。
在DLL中创建共享内存,在DLL中创建一个变量,然后将DLL加载到多个进程空间。
只要一个修改了,其他进程DLL中的值也会改变,相当于多个进程共享内存。
3.2 远线程注入
远线程注入是指一个进程在另一个进程里创建线程的技术。
HANDLE OpenProcess(
DWORD dwDesiredAccess, //进程对象,会对进程的安全描述符进行检查
BOOL bInheritHandle, //若为True,由此进程创建的进程将继承该句柄
DWORD dwProcessId //本地进程PID
);
OpenProcess()用来打开本地的进程对象。
LPVOID VirtualAllocEx(
HANDLE hProcess, //进程的句柄
LPVOID lpAddress, //分配页面起始指针
SIZE_T dwSize, //分配内存大小
DWORD flAllocationType, //分配内存类型
DWORD flProtect //要分配的页面区域的内存保护
);
VirtualAllocEx()在指定的虚拟地址空间内保存、提交或者更改内存状态。
BOOL WriteProcessMemory(
HANDLE hProcess, //进程内存句柄
LPVOID lpBaseAddress, //基地址指针
LPCVOID lpBuffer, //指向缓冲区的指针
SIZE_T nSize