VMProtect/unit-tests/pefile_tests.cc

554 lines
20 KiB
C++

#include "../runtime/common.h"
#include "../runtime/crypto.h"
#include "../core/objects.h"
#include "../core/osutils.h"
#include "../core/streams.h"
#include "../core/core.h"
#include "../core/files.h"
#include "../core/processors.h"
#include "../core/pefile.h"
#include "../core/packer.h"
#include "../third-party/lzma/LzmaDecode.h"
#ifdef DEMO
#include "../core/win_runtime32demo.dll.inc"
#include "../core/win_runtime64demo.dll.inc"
#else
#include "../core/win_runtime32.dll.inc"
#include "../core/win_runtime64.dll.inc"
#endif
#ifdef VMP_GNU
#include <stdlib.h>
#endif
TEST(PEFileTest, OpenEXE)
{
// Test: read header of Win32/Intel file. Read should finish successfully.
PEFile pf(NULL);
ASSERT_EQ(pf.Open("test-binaries/win32-app-test1-i386", foRead), osSuccess);
// Check architectures.
ASSERT_EQ(pf.count(), 1ul);
PEArchitecture *arch = pf.arch_pe();
EXPECT_EQ(arch->name().compare("i386"), 0);
EXPECT_EQ(arch->owner()->format_name().compare("PE"), 0);
EXPECT_EQ(arch->cpu_address_size(), osDWord);
EXPECT_EQ(arch->image_base(), 0x400000ull);
EXPECT_EQ(arch->entry_point(), 0x401000ull);
// Check segments.
ISectionList *segment_list = arch->segment_list();
ASSERT_EQ(segment_list->count(), 3ul);
EXPECT_EQ(segment_list->item(0)->name().compare(".text"), 0);
EXPECT_EQ(segment_list->item(1)->name().compare(".rdata"), 0);
EXPECT_EQ(segment_list->item(2)->name().compare(".data"), 0);
EXPECT_EQ((int)segment_list->item(0)->memory_type(), (mtReadable | mtExecutable));
EXPECT_EQ((int)segment_list->item(1)->memory_type(), mtReadable);
EXPECT_EQ((int)segment_list->item(2)->memory_type(), (mtReadable | mtWritable));
// Check imports.
IImportList *imp = arch->import_list();
ASSERT_EQ(imp->count(), 3ul);
EXPECT_EQ(imp->item(0)->name().compare("user32.dll"), 0);
ASSERT_EQ(imp->item(0)->count(), 6ul);
EXPECT_EQ(imp->item(0)->item(0)->name().compare("SetFocus"), 0);
EXPECT_EQ(imp->item(0)->item(0)->address(), 0x402028ull);
EXPECT_EQ(imp->item(0)->item(1)->name().compare("MessageBoxA"), 0);
EXPECT_EQ(imp->item(0)->item(1)->address(), 0x40202cull);
EXPECT_EQ(imp->item(0)->item(2)->name().compare("GetDlgItemTextA"), 0);
EXPECT_EQ(imp->item(0)->item(2)->address(), 0x402030ull);
EXPECT_EQ(imp->item(0)->item(3)->name().compare("GetDlgItem"), 0);
EXPECT_EQ(imp->item(0)->item(3)->address(), 0x402034ull);
EXPECT_EQ(imp->item(0)->item(4)->name().compare("EndDialog"), 0);
EXPECT_EQ(imp->item(0)->item(4)->address(), 0x402038ull);
EXPECT_EQ(imp->item(0)->item(5)->name().compare("DialogBoxIndirectParamA"), 0);
EXPECT_EQ(imp->item(0)->item(5)->address(), 0x40203cull);
EXPECT_EQ(imp->item(1)->name().compare("kernel32.dll"), 0);
ASSERT_EQ(imp->item(1)->count(), 5ul);
EXPECT_EQ(imp->item(1)->item(0)->name().compare("MultiByteToWideChar"), 0);
EXPECT_EQ(imp->item(1)->item(0)->address(), 0x402010ull);
EXPECT_EQ(imp->item(1)->item(1)->name().compare("GlobalFree"), 0);
EXPECT_EQ(imp->item(1)->item(1)->address(), 0x402014ull);
EXPECT_EQ(imp->item(1)->item(2)->name().compare("ExitProcess"), 0);
EXPECT_EQ(imp->item(1)->item(2)->address(), 0x402018ull);
EXPECT_EQ(imp->item(1)->item(3)->name().compare("GetModuleHandleA"), 0);
EXPECT_EQ(imp->item(1)->item(3)->address(), 0x40201cull);
EXPECT_EQ(imp->item(1)->item(4)->name().compare("GlobalAlloc"), 0);
EXPECT_EQ(imp->item(1)->item(4)->address(), 0x402020ull);
EXPECT_EQ(imp->item(2)->name().compare("VMProtectSDK32.dll"), 0);
ASSERT_EQ(imp->item(2)->count(), 3ul);
EXPECT_EQ(imp->item(2)->item(0)->name().compare("VMProtectDecryptStringA"), 0);
EXPECT_EQ(imp->item(2)->item(0)->address(), 0x402000ull);
EXPECT_EQ(imp->item(2)->item(1)->name().compare("VMProtectEnd"), 0);
EXPECT_EQ(imp->item(2)->item(1)->address(), 0x402004ull);
EXPECT_EQ(imp->item(2)->item(2)->name().compare("VMProtectBegin"), 0);
EXPECT_EQ(imp->item(2)->item(2)->address(), 0x402008ull);
// Check fixups.
IFixupList *fixup_list = arch->fixup_list();
EXPECT_EQ(fixup_list->count(), 0ul);
// Check resources.
IResourceList *resource_list = arch->resource_list();
EXPECT_EQ(resource_list->count(), 0ul);
// Check lists were cleared.
pf.Close();
EXPECT_EQ(pf.count(), 0ul);
}
TEST(PEFileTest, OpenDLL)
{
PEFile pf(NULL);
ASSERT_EQ(pf.Open("test-binaries/win32-dll-test1-i386", foRead), osSuccess);
// Check architectures.
ASSERT_EQ(pf.count(), 1ul);
PEArchitecture *arch = pf.arch_pe();
// Check exports.
IExportList *exp = arch->export_list();
EXPECT_EQ(exp->name().compare("ShimEng.dll"), 0);
ASSERT_EQ(exp->count(), 11ul);
EXPECT_EQ(exp->item(0)->name().compare("SE_DllLoaded"), 0);
EXPECT_EQ(exp->item(0)->forwarded_name().compare("APPHELP.SE_DllLoaded"), 0);
EXPECT_EQ(exp->item(0)->address(), 0x3ff31257ull);
EXPECT_EQ(exp->item(10)->name().compare("SE_ProcessDying"), 0);
EXPECT_EQ(exp->item(10)->forwarded_name().compare("APPHELP.SE_ProcessDying"), 0);
EXPECT_EQ(exp->item(10)->address(), 0x3ff31358ull);
// Check fixups.
IFixupList *fixup_list = arch->fixup_list();
ASSERT_EQ(fixup_list->count(), 12ul);
EXPECT_EQ(fixup_list->item(0)->address(), 0x3ff3103aull);
EXPECT_EQ(fixup_list->item(0)->type(), ftHighLow);
EXPECT_EQ(fixup_list->item(1)->address(), 0x3ff31042ull);
EXPECT_EQ(fixup_list->item(1)->type(), ftHighLow);
EXPECT_EQ(fixup_list->item(2)->address(), 0x3ff3104dull);
EXPECT_EQ(fixup_list->item(2)->type(), ftHighLow);
EXPECT_EQ(fixup_list->item(3)->address(), 0x3ff31089ull);
EXPECT_EQ(fixup_list->item(3)->type(), ftHighLow);
EXPECT_EQ(fixup_list->item(4)->address(), 0x3ff310a2ull);
EXPECT_EQ(fixup_list->item(4)->type(), ftHighLow);
EXPECT_EQ(fixup_list->item(5)->address(), 0x3FF310AEull);
EXPECT_EQ(fixup_list->item(5)->type(), ftHighLow);
EXPECT_EQ(fixup_list->item(6)->address(), 0x3FF310B6ull);
EXPECT_EQ(fixup_list->item(6)->type(), ftHighLow);
EXPECT_EQ(fixup_list->item(7)->address(), 0x3FF310BEull);
EXPECT_EQ(fixup_list->item(7)->type(), ftHighLow);
EXPECT_EQ(fixup_list->item(8)->address(), 0x3FF310CAull);
EXPECT_EQ(fixup_list->item(8)->type(), ftHighLow);
EXPECT_EQ(fixup_list->item(9)->address(), 0x3FF310E0ull);
EXPECT_EQ(fixup_list->item(9)->type(), ftHighLow);
EXPECT_EQ(fixup_list->item(10)->address(), 0x3FF310E8ull);
EXPECT_EQ(fixup_list->item(10)->type(), ftHighLow);
EXPECT_EQ(fixup_list->item(11)->address(), 0x3ff310f0ull);
EXPECT_EQ(fixup_list->item(11)->type(), ftHighLow);
// Check resources.
IResourceList *resource_list = arch->resource_list();
ASSERT_EQ(resource_list->count(), 1ul);
EXPECT_EQ(resource_list->item(0)->type(), rtVersionInfo);
ASSERT_EQ(resource_list->item(0)->count(), 1ul);
EXPECT_EQ(resource_list->item(0)->item(0)->name(), "1");
EXPECT_EQ(resource_list->item(0)->item(0)->count(), 1ul);
EXPECT_EQ(resource_list->item(0)->item(0)->item(0)->name(), "1033");
EXPECT_EQ(resource_list->item(0)->item(0)->item(0)->address(), 0x3ff33060ull);
EXPECT_EQ(resource_list->item(0)->item(0)->item(0)->size(), 0x3acul);
// Check lists were cleared.
pf.Close();
EXPECT_EQ(pf.count(), 0ul);
}
TEST(PEFileTest, Clone)
{
PEFile pf(NULL);
ASSERT_EQ(pf.Open("test-binaries/win32-app-test1-i386", foRead), osSuccess);
PEFile *f = pf.Clone(pf.file_name().c_str());
EXPECT_EQ(pf.count(), f->count());
PEArchitecture &src = *pf.arch_pe();
PEArchitecture &dst = *f->arch_pe();
EXPECT_EQ(src.owner()->format_name().compare(dst.owner()->format_name()), 0);
EXPECT_EQ(src.name().compare(dst.name()), 0);
EXPECT_EQ(src.cpu_address_size(), dst.cpu_address_size());
EXPECT_EQ(src.entry_point(), dst.entry_point());
EXPECT_EQ(src.command_list()->count(), dst.command_list()->count());
EXPECT_EQ(src.segment_list()->count(), dst.segment_list()->count());
EXPECT_EQ(src.import_list()->count(), dst.import_list()->count());
EXPECT_EQ(src.fixup_list()->count(), dst.fixup_list()->count());
EXPECT_EQ(src.export_list()->count(), dst.export_list()->count());
EXPECT_EQ(src.resource_list()->count(), dst.resource_list()->count());
delete f;
}
TEST(PEFileTest, Runtime_x32)
{
PEFile file(NULL);
ASSERT_TRUE(file.OpenResource(win_runtime32_dll_file, sizeof(win_runtime32_dll_file), true));
ASSERT_EQ(file.count(), 1ul);
PEArchitecture *arch = file.arch_pe();
Buffer buffer(&win_runtime32_dll_code[0]);
arch->ReadFromBuffer(buffer);
EXPECT_GT(arch->export_list()->count(), 0ul);
EXPECT_GT(arch->function_list()->count(), 0ul);
}
TEST(PEFileTest, Runtime_x64)
{
PEFile file(NULL);
ASSERT_TRUE(file.OpenResource(win_runtime64_dll_file, sizeof(win_runtime64_dll_file), true));
ASSERT_EQ(file.count(), 1ul);
PEArchitecture *arch = file.arch_pe();
Buffer buffer(&win_runtime64_dll_code[0]);
arch->ReadFromBuffer(buffer);
EXPECT_GT(arch->export_list()->count(), 0ul);
EXPECT_GT(arch->function_list()->count(), 0ul);
}
TEST(PEFileTest, Compile_x32)
{
PEFile pf(NULL);
size_t i;
ASSERT_EQ(pf.Open("test-binaries/win32-app-delphi-i386", foRead), osSuccess);
PEArchitecture *arch = pf.arch_pe();
for (i = 0; i < arch->map_function_list()->count(); i++) {
MapFunction *map_function = arch->map_function_list()->item(i);
if (map_function->type() == otString || map_function->type() == otAPIMarker || map_function->type() == otMarker)
arch->function_list()->AddByAddress(map_function->address(), ctVirtualization, 0, true, NULL);
}
ASSERT_EQ(arch->function_list()->count(), 4ul);
std::string file_name = pf.file_name()+".exe";
PEFile *f = pf.Clone(file_name.c_str());
CompileOptions options;
options.flags = cpMaximumProtection;
options.section_name = ".vmp";
ASSERT_TRUE(f->Compile(options));
delete f;
PEFile pf2(NULL);
ASSERT_EQ(pf2.Open(file_name.c_str(), foRead | foHeaderOnly), osSuccess);
ASSERT_EQ(pf2.count(), pf.count());
PEArchitecture &src = *pf.arch_pe();
PEArchitecture &dst = *pf2.arch_pe();
for (i = 0; i < src.fixup_list()->count(); i++) {
IFixup *src_fixup = src.fixup_list()->item(i);
IFixup *dst_fixup = src.fixup_list()->GetFixupByAddress(src_fixup->address());
EXPECT_EQ(src_fixup->address(), dst_fixup->address());
EXPECT_EQ(src_fixup->type(), dst_fixup->type());
EXPECT_EQ(src_fixup->size(), dst_fixup->size());
}
if (options.flags & cpResourceProtection) {
EXPECT_EQ(dst.resource_list()->count(), 4ul);
} else {
EXPECT_EQ(src.resource_list()->count(), dst.resource_list()->count());
for (i = 0; i < src.resource_list()->count(); i++) {
PEResource *src_resource = src.resource_list()->item(i);
PEResource *dst_resource = dst.resource_list()->item(i);
EXPECT_EQ(src_resource->count(), dst_resource->count());
EXPECT_EQ(src_resource->address(), dst_resource->address());
EXPECT_EQ(src_resource->size(), dst_resource->size());
EXPECT_EQ(src_resource->type(), dst_resource->type());
EXPECT_EQ(src_resource->name(), dst_resource->name());
}
}
// check AV buffer
ASSERT_EQ(dst.segment_list()->count(), 13ul);
ASSERT_TRUE(dst.AddressSeek(dst.segment_list()->item(10)->address()));
uint32_t sum = 0;
for (i = 0; i < 64; i++) {
sum += dst.ReadDWord();
}
EXPECT_EQ(sum, 0xB7896EB5);
// delete file from disk
pf2.Close();
remove(file_name.c_str());
}
TEST(PEFileTest, Compile_DLL)
{
PEFile pf(NULL);
ASSERT_EQ(pf.Open("test-binaries/win32-dll-test1-i386", foRead), osSuccess);
std::string file_name = pf.file_name()+".dll";
PEFile *f = pf.Clone(file_name.c_str());
CompileOptions options;
options.flags = cpPack;
options.section_name = ".vmp";
ASSERT_TRUE(f->Compile(options));
delete f;
PEFile pf2(NULL);
ASSERT_EQ(pf2.Open(file_name.c_str(), foRead | foHeaderOnly), osSuccess);
ASSERT_EQ(pf2.count(), pf.count());
PEArchitecture &src = *pf.arch_pe();
PEArchitecture &dst = *pf2.arch_pe();
size_t i;
for (i = 0; i < src.fixup_list()->count(); i++) {
IFixup *src_fixup = src.fixup_list()->item(i);
IFixup *dst_fixup = src.fixup_list()->GetFixupByAddress(src_fixup->address());
EXPECT_EQ(src_fixup->address(), dst_fixup->address());
EXPECT_EQ(src_fixup->type(), dst_fixup->type());
EXPECT_EQ(src_fixup->size(), dst_fixup->size());
}
ASSERT_EQ(src.resource_list()->count(), dst.resource_list()->count());
for (i = 0; i < src.resource_list()->count(); i++) {
PEResource *src_resource = src.resource_list()->item(i);
PEResource *dst_resource = dst.resource_list()->item(i);
EXPECT_EQ(src_resource->count(), dst_resource->count());
EXPECT_EQ(src_resource->address(), dst_resource->address());
EXPECT_EQ(src_resource->size(), dst_resource->size());
EXPECT_EQ(src_resource->type(), dst_resource->type());
EXPECT_EQ(src_resource->name(), dst_resource->name());
}
ASSERT_EQ(src.export_list()->count(), dst.export_list()->count());
for (i = 0; i < src.export_list()->count(); i++) {
PEExport *src_export = src.export_list()->item(i);
PEExport *dst_export = dst.export_list()->item(i);
EXPECT_EQ(src_export->name(), dst_export->name());
EXPECT_EQ(src_export->ordinal(), dst_export->ordinal());
if (src_export->forwarded_name().empty()) {
EXPECT_EQ(src_export->address(), dst_export->address());
} else {
EXPECT_EQ(src_export->forwarded_name(), dst_export->forwarded_name());
}
}
// check AV buffer
ASSERT_EQ(dst.segment_list()->count(), 7ul);
ASSERT_TRUE(dst.AddressSeek(dst.segment_list()->item(4)->address()));
uint32_t sum = 0;
for (i = 0; i < 64; i++) {
sum += dst.ReadDWord();
}
EXPECT_EQ(sum, 0xB7896EB5);
// delete file from disk
pf2.Close();
remove(file_name.c_str());
}
TEST(PEFileTest, Compile_x64)
{
PEFile pf(NULL);
ASSERT_EQ(pf.Open("test-binaries/win64-app-msvc-amd64", foRead), osSuccess);
PEArchitecture *arch = pf.arch_pe();
size_t i;
for (i = 0; i < arch->map_function_list()->count(); i++) {
MapFunction *map_function = arch->map_function_list()->item(i);
if (map_function->type() == otString)
arch->function_list()->AddByAddress(map_function->address(), ctVirtualization, 0, true, NULL);
}
ASSERT_EQ(arch->function_list()->count(), 2ul);
std::string file_name = pf.file_name()+".exe";
PEFile *f = pf.Clone(file_name.c_str());
CompileOptions options;
options.flags = cpMaximumProtection;
options.section_name = ".vmp";
ASSERT_TRUE(f->Compile(options));
delete f;
PEFile pf2(NULL);
ASSERT_EQ(pf2.Open(file_name.c_str(), foRead | foHeaderOnly), osSuccess);
ASSERT_EQ(pf2.count(), pf.count());
PEArchitecture &src = *pf.arch_pe();
PEArchitecture &dst = *pf2.arch_pe();
for (i = 0; i < src.fixup_list()->count(); i++) {
IFixup *src_fixup = src.fixup_list()->item(i);
IFixup *dst_fixup = src.fixup_list()->GetFixupByAddress(src_fixup->address());
EXPECT_EQ(src_fixup->address(), dst_fixup->address());
EXPECT_EQ(src_fixup->type(), dst_fixup->type());
EXPECT_EQ(src_fixup->size(), dst_fixup->size());
}
if (options.flags & cpResourceProtection) {
EXPECT_EQ(dst.resource_list()->count(), 1ul);
} else {
ASSERT_EQ(src.resource_list()->count(), dst.resource_list()->count());
for (i = 0; i < src.resource_list()->count(); i++) {
PEResource *src_resource = src.resource_list()->item(i);
PEResource *dst_resource = dst.resource_list()->item(i);
EXPECT_EQ(src_resource->count(), dst_resource->count());
EXPECT_EQ(src_resource->address(), dst_resource->address());
EXPECT_EQ(src_resource->size(), dst_resource->size());
EXPECT_EQ(src_resource->type(), dst_resource->type());
EXPECT_EQ(src_resource->name(), dst_resource->name());
}
}
// check AV buffer
ASSERT_EQ(dst.segment_list()->count(), 9ul);
ASSERT_TRUE(dst.AddressSeek(dst.segment_list()->item(6)->address()));
uint32_t sum = 0;
for (i = 0; i < 64; i++) {
sum += dst.ReadDWord();
}
EXPECT_EQ(sum, 0xB7896EB5);
// delete file from disk
pf2.Close();
remove(file_name.c_str());
}
TEST(PEFileTest, Pack)
{
PEFile pf(NULL);
ASSERT_EQ(pf.Open("test-binaries/win32-app-delphi-i386", foRead), osSuccess);
PEArchitecture *arch = pf.arch_pe();
PESegment *section = arch->segment_list()->item(0);
Data data, props;
Packer packer;
size_t data_size = static_cast<size_t>(section->physical_size());
ASSERT_TRUE(packer.WriteProps(&props));
ASSERT_TRUE(arch->AddressSeek(section->address()));
ASSERT_TRUE(packer.Code(arch, data_size, &data));
Byte *dst = new Byte[data_size];
CLzmaDecoderState state;
EXPECT_EQ(LzmaDecodeProperties(&state.Properties, props.data(), (unsigned)props.size()), LZMA_RESULT_OK);
state.Probs = (CProb *)new Byte[LzmaGetNumProbs(&state.Properties) * sizeof(CProb)];
SizeT src_processed_size;
SizeT dst_processed_size;
EXPECT_EQ(LzmaDecode(&state, data.data(), -1, &src_processed_size, dst, -1, &dst_processed_size), LZMA_RESULT_OK);
delete [] state.Probs;
ASSERT_EQ(dst_processed_size, data_size);
arch->AddressSeek(section->address());
for (size_t i = 0; i < data_size; i++) {
EXPECT_EQ(dst[i], arch->ReadByte());
}
delete [] dst;
}
TEST(PEFileTest, CalcCheckSum)
{
uint32_t sum;
ASSERT_TRUE(os::FileGetCheckSum("test-binaries/win32-app-delphi-i386", &sum));
EXPECT_EQ(sum, 0x000e4490ul);
ASSERT_TRUE(os::FileGetCheckSum("test-binaries/win64-app-msvc-amd64", &sum));
EXPECT_EQ(sum, 0x0000b8c9ul);
}
#ifndef DEMO
#ifndef __APPLE__
static bool execFile(const std::string &fileName, DWORD &exitCode)
{
exitCode = 0xFFFFFFF;
#ifdef VMP_GNU
int ret = system(("wine " + fileName).c_str());
if (ret != -1)
{
exitCode = DWORD(ret);
return true;
}
return false;
#else
PROCESS_INFORMATION processInformation = { };
STARTUPINFOW startupInfo = { };
startupInfo.cb = sizeof(startupInfo);
os::unicode_string unicodeName = os::FromUTF8(fileName);
BOOL result = CreateProcessW(NULL, const_cast<wchar_t *>(unicodeName.c_str()),
NULL, NULL, FALSE,
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
NULL, NULL, &startupInfo, &processInformation);
if (!result)
return false;
WaitForSingleObject(processInformation.hProcess, 10000);
result = GetExitCodeProcess(processInformation.hProcess, &exitCode);
if (exitCode == STILL_ACTIVE)
TerminateProcess(processInformation.hProcess, 0xFFFFFFFF);
CloseHandle(processInformation.hProcess);
CloseHandle(processInformation.hThread);
return (result && (exitCode != STILL_ACTIVE));
#endif
}
/* seh.cpp:
#include <windows.h>
#include "VMProtectSDK.h"
__declspec(noinline) void try1()
{
printf("try 1\n");
try {
throw 1;
}
catch (int) {
printf("catch 1\n");
throw;
}
printf("end 1\n\n");
}
__declspec(noinline) void try2()
{
printf("try 2\n");
PEXCEPTION_POINTERS info = NULL;
__try {
if (*reinterpret_cast<char *>(0xFACE) == 0)
return;
}
__except (info = GetExceptionInformation(), EXCEPTION_EXECUTE_HANDLER) {
printf("throw at %p\n", info->ExceptionRecord->ExceptionAddress);
}
printf("end 2\n\n");
}
int main()
{
if (VMProtectIsDebuggerPresent(true))
printf("debugger detected\n");
if (VMProtectIsVirtualMachinePresent())
printf("virtual machine detected\n");
printf("try main\n");
try {
try1();
}
catch (...) {
printf("catch main\n");
}
printf("end main\n");
try2();
return 0;
}
*/
TEST(PEFileTest, SEH_x32)
{
PEFile pf(NULL);
ASSERT_EQ(pf.Open("test-binaries/seh-x86", foRead), osSuccess);
PEArchitecture *arch = pf.arch_pe();
arch->function_list()->AddByAddress(0x00401130, ctVirtualization, 0, true, NULL); // main
arch->function_list()->AddByAddress(0x00401000, ctUltra, 0, true, NULL); // try1
arch->function_list()->AddByAddress(0x00401070, ctMutation, 0, true, NULL); // try2
std::string file_name = pf.file_name() + ".exe";
PEFile *f = pf.Clone(file_name.c_str());
CompileOptions options;
options.flags = cpMaximumProtection;
options.section_name = ".vmp";
ASSERT_TRUE(f->Compile(options));
delete f;
DWORD ret;
ASSERT_TRUE(execFile(file_name, ret));
ASSERT_EQ(ret, 0u);
}
#endif
#ifndef VMP_GNU
TEST(PEFileTest, SEH_x64)
{
PEFile pf(NULL);
ASSERT_EQ(pf.Open("test-binaries/seh-x64", foRead), osSuccess);
PEArchitecture *arch = pf.arch_pe();
arch->function_list()->AddByAddress(0x00000001400010A0, ctVirtualization, 0, true, NULL); // main
arch->function_list()->AddByAddress(0x0000000140001000, ctUltra, 0, true, NULL); // try1
arch->function_list()->AddByAddress(0x0000000140001040, ctMutation, 0, true, NULL); // try2
std::string file_name = pf.file_name() + ".exe";
PEFile *f = pf.Clone(file_name.c_str());
CompileOptions options;
options.flags = cpMaximumProtection;
options.section_name = ".vmp";
ASSERT_TRUE(f->Compile(options));
delete f;
DWORD ret;
ASSERT_TRUE(execFile(file_name, ret));
ASSERT_EQ(ret, 0u);
}
#endif
#endif