- 已关闭**。此问题需要超过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.* 动态链接库 *:
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;
}
有什么建议吗?
问候...
1条答案
按热度按时间tkclm6bt1#
嗯,不。永远不要复制用C写的函数。那样做很疯狂。
我看不出你有什么理由不按正常的方式来。
通常,您需要在
DllEntryPoint
中执行的操作;通常称为CreateThread
。