DLL基础以及注入
DLL基础入门笔记
大一时候写的笔记吧好像是。。。现在回首一看简直就是一坨,放博客里记录一下鼠鼠的阴暗成长史吧。(喜)
0x01
DLL(动态链接库)
1.一般步骤:将共享DLL文件感染掉,电脑啥的重启时,所有调用它的都会被感染掉。
2.注意事项:
DLL模块中包含各种导出函数,用于向外界提供服务,exe。
一个DLL在内存中只有一个实例。
DLL实现了代码的封装性;编程->接口
DLL的编制与具体的编程语言及编译器无关。
DLL模块需要的堆栈内存都是从运行进程的堆栈中分配出来的。
DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。
Windows API基础速成
1.其中32位Windows操作系统的编程接口称为Win32 API
2.应用层编程都是32位的API 而内核层才会用到64位的
3.函数分类:
基本服务(开关机)
组件服务(打开任务管理器即可查看)
用户界面服务(平时编辑的窗口)
图形多媒体服务(听歌,看电影)
消息和协作(发信息,复制,粘贴,剪贴等等)
网络
web服务(网页)
通过系统文件函数的操作掌握学习方法
eg. DeleteFileA 是 DeleteFile的净化版本
1.可适当取用错误码的返回函数来判断程序的出错原因,对照官网api函数详解。
DLL文件的编写速成
①.创建DLL
调用约定:
__stdcall(函数的调用约定 )
__cdel
②.
1 | BOOL WINAPI DllMain( HMODULE hModule, |
上面这则代码是核心的入口函数 DLL文件 动态链接库入口函数
DLL模块的句柄 handle
DLLMain函数被调用的原因
调用原因集合大全:
保留项,也就是Windows的保留参数 lpReserved
保留参数:不是不使用的参数,而是Windows不想让我们知 道作用的参数
导出函数(相当于一个接口)
1.DLL文件提供接口,前提是DLL文件中有导出函数了才能让外部程序实现对于DLL的调用
2.如果声明没有dllimport或dllexport特性的函数,则该函数不能视为DLL接口的一部分。
应用程序与导出函数的静态通讯方法
1.静态库是指在我们的应用中,有一些公共代码是需要反复使用,就把这些代码编译为“库”文件,链接器将从库文件取得所需代码,复制到生成的可执行文件中的这种库。
2.#pragma comment(lib , “dll”) 注意:没有分号 (函数参数是 后面那个)
注意事项:
extern “C” void 函数名(参数);注意有分号 //防止编译后函数名被篡改或者粉碎
__declspec(dllexport):声明导出函数,将该函数从本DLL开放提供给其他应用程序使用
如果没有声明DLLimport或dllexport特性的函数,则该函数不被视为DLL接口的一部分。因此,函数的定义必须存在于该模块或同一程序程序的另一个模块中。若要使函数成为DLL接口的一部分,必须将其他模块中的函数的定义声明为 dllexport。
1.**编译的时候:**编译exe文件的时候必须将所注入的DLL文件复制到exe文件所在的解决方案目录中(如果不详写路径的话)
2.**运行的时候:**不需要lib,只需要dll
复现成功!
0x02
一.应用程序与DLL导出函数的“动态”通讯:
静态调用:通过连接器将DLL函数的导出函数写进可执行文件。(见part1中的后面部分)
动态调用:相对于前一种调用属于动态调用,不是在连接时完成的,而是在运行时候完成的。
二.动态调用的核心代码:
此处只需要将原本静态调用下编写的dll文件与新编写的动态调用所生成的exe放在同一文件下即可
动态调用的详细改写代码如下:
1 |
|
实现截图如下:
实现成功
0x03
一.导出函数查看工具的使用:
一键略过,说一下可记知识点:
X86 -> 32位
X64 -> 64位
RVA:RVA是相对虚拟地址(Relative Virtual Address)的缩写,顾名思义,它是一个“相对”地址,也可以说是“偏移量”,PE文件的各种数据结构中涉及到地址的字段大部分都是以RVA表示的。
主要就是查看dll中函数导出的RVA地址
二.DLL注入工具使用
使用注入工具的话需要对于原来的dll文件有一个修改
三.进程和线程的概念:
1.进程,线程,CPU之间的关系就好像车间,车间资源,工厂之间的关系。
2.操作系统的设计可以归结为三点:
(1).以多进程形式,允许多个任务同时运行;
(2).以多线程形式,允许单个任务分成不同的部分运行;
(3).提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源。
3.远线程注入:创建一个远程的线程到目标的进程中去执行LoadLibraryA函数,代码如下:
1 |
|
4.地址获取;
5.模块擦除:
在调用完一个dll之后,记得用FreeLibrary(“被调用模块的句柄”)擦除一下,如若要加载的应用中存在自动扫描dll,那么这个模块将会暴露,所以要擦除。
四.远程卸载dll模块实战
废话不多说,直接上代码
1 | void Unject(int pid) |