在另一个进程中使用CreateRemoteThread注入DLL(从内存)[已关闭]

yx2lnoni  于 2023-01-20  发布在  其他
关注(0)|答案(1)|浏览(108)
    • 已关闭**。此问题需要超过focused。当前不接受答案。
    • 想要改进此问题吗?**更新此问题,使其仅关注editing this post的一个问题。

昨天关门了。
截至7小时前,社区正在审查是否重新讨论此问题。
Improve this question
一般来说,我会将我的 * DLL * 作为一个字节序列注入到另一个进程中,场景如下:
1.进样器:
1.使用OpenProcess获取指定进程的进程ID(例如 "notepad.exe"
1.使用VirtualAllocEx在指定的process内分配新内存空间
1.使用WriteProcessMemory在分配的空间内写入 * DLL * 缓冲区
1.准备一个函数指针来调用我的 * DLL * 中的exported函数,以便从内存加载我的 * DLL *
1.使用CreateRemoteThread在目标进程中创建thread,以调用 * DLL * 中的exported函数
1.* 动态链接库 *:

  1. exported函数,用于从内存加载给定的 * DLL *(参数)
    1.也实现了DllMain函数
    我的注入器工作正常,但发生了意外情况。当CreateRemoteThread尝试调用 * DLL * 中的exported函数时,目标进程崩溃。步骤似乎正确,因为 * DLL * 加载成功,而且我实现了一些codes从内存加载 * DLL *,并在exported函数中使用了此操作(尽管,通过解析PE头和 * EAT * 部分,实现了一些标准公式来计算 * DLL * 字节中exported函数的地址)

提示:

1.进样器和 * DLL * 均内置于X64模式
1.我使用这个LINK来实现 * DLL * 加载程序(从内存)
1.构建的 * DLL * 内容,转换为c数组并分配给data(由于code长度限制,我无法添加它)
下面是codes
进样器code

#include <Windows.h>
#include <Shlwapi.h>
#include <TlHelp32.h>

#pragma comment(lib, "shlwapi.lib")

#define DEREF_16( name )*(WORD *)(name)
#define DEREF_32( name )*(DWORD *)(name)

DWORD Rva2Offset(DWORD dwRva, UINT_PTR uiBaseAddress)
{
    WORD wIndex = 0;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
    PIMAGE_NT_HEADERS pNtHeaders = NULL;

    pNtHeaders = (PIMAGE_NT_HEADERS)(uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew);

    pSectionHeader = (PIMAGE_SECTION_HEADER)((UINT_PTR)(&pNtHeaders->OptionalHeader) + pNtHeaders->FileHeader.SizeOfOptionalHeader);

    if (dwRva < pSectionHeader[0].PointerToRawData)
        return dwRva;

    for (wIndex = 0; wIndex < pNtHeaders->FileHeader.NumberOfSections; wIndex++)
    {
        if (dwRva >= pSectionHeader[wIndex].VirtualAddress && dwRva < (pSectionHeader[wIndex].VirtualAddress + pSectionHeader[wIndex].SizeOfRawData))
            return (dwRva - pSectionHeader[wIndex].VirtualAddress + pSectionHeader[wIndex].PointerToRawData);
    }

    return 0;
}

DWORD GetReflectiveLoaderOffset(VOID * lpReflectiveDllBuffer)
{
    UINT_PTR uiBaseAddress = 0;
    UINT_PTR uiExportDir = 0;
    UINT_PTR uiNameArray = 0;
    UINT_PTR uiAddressArray = 0;
    UINT_PTR uiNameOrdinals = 0;
    DWORD dwCounter = 0;
#ifdef WIN_X64
    DWORD dwCompiledArch = 2;
#else
    // This will catch Win32 and WinRT.
    DWORD dwCompiledArch = 1;
#endif

    uiBaseAddress = (UINT_PTR)lpReflectiveDllBuffer;

    // get the File Offset of the modules NT Header
    uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew;

    // uiNameArray = the address of the modules export directory entry
    uiNameArray = (UINT_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];

    // get the File Offset of the export directory
    uiExportDir = uiBaseAddress + Rva2Offset(((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress, uiBaseAddress);

    // get the File Offset for the array of name pointers
    uiNameArray = uiBaseAddress + Rva2Offset(((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfNames, uiBaseAddress);

    // get the File Offset for the array of addresses
    uiAddressArray = uiBaseAddress + Rva2Offset(((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfFunctions, uiBaseAddress);

    // get the File Offset for the array of name ordinals
    uiNameOrdinals = uiBaseAddress + Rva2Offset(((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfNameOrdinals, uiBaseAddress);

    // get a counter for the number of exported functions...
    dwCounter = ((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->NumberOfNames;

    // loop through all the exported functions to find the ReflectiveLoader
    while (dwCounter--)
    {
        char * cpExportedFunctionName = (char *)(uiBaseAddress + Rva2Offset(DEREF_32(uiNameArray), uiBaseAddress));

        if (StrStrA(cpExportedFunctionName, "ReflectiveLoader") != 0)
        {
            // get the File Offset for the array of addresses
            uiAddressArray = uiBaseAddress + Rva2Offset(((PIMAGE_EXPORT_DIRECTORY)uiExportDir)->AddressOfFunctions, uiBaseAddress);

            // use the functions name ordinal as an index into the array of name pointers
            uiAddressArray += (DEREF_16(uiNameOrdinals) * sizeof(DWORD));

            // return the File Offset to the ReflectiveLoader() functions code...
            return Rva2Offset(DEREF_32(uiAddressArray), uiBaseAddress);
        }
        // get the next exported function name
        uiNameArray += sizeof(DWORD);

        // get the next exported function name ordinal
        uiNameOrdinals += sizeof(WORD);
    }

    return 0;
}

DWORD GetProcessIdByName(LPCWSTR lpwszProcessName)
{
    DWORD dwProcessID = 0;                      // Process ID
    HANDLE hSnapshot = INVALID_HANDLE_VALUE;    // Snapshoe handle
    PROCESSENTRY32W entry = { 0 };              // Describes an entry process
    entry.dwSize = sizeof(PROCESSENTRY32W);

    // Take snapshot of the specified processes
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
    if (hSnapshot != INVALID_HANDLE_VALUE)
    {
        if (Process32FirstW(hSnapshot, &entry) == TRUE)
        {
            while (Process32NextW(hSnapshot, &entry) == TRUE)
            {
                // Looking for ths process name
                if (StrCmpIW(entry.szExeFile, lpwszProcessName) == 0)
                {
                    dwProcessID = entry.th32ProcessID;
                    break;
                }
            }
        }

        // Close the snaphot handle
        CloseHandle(hSnapshot);
    }

    return dwProcessID;
}

INT main(INT argc, LPSTR argv[])
{
    DWORD dwProcessID = 0;
    DWORD dwDllSize = 0;                        // Dll buffer size
    LPVOID lpDllBytes = NULL;                   // Point to the first of dll buffer
    PIMAGE_DOS_HEADER imgDosHeader = NULL;      // Represents the COFF header format
    PIMAGE_NT_HEADERS imgNtHeader = NULL;       // Represents the PE header format
    LPVOID lpDllBase = NULL;                    // The address of allocated memory (with VirtualAlloc) in DLL
    HANDLE hProcess = NULL;                     // Process handle
    HANDLE hThread = NULL;                      // Thread handle

    LPTHREAD_START_ROUTINE dllEntry = NULL;
 
    // lpDllBytes = data;   // Suppose that data is an array content the built dll file
    dwDllSize = 11264;      // This is the size of data array

    if (lpDllBytes != NULL)
    {
        // Get the notepad.exe process ID and full path of our dll file
        dwProcessID = GetProcessIdByName(L"notepad.exe");

        // Open the process for inject to it
        hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION |
            PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, dwProcessID);
        if (hProcess != NULL)
        {
            // Allocate new memory space for the DLL
            lpDllBase = VirtualAllocEx(hProcess, NULL, dwDllSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
            if (lpDllBase != NULL)
            {
                // Write the dll buffer in the specified process memory
                if (WriteProcessMemory(hProcess, lpDllBase, lpDllBytes, dwDllSize, NULL))
                {
                    dllEntry = (LPTHREAD_START_ROUTINE)((ULONG_PTR)lpDllBase + GetReflectiveLoaderOffset(lpDllBytes));
                    DWORD dwThreadID = 0;
                    // Run a thread in the specified process
                    hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)dllEntry, NULL, DWORD(NULL), &dwThreadID);
                    if(hThread != NULL)
                    {
                        MessageBoxA(NULL, "ok", "", MB_OK);
                    }
                }
            }

        }
    }

    return 0;
}
  • 动态链接库 * code
#include <Windows.h>
#include <Shlwapi.h>
#include <intrin.h>

extern "C"
{
    __declspec(dllexport) ULONG_PTR WINAPI ReflectiveLoader(LPVOID lpDllBytes);
}

typedef struct BASE_RELOCATION_BLOCK
{
    DWORD dwPageAddress;
    DWORD dwBlockSize;
} BASE_RELOCATION_BLOCK, *PBASE_RELOCATION_BLOCK;

typedef struct BASE_RELOCATION_ENTRY
{
    USHORT usOffset : 12;
    USHORT usType : 4;
} BASE_RELOCATION_ENTRY, *PBASE_RELOCATION_ENTRY;

ULONG_PTR WINAPI ReflectiveLoader(LPVOID lpDllBytes)
{
    PIMAGE_DOS_HEADER imgDosHeader = NULL;                  // Represents the COFF header format
    PIMAGE_NT_HEADERS imgNtHeader = NULL;                   // Represents the PE header format
    SIZE_T nDllImageSize = 0;                               // Image size of DLL

    LPVOID lpDllBase = NULL;                                // The address of allocated memory (with VirtualAlloc) in DLL
    DWORD_PTR dwDeltaDllBase = NULL;                        // The delta between the new DLL image base with the DLL that was read into memory

    PIMAGE_SECTION_HEADER imgSectionHeader = NULL;          // Represents the section header format
    PIMAGE_SECTION_HEADER imgDestSectionHeader = NULL;      // Represents the section header format for destination
    LPVOID lpSectionBytes = NULL;                           // The section address

    IMAGE_DATA_DIRECTORY imgRelocations = { 0 };            // Represent the data directory
    DWORD_PTR dwRelocationTable = NULL;                     // Relocation table
    DWORD dwRelocationsProcessed = 0;                       // Relocation processed
    PBASE_RELOCATION_BLOCK baseRelocationBlock = NULL;      // Relocation block
    DWORD dwRelocationsCount = 0;                           // Count of relocations
    PBASE_RELOCATION_ENTRY baseRelocationEntries = NULL;    // Relocation entry
    DWORD_PTR dwRelocationRVA = 0;                          // Relocation RVA
    DWORD_PTR dwAddressToPatch = 0;                         // Address to patch

    PIMAGE_IMPORT_DESCRIPTOR imgImportDescriptor = NULL;    // The import descriptor's file offset
    IMAGE_DATA_DIRECTORY imgImportDataDirectory = { 0 };    // Represents the data directory
    LPSTR lpszLibraryName = NULL;                           // Library name
    HMODULE hModule = NULL;                                 // Library module
    PIMAGE_THUNK_DATA imgThnkData = NULL;                   // The function structure of a library
    LPSTR lpszFunctionOrdinal = NULL;                       // The function as ordinal
    PIMAGE_IMPORT_BY_NAME imgImportFunctionName = NULL;     // The imported function name
    DWORD_PTR dwFunctionAddress = NULL;

    // My dll entry point
    typedef BOOL(*WINAPI DllEntry)(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved);
    DllEntry dllEntry;

    // Get pointers to in-memory DLL headers
    imgDosHeader = (PIMAGE_DOS_HEADER)lpDllBytes;
    imgNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)lpDllBytes + imgDosHeader->e_lfanew);
    nDllImageSize = imgNtHeader->OptionalHeader.SizeOfImage;

    // Allocate new memory space for the DLL
    lpDllBase = VirtualAlloc((LPVOID)imgNtHeader->OptionalHeader.ImageBase,
        nDllImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    if (lpDllBase != NULL)
    {
        // The delta between the new DLL image base with the DLL that was read into memory
        dwDeltaDllBase = (DWORD_PTR)lpDllBase - (DWORD_PTR)imgNtHeader->OptionalHeader.ImageBase;

        // Copy over DLL image headers to the newly allocated space for the DLL
        CopyMemory(lpDllBase, lpDllBytes, imgNtHeader->OptionalHeader.SizeOfHeaders);

        // Copy over DLL image sections to the newly allocated space for the DLL
        imgSectionHeader = IMAGE_FIRST_SECTION(imgNtHeader);
        for (size_t i = 0; i < imgNtHeader->FileHeader.NumberOfSections; i++)
        {
            imgDestSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)lpDllBase + (DWORD_PTR)imgSectionHeader->VirtualAddress);
            lpSectionBytes = (LPVOID)((DWORD_PTR)lpDllBytes + (DWORD_PTR)imgSectionHeader->PointerToRawData);
            CopyMemory(imgDestSectionHeader, lpSectionBytes, imgSectionHeader->SizeOfRawData);
            imgSectionHeader++;
        }

        // Perform image base relocations
        imgRelocations = imgNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
        dwRelocationTable = imgRelocations.VirtualAddress + (DWORD_PTR)lpDllBase;

        while (dwRelocationsProcessed < imgRelocations.Size)
        {
            baseRelocationBlock = (PBASE_RELOCATION_BLOCK)(dwRelocationTable + dwRelocationsProcessed);
            dwRelocationsProcessed += sizeof(BASE_RELOCATION_BLOCK);
            dwRelocationsCount = (baseRelocationBlock->dwBlockSize - sizeof(BASE_RELOCATION_BLOCK)) / sizeof(BASE_RELOCATION_ENTRY);
            baseRelocationEntries = (PBASE_RELOCATION_ENTRY)(dwRelocationTable + dwRelocationsProcessed);

            for (DWORD i = 0; i < dwRelocationsCount; i++)
            {
                dwRelocationsProcessed += sizeof(BASE_RELOCATION_ENTRY);

                if (baseRelocationEntries[i].usType == 0)
                {
                    continue;
                }

                dwRelocationRVA = baseRelocationBlock->dwPageAddress + baseRelocationEntries[i].usOffset;
                if (ReadProcessMemory(GetCurrentProcess(), (LPCVOID)((DWORD_PTR)lpDllBase + dwRelocationRVA),
                    &dwAddressToPatch, sizeof(DWORD_PTR), NULL))
                {
                    dwAddressToPatch += dwDeltaDllBase;
                    CopyMemory((PVOID)((DWORD_PTR)lpDllBase + dwRelocationRVA), &dwAddressToPatch, sizeof(DWORD_PTR));
                }
            }
        }

        // Resolve import address table
        imgImportDataDirectory = imgNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
        imgImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(imgImportDataDirectory.VirtualAddress + (DWORD_PTR)lpDllBase);
        while (imgImportDescriptor->Name != NULL)
        {
            // Get the imported libraries and their functions
            lpszLibraryName = (LPSTR)imgImportDescriptor->Name + (DWORD_PTR)lpDllBase;
            hModule = LoadLibraryA(lpszLibraryName);

            if (hModule != NULL)
            {
                imgThnkData = (PIMAGE_THUNK_DATA)((DWORD_PTR)lpDllBase + imgImportDescriptor->FirstThunk);
                while (imgThnkData->u1.AddressOfData != NULL)
                {
                    if (IMAGE_SNAP_BY_ORDINAL(imgThnkData->u1.Ordinal))
                    {
                        lpszFunctionOrdinal = (LPSTR)IMAGE_ORDINAL(imgThnkData->u1.Ordinal);
                        imgThnkData->u1.Function = (DWORD_PTR)GetProcAddress(hModule, lpszFunctionOrdinal);
                    }
                    else
                    {
                        imgImportFunctionName = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)lpDllBase + imgThnkData->u1.AddressOfData);
                        dwFunctionAddress = (DWORD_PTR)(GetProcAddress(hModule, imgImportFunctionName->Name));
                        imgThnkData->u1.Function = dwFunctionAddress;
                    }

                    imgThnkData++;
                }
            }

            imgImportDescriptor++;
        }

        dllEntry = (DllEntry)((DWORD_PTR)lpDllBase + imgNtHeader->OptionalHeader.AddressOfEntryPoint);
        (*dllEntry)((HINSTANCE)lpDllBase, DLL_PROCESS_ATTACH, 0);
    }

    return TRUE;
}

BOOL WINAPI DllMain(HINSTANCE hInstanxe, DWORD dwReason, LPVOID lpvReserved)
{
    switch (dwReason)
    {
    case DLL_PROCESS_ATTACH:
        MessageBoxA(NULL, "here from dll", "", MB_OK);
        break;
    default:
        break;
    }

    return TRUE;
}

有什么建议吗?
问候...

tkclm6bt

tkclm6bt1#

嗯,不。永远不要复制用C写的函数。那样做很疯狂。
我看不出你有什么理由不按正常的方式来。

dlladdr = VirtualAllocEx(...); // Get some space in target process
WriteProcessMemory(..., dlladdr, "mydllname", sizeof("mydllname"); // Copy name into dll
hThread = CreateRemoteThread(..., GetProcAddress(hKernel32, "LoadLibrary")..., dlladdr); // Load your dll
WaitForSingleObject(hThread, INFINITE);
VirtualFreeEx(..., dlladdr, ...);

通常,您需要在DllEntryPoint中执行的操作;通常称为CreateThread

相关问题