Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] CFG property page for Peview #101

Merged
merged 12 commits into from
Jan 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
67 changes: 67 additions & 0 deletions phlib/include/mapimg.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ typedef struct _PH_MAPPED_IMAGE_EXPORT_FUNCTION
PSTR ForwardedName;
} PH_MAPPED_IMAGE_EXPORT_FUNCTION, *PPH_MAPPED_IMAGE_EXPORT_FUNCTION;


PHLIBAPI
NTSTATUS
NTAPI
Expand Down Expand Up @@ -381,6 +382,72 @@ PhGetMappedArchiveImportEntry(
_Out_ PPH_MAPPED_ARCHIVE_IMPORT_ENTRY Entry
);

typedef struct _PH_MAPPED_IMAGE_CFG_ENTRY
{
DWORD Rva;
struct
{
BYTE SuppressedCall : 1;
BYTE Reserved : 7;
} Flags;

} PH_MAPPED_IMAGE_CFG_ENTRY, *PPH_MAPPED_IMAGE_CFG_ENTRY;

typedef struct _PH_MAPPED_IMAGE_CFG
{
PPH_MAPPED_IMAGE MappedImage;
ULONG EntrySize;

struct
{
BOOLEAN CfgInstrumented;
BOOLEAN WriteIntegrityChecks;
BOOLEAN CfgFunctionTablePresent;
BOOLEAN SecurityCookieUnused;
BOOLEAN ProtectDelayLoadedIat;
BOOLEAN DelayLoadInDidatSection;
BOOLEAN HasExportSuppressionInfos;
BOOLEAN EnableExportSuppression;
BOOLEAN CfgLongJumpTablePresent;
} GuardFlags;

PULONGLONG GuardFunctionTable;
ULONGLONG NumberOfGuardFunctionEntries;

PULONGLONG GuardAdressIatTable; // not currently used
ULONGLONG NumberOfGuardAdressIatEntries;

PULONGLONG GuardLongJumpTable; // not currently used
ULONGLONG NumberOfGuardLongJumpEntries;

} PH_MAPPED_IMAGE_CFG, *PPH_MAPPED_IMAGE_CFG;


typedef enum _PH_MAPPED_CFG_ENTRY_TYPE
{
ControlFlowGuardFunction,
ControlFlowGuardtakenIatEntry,
ControlFlowGuardLongJump
} PH_MAPPED_ARCHIVE_MEMBER_TYPE;

PHLIBAPI
NTSTATUS
NTAPI
PhGetMappedImageCfg(
_Out_ PPH_MAPPED_IMAGE_CFG CfgConfig,
_In_ PPH_MAPPED_IMAGE MappedImage
);

PHLIBAPI
NTSTATUS
NTAPI
PhGetMappedImageCfgEntry(
_In_ PPH_MAPPED_IMAGE_CFG CfgConfig,
_In_ ULONGLONG Index,
_In_ PH_MAPPED_ARCHIVE_MEMBER_TYPE Type,
_Out_ PPH_MAPPED_IMAGE_CFG_ENTRY Entry
);

#ifdef __cplusplus
}
#endif
Expand Down
153 changes: 153 additions & 0 deletions phlib/mapimg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1217,3 +1217,156 @@ ULONG PhCheckSumMappedImage(

return checkSum;
}

