<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    反射式DLL注入實現

    VSole2022-05-13 15:59:21

    一般而言要注入DLL到一個目標進程最簡單的方法 就是先獲取DLL文件路徑,然后在目標進程分配內存空間將路徑寫入到目標進程,寫入到目標進程后再調用CreateRemoteThread()/NtCreateThread()/RtlCreateUserThread()函數來運行LoadLibraryA/W函數調用自己的DLL,這種方法的缺陷也很明顯那就是容易被游戲檢測到,很容易被游戲攔截,比如CSGO最新版就已經有這個限制了。

    想要突破CSGO的限制注入DLL進去,我們可以采用反射式注入的方法(也可以先恢復CSGOhook的api進行遠程線程注入),那么什么是反射式注入呢?又有什么有點呢?

    反射式dll注入與常規dll注入類似,而不同的地方在于反射式dll注入技術自己實現了一個reflective loader()函數來代替LoadLibaryA()函數去加載dll,示意圖如下圖所示。藍色的線表示與用常規dll注入相同的步驟,紅框中的是reflective loader()函數行為,也是下面重點描述的地方。

    Reflective loader實現思路如下: 

    1.獲得被注入進程未解析的dll的基地址。

    2.獲得必要的dll句柄和函數為修復導入表做準備。

    3.分配一塊新內存去取解析dll,并把pe頭復制到新內存中和將各節復制到新內存中。

    4.修復導入表和重定向表。

    5.執行DllMain()函數。

    核心代碼如下:

    ManualMapInject.h

    #pragma once#include "Injector.h" using f_LoadLibraryA = HINSTANCE(WINAPI*)(const char* lpLibFilename);using f_GetProcAddress = FARPROC(WINAPI*)(HMODULE hModule, LPCSTR lpProcName);using f_DLL_ENTRY_POINT = BOOL(WINAPI*)(void* hDll, DWORD dwReason, void* pReserved); #ifdef _WIN64using f_RtlAddFunctionTable = BOOL(WINAPIV*)(PRUNTIME_FUNCTION FunctionTable, DWORD EntryCount, DWORD64 BaseAddress);#endif struct MANUAL_MAPPING_DATA{    f_LoadLibraryA pLoadLibraryA;    f_GetProcAddress pGetProcAddress;#ifdef _WIN64    f_RtlAddFunctionTable pRtlAddFunctionTable;#endif    BYTE* pbase;    HINSTANCE hMod;    DWORD fdwReasonParam;    LPVOID reservedParam;    BOOL SEHSupport;};  //Note: Exception support only x64 with build params /EHa or /EHcbool ManualMapDll(HANDLE hProc, BYTE* pSrcData, SIZE_T FileSize, bool ClearHeader = true, bool ClearNonNeededSections = true, bool AdjustProtections = true, bool SEHExceptionSupport = true, DWORD fdwReason = DLL_PROCESS_ATTACH, LPVOID lpReserved = 0);void __stdcall Shellcode(MANUAL_MAPPING_DATA* pData); class CManualMapInject :public CInjector{public:    CManualMapInject();    virtual ~CManualMapInject();    virtual bool InjectorDLL(TCHAR* szPath,DWORD dwPid);};
    

    ManualMapInject.cpp

    #include "pch.h"#include "ManualMapInject.h"  #ifdef _WIN64#define CURRENT_ARCH IMAGE_FILE_MACHINE_AMD64#else#define CURRENT_ARCH IMAGE_FILE_MACHINE_I386#endif#define RELOC_FLAG32(RelInfo) ((RelInfo >> 0x0C) == IMAGE_REL_BASED_HIGHLOW)#define RELOC_FLAG64(RelInfo) ((RelInfo >> 0x0C) == IMAGE_REL_BASED_DIR64) #ifdef _WIN64#define RELOC_FLAG RELOC_FLAG64#else#define RELOC_FLAG RELOC_FLAG32#endif   CManualMapInject::CManualMapInject(){} CManualMapInject::~CManualMapInject(){} bool CManualMapInject::InjectorDLL(TCHAR* szPath, DWORD dwPid){    HANDLE hProc = GetProcessHandle(dwPid);    if (!hProc || !IsCorrectTargetArchitecture(hProc) || GetFileAttributes(szPath) == INVALID_FILE_ATTRIBUTES)    {        return false;    } //     std::ifstream File(szPath, std::ios::binary | std::ios::ate);////     if (File.fail())//     {//         printf("Opening the file failed: %X", (DWORD)File.rdstate());//         File.close();//         CloseHandle(hProc);//         system("PAUSE");//         return -5;//     }////     auto FileSize = File.tellg();//     if (FileSize < 0x1000)//     {//         printf("Filesize invalid.");//         File.close();//         CloseHandle(hProc);//         system("PAUSE");//         return -6;//     }////     BYTE* pSrcData = new BYTE[(UINT_PTR)FileSize];//     if (!pSrcData)//     {//         printf("Can't allocate dll file.");//         File.close();//         CloseHandle(hProc);//         system("PAUSE");//         return -7;//     }////     File.seekg(0, std::ios::beg);//     File.read((char*)(pSrcData), FileSize);//     File.close();    CFile file;    file.Open(szPath, CFile::modeRead);    ULONGLONG nFileSize = file.GetLength();    BYTE* pSrcData = new BYTE[nFileSize];    ZeroMemory(pSrcData,nFileSize);    file.SeekToBegin();    file.Read(pSrcData,nFileSize);    file.Close();     if (!ManualMapDll(hProc, pSrcData, nFileSize))    {        delete[] pSrcData;        CloseHandle(hProc);        return false;    }    delete[] pSrcData;     CloseHandle(hProc);    return false;} bool ManualMapDll(HANDLE hProc, BYTE* pSrcData, SIZE_T FileSize, bool ClearHeader,    bool ClearNonNeededSections, bool AdjustProtections,    bool SEHExceptionSupport, DWORD fdwReason, LPVOID lpReserved){    IMAGE_NT_HEADERS* pOldNtHeader = nullptr;    IMAGE_OPTIONAL_HEADER* pOldOptHeader = nullptr;    IMAGE_FILE_HEADER* pOldFileHeader = nullptr;    BYTE* pTargetBase = nullptr;     if (reinterpret_cast(pSrcData)->e_magic != 0x5A4D)//"MZ"    {        return false;    }     pOldNtHeader = reinterpret_cast(pSrcData + reinterpret_cast(pSrcData)->e_lfanew);    pOldOptHeader = &pOldNtHeader->OptionalHeader;    pOldFileHeader = &pOldNtHeader->FileHeader;     if (pOldFileHeader->Machine != CURRENT_ARCH)    {        return false;    }     pTargetBase = reinterpret_cast(VirtualAllocEx(hProc, nullptr, pOldOptHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE));    if (!pTargetBase)    {        return false;    }     DWORD oldp = 0;    VirtualProtectEx(hProc, pTargetBase, pOldOptHeader->SizeOfImage, PAGE_EXECUTE_READWRITE, &oldp);     MANUAL_MAPPING_DATA data{ 0 };    data.pLoadLibraryA = LoadLibraryA;    data.pGetProcAddress = GetProcAddress;#ifdef _WIN64    data.pRtlAddFunctionTable = (f_RtlAddFunctionTable)RtlAddFunctionTable;#else    SEHExceptionSupport = false;#endif    data.pbase = pTargetBase;    data.fdwReasonParam = fdwReason;    data.reservedParam = lpReserved;    data.SEHSupport = SEHExceptionSupport;      //PE header    if (!WriteProcessMemory(hProc, pTargetBase, pSrcData, 0x1000, nullptr)) //only first 0x1000 bytes for the header    {        VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);        return false;    }     IMAGE_SECTION_HEADER* pSectionHeader = IMAGE_FIRST_SECTION(pOldNtHeader);    for (UINT i = 0; i != pOldFileHeader->NumberOfSections; ++i, ++pSectionHeader)    {        if (pSectionHeader->SizeOfRawData)        {            if (!WriteProcessMemory(hProc, pTargetBase + pSectionHeader->VirtualAddress, pSrcData + pSectionHeader->PointerToRawData, pSectionHeader->SizeOfRawData, nullptr))            {                VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);                return false;            }        }    }     //Mapping params    BYTE* MappingDataAlloc = reinterpret_cast(VirtualAllocEx(hProc, nullptr, sizeof(MANUAL_MAPPING_DATA), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE));    if (!MappingDataAlloc)    {        VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);        return false;    }     if (!WriteProcessMemory(hProc, MappingDataAlloc, &data, sizeof(MANUAL_MAPPING_DATA), nullptr))    {        VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);        VirtualFreeEx(hProc, MappingDataAlloc, 0, MEM_RELEASE);        return false;    }     //Shell code    void* pShellcode = VirtualAllocEx(hProc, nullptr, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);    if (!pShellcode)    {        VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);        VirtualFreeEx(hProc, MappingDataAlloc, 0, MEM_RELEASE);        return false;    }     if (!WriteProcessMemory(hProc, pShellcode, Shellcode, 0x1000, nullptr))    {        VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);        VirtualFreeEx(hProc, MappingDataAlloc, 0, MEM_RELEASE);        VirtualFreeEx(hProc, pShellcode, 0, MEM_RELEASE);        return false;    }      HANDLE hThread = CreateRemoteThread(hProc, nullptr, 0, reinterpret_cast(pShellcode), MappingDataAlloc, 0, nullptr);    if (!hThread)    {        VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);        VirtualFreeEx(hProc, MappingDataAlloc, 0, MEM_RELEASE);        VirtualFreeEx(hProc, pShellcode, 0, MEM_RELEASE);        return false;    }    WaitForSingleObject(hThread, INFINITE);    CloseHandle(hThread);      HINSTANCE hCheck = NULL;    while (!hCheck)    {        DWORD exitcode = 0;        GetExitCodeProcess(hProc, &exitcode);        if (exitcode != STILL_ACTIVE)        {            return false;        }         MANUAL_MAPPING_DATA data_checked{ 0 };        ReadProcessMemory(hProc, MappingDataAlloc, &data_checked, sizeof(data_checked), nullptr);        hCheck = data_checked.hMod;         if (hCheck == (HINSTANCE)0x404040)        {            VirtualFreeEx(hProc, pTargetBase, 0, MEM_RELEASE);            VirtualFreeEx(hProc, MappingDataAlloc, 0, MEM_RELEASE);            VirtualFreeEx(hProc, pShellcode, 0, MEM_RELEASE);            return false;        }        else if (hCheck == (HINSTANCE)0x505050)        {            //Exception support failed!        }         Sleep(10);    }     BYTE* emptyBuffer = (BYTE*)malloc(1024 * 1024 * 20);    if (emptyBuffer == nullptr)    {        return false;    }    memset(emptyBuffer, 0, 1024 * 1024 * 20);     //CLEAR PE HEAD    if (ClearHeader)    {        WriteProcessMemory(hProc, pTargetBase, emptyBuffer, 0x1000, nullptr);    }    //END CLEAR PE HEAD      if (ClearNonNeededSections)    {        pSectionHeader = IMAGE_FIRST_SECTION(pOldNtHeader);        for (UINT i = 0; i != pOldFileHeader->NumberOfSections; ++i, ++pSectionHeader)        {            if (pSectionHeader->Misc.VirtualSize)            {                if ((SEHExceptionSupport ? 0 : strcmp((char*)pSectionHeader->Name, ".pdata") == 0) ||                    strcmp((char*)pSectionHeader->Name, ".rsrc") == 0 ||                    strcmp((char*)pSectionHeader->Name, ".reloc") == 0)                {                    WriteProcessMemory(hProc, pTargetBase + pSectionHeader->VirtualAddress, emptyBuffer, pSectionHeader->Misc.VirtualSize, nullptr);                }            }        }    }     if (AdjustProtections)    {        pSectionHeader = IMAGE_FIRST_SECTION(pOldNtHeader);        for (UINT i = 0; i != pOldFileHeader->NumberOfSections; ++i, ++pSectionHeader)        {            if (pSectionHeader->Misc.VirtualSize)            {                DWORD old = 0;                DWORD newP = PAGE_READONLY;                 if ((pSectionHeader->Characteristics & IMAGE_SCN_MEM_WRITE) > 0)                {                    newP = PAGE_READWRITE;                }                else if ((pSectionHeader->Characteristics & IMAGE_SCN_MEM_EXECUTE) > 0)                {                    newP = PAGE_EXECUTE_READ;                }                VirtualProtectEx(hProc, pTargetBase + pSectionHeader->VirtualAddress, pSectionHeader->Misc.VirtualSize, newP, &old);            }        }        DWORD old = 0;        VirtualProtectEx(hProc, pTargetBase, IMAGE_FIRST_SECTION(pOldNtHeader)->VirtualAddress, PAGE_READONLY, &old);    }     WriteProcessMemory(hProc, pShellcode, emptyBuffer, 0x1000, nullptr);    VirtualFreeEx(hProc, pShellcode, 0, MEM_RELEASE);    VirtualFreeEx(hProc, MappingDataAlloc, 0, MEM_RELEASE);     return true;}   //#pragma runtime_checks( "", off )//#pragma optimize( "", off )void __stdcall Shellcode(MANUAL_MAPPING_DATA* pData){    if (!pData)    {        pData->hMod = (HINSTANCE)0x404040;        return;    }     BYTE* pBase = pData->pbase;    auto* pOpt = &reinterpret_cast(pBase + reinterpret_cast((uintptr_t)pBase)->e_lfanew)->OptionalHeader;     auto _LoadLibraryA = pData->pLoadLibraryA;    auto _GetProcAddress = pData->pGetProcAddress;#ifdef _WIN64    auto _RtlAddFunctionTable = pData->pRtlAddFunctionTable;#endif    auto _DllMain = reinterpret_cast(pBase + pOpt->AddressOfEntryPoint);     BYTE* LocationDelta = pBase - pOpt->ImageBase;    if (LocationDelta) {        if (pOpt->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size)        {            auto* pRelocData = reinterpret_cast(pBase + pOpt->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);            const auto* pRelocEnd = reinterpret_cast(reinterpret_cast<uintptr_t>(pRelocData) + pOpt->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);            while (pRelocData < pRelocEnd && pRelocData->SizeOfBlock)            {                UINT AmountOfEntries = (pRelocData->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);                WORD* pRelativeInfo = reinterpret_cast(pRelocData + 1);                 for (UINT i = 0; i != AmountOfEntries; ++i, ++pRelativeInfo)                {                    if (RELOC_FLAG(*pRelativeInfo))                    {                        UINT_PTR* pPatch = reinterpret_cast(pBase + pRelocData->VirtualAddress + ((*pRelativeInfo) & 0xFFF));                        *pPatch += reinterpret_cast(LocationDelta);                    }                }                pRelocData = reinterpret_cast(reinterpret_cast(pRelocData) + pRelocData->SizeOfBlock);            }        }    }     if (pOpt->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size)    {        auto* pImportDescr = reinterpret_cast(pBase + pOpt->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);        while (pImportDescr->Name)        {            char* szMod = reinterpret_cast<char*>(pBase + pImportDescr->Name);            HINSTANCE hDll = _LoadLibraryA(szMod);             ULONG_PTR* pThunkRef = reinterpret_cast(pBase + pImportDescr->OriginalFirstThunk);            ULONG_PTR* pFuncRef = reinterpret_cast(pBase + pImportDescr->FirstThunk);             if (!pThunkRef)                pThunkRef = pFuncRef;             for (; *pThunkRef; ++pThunkRef, ++pFuncRef)            {                if (IMAGE_SNAP_BY_ORDINAL(*pThunkRef))                {                    *pFuncRef = (ULONG_PTR)_GetProcAddress(hDll, reinterpret_cast<char*>(*pThunkRef & 0xFFFF));                }                else                {                    auto* pImport = reinterpret_cast(pBase + (*pThunkRef));                    *pFuncRef = (ULONG_PTR)_GetProcAddress(hDll, pImport->Name);                }            }            ++pImportDescr;        }    }     if (pOpt->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size)    {        auto* pTLS = reinterpret_cast(pBase + pOpt->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);        auto* pCallback = reinterpret_cast(pTLS->AddressOfCallBacks);        for (; pCallback && *pCallback; ++pCallback)            (*pCallback)(pBase, DLL_PROCESS_ATTACH, nullptr);    }     bool ExceptionSupportFailed = false; #ifdef _WIN64     if (pData->SEHSupport)    {        auto excep = pOpt->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];        if (excep.Size) {            if (!_RtlAddFunctionTable(                reinterpret_cast(pBase + excep.VirtualAddress),                excep.Size / sizeof(IMAGE_RUNTIME_FUNCTION_ENTRY), (DWORD64)pBase))            {                ExceptionSupportFailed = true;            }        }    } #endif     _DllMain(pBase, pData->fdwReasonParam, pData->reservedParam);     if (ExceptionSupportFailed)        pData->hMod = reinterpret_cast(0x505050);    else        pData->hMod = reinterpret_cast(pBase);}
    

    運行效果如下:

    dll注入reinterpret_cast
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    反射式DLL注入實現
    2022-05-13 15:59:21
    反射式dll注入與常規dll注入類似,而不同的地方在于反射式dll注入技術自己實現了一個reflective loader()函數來代替LoadLibaryA()函數去加載dll,示意圖如下圖所示。藍色的線表示與用常規dll注入相同的步驟,紅框中的是reflective loader()函數行為,也是下面重點描述的地方。
    0x01 進程遍歷因為進程是在隨時進行變動的所以我們需要獲取一張快照1.1 CreateToolhelp32
    前言最近一段時間在研究Android加殼和脫殼技術,其中涉及到了一些hook技術,于是將自己學習的一些hook技術進行了一下梳理,以便后面回顧和大家學習。主要是進行文本替換、宏展開、刪除注釋這類簡單工作。所以動態鏈接是將鏈接過程推遲到了運行時才進行。
    初探DLL注入
    2023-02-06 10:35:24
    DLL注入是指向運行中的其它進程強制插入特定的DLL文件。從技術細節來說,DLL注入命令其它進程自行調用LoadLibrary()API,加載用戶指定的DLL文件。從上圖可以看到,test.dll已被強制插入進程。加載到某一進程中的test.dll與已經加載到某一進程中的dll一樣,擁有訪問notepad.exe進程內存的權限。DLL被加載到進程后會自動運行DLLMain()函數,用戶可以把想執行的代碼放到DLLMain()函數,每當加載DLL時,添加的代碼就會得到執行。利用這種特性可以修復程序Bug以及添加新功能
    Dll注入
    2021-11-08 14:57:41
    最近太忙啦XDM,又在做一些列的分析復現工作量有點大,更新要慢一點了。一致,也不會覆蓋其他的進程信息。
    本文從 dll 注入技術、msf migrate 模塊剖析、檢測思路等方面展開說明。
    在Windows大部分應用都是基于消息機制,他們都擁有一個消息過程函數,根據不同消息完成不同功能,windows通過鉤子機制來截獲和監視系統中的這些消息。一般鉤子分局部鉤子與全局鉤子,局部鉤子一般用于某個線程,而全局鉤子一般通過dll文件實現相應的鉤子函數。
    全局鉤子注入在Windows大部分應用都是基于消息機制,他們都擁有一個消息過程函數,根據不同消息完成不同功能,windows通過鉤子機制來截獲和監視系統中的這些消息。一般鉤子分局部鉤子與全局鉤子,局部鉤子一般用于某個線程,而全局鉤子一般通過dll文件實現相應的鉤子函數。
    簡介這次實驗是在WIN7 X86系統上進程,使用的編譯器是VS2017。所謂的DLL注入,其實就是在其他的進程中把我們編寫的DLL加載進去。所以DLL注入的核心就是把要注入DLL的路徑寫到目標進程中,然后在目標進程中調用LoadLibrary函數,并且指定參數為保存了DLL路徑的地址。要實現DLL注入,首先就要創建一個用來注入DLL
    Kaspersky AVP.exe DLL 劫持
    2022-07-21 22:53:31
    Kaspersky AVP.exe 中的 DLL 注入允許本地管理員在不知道 Kaspersky 密碼的情況
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类