|
6 | 6 |
|
7 | 7 | #define RELEASE_ASSERT(condition) ((condition) ? (void)0 : (std::abort(), (void)0)) |
8 | 8 |
|
| 9 | +#define MAX_PROTOCOL_COUNT 0x1000 |
| 10 | +#define MAX_METHOD_LIST_COUNT 0x1000 |
| 11 | +#define MAX_IVAR_LIST_COUNT 0x1000 |
| 12 | + |
9 | 13 | using namespace BinaryNinja; |
10 | 14 |
|
11 | 15 | namespace { |
@@ -847,6 +851,11 @@ void ObjCProcessor::LoadProtocols(ObjCReader* reader, Ref<Section> listSection) |
847 | 851 | "protoProtocols_" + protocolName, protocol.protocols, true); |
848 | 852 | reader->Seek(protocol.protocols); |
849 | 853 | uint32_t count = reader->Read64(); |
| 854 | + if (count > MAX_PROTOCOL_COUNT) |
| 855 | + { |
| 856 | + m_logger->LogWarn("List of protocols at 0x%llx has too large a count of 0x%x, skipping...", protocol.protocols, count); |
| 857 | + continue; |
| 858 | + } |
850 | 859 | view_ptr_t addr = reader->GetOffset(); |
851 | 860 | for (uint32_t j = 0; j < count; j++) |
852 | 861 | { |
@@ -928,7 +937,7 @@ void ObjCProcessor::ReadListOfMethodLists(ObjCReader* reader, ClassBase& cls, st |
928 | 937 | head.entsizeAndFlags = reader->Read32(); |
929 | 938 | head.count = reader->Read32(); |
930 | 939 |
|
931 | | - if (head.count > 0x1000) |
| 940 | + if (head.count > MAX_METHOD_LIST_COUNT) |
932 | 941 | { |
933 | 942 | m_logger->LogError("List of method lists at 0x%llx has an invalid count of 0x%x", start, head.count); |
934 | 943 | return; |
@@ -962,7 +971,7 @@ void ObjCProcessor::ReadMethodList(ObjCReader* reader, ClassBase& cls, std::stri |
962 | 971 | head.entsizeAndFlags = reader->Read32(); |
963 | 972 | head.count = reader->Read32(); |
964 | 973 |
|
965 | | - if (head.count > 0x1000) |
| 974 | + if (head.count > MAX_METHOD_LIST_COUNT) |
966 | 975 | { |
967 | 976 | m_logger->LogError("Method list at 0x%llx has an invalid count of 0x%x", start, head.count); |
968 | 977 | return; |
@@ -1066,6 +1075,11 @@ void ObjCProcessor::ReadIvarList(ObjCReader* reader, ClassBase& cls, std::string |
1066 | 1075 | ivar_list_t head; |
1067 | 1076 | head.entsizeAndFlags = reader->Read32(); |
1068 | 1077 | head.count = reader->Read32(); |
| 1078 | + if (head.count > MAX_IVAR_LIST_COUNT) |
| 1079 | + { |
| 1080 | + m_logger->LogWarn("Ivar list at 0x%llx has an invalid count of 0x%x, skipping..", start, head.count); |
| 1081 | + return; |
| 1082 | + } |
1069 | 1083 | auto addressSize = m_data->GetAddressSize(); |
1070 | 1084 | DefineObjCSymbol(DataSymbol, m_typeNames.ivarList, "ivar_list_" + std::string(name), start, true); |
1071 | 1085 | for (unsigned i = 0; i < head.count; i++) |
@@ -1681,6 +1695,11 @@ void ObjCProcessor::ProcessCFStrings() |
1681 | 1695 | uint64_t flags = reader->ReadPointer(); |
1682 | 1696 | auto strLoc = ReadPointerAccountingForRelocations(reader.get()); |
1683 | 1697 | auto size = reader->ReadPointer(); |
| 1698 | + if (reader->GetOffset() + size > cfstrings->GetEnd()) |
| 1699 | + { |
| 1700 | + m_logger->LogWarn("CFString at 0x%llx has invalid size 0x%llx, skipping...", i, size); |
| 1701 | + continue; |
| 1702 | + } |
1684 | 1703 | std::string str; |
1685 | 1704 | if (flags & 0b10000) // UTF16 |
1686 | 1705 | { |
|
0 commit comments