diff options
| author | Mason Reed <mason@vector35.com> | 2026-05-26 17:15:49 -0400 |
|---|---|---|
| committer | Mason Reed <35282038+emesare@users.noreply.github.com> | 2026-05-28 14:09:06 -0400 |
| commit | 912465b5cf1d0442443d9584e15111361f27751c (patch) | |
| tree | 0aa025f8b6b2e5e3ef51b121c727ce64ab5dd293 | |
| parent | c1a970b68f70d536d8196c07e9163c1ef41ed5c8 (diff) | |
[Objective-C] Fix misc crashes for bad input binaries
Fixes https://github.com/Vector35/binaryninja/issues/1470
| -rw-r--r-- | objectivec/objc.cpp | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/objectivec/objc.cpp b/objectivec/objc.cpp index 6575ed51..1b53a366 100644 --- a/objectivec/objc.cpp +++ b/objectivec/objc.cpp @@ -6,6 +6,10 @@ #define RELEASE_ASSERT(condition) ((condition) ? (void)0 : (std::abort(), (void)0)) +#define MAX_PROTOCOL_COUNT 0x1000 +#define MAX_METHOD_LIST_COUNT 0x1000 +#define MAX_IVAR_LIST_COUNT 0x1000 + using namespace BinaryNinja; namespace { @@ -847,6 +851,11 @@ void ObjCProcessor::LoadProtocols(ObjCReader* reader, Ref<Section> listSection) "protoProtocols_" + protocolName, protocol.protocols, true); reader->Seek(protocol.protocols); uint32_t count = reader->Read64(); + if (count > MAX_PROTOCOL_COUNT) + { + m_logger->LogWarn("List of protocols at 0x%llx has too large a count of 0x%x, skipping...", protocol.protocols, count); + continue; + } view_ptr_t addr = reader->GetOffset(); for (uint32_t j = 0; j < count; j++) { @@ -928,7 +937,7 @@ void ObjCProcessor::ReadListOfMethodLists(ObjCReader* reader, ClassBase& cls, st head.entsizeAndFlags = reader->Read32(); head.count = reader->Read32(); - if (head.count > 0x1000) + if (head.count > MAX_METHOD_LIST_COUNT) { m_logger->LogError("List of method lists at 0x%llx has an invalid count of 0x%x", start, head.count); return; @@ -962,7 +971,7 @@ void ObjCProcessor::ReadMethodList(ObjCReader* reader, ClassBase& cls, std::stri head.entsizeAndFlags = reader->Read32(); head.count = reader->Read32(); - if (head.count > 0x1000) + if (head.count > MAX_METHOD_LIST_COUNT) { m_logger->LogError("Method list at 0x%llx has an invalid count of 0x%x", start, head.count); return; @@ -1066,6 +1075,11 @@ void ObjCProcessor::ReadIvarList(ObjCReader* reader, ClassBase& cls, std::string ivar_list_t head; head.entsizeAndFlags = reader->Read32(); head.count = reader->Read32(); + if (head.count > MAX_IVAR_LIST_COUNT) + { + m_logger->LogWarn("Ivar list at 0x%llx has an invalid count of 0x%x, skipping..", start, head.count); + return; + } auto addressSize = m_data->GetAddressSize(); DefineObjCSymbol(DataSymbol, m_typeNames.ivarList, "ivar_list_" + std::string(name), start, true); for (unsigned i = 0; i < head.count; i++) @@ -1681,6 +1695,11 @@ void ObjCProcessor::ProcessCFStrings() uint64_t flags = reader->ReadPointer(); auto strLoc = ReadPointerAccountingForRelocations(reader.get()); auto size = reader->ReadPointer(); + if (size > cfstrings->GetEnd() || reader->GetOffset() > cfstrings->GetEnd() - size) + { + m_logger->LogWarn("CFString at 0x%llx has invalid size 0x%llx, skipping...", i, size); + continue; + } std::string str; if (flags & 0b10000) // UTF16 { |
