void TestPeFile() { hadesmem::Process const process(::GetCurrentProcessId()); hadesmem::PeFile pe_file_1( process, ::GetModuleHandleW(nullptr), hadesmem::PeFileType::kImage, 0); hadesmem::PeFile pe_file_2(pe_file_1); BOOST_TEST_EQ(pe_file_1, pe_file_2); pe_file_1 = pe_file_2; BOOST_TEST_EQ(pe_file_1, pe_file_2); hadesmem::PeFile pe_file_3(std::move(pe_file_2)); BOOST_TEST_EQ(pe_file_3, pe_file_1); pe_file_2 = std::move(pe_file_3); BOOST_TEST_EQ(pe_file_1, pe_file_2); hadesmem::PeFile pe_file_this( process, ::GetModuleHandleW(nullptr), hadesmem::PeFileType::kImage, 0); BOOST_TEST_EQ(pe_file_this.GetBase(), ::GetModuleHandle(nullptr)); BOOST_TEST(pe_file_this.GetType() == hadesmem::PeFileType::kImage); BOOST_TEST_EQ(hadesmem::RvaToVa(process, pe_file_this, 0), static_cast<void*>(nullptr)); hadesmem::PeFile pe_file_ntdll( process, ::GetModuleHandleW(L"ntdll"), hadesmem::PeFileType::kImage, 0); BOOST_TEST_EQ(pe_file_ntdll.GetBase(), ::GetModuleHandle(L"ntdll")); BOOST_TEST(pe_file_ntdll.GetType() == hadesmem::PeFileType::kImage); BOOST_TEST_EQ(hadesmem::RvaToVa(process, pe_file_ntdll, 0), static_cast<void*>(nullptr)); BOOST_TEST_EQ(pe_file_this, pe_file_this); BOOST_TEST_NE(pe_file_this, pe_file_ntdll); BOOST_TEST_NE(pe_file_ntdll, pe_file_this); if (pe_file_this > pe_file_ntdll) { BOOST_TEST(pe_file_this > pe_file_ntdll); BOOST_TEST(pe_file_this >= pe_file_ntdll); BOOST_TEST(!(pe_file_this < pe_file_ntdll)); BOOST_TEST(!(pe_file_this <= pe_file_ntdll)); } else { BOOST_TEST(pe_file_ntdll > pe_file_this); BOOST_TEST(pe_file_ntdll >= pe_file_this); BOOST_TEST(!(pe_file_ntdll < pe_file_this)); BOOST_TEST(!(pe_file_ntdll <= pe_file_this)); } std::stringstream test_str_1; test_str_1.imbue(std::locale::classic()); test_str_1 << pe_file_this; std::stringstream test_str_2; test_str_2.imbue(std::locale::classic()); test_str_2 << pe_file_this.GetBase(); BOOST_TEST_EQ(test_str_1.str(), test_str_2.str()); std::stringstream test_str_3; test_str_3.imbue(std::locale::classic()); test_str_3 << pe_file_ntdll.GetBase(); BOOST_TEST_NE(test_str_1.str(), test_str_3.str()); }
void TestTlsDir() { // Use TLS to ensure that at least one module has a TLS dir thread_local static std::int32_t tls_dummy = 0; hadesmem::Process const process(::GetCurrentProcessId()); hadesmem::PeFile pe_file_1( process, ::GetModuleHandleW(nullptr), hadesmem::PeFileType::kImage, 0); hadesmem::TlsDir tls_dir_1(process, pe_file_1); hadesmem::TlsDir tls_dir_2(tls_dir_1); BOOST_TEST_EQ(tls_dir_1, tls_dir_2); tls_dir_1 = tls_dir_2; BOOST_TEST_EQ(tls_dir_1, tls_dir_2); hadesmem::TlsDir tls_dir_3(std::move(tls_dir_2)); BOOST_TEST_EQ(tls_dir_3, tls_dir_1); tls_dir_2 = std::move(tls_dir_3); BOOST_TEST_EQ(tls_dir_1, tls_dir_2); hadesmem::ModuleList modules(process); for (auto const& mod : modules) { hadesmem::PeFile const cur_pe_file( process, mod.GetHandle(), hadesmem::PeFileType::kImage, 0); std::unique_ptr<hadesmem::TlsDir> cur_tls_dir; try { cur_tls_dir = std::make_unique<hadesmem::TlsDir>(process, cur_pe_file); } catch (std::exception const& /*e*/) { continue; } ++tls_dummy; auto const tls_dir_raw = hadesmem::Read<IMAGE_TLS_DIRECTORY>(process, cur_tls_dir->GetBase()); cur_tls_dir->SetStartAddressOfRawData( cur_tls_dir->GetStartAddressOfRawData()); cur_tls_dir->SetEndAddressOfRawData(cur_tls_dir->GetEndAddressOfRawData()); cur_tls_dir->SetAddressOfIndex(cur_tls_dir->GetAddressOfIndex()); cur_tls_dir->SetAddressOfCallBacks(cur_tls_dir->GetAddressOfCallBacks()); cur_tls_dir->SetSizeOfZeroFill(cur_tls_dir->GetSizeOfZeroFill()); cur_tls_dir->SetCharacteristics(cur_tls_dir->GetCharacteristics()); std::vector<ULONGLONG> callbacks; cur_tls_dir->GetCallbacks(std::back_inserter(callbacks)); cur_tls_dir->UpdateWrite(); cur_tls_dir->UpdateRead(); auto const tls_dir_raw_new = hadesmem::Read<IMAGE_TLS_DIRECTORY>(process, cur_tls_dir->GetBase()); BOOST_TEST_EQ( std::memcmp(&tls_dir_raw, &tls_dir_raw_new, sizeof(tls_dir_raw)), 0); std::stringstream test_str_1; test_str_1.imbue(std::locale::classic()); test_str_1 << *cur_tls_dir; std::stringstream test_str_2; test_str_2.imbue(std::locale::classic()); test_str_2 << cur_tls_dir->GetBase(); BOOST_TEST_EQ(test_str_1.str(), test_str_2.str()); } BOOST_TEST_NE(tls_dummy, 0); }
void TestSectionList() { hadesmem::Process const process(::GetCurrentProcessId()); hadesmem::PeFile pe_file_1( process, ::GetModuleHandleW(nullptr), hadesmem::PeFileType::Image, 0); hadesmem::NtHeaders nt_headers_1(process, pe_file_1); BOOST_TEST(nt_headers_1.GetNumberOfSections() >= 1); hadesmem::Section section_1(process, pe_file_1, 0); hadesmem::Section section_2(section_1); BOOST_TEST_EQ(section_1, section_2); section_1 = section_2; BOOST_TEST_EQ(section_1, section_2); hadesmem::Section section_3(std::move(section_2)); BOOST_TEST_EQ(section_3, section_1); section_2 = std::move(section_3); BOOST_TEST_EQ(section_1, section_2); hadesmem::ModuleList modules(process); for (auto const& mod : modules) { hadesmem::PeFile const pe_file( process, mod.GetHandle(), hadesmem::PeFileType::Image, 0); hadesmem::NtHeaders const nt_headers(process, pe_file); WORD const num_sections = nt_headers.GetNumberOfSections(); // Assume every module has at least one section. hadesmem::SectionList sections(process, pe_file); WORD section_count = 0; for (auto& section : sections) { section_count = static_cast<WORD>(section_count + 1); auto const section_header_raw = hadesmem::Read<IMAGE_SECTION_HEADER>(process, section.GetBase()); section.SetName(section.GetName()); section.SetVirtualAddress(section.GetVirtualAddress()); section.SetVirtualSize(section.GetVirtualSize()); section.SetSizeOfRawData(section.GetSizeOfRawData()); section.SetPointerToRawData(section.GetPointerToRawData()); section.SetPointerToRelocations(section.GetPointerToRelocations()); section.SetPointerToLinenumbers(section.GetPointerToLinenumbers()); section.SetNumberOfRelocations(section.GetNumberOfRelocations()); section.SetNumberOfLinenumbers(section.GetNumberOfLinenumbers()); section.SetCharacteristics(section.GetCharacteristics()); section.UpdateWrite(); section.UpdateRead(); auto const section_header_raw_new = hadesmem::Read<IMAGE_SECTION_HEADER>(process, section.GetBase()); BOOST_TEST_EQ(std::memcmp(§ion_header_raw, §ion_header_raw_new, sizeof(section_header_raw)), 0); std::stringstream test_str_1; test_str_1.imbue(std::locale::classic()); test_str_1 << section; std::stringstream test_str_2; test_str_2.imbue(std::locale::classic()); test_str_2 << section.GetBase(); BOOST_TEST_EQ(test_str_1.str(), test_str_2.str()); if (mod.GetHandle() != GetModuleHandle(L"ntdll")) { hadesmem::PeFile const pe_file_ntdll(process, ::GetModuleHandleW(L"ntdll"), hadesmem::PeFileType::Image, 0); hadesmem::Section const section_ntdll(process, pe_file_ntdll, 0); std::stringstream test_str_3; test_str_3.imbue(std::locale::classic()); test_str_3 << section_ntdll.GetBase(); BOOST_TEST_NE(test_str_1.str(), test_str_3.str()); } } BOOST_TEST(section_count == num_sections); // Assume every module has a '.text' section. auto text_iter = std::find_if(std::begin(sections), std::end(sections), [](hadesmem::Section const& section) { return section.GetName() == ".data"; }); BOOST_TEST(text_iter != std::end(sections)); } }
void TestNtHeaders() { hadesmem::Process const process(::GetCurrentProcessId()); hadesmem::PeFile pe_file_1( process, ::GetModuleHandleW(nullptr), hadesmem::PeFileType::Image, 0); hadesmem::NtHeaders nt_headers_1(process, pe_file_1); hadesmem::NtHeaders nt_headers_2(nt_headers_1); BOOST_TEST_EQ(nt_headers_1, nt_headers_2); nt_headers_1 = nt_headers_2; BOOST_TEST_EQ(nt_headers_1, nt_headers_2); hadesmem::NtHeaders nt_headers_3(std::move(nt_headers_2)); BOOST_TEST_EQ(nt_headers_3, nt_headers_1); nt_headers_2 = std::move(nt_headers_3); BOOST_TEST_EQ(nt_headers_1, nt_headers_2); hadesmem::ModuleList modules(process); for (auto const& mod : modules) { hadesmem::PeFile const cur_pe_file( process, mod.GetHandle(), hadesmem::PeFileType::Image, 0); hadesmem::NtHeaders cur_nt_headers(process, cur_pe_file); auto const nt_headers_raw = hadesmem::Read<IMAGE_NT_HEADERS>(process, cur_nt_headers.GetBase()); BOOST_TEST_EQ(cur_nt_headers.IsValid(), true); cur_nt_headers.EnsureValid(); cur_nt_headers.SetSignature(cur_nt_headers.GetSignature()); cur_nt_headers.SetMachine(cur_nt_headers.GetMachine()); cur_nt_headers.SetNumberOfSections(cur_nt_headers.GetNumberOfSections()); cur_nt_headers.SetTimeDateStamp(cur_nt_headers.GetTimeDateStamp()); cur_nt_headers.SetPointerToSymbolTable( cur_nt_headers.GetPointerToSymbolTable()); cur_nt_headers.SetNumberOfSymbols(cur_nt_headers.GetNumberOfSymbols()); cur_nt_headers.SetSizeOfOptionalHeader( cur_nt_headers.GetSizeOfOptionalHeader()); cur_nt_headers.SetCharacteristics(cur_nt_headers.GetCharacteristics()); cur_nt_headers.SetMagic(cur_nt_headers.GetMagic()); cur_nt_headers.SetMajorLinkerVersion( cur_nt_headers.GetMajorLinkerVersion()); cur_nt_headers.SetMinorLinkerVersion( cur_nt_headers.GetMinorLinkerVersion()); cur_nt_headers.SetSizeOfCode(cur_nt_headers.GetSizeOfCode()); cur_nt_headers.SetSizeOfInitializedData( cur_nt_headers.GetSizeOfInitializedData()); cur_nt_headers.SetSizeOfUninitializedData( cur_nt_headers.GetSizeOfUninitializedData()); cur_nt_headers.SetAddressOfEntryPoint( cur_nt_headers.GetAddressOfEntryPoint()); cur_nt_headers.SetBaseOfCode(cur_nt_headers.GetBaseOfCode()); #if defined(HADESMEM_DETAIL_ARCH_X86) cur_nt_headers.SetBaseOfData(cur_nt_headers.GetBaseOfData()); #endif cur_nt_headers.SetImageBase(cur_nt_headers.GetImageBase()); cur_nt_headers.SetSectionAlignment(cur_nt_headers.GetSectionAlignment()); cur_nt_headers.SetFileAlignment(cur_nt_headers.GetFileAlignment()); cur_nt_headers.SetMajorOperatingSystemVersion( cur_nt_headers.GetMajorOperatingSystemVersion()); cur_nt_headers.SetMinorOperatingSystemVersion( cur_nt_headers.GetMinorOperatingSystemVersion()); cur_nt_headers.SetMajorImageVersion(cur_nt_headers.GetMajorImageVersion()); cur_nt_headers.SetMinorImageVersion(cur_nt_headers.GetMinorImageVersion()); cur_nt_headers.SetMajorSubsystemVersion( cur_nt_headers.GetMajorSubsystemVersion()); cur_nt_headers.SetMinorSubsystemVersion( cur_nt_headers.GetMinorSubsystemVersion()); cur_nt_headers.SetWin32VersionValue(cur_nt_headers.GetWin32VersionValue()); cur_nt_headers.SetSizeOfImage(cur_nt_headers.GetSizeOfImage()); cur_nt_headers.SetSizeOfHeaders(cur_nt_headers.GetSizeOfHeaders()); cur_nt_headers.SetCheckSum(cur_nt_headers.GetCheckSum()); cur_nt_headers.SetSubsystem(cur_nt_headers.GetSubsystem()); cur_nt_headers.SetDllCharacteristics( cur_nt_headers.GetDllCharacteristics()); cur_nt_headers.SetSizeOfStackReserve( cur_nt_headers.GetSizeOfStackReserve()); cur_nt_headers.SetSizeOfStackCommit(cur_nt_headers.GetSizeOfStackCommit()); cur_nt_headers.SetSizeOfHeapReserve(cur_nt_headers.GetSizeOfHeapReserve()); cur_nt_headers.SetSizeOfHeapCommit(cur_nt_headers.GetSizeOfHeapCommit()); cur_nt_headers.SetLoaderFlags(cur_nt_headers.GetLoaderFlags()); cur_nt_headers.SetNumberOfRvaAndSizes( cur_nt_headers.GetNumberOfRvaAndSizes()); for (std::size_t i = 0; i < cur_nt_headers.GetNumberOfRvaAndSizes(); ++i) { auto data_dir = static_cast<hadesmem::PeDataDir>(i); cur_nt_headers.SetDataDirectoryVirtualAddress( data_dir, cur_nt_headers.GetDataDirectoryVirtualAddress(data_dir)); cur_nt_headers.SetDataDirectorySize( data_dir, cur_nt_headers.GetDataDirectorySize(data_dir)); } cur_nt_headers.UpdateWrite(); cur_nt_headers.UpdateRead(); auto const nt_headers_raw_new = hadesmem::Read<IMAGE_NT_HEADERS>(process, cur_nt_headers.GetBase()); BOOST_TEST_EQ( std::memcmp(&nt_headers_raw, &nt_headers_raw_new, sizeof(nt_headers_raw)), 0); std::stringstream test_str_1; test_str_1.imbue(std::locale::classic()); test_str_1 << cur_nt_headers; std::stringstream test_str_2; test_str_2.imbue(std::locale::classic()); test_str_2 << cur_nt_headers.GetBase(); BOOST_TEST_EQ(test_str_1.str(), test_str_2.str()); if (mod.GetHandle() != ::GetModuleHandle(L"ntdll")) { hadesmem::PeFile const pe_file_ntdll( process, ::GetModuleHandleW(L"ntdll"), hadesmem::PeFileType::Image, 0); hadesmem::NtHeaders const nt_headers_ntdll(process, pe_file_ntdll); std::stringstream test_str_3; test_str_3.imbue(std::locale::classic()); test_str_3 << nt_headers_ntdll.GetBase(); BOOST_TEST_NE(test_str_1.str(), test_str_3.str()); } } }
void TestDosHeader() { hadesmem::Process const process(::GetCurrentProcessId()); hadesmem::PeFile pe_file_1( process, ::GetModuleHandleW(nullptr), hadesmem::PeFileType::Image, 0); hadesmem::DosHeader dos_header_1(process, pe_file_1); hadesmem::DosHeader dos_header_2(dos_header_1); BOOST_TEST_EQ(dos_header_1, dos_header_2); dos_header_1 = dos_header_2; BOOST_TEST_EQ(dos_header_1, dos_header_2); hadesmem::DosHeader dos_header_3(std::move(dos_header_2)); BOOST_TEST_EQ(dos_header_3, dos_header_1); dos_header_2 = std::move(dos_header_3); BOOST_TEST_EQ(dos_header_1, dos_header_2); hadesmem::ModuleList modules(process); for (auto const& mod : modules) { hadesmem::PeFile const cur_pe_file( process, mod.GetHandle(), hadesmem::PeFileType::Image, 0); hadesmem::DosHeader cur_dos_header(process, cur_pe_file); auto const dos_header_raw = hadesmem::Read<IMAGE_DOS_HEADER>(process, cur_dos_header.GetBase()); BOOST_TEST_EQ(cur_dos_header.IsValid(), true); cur_dos_header.EnsureValid(); cur_dos_header.SetMagic(cur_dos_header.GetMagic()); cur_dos_header.SetBytesOnLastPage(cur_dos_header.GetBytesOnLastPage()); cur_dos_header.SetPagesInFile(cur_dos_header.GetPagesInFile()); cur_dos_header.SetRelocations(cur_dos_header.GetRelocations()); cur_dos_header.SetSizeOfHeaderInParagraphs( cur_dos_header.GetSizeOfHeaderInParagraphs()); cur_dos_header.SetMinExtraParagraphs( cur_dos_header.GetMinExtraParagraphs()); cur_dos_header.SetMaxExtraParagraphs( cur_dos_header.GetMaxExtraParagraphs()); cur_dos_header.SetInitialSS(cur_dos_header.GetInitialSS()); cur_dos_header.SetInitialSP(cur_dos_header.GetInitialSP()); cur_dos_header.SetChecksum(cur_dos_header.GetChecksum()); cur_dos_header.SetInitialIP(cur_dos_header.GetInitialIP()); cur_dos_header.SetInitialCS(cur_dos_header.GetInitialCS()); cur_dos_header.SetRelocTableFileAddr( cur_dos_header.GetRelocTableFileAddr()); cur_dos_header.SetOverlayNum(cur_dos_header.GetOverlayNum()); cur_dos_header.SetReservedWords1(cur_dos_header.GetReservedWords1()); cur_dos_header.SetOEMID(cur_dos_header.GetOEMID()); cur_dos_header.SetOEMInfo(cur_dos_header.GetOEMInfo()); cur_dos_header.SetReservedWords2(cur_dos_header.GetReservedWords2()); cur_dos_header.SetNewHeaderOffset(cur_dos_header.GetNewHeaderOffset()); cur_dos_header.UpdateWrite(); cur_dos_header.UpdateRead(); auto const dos_header_raw_new = hadesmem::Read<IMAGE_DOS_HEADER>(process, cur_pe_file.GetBase()); BOOST_TEST_EQ( std::memcmp(&dos_header_raw, &dos_header_raw_new, sizeof(dos_header_raw)), 0); std::stringstream test_str_1; test_str_1.imbue(std::locale::classic()); test_str_1 << cur_dos_header; std::stringstream test_str_2; test_str_2.imbue(std::locale::classic()); test_str_2 << cur_dos_header.GetBase(); BOOST_TEST_EQ(test_str_1.str(), test_str_2.str()); if (mod.GetHandle() != ::GetModuleHandleW(L"ntdll")) { hadesmem::PeFile const pe_file_ntdll( process, ::GetModuleHandleW(L"ntdll"), hadesmem::PeFileType::Image, 0); hadesmem::DosHeader const dos_header_ntdll(process, pe_file_ntdll); std::stringstream test_str_3; test_str_3.imbue(std::locale::classic()); test_str_3 << dos_header_ntdll.GetBase(); BOOST_TEST_NE(test_str_1.str(), test_str_3.str()); } } }