Skip to content

Commit

Permalink
More OS-dependent cases in Image Loader
Browse files Browse the repository at this point in the history
  • Loading branch information
Ladislav Zezula authored and PeterMatula committed Oct 6, 2020
1 parent 5f61574 commit 9e2d08f
Show file tree
Hide file tree
Showing 4 changed files with 446 additions and 29 deletions.
19 changes: 16 additions & 3 deletions include/retdec/pelib/ImageLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ enum struct PELIB_COMPARE_RESULT : std::uint32_t
ImagesDifferentSize, // The images have different size
ImagesDifferentPageAccess, // An image page is different (accessible vs non-accessible)
ImagesDifferentPageValue, // There is a different value at a certain offset
ImagesInvalidPageInImage, // A page in the image mapped by Windows is invalid
ImagesCompareInvalid,
};

Expand Down Expand Up @@ -398,8 +399,14 @@ class ImageLoader
bool isLegacyImageArchitecture(std::uint16_t Machine);
bool checkForValid64BitMachine();
bool checkForValid32BitMachine();
bool isValidMachineForCodeIntegrifyCheck(std::uint32_t Bits);
bool checkForSectionTablesWithinHeader(std::uint32_t e_lfanew);
bool checkForBadAppContainer();
bool checkForBadCodeIntegrityImages(ByteBuffer & fileData);
bool checkForBadArchitectureSpecific();
bool checkForImageAfterMapping();

template <typename LOAD_CONFIG>
bool checkForBadLoadConfigXX(std::uint32_t loadConfigRva, std::uint32_t loadConfigSize);

// isImageLoadable returns true if the image is OK and can be mapped by NtCreateSection(SEC_IMAGE).
// This does NOT mean that the image is executable by CreateProcess - more checks are done,
Expand Down Expand Up @@ -446,12 +453,18 @@ class ImageLoader
std::uint32_t checkSumFileOffset; // File offset of the image checksum
std::uint32_t securityDirFileOffset; // File offset of security directory
std::uint32_t ssiImageAlignment32; // Alignment of signle-section images under 32-bit OS
bool is64BitWindows; // If true, we simulate 64-bit Windows
bool ntHeadersSizeCheck; // If true, the loader requires minimum size of NT headers
bool sizeofImageMustMatch; // If true, the SizeOfImage must match virtual end of the last section
bool appContainerCheck; // If true, app container flag is tested in the optional header
bool is64BitWindows; // If true, we simulate 64-bit Windows
bool architectureSpecificChecks; // If true, architecture-specific checks are also performed
bool headerSizeCheck; // If true, image loader will imitate Windows XP header size check
bool loadArmImages; // If true, image loader will load ARM binaries
bool loadArm64Images; // If true, image loader will load ARM64 binaries
bool loadItaniumImages; // If true, image loader will load IA64 binaries
bool forceIntegrityCheckEnabled; // If true, extra checks will be done if IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY is set
bool forceIntegrityCheckCertificate; // If true, extra check for certificate will be provided
bool checkNonLegacyDllCharacteristics; // If true, extra checks will be performed on DllCharacteristics
bool checkImagePostMapping; // If true, extra checks will be performed after the image is mapped
};

} // namespace PeLib
Expand Down
112 changes: 111 additions & 1 deletion include/retdec/pelib/PeLibAux.h
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,12 @@ namespace PeLib
std::uint32_t VirtualAddress;
std::uint32_t SizeOfBlock;

PELIB_IMAGE_BASE_RELOCATION();
PELIB_IMAGE_BASE_RELOCATION()
{
VirtualAddress = 0;
SizeOfBlock = 0;
}

static inline std::size_t size() {return 72;}
};

Expand Down Expand Up @@ -1271,6 +1276,111 @@ namespace PeLib
}
};

struct PELIB_IMAGE_LOAD_CONFIG_CODE_INTEGRITY
{
std::uint16_t Flags; // Flags to indicate if CI information is available, etc.
std::uint16_t Catalog; // 0xFFFF means not available
std::uint32_t CatalogOffset;
std::uint32_t Reserved; // Additional bitmask to be defined later
};

