-
-
反射式注入
-
发表于: 2024-12-19 17:18 4157
-
感觉反射式注入与普通注入的最大区别就是不加载系统的API去加载我们的文件,也就是不调用Loadlibrary,而是让我们手动实现装载过程,网上的文章说可以在DLL的导出表中添加ReflectiveLoader函数调用它。由于调用它的时候,不确定DLL文件写到目标进程的哪个虚拟空间上,所以这个编写的函数必须与地址无关,这种代码叫(position-independent code)PIC,暂时理解成在DLL的导出表写入一个函数,这个函数的功能就是PELOADER
一个注射器和一个被注入的DLL
PEB和TEB,PEloader,dll注入(创建远程线程),函数指针,手动实现strncpy,memmove等
我们需要x64dbg去调试查看函数的调用,内存窗口等查看值是否在里面,这里在文件—附加里面可以附加进程
然后用vs去附加进程调试
这里可以添加监视,然后复制值到x64dbg里面,就可以实时监视我们的文件在如何被操作。
大致流程
1.将注入DLL读入自身内存
2.利用VirtualAlloc和WriteProcessMemory在目标进程中写入待注入的DLL文件
3.利用CreateRemoteThread等函数启动目标进程的ReflectiveLoader
因为我的注射器采用的是以创建远程线程为模板,具体的代码不过多分析,就分析和普通创建远程线程不一样的调用自身函数的地方,前面所说,我们是把类似于PEloader的代码写成一个函数放在DLL文件的导出表当中
RVA函数是将虚拟地址RVA转换为文件的偏移量,这里通过遍历导出函数名称表去寻找函数,找到之后返回这个函数的地址的偏移量
这里就很明显了,先是申请内存装DLL,再把DLL写进去,接下来就是去加载DLL,注意,CreatRemoteThread的第四个参数的强制类型转换是转换成远程函数的入口地址,第五个参数是给函数的参数
源码放在最后
前面提到的注射器中也要遍历dll找导出函数,不过因为我的这个dll还没有被加载,所以肯定不能直接使用strstr这些函数,以及调用自己的函数(如果想自己写函数可以先加载节区头),这里我一共找了三个函数,这里列举一个
跳过这个异常执行后面的用户代码再后来看看。
看第一段,代码点进去发现没有什么用,后来才知道 Visual Studio 的 MSVC 编译器会对类成员函数默认使用 __thiscall
调用约定。这是微软编译器的一种特性,特别是当处理 C++ 类成员函数时,this
指针会被隐式传递。
明确了,先学PEB和TEB寻找函数,然后再调用函数去使用,可以详细看看rdi的代码是如何运行的。
这里如果改了优化,代码块可能会被vs自动识别一些冗余或者大小的代码,所以如果遇到代码突然消失(指的是在x64,ida死活找不到代码的时候),先看看这个吧。我这里消失了因为我改优化成了一些最大优化。
这种定义因为会在下面里面继续用,所以不要放在循环里面去定义它,不然会只是一个局部变量,就会是一个空指针
请注意一些32位和64位的区别
1. 基础字符类型
类型
定义
说明
char
单字节字符
用于表示 ANSI 或 ASCII 字符。
wchar_t
宽字符(2 字节/4 字节)
用于表示 Unicode 字符(Windows 下为 UTF-16)。
TCHAR
宏定义的字符类型
根据字符集(ANSI/Unicode)选择 char
或 wchar_t
2. 字符串指针类型
类型
定义
说明
LPSTR
typedef char* LPSTR;
指向普通字符串(char*
)。
LPCSTR
typedef const char* LPCSTR;
指向常量普通字符串(const char*
)。
LPWSTR
typedef wchar_t* LPWSTR;
指向宽字符字符串(wchar_t*
)。
LPCWSTR
typedef const wchar_t* LPCWSTR;
指向常量宽字符字符串(const wchar_t*
)。
LPTSTR
typedef TCHAR* LPTSTR;
指向 TCHAR
字符串。
LPCTSTR
typedef const TCHAR* LPCTSTR;
指向常量 TCHAR
字符串