rizin/librz/arch/objc_rtti.c
Naren Sirigere 22ce81d719
Fix Objective-C RTTI superclass decoding on big endian (#6588)
Fix Coverity issues: 910855, 910854
2026-07-03 10:40:33 +08:00

73 lines
2.3 KiB
C

// SPDX-FileCopyrightText: 2025 tushar3q34 <tushar3q34@gmail.com>
// SPDX-FileCopyrightText: 2026 historicattle <sirigere.naren@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
#include "analysis_private.h"
static const RzBinSymbol *get_objc_superclass(RzAnalysis *analysis, const RzPVector /*<RzBinSymbol *>*/ *symbols, const RzBinSymbol *meta_info) {
ut8 buf[8];
if (!analysis->iob.read_at(analysis->iob.io, meta_info->vaddr + 8, buf, sizeof(buf))) {
return NULL;
}
ut64 addr = rz_read_ble64(buf, analysis->big_endian);
void **it;
rz_pvector_foreach (symbols, it) {
RzBinSymbol *super_meta = *it;
if (!super_meta) {
continue;
}
if (super_meta->vaddr == addr) {
return super_meta;
}
}
return NULL;
}
static void add_objc_superclass(RzAnalysis *analysis, RzPVector /*<SdbKv *>*/ *classes, RzBinSymbol *meta_class, const RzBinSymbol *meta_superclass) {
if (!strstr(meta_superclass->name, "_OBJC_METACLASS_$_")) {
return;
}
// meta class info symbol is of the form _OBJC_METACLASS_$_<class_name>
const size_t meta_len = strlen("_OBJC_METACLASS_$_");
char *class_name = meta_class->name + meta_len;
char *superclass_name = rz_str_dup(meta_superclass->name + meta_len);
RzAnalysisBaseClass base = { .class_name = superclass_name, .offset = 0 };
rz_analysis_class_base_set(analysis, class_name, &base);
rz_analysis_class_base_fini(&base);
}
/**
* \brief Recover Objective-C Runtime Type Information (RTTI)
*
* This function iterates over the binary symbols to find Objective-C
* metaclass structures and reconstructs the class hierarchy
*
* \param analysis Pointer to the RzAnalysis structure
*/
RZ_API void rz_analysis_rtti_objc(RZ_NONNULL RzAnalysis *analysis) {
RzPVector *classes = rz_analysis_class_get_all(analysis, false);
if (!classes) {
return;
}
RzBinObject *o = rz_bin_cur_object(analysis->binb.bin);
if (!o) {
return;
}
const RzPVector *symbols = rz_bin_object_get_symbols(o);
void **it;
rz_pvector_foreach (symbols, it) {
RzBinSymbol *sym = *it;
if (!sym) {
continue;
}
const RzBinSymbol *meta_superclass = NULL;
if (strstr(sym->name, "_OBJC_METACLASS_$_")) {
meta_superclass = get_objc_superclass(analysis, symbols, sym);
}
if (meta_superclass) {
add_objc_superclass(analysis, classes, sym, meta_superclass);
}
}
rz_pvector_free(classes);
}