// Load config directory
struct PELIB_IMAGE_LOAD_CONFIG_DIRECTORY32
{
std::uint32_t Size;
std::uint32_t TimeDateStamp;
std::uint16_t MajorVersion;
std::uint16_t MinorVersion;
std::uint32_t GlobalFlagsClear;
std::uint32_t GlobalFlagsSet;
std::uint32_t CriticalSectionDefaultTimeout;
std::uint32_t DeCommitFreeBlockThreshold;
std::uint32_t DeCommitTotalFreeThreshold;
std::uint32_t LockPrefixTable;
std::uint32_t MaximumAllocationSize;
std::uint32_t VirtualMemoryThreshold;
std::uint32_t ProcessHeapFlags;
std::uint32_t ProcessAffinityMask;
std::uint16_t CSDVersion;
std::uint16_t DependentLoadFlags;
std::uint32_t EditList;
std::uint32_t SecurityCookie;
std::uint32_t SEHandlerTable;
std::uint32_t SEHandlerCount;
std::uint32_t GuardCFCheckFunctionPointer;
std::uint32_t GuardCFDispatchFunctionPointer;
std::uint32_t GuardCFFunctionTable;
std::uint32_t GuardCFFunctionCount;
std::uint32_t GuardFlags;
PELIB_IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity;
std::uint32_t GuardAddressTakenIatEntryTable;
std::uint32_t GuardAddressTakenIatEntryCount;
std::uint32_t GuardLongJumpTargetTable;
std::uint32_t GuardLongJumpTargetCount;
std::uint32_t DynamicValueRelocTable;
std::uint32_t CHPEMetadataPointer;
std::uint32_t GuardRFFailureRoutine;
std::uint32_t GuardRFFailureRoutineFunctionPointer;
std::uint32_t DynamicValueRelocTableOffset;
std::uint16_t DynamicValueRelocTableSection;
std::uint16_t Reserved2;
std::uint32_t GuardRFVerifyStackPointerFunctionPointer;
std::uint32_t HotPatchTableOffset;
std::uint32_t Reserved3;
std::uint32_t EnclaveConfigurationPointer;
std::uint32_t VolatileMetadataPointer;
std::uint32_t GuardEHContinuationTable;
std::uint32_t GuardEHContinuationCount;
};

struct PELIB_IMAGE_LOAD_CONFIG_DIRECTORY64
{
std::uint32_t Size;
std::uint32_t TimeDateStamp;
std::uint16_t MajorVersion;
std::uint16_t MinorVersion;
std::uint32_t GlobalFlagsClear;
std::uint32_t GlobalFlagsSet;
std::uint32_t CriticalSectionDefaultTimeout;
std::uint64_t DeCommitFreeBlockThreshold;
std::uint64_t DeCommitTotalFreeThreshold;
std::uint64_t LockPrefixTable;
std::uint64_t MaximumAllocationSize;
std::uint64_t VirtualMemoryThreshold;
std::uint64_t ProcessAffinityMask;
std::uint32_t ProcessHeapFlags;
std::uint16_t CSDVersion;
std::uint16_t DependentLoadFlags;
std::uint64_t EditList;
std::uint64_t SecurityCookie;
std::uint64_t SEHandlerTable;
std::uint64_t SEHandlerCount;
std::uint64_t GuardCFCheckFunctionPointer;
std::uint64_t GuardCFDispatchFunctionPointer;
std::uint64_t GuardCFFunctionTable;
std::uint64_t GuardCFFunctionCount;
std::uint32_t GuardFlags;
PELIB_IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity;
std::uint64_t GuardAddressTakenIatEntryTable;
std::uint64_t GuardAddressTakenIatEntryCount;
std::uint64_t GuardLongJumpTargetTable;
std::uint64_t GuardLongJumpTargetCount;
std::uint64_t DynamicValueRelocTable;
std::uint64_t CHPEMetadataPointer;
std::uint64_t GuardRFFailureRoutine;
std::uint64_t GuardRFFailureRoutineFunctionPointer;
std::uint32_t DynamicValueRelocTableOffset;
std::uint16_t DynamicValueRelocTableSection;
std::uint16_t Reserved2;
std::uint64_t GuardRFVerifyStackPointerFunctionPointer;
std::uint32_t HotPatchTableOffset;
std::uint32_t Reserved3;
std::uint64_t EnclaveConfigurationPointer;
std::uint64_t VolatileMetadataPointer;
std::uint64_t GuardEHContinuationTable;
std::uint64_t GuardEHContinuationCount;
};

// This structure is defined in the "delayimp.h" header file as ImgDelayDescrV1 or ImgDelayDescrV2.
// Fields suffixed with "Rva" are direct virtual addresses in the "V1" version of the structure.
struct PELIB_IMAGE_DELAY_LOAD_DESCRIPTOR
Expand Down
Loading

0 comments on commit 9e2d08f

Please sign in to comment.