73 lines
2.3 KiB
C
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);
|
|
}
|