mirror of https://github.com/infosecn1nja/C3.git
Separarte PE image utils
parent
2f3052a5c1
commit
820467f83b
|
@ -131,6 +131,7 @@ Global
|
|||
{53182258-F40E-4104-AFC6-1F327E556E77}.ReleaseWithDebInfo|x64.Deploy.0 = ReleaseWithDebInfo|x64
|
||||
{53182258-F40E-4104-AFC6-1F327E556E77}.ReleaseWithDebInfo|x86.ActiveCfg = ReleaseWithDebInfo|Win32
|
||||
{53182258-F40E-4104-AFC6-1F327E556E77}.ReleaseWithDebInfo|x86.Build.0 = ReleaseWithDebInfo|Win32
|
||||
{53182258-F40E-4104-AFC6-1F327E556E77}.ReleaseWithDebInfo|x86.Deploy.0 = ReleaseWithDebInfo|Win32
|
||||
{BC9BC3C3-4FBC-4F36-866C-AC2B4758BEBE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{BC9BC3C3-4FBC-4F36-866C-AC2B4758BEBE}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{BC9BC3C3-4FBC-4F36-866C-AC2B4758BEBE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
|
|
|
@ -239,7 +239,7 @@
|
|||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<SupportJustMyCode>true</SupportJustMyCode>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
|
@ -310,7 +310,7 @@
|
|||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<SupportJustMyCode>true</SupportJustMyCode>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
|
@ -346,6 +346,7 @@
|
|||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='ReleaseWithDebInfo|x64'">StdAfx.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UnexportedWinApi.cpp" />
|
||||
<ClCompile Include="PeUtils.cpp" />
|
||||
<ClCompile Include="WindowsVersion.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -354,6 +355,7 @@
|
|||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="Stdafx.h" />
|
||||
<ClInclude Include="UnexportedWinApi.h" />
|
||||
<ClInclude Include="PeUtils.h" />
|
||||
<ClInclude Include="WindowsVersion.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -9,17 +9,6 @@
|
|||
#define HOST_MACHINE IMAGE_FILE_MACHINE_I386
|
||||
#endif
|
||||
|
||||
template<typename T, typename V, typename U>
|
||||
T Rva2Va(V base, U rva)
|
||||
{
|
||||
return reinterpret_cast<T>((ULONG_PTR)base + rva);
|
||||
}
|
||||
|
||||
static inline size_t AlignValueUp(size_t value, size_t alignment)
|
||||
{
|
||||
return (value + alignment - 1) & ~(alignment - 1);
|
||||
}
|
||||
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4214 ) // nonstandard extension
|
||||
typedef struct
|
||||
|
@ -64,6 +53,7 @@ LONG CALLBACK PatchCppException(PEXCEPTION_POINTERS exceptionInfo)
|
|||
/// @param callExport - name of an exported function to call. Function must have a signature of ExportFunc [typedef void (*ExportFunc)(void)]
|
||||
int LoadPe(void* dllData, std::string_view callExport)
|
||||
{
|
||||
using namespace MWR::Loader;
|
||||
// Loader code based on Shellcode Reflective DLL Injection by Nick Landers https://github.com/monoxgas/sRDI
|
||||
// which is derived from "Improved Reflective DLL Injection" from Dan Staples https://disman.tl/2015/01/30/an-improved-reflective-dll-injection-technique.html
|
||||
// which itself is derived from the original project by Stephen Fewer. https://github.com/stephenfewer/ReflectiveDLLInjection
|
||||
|
@ -105,7 +95,7 @@ int LoadPe(void* dllData, std::string_view callExport)
|
|||
if (alignedImageSize != AlignValueUp(lastSectionEnd, sysInfo.dwPageSize))
|
||||
return 1;
|
||||
|
||||
UINT_PTR baseAddress = (UINT_PTR)VirtualAlloc(NULL, alignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
UINT_PTR baseAddress = (UINT_PTR)VirtualAlloc(NULL, alignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
if (!baseAddress)
|
||||
return 1;
|
||||
|
||||
|
@ -165,11 +155,6 @@ int LoadPe(void* dllData, std::string_view callExport)
|
|||
if (dataDir->Size)
|
||||
{
|
||||
auto importDesc = Rva2Va<PIMAGE_IMPORT_DESCRIPTOR>(baseAddress, dataDir->VirtualAddress);
|
||||
auto importCount = 0;
|
||||
for (; importDesc->Name; importDesc++)
|
||||
importCount++;
|
||||
|
||||
importDesc = Rva2Va<PIMAGE_IMPORT_DESCRIPTOR>(baseAddress, dataDir->VirtualAddress);
|
||||
for (; importDesc->Name; importDesc++)
|
||||
{
|
||||
auto libraryAddress = (PBYTE)LoadLibraryA((LPCSTR)(baseAddress + importDesc->Name));
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
#include "stdafx.h"
|
||||
#include "PeUtils.h"
|
||||
|
||||
namespace MWR::Loader
|
||||
{
|
||||
PIMAGE_DOS_HEADER GetDosHeader(UINT_PTR baseAddress)
|
||||
{
|
||||
return Rva2Va<PIMAGE_DOS_HEADER>(baseAddress, 0);
|
||||
}
|
||||
|
||||
PIMAGE_NT_HEADERS GetNtHeaders(UINT_PTR baseAddress)
|
||||
{
|
||||
auto dosHeader = GetDosHeader(baseAddress);
|
||||
return Rva2Va<PIMAGE_NT_HEADERS>(baseAddress, dosHeader->e_lfanew);
|
||||
}
|
||||
|
||||
DWORD GetSizeOfImage(UINT_PTR baseAddress)
|
||||
{
|
||||
auto ntHeaders = GetNtHeaders(baseAddress);
|
||||
return ntHeaders->OptionalHeader.SizeOfImage;
|
||||
}
|
||||
|
||||
std::pair<void*, void*> GetSectionRange(void* dllBase, std::string const& sectionName)
|
||||
{
|
||||
auto ntHeaders = GetNtHeaders((UINT_PTR)dllBase);
|
||||
auto sectionHeader = IMAGE_FIRST_SECTION(ntHeaders);
|
||||
for (int i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++, sectionHeader++)
|
||||
{
|
||||
char currentSection[9];
|
||||
memcpy(currentSection, sectionHeader->Name, 8);
|
||||
currentSection[8] = 0; // ensure null-termination
|
||||
if (_stricmp(sectionName.c_str(), currentSection) == 0)
|
||||
{
|
||||
auto sectionVa = Rva2Va<char*>(dllBase, sectionHeader->VirtualAddress);
|
||||
return { sectionVa, sectionVa + sectionHeader->Misc.VirtualSize };
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
namespace MWR::Loader
|
||||
{
|
||||
template<typename T, typename V, typename U>
|
||||
T Rva2Va(V base, U rva)
|
||||
{
|
||||
return reinterpret_cast<T>(reinterpret_cast<ULONG_PTR&>(base) + rva);
|
||||
}
|
||||
|
||||
PIMAGE_DOS_HEADER GetDosHeader(UINT_PTR baseAddress);
|
||||
|
||||
PIMAGE_NT_HEADERS GetNtHeaders(UINT_PTR baseAddress);
|
||||
|
||||
/// Get size of image from NT headers
|
||||
/// @param baseAddress - base address of PE file image
|
||||
/// @returns size of image specified image
|
||||
DWORD GetSizeOfImage(UINT_PTR baseAddress);
|
||||
|
||||
std::pair<void*, void*> GetSectionRange(void* dllBase, std::string const& sectionName);
|
||||
|
||||
static inline size_t AlignValueUp(size_t value, size_t alignment)
|
||||
{
|
||||
return (value + alignment - 1) & ~(alignment - 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -5,12 +5,14 @@
|
|||
// Standard library includes.
|
||||
#include <iostream> //< For std::cout, std::cerr. Remove when common files will not nead it.
|
||||
#include <algorithm>
|
||||
#include <ciso646>
|
||||
#include <string>
|
||||
#include <csetjmp>
|
||||
|
||||
// Custom includes
|
||||
#include "WindowsVersion.h"
|
||||
#include "QuietAbort.h"
|
||||
#include "PeUtils.h"
|
||||
#include "UnexportedWinApi.h"
|
||||
|
||||
// C3 includes
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "stdafx.h"
|
||||
#include "UnexportedWinApi.h"
|
||||
|
||||
#include "PeUtils.h"
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
using namespace std::string_literals;
|
||||
|
@ -141,31 +141,6 @@ namespace MWR::Loader::UnexportedWinApi
|
|||
return (void*)(match - offsetData.second);
|
||||
}
|
||||
|
||||
template<typename T, typename V, typename U>
|
||||
T Rva2Va(V base, U rva)
|
||||
{
|
||||
return reinterpret_cast<T>((ULONG_PTR)base + rva);
|
||||
}
|
||||
|
||||
std::pair<void*, void*> GetSectionRange(void* dllBase, std::string const& section)
|
||||
{
|
||||
auto dosHeaders = reinterpret_cast<PIMAGE_DOS_HEADER>(dllBase);
|
||||
auto ntHeaders = Rva2Va<PIMAGE_NT_HEADERS>(dllBase, dosHeaders->e_lfanew);
|
||||
auto sectionHeader = IMAGE_FIRST_SECTION(ntHeaders);
|
||||
for (int i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++, sectionHeader++)
|
||||
{
|
||||
char currentSection[9];
|
||||
memcpy(currentSection, sectionHeader->Name, 8);
|
||||
currentSection[8] = 0; // ensure null-termination
|
||||
if (_stricmp(section.c_str(), currentSection) == 0)
|
||||
{
|
||||
auto sectionVa = Rva2Va<char*>(dllBase, sectionHeader->VirtualAddress);
|
||||
return { sectionVa, sectionVa + sectionHeader->Misc.VirtualSize };
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void* FindInSection(std::wstring const& dll, std::string const& section, std::pair<std::string, size_t> const& offsetData)
|
||||
{
|
||||
auto dllBase = GetModuleHandleW(dll.c_str());
|
||||
|
|
|
@ -2,15 +2,6 @@
|
|||
|
||||
namespace MWR::Loader::UnexportedWinApi
|
||||
{
|
||||
/// Get size of image from NT headers
|
||||
/// @param baseAddress - base address of PE file image
|
||||
/// @returns size of image specified image
|
||||
inline DWORD GetSizeOfImage(UINT_PTR baseAddress)
|
||||
{
|
||||
auto ntHeader = baseAddress + ((PIMAGE_DOS_HEADER)baseAddress)->e_lfanew;
|
||||
return reinterpret_cast<PIMAGE_NT_HEADERS>(ntHeader)->OptionalHeader.SizeOfImage;
|
||||
}
|
||||
|
||||
/// Wrapper around private ntdll!LdrpHandleTlsData
|
||||
/// Initializes static data from .tls section
|
||||
/// @param baseAddress of PE file image
|
||||
|
|
Loading…
Reference in New Issue