Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions objectivec/objc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Comment thread
emesare marked this conversation as resolved.
}
view_ptr_t addr = reader->GetOffset();
for (uint32_t j = 0; j < count; j++)
{
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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++)
Expand Down Expand Up @@ -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
{
Expand Down
3 changes: 3 additions & 0 deletions platform/windows/platform_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class WindowsX64Platform: public Platform
{
uint32_t m_gsbase;
Ref<Type> m_teb;
std::mutex m_tebMutex;

public:
WindowsX64Platform(Architecture* arch): Platform(arch, "windows-x86_64")
Expand All @@ -113,6 +114,8 @@ class WindowsX64Platform: public Platform

virtual void BinaryViewInit(BinaryView* view) override
{
// Locking here so that if we have two views in BinaryViewInit at once we don't race to init m_teb.
std::lock_guard<std::mutex> lock(m_tebMutex);
if (!m_teb)
m_teb = Type::PointerType(GetArchitecture()->GetAddressSize(), Type::NamedType(QualifiedName("TEB"), GetTypeByName(QualifiedName("TEB"))));
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/rtti/itanium.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ void ItaniumRTTIProcessor::ProcessRTTI()
int failedAttempts = 0;
for (uint64_t currAddr = section->GetStart(); currAddr <= section->GetEnd() - maxTypeInfoSize; currAddr += addrSize)
{
if (bgTask->IsCancelled())
if (bgTask->IsCancelled() || !m_view->IsValidOffset(currAddr))
break;
try
{
Expand Down
7 changes: 5 additions & 2 deletions plugins/warp/ui/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <QToolBar>
#include <QVBoxLayout>
#include <QtCore/QMetaObject>
#include <utility>

using namespace BinaryNinja;
Expand Down Expand Up @@ -170,11 +171,13 @@ WarpSidebarWidget::WarpSidebarWidget(BinaryViewRef data) : SidebarWidget("WARP")
this->setLayout(layout);

// Do a full update if analysis has been done, otherwise we may persist old data and not have new data.
m_analysisEvent = new AnalysisCompletionEvent(m_data, [this]() { ExecuteOnMainThread([this]() { Update(); }); });
m_analysisEvent = new AnalysisCompletionEvent(m_data, [this]() {
QMetaObject::invokeMethod(this, [this]() { Update(); });
});

m_fetcher = WarpFetcher::Global();
m_callbackId = m_fetcher->AddCompletionCallback([this]() {
ExecuteOnMainThread([this]() {
QMetaObject::invokeMethod(this, [this]() {
// Instead of doing a full update after fetching, we only want to make sure the current function has
// up-to-date matches, since the other two tabs (all matches, container list) do not get populated with
// additional information or manage their own updates (e.g. container source list).
Expand Down
6 changes: 5 additions & 1 deletion rust/src/architecture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1776,7 +1776,11 @@ where
};

let mut ctx = unsafe {
FunctionLifterContext::from_raw_with_arch(function, context, Some(*custom_arch.as_ref()))
FunctionLifterContext::from_raw_with_arch(
function,
context,
Some(*custom_arch.as_ref()),
)
};
custom_arch.lift_function(llil, &mut ctx)
}
Expand Down
5 changes: 5 additions & 0 deletions view/elf/elfview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,11 @@ bool ElfView::Init()
for (uint64_t i = firstMipsSym; i < (m_auxSymbolTable.size / (m_elf32 ? 16 : 24)); i++)
{
uint64_t gotEntry = gotStart + ((localMipsSyms + i - firstMipsSym) * (m_elf32 ? 4 : 8));
if (!IsValidOffset(gotEntry))
{
m_logger->LogWarn("ELF GOT entry %" PRIx64 " is invalid", gotEntry);
break;
}

ElfSymbolTableEntry entry;
if (!ParseSymbolTableEntry(virtualReader, entry, i, m_auxSymbolTable, m_dynamicStringTable, true))
Expand Down
9 changes: 7 additions & 2 deletions view/pe/peview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1753,10 +1753,15 @@ bool PEView::Init()
}
}

if (m_dataDirs[IMAGE_DIRECTORY_ENTRY_EXCEPTION].size % entrySize)
const auto& exceptionDir = m_dataDirs[IMAGE_DIRECTORY_ENTRY_EXCEPTION];
if (exceptionDir.size % entrySize)
throw PEFormatException("invalid table size");
numExceptionEntries = m_dataDirs[IMAGE_DIRECTORY_ENTRY_EXCEPTION].size / entrySize;
const auto imageSize = GetEnd() - GetStart();
if ((exceptionDir.virtualAddress > imageSize)
|| (exceptionDir.size > (imageSize - exceptionDir.virtualAddress)))
throw PEFormatException("too many exception entries, table size exceeds available memory range");

numExceptionEntries = exceptionDir.size / entrySize;
// This DataVariable can end up creating a large array and rendering this in LinearView currently has performance implications
// So instead we just create separate structures not in an array
Ref<Structure> exceptionEntryStruct = exceptionEntryBuilder.Finalize();
Expand Down
Loading