NTSTATUS PhGetMappedImageCfg(
_Out_ PPH_MAPPED_IMAGE_CFG CfgConfig,
_In_ PPH_MAPPED_IMAGE MappedImage
)
{
NTSTATUS Status = STATUS_SUCCESS;
PIMAGE_LOAD_CONFIG_DIRECTORY64 config64;


if (!NT_SUCCESS(Status = PhGetMappedImageLoadConfig64(MappedImage, &config64)))
{
return Status;
}

CfgConfig->MappedImage = MappedImage;


CfgConfig->GuardFlags.CfgInstrumented = !!(config64->GuardFlags & IMAGE_GUARD_CF_INSTRUMENTED);
CfgConfig->GuardFlags.WriteIntegrityChecks = !!(config64->GuardFlags & IMAGE_GUARD_CFW_INSTRUMENTED);
CfgConfig->GuardFlags.CfgFunctionTablePresent = !!(config64->GuardFlags & IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT);
CfgConfig->GuardFlags.SecurityCookieUnused = !!(config64->GuardFlags & IMAGE_GUARD_SECURITY_COOKIE_UNUSED);
CfgConfig->GuardFlags.ProtectDelayLoadedIat = !!(config64->GuardFlags & IMAGE_GUARD_PROTECT_DELAYLOAD_IAT);
CfgConfig->GuardFlags.DelayLoadInDidatSection = !!(config64->GuardFlags & IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION);
CfgConfig->GuardFlags.EnableExportSuppression = !!(config64->GuardFlags & IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION);
CfgConfig->GuardFlags.HasExportSuppressionInfos = !!(config64->GuardFlags & IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT);
CfgConfig->GuardFlags.CfgLongJumpTablePresent = !!(config64->GuardFlags & IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT);


ULONG OptionalHeaderSize = ((config64->GuardFlags & IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK) >> IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT);
CfgConfig->EntrySize = sizeof(FIELD_OFFSET(PH_MAPPED_IMAGE_CFG_ENTRY, Rva)) + OptionalHeaderSize;


CfgConfig->NumberOfGuardFunctionEntries = config64->GuardCFFunctionCount;
CfgConfig->GuardFunctionTable = PhMappedImageRvaToVa(
MappedImage,
(ULONG) (config64->GuardCFFunctionTable - MappedImage->NtHeaders->OptionalHeader.ImageBase),
NULL);

if (CfgConfig->GuardFunctionTable && CfgConfig->NumberOfGuardFunctionEntries)
{
__try
{
PhpMappedImageProbe(
MappedImage,
CfgConfig->GuardFunctionTable,
CfgConfig->EntrySize * CfgConfig->NumberOfGuardFunctionEntries
);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return GetExceptionCode();
}
}


CfgConfig->NumberOfGuardAdressIatEntries = config64->GuardAddressTakenIatEntryCount;
CfgConfig->GuardAdressIatTable = PhMappedImageRvaToVa(
MappedImage,
(ULONG) (config64->GuardAddressTakenIatEntryTable - MappedImage->NtHeaders->OptionalHeader.ImageBase),
NULL);

if (CfgConfig->GuardAdressIatTable && CfgConfig->NumberOfGuardAdressIatEntries)
{
__try
{
PhpMappedImageProbe(
MappedImage,
CfgConfig->GuardAdressIatTable,
CfgConfig->EntrySize * CfgConfig->NumberOfGuardAdressIatEntries
);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return GetExceptionCode();
}
}

CfgConfig->NumberOfGuardLongJumpEntries = config64->GuardLongJumpTargetCount;
CfgConfig->GuardLongJumpTable = PhMappedImageRvaToVa(
MappedImage,
(ULONG) (config64->GuardLongJumpTargetTable - MappedImage->NtHeaders->OptionalHeader.ImageBase),
NULL);

if (CfgConfig->GuardLongJumpTable && CfgConfig->NumberOfGuardLongJumpEntries)
{
__try
{
PhpMappedImageProbe(
MappedImage,
CfgConfig->GuardLongJumpTable,
CfgConfig->EntrySize * CfgConfig->NumberOfGuardLongJumpEntries
);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return GetExceptionCode();
}
}

return STATUS_SUCCESS;
}


NTSTATUS PhGetMappedImageCfgEntry(
_In_ PPH_MAPPED_IMAGE_CFG CfgConfig,
_In_ ULONGLONG Index,
_In_ PH_MAPPED_ARCHIVE_MEMBER_TYPE Type,
_Out_ PPH_MAPPED_IMAGE_CFG_ENTRY Entry
)
{
PULONGLONG GuardTable;
ULONGLONG NumberofGuardEntries;
PPH_MAPPED_IMAGE_CFG_ENTRY cfgMappedEntry;

switch (Type)
{
case ControlFlowGuardFunction :
{
GuardTable = CfgConfig->GuardFunctionTable;
NumberofGuardEntries = CfgConfig->NumberOfGuardFunctionEntries;
}
break;
case ControlFlowGuardtakenIatEntry :
{
GuardTable = CfgConfig->GuardAdressIatTable;
NumberofGuardEntries = CfgConfig->NumberOfGuardAdressIatEntries;
}
break;
case ControlFlowGuardLongJump :
{
GuardTable = CfgConfig->GuardLongJumpTable;
NumberofGuardEntries = CfgConfig->NumberOfGuardLongJumpEntries;
}
break;
default:
return STATUS_INVALID_PARAMETER_3;
}

if ((!GuardTable) || (Index >= NumberofGuardEntries))
return STATUS_PROCEDURE_NOT_FOUND;

cfgMappedEntry = (PPH_MAPPED_IMAGE_CFG_ENTRY) PTR_ADD_OFFSET(GuardTable, Index*CfgConfig->EntrySize);

Entry->Rva = cfgMappedEntry->Rva;
memset(&Entry->Flags ,0, sizeof(Entry->Flags));

// Optional header after the rva entry
if (CfgConfig->EntrySize > sizeof(FIELD_OFFSET(PH_MAPPED_IMAGE_CFG_ENTRY, Rva)))
Entry->Flags = cfgMappedEntry->Flags;

return STATUS_SUCCESS;
}