Fixup patterns for UPX executables

Adapted ScopedUnprotect for UPX executables
This commit is contained in:
Silent 2017-09-16 23:32:17 +02:00
parent 92fb1798f9
commit 29cea98c70
4 changed files with 82 additions and 34 deletions

View file

@ -626,57 +626,85 @@ namespace Memory
#include <forward_list>
#include <tuple>
class ScopedUnprotect
namespace ScopedUnprotect
{
public:
class Section
class unprotect
{
public:
Section( HINSTANCE hInstance, const char* name )
protected:
void UnprotectRange( DWORD_PTR BaseAddress, SIZE_T Size )
{
IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)((BYTE*)hInstance + ((IMAGE_DOS_HEADER*)hInstance)->e_lfanew);
IMAGE_SECTION_HEADER* pSection = IMAGE_FIRST_SECTION(ntHeader);
DWORD VirtualAddress = MAXDWORD;
SIZE_T VirtualSize = MAXDWORD;
for ( SIZE_T i = 0, j = ntHeader->FileHeader.NumberOfSections; i < j; ++i, ++pSection )
{
if ( strncmp( (const char*)pSection->Name, name, IMAGE_SIZEOF_SHORT_NAME ) == 0 )
{
VirtualAddress = (DWORD)hInstance + pSection->VirtualAddress;
VirtualSize = pSection->Misc.VirtualSize;
break;
}
}
if ( VirtualAddress == MAXDWORD )
return;
SIZE_T QueriedSize = 0;
while ( QueriedSize < VirtualSize )
while ( QueriedSize < Size )
{
MEMORY_BASIC_INFORMATION MemoryInf;
DWORD dwOldProtect;
VirtualQuery( (LPCVOID)(VirtualAddress + QueriedSize), &MemoryInf, sizeof(MemoryInf) );
VirtualProtect( MemoryInf.BaseAddress, MemoryInf.RegionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect );
m_queriedProtects.emplace_front( MemoryInf.BaseAddress, MemoryInf.RegionSize, MemoryInf.Protect );
VirtualQuery( (LPCVOID)(BaseAddress + QueriedSize), &MemoryInf, sizeof(MemoryInf) );
if ( MemoryInf.State == MEM_COMMIT && (MemoryInf.Type & MEM_IMAGE) != 0 &&
(MemoryInf.Protect & (PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY|PAGE_READWRITE|PAGE_WRITECOPY)) == 0 )
{
VirtualProtect( MemoryInf.BaseAddress, MemoryInf.RegionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect );
m_queriedProtects.emplace_front( MemoryInf.BaseAddress, MemoryInf.RegionSize, MemoryInf.Protect );
}
QueriedSize += MemoryInf.RegionSize;
}
};
}
~Section()
~unprotect()
{
for ( auto& it : m_queriedProtects )
{
DWORD dwOldProtect;
VirtualProtect( std::get<0>(it), std::get<1>(it), std::get<2>(it), &dwOldProtect );
}
}
}
private:
std::forward_list< std::tuple< LPVOID, SIZE_T, DWORD > > m_queriedProtects;
};
class Section : protected unprotect
{
public:
Section( HINSTANCE hInstance, const char* name )
{
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)hInstance + ((PIMAGE_DOS_HEADER)hInstance)->e_lfanew);
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(ntHeader);
DWORD_PTR VirtualAddress = DWORD_PTR(-1);
SIZE_T VirtualSize = SIZE_T(-1);
for ( SIZE_T i = 0, j = ntHeader->FileHeader.NumberOfSections; i < j; ++i, ++pSection )
{
if ( strncmp( (const char*)pSection->Name, name, IMAGE_SIZEOF_SHORT_NAME ) == 0 )
{
VirtualAddress = (DWORD_PTR)hInstance + pSection->VirtualAddress;
VirtualSize = pSection->Misc.VirtualSize;
m_locatedSection = true;
break;
}
}
if ( VirtualAddress == DWORD_PTR(-1) )
return;
UnprotectRange( VirtualAddress, VirtualSize );
};
bool SectionLocated() const { return m_locatedSection; }
private:
bool m_locatedSection = false;
};
class FullModule : protected unprotect
{
public:
FullModule( HINSTANCE hInstance )
{
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)hInstance + ((PIMAGE_DOS_HEADER)hInstance)->e_lfanew);
UnprotectRange( (DWORD_PTR)hInstance, ntHeader->OptionalHeader.SizeOfImage );
}
};
};
#endif

View file

@ -126,7 +126,7 @@ public:
PIMAGE_DOS_HEADER dosHeader = getRVA<IMAGE_DOS_HEADER>(0);
PIMAGE_NT_HEADERS ntHeader = getRVA<IMAGE_NT_HEADERS>(dosHeader->e_lfanew);
m_end = m_begin + ntHeader->OptionalHeader.SizeOfCode;
m_end = m_begin + ntHeader->OptionalHeader.SizeOfImage;
}
executable_meta(uintptr_t begin, uintptr_t end)
@ -156,7 +156,7 @@ void pattern::Initialize(const char* pattern, size_t length)
if (range.first != range.second)
{
std::for_each(range.first, range.second, [&] (const std::pair<uint64_t, uintptr_t>& hint)
std::for_each(range.first, range.second, [&] (const auto& hint)
{
ConsiderHint(hint.second);
});

View file

@ -4,6 +4,8 @@
#include "Timer.h"
#include "Patterns.h"
#include <memory>
struct PsGlobalType
{
HWND window;
@ -888,7 +890,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
GetWindowRect(GetDesktopWindow(), &desktop);
sprintf_s(aNoDesktopMode, "Cannot find %dx%dx32 video mode", desktop.right, desktop.bottom);
ScopedUnprotect::Section Protect( GetModuleHandle( nullptr ), ".text" );
const HINSTANCE hModule = GetModuleHandle( nullptr );
std::unique_ptr<ScopedUnprotect::Section> SectionProtect = std::make_unique<ScopedUnprotect::Section>( hModule, ".text" );
std::unique_ptr<ScopedUnprotect::FullModule> ModuleProtect = nullptr;
if ( !SectionProtect->SectionLocated() )
{
SectionProtect = nullptr;
ModuleProtect = std::make_unique<ScopedUnprotect::FullModule>( hModule );
}
if (*(DWORD*)0x5C1E75 == 0xB85548EC) Patch_III_10(desktop);
else if (*(DWORD*)0x5C2135 == 0xB85548EC) Patch_III_11(desktop);

View file

@ -3,6 +3,8 @@
#include "Timer.h"
#include "Patterns.h"
#include <memory>
struct RsGlobalType
{
const char* AppName;
@ -706,7 +708,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
GetWindowRect(GetDesktopWindow(), &desktop);
sprintf_s(aNoDesktopMode, "Cannot find %dx%dx32 video mode", desktop.right, desktop.bottom);
ScopedUnprotect::Section Protect( GetModuleHandle( nullptr ), ".text" );
const HINSTANCE hModule = GetModuleHandle( nullptr );
std::unique_ptr<ScopedUnprotect::Section> SectionProtect = std::make_unique<ScopedUnprotect::Section>( hModule, ".text" );
std::unique_ptr<ScopedUnprotect::FullModule> ModuleProtect = nullptr;
if ( !SectionProtect->SectionLocated() )
{
SectionProtect = nullptr;
ModuleProtect = std::make_unique<ScopedUnprotect::FullModule>( hModule );
}
if(*(DWORD*)0x667BF5 == 0xB85548EC) Patch_VC_10(desktop);
else if(*(DWORD*)0x667C45 == 0xB85548EC) Patch_VC_11(desktop);