} BOOLEAN PhGetMappedImageSectionName( _In_ PIMAGE_SECTION_HEADER Section, _Out_writes_opt_z_(Count) PSTR Buffer, _In_ ULONG Count, _Out_opt_ PULONG ReturnCount ) { BOOLEAN result; SIZE_T returnCount; result = PhCopyBytesZ( Section->Name, IMAGE_SIZEOF_SHORT_NAME, Buffer, Count, &returnCount ); if (ReturnCount) *ReturnCount = (ULONG)returnCount; return result; } NTSTATUS PhGetMappedImageDataEntry( _In_ PPH_MAPPED_IMAGE MappedImage, _In_ ULONG Index, _Out_ PIMAGE_DATA_DIRECTORY *Entry )
NTSTATUS PhpGetMappedArchiveMemberFromHeader( _In_ PPH_MAPPED_ARCHIVE MappedArchive, _In_ PIMAGE_ARCHIVE_MEMBER_HEADER Header, _Out_ PPH_MAPPED_ARCHIVE_MEMBER Member ) { WCHAR integerString[11]; ULONG64 size; PH_STRINGREF string; PWSTR digit; PSTR slash; if ((ULONG_PTR)Header >= (ULONG_PTR)MappedArchive->ViewBase + MappedArchive->Size) return STATUS_NO_MORE_ENTRIES; __try { PhpMappedArchiveProbe(MappedArchive, Header, sizeof(IMAGE_ARCHIVE_MEMBER_HEADER)); } __except (EXCEPTION_EXECUTE_HANDLER) { return GetExceptionCode(); } Member->MappedArchive = MappedArchive; Member->Header = Header; Member->Data = PTR_ADD_OFFSET(Header, sizeof(IMAGE_ARCHIVE_MEMBER_HEADER)); Member->Type = NormalArchiveMemberType; // Read the size string, terminate it after the last digit and parse it. if (!PhCopyStringZFromBytes(Header->Size, 10, integerString, 11, NULL)) return STATUS_INVALID_PARAMETER; string.Buffer = integerString; string.Length = 0; digit = string.Buffer; while (iswdigit(*digit++)) string.Length += sizeof(WCHAR); if (!PhStringToInteger64(&string, 10, &size)) return STATUS_INVALID_PARAMETER; Member->Size = (ULONG)size; __try { PhpMappedArchiveProbe(MappedArchive, Member->Data, Member->Size); } __except (EXCEPTION_EXECUTE_HANDLER) { return GetExceptionCode(); } // Parse the name. if (!PhCopyBytesZ(Header->Name, 16, Member->NameBuffer, 20, NULL)) return STATUS_INVALID_PARAMETER; Member->Name = Member->NameBuffer; slash = strchr(Member->NameBuffer, '/'); if (!slash) return STATUS_INVALID_PARAMETER; // Special names: // * If the slash is the first character, then this is a linker member. // * If there is a slash after the slash which is a first character, then this is the longnames // member. // * If there are digits after the slash, then the real name is stored in the longnames member. if (slash == Member->NameBuffer) { if (Member->NameBuffer[1] == '/') { // Longnames member. Set the name to "/". Member->NameBuffer[0] = '/'; Member->NameBuffer[1] = 0; Member->Type = LongnamesArchiveMemberType; } else { // Linker member. Set the name to "". Member->NameBuffer[0] = 0; Member->Type = LinkerArchiveMemberType; } } else { if (isdigit(slash[1])) { PSTR digita; ULONG64 offset64; ULONG offset; // The name is stored in the longnames member. // Note: we make sure we have the longnames member first. if (!MappedArchive->LongnamesMember.Header) return STATUS_INVALID_PARAMETER; // Find the last digit and null terminate the string there. digita = slash + 2; while (isdigit(*digita)) digita++; *digita = 0; // Parse the offset and make sure it lies within the longnames member. if (!PhCopyStringZFromBytes(slash + 1, -1, integerString, 11, NULL)) return STATUS_INVALID_PARAMETER; PhInitializeStringRefLongHint(&string, integerString); if (!PhStringToInteger64(&string, 10, &offset64)) return STATUS_INVALID_PARAMETER; offset = (ULONG)offset64; if (offset >= MappedArchive->LongnamesMember.Size) return STATUS_INVALID_PARAMETER; // TODO: Probe the name. Member->Name = (PSTR)PTR_ADD_OFFSET(MappedArchive->LongnamesMember.Data, offset); } else { // Null terminate the string. slash[0] = 0; } } return STATUS_SUCCESS; }