mirror of
https://github.com/radareorg/r2unity.git
synced 2026-11-07 06:36:00 -10:00
Add typed IL2CPP method metadata
This commit is contained in:
1 parent
80701514cd
commit
57cda9236e
6 files changed
+289
-36
No files matched your search
+8
-4
@@ -355,10 +355,14 @@ int32_t customAttributeIndex; /* removed at v24.1 */
|
||||
int32_t typeIndex; /* -> MetadataRegistration.types */
|
||||
```
|
||||
|
||||
Not decoded by r2unity today. Without it, every dumped method
|
||||
degrades to `Method()` with no parameter types or names. Combined
|
||||
with `parameterDefaultValues` (§2.4) this is what reconstructs real
|
||||
C# signatures like `Foo(string name, int count = 0)`.
|
||||
r2unity decodes this table and exposes parameter tokens, names, and
|
||||
type indices in `r2unity-sj`; it also emits a canonical signature such
|
||||
as `Namespace.Type.Foo(this;string:name,int:count):void`. Type indices
|
||||
that refer directly to a type definition are resolved to source names.
|
||||
Pointer, array, and constructed-generic indices still require the native
|
||||
`MetadataRegistration.types` table and use `type_index.N` until that
|
||||
table is available. `parameterDefaultValues` (§2.4) remains necessary
|
||||
to reconstruct optional values such as `int count = 0`.
|
||||
|
||||
### 2.4 Default values: `fieldDefaultValues`, `parameterDefaultValues`,
|
||||
`fieldAndParameterDefaultValueData`
|
||||
|
||||
+1
-1
@@ -119,7 +119,7 @@ Still missing:
|
||||
|
||||
Add or improve decoding for:
|
||||
|
||||
- parameters and full method signatures
|
||||
- generic method/type substitutions in signatures
|
||||
- default values for fields and parameters
|
||||
- properties and events
|
||||
- nested types
|
||||
|
||||
+125
@@ -295,6 +295,12 @@ static ut64 field_definition_entry_size(R2UnityMetadata *meta) {
|
||||
return 4 + type_index_size + 4;
|
||||
}
|
||||
|
||||
static ut64 parameter_definition_entry_size(R2UnityMetadata *meta) {
|
||||
const bool compact_indices = (meta->version >= 35);
|
||||
const int type_index_size = compact_indices? meta->typeIndexSize: 4;
|
||||
return 4 + 4 + type_index_size;
|
||||
}
|
||||
|
||||
/* Detect v24.0 vs v24.1+ (both land on disk as version==24).
|
||||
*
|
||||
* At v24.1 the ImageDefinition row grew by 8 bytes (added
|
||||
@@ -507,6 +513,8 @@ R_API ut64 r2unity_metadata_section_entry_size(R2UnityMetadata *meta, R2UMetadat
|
||||
return method_definition_entry_size (meta);
|
||||
case R2U_SEC_FIELDS:
|
||||
return field_definition_entry_size (meta);
|
||||
case R2U_SEC_PARAMETERS:
|
||||
return parameter_definition_entry_size (meta);
|
||||
case R2U_SEC_TYPE_DEFINITIONS:
|
||||
return type_definition_entry_size (meta);
|
||||
case R2U_SEC_IMAGES:
|
||||
@@ -820,6 +828,123 @@ R_API Il2CppFieldDefinition *r2unity_get_field_definitions(R2UnityMetadata *meta
|
||||
return fields;
|
||||
}
|
||||
|
||||
R_API Il2CppParameterDefinition *r2unity_get_parameter_definitions(R2UnityMetadata *meta, size_t *count) {
|
||||
R_RETURN_VAL_IF_FAIL (meta && count, NULL);
|
||||
const bool compact_indices = (meta->version >= 35);
|
||||
const int type_index_size = compact_indices? meta->typeIndexSize: 4;
|
||||
const ut64 entry = parameter_definition_entry_size (meta);
|
||||
ut8 *buf = read_metadata_table (meta, R2U_SEC_PARAMETERS, entry, count);
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
Il2CppParameterDefinition *parameters = R_NEWS (Il2CppParameterDefinition, *count);
|
||||
if (!parameters) {
|
||||
R_FREE (buf);
|
||||
return NULL;
|
||||
}
|
||||
for (size_t i = 0; i < *count; i++) {
|
||||
const ut8 *p = buf + i * entry;
|
||||
parameters[i].nameIndex = read_u32p (&p);
|
||||
parameters[i].token = read_u32p (&p);
|
||||
parameters[i].typeIndex = read_indexp (&p, type_index_size);
|
||||
}
|
||||
R_FREE (buf);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
static const char *csharp_type_alias(const char *name) {
|
||||
static const struct {
|
||||
const char *fullname;
|
||||
const char *alias;
|
||||
} aliases[] = {
|
||||
{ "System.Void", "void" },
|
||||
{ "System.Boolean", "bool" },
|
||||
{ "System.Byte", "byte" },
|
||||
{ "System.SByte", "sbyte" },
|
||||
{ "System.Char", "char" },
|
||||
{ "System.Decimal", "decimal" },
|
||||
{ "System.Double", "double" },
|
||||
{ "System.Single", "float" },
|
||||
{ "System.Int16", "short" },
|
||||
{ "System.UInt16", "ushort" },
|
||||
{ "System.Int32", "int" },
|
||||
{ "System.UInt32", "uint" },
|
||||
{ "System.Int64", "long" },
|
||||
{ "System.UInt64", "ulong" },
|
||||
{ "System.IntPtr", "nint" },
|
||||
{ "System.UIntPtr", "nuint" },
|
||||
{ "System.Object", "object" },
|
||||
{ "System.String", "string" },
|
||||
};
|
||||
for (size_t i = 0; i < R_ARRAY_SIZE (aliases); i++) {
|
||||
if (!strcmp (name, aliases[i].fullname)) {
|
||||
return aliases[i].alias;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API char *r2unity_type_name_from_index(R2UnityMetadata *meta, const Il2CppTypeDefinition *types, size_t type_count, int32_t type_index, bool fallback) {
|
||||
R_RETURN_VAL_IF_FAIL (meta, NULL);
|
||||
if (type_index >= 0) {
|
||||
for (size_t i = 0; types && i < type_count; i++) {
|
||||
if (types[i].byvalTypeIndex != type_index) {
|
||||
continue;
|
||||
}
|
||||
char *name = r2unity_type_fullname (meta, &types[i], i, R2U_NAME_FALLBACK_TYPE);
|
||||
if (name) {
|
||||
const char *alias = csharp_type_alias (name);
|
||||
if (alias) {
|
||||
free (name);
|
||||
return strdup (alias);
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return fallback? r_str_newf ("type_index.%d", type_index): NULL;
|
||||
}
|
||||
|
||||
R_API char *r2unity_method_signature(R2UnityMetadata *meta, const Il2CppMethodDefinition *method, const Il2CppTypeDefinition *owner, size_t owner_index, const Il2CppTypeDefinition *types, size_t type_count, const Il2CppParameterDefinition *parameters, size_t parameter_count, bool fallback) {
|
||||
R_RETURN_VAL_IF_FAIL (meta && method, NULL);
|
||||
char *return_type = r2unity_type_name_from_index (meta, types, type_count, method->returnType, fallback);
|
||||
char *method_name = r2unity_method_fullname (meta, method, owner, owner_index,
|
||||
fallback? R2U_NAME_FALLBACK_TYPE: 0);
|
||||
if (!method_name) {
|
||||
free (return_type);
|
||||
return NULL;
|
||||
}
|
||||
RStrBuf *sb = r_strbuf_new (method_name);
|
||||
r_strbuf_append (sb, "(");
|
||||
bool is_instance = !(method->flags & 0x0010);
|
||||
if (is_instance) {
|
||||
r_strbuf_append (sb, "this;");
|
||||
}
|
||||
for (size_t i = 0; i < method->parameterCount; i++) {
|
||||
st64 pi = (st64)method->parameterStart + (st64)i;
|
||||
const Il2CppParameterDefinition *parameter = parameters
|
||||
&& pi >= 0 && (ut64)pi < parameter_count
|
||||
? ¶meters[pi]: NULL;
|
||||
char *type_name = parameter
|
||||
? r2unity_type_name_from_index (meta, types, type_count, parameter->typeIndex, fallback)
|
||||
: NULL;
|
||||
char *parameter_name = parameter? r2unity_get_string (meta, parameter->nameIndex): NULL;
|
||||
r_strbuf_appendf (sb, "%s%s", i? ",": "",
|
||||
type_name? type_name: "unknown");
|
||||
if (R_STR_ISNOTEMPTY (parameter_name)) {
|
||||
r_strbuf_appendf (sb, ":%s", parameter_name);
|
||||
} else {
|
||||
r_strbuf_appendf (sb, ":arg%zu", i);
|
||||
}
|
||||
free (parameter_name);
|
||||
free (type_name);
|
||||
}
|
||||
r_strbuf_appendf (sb, "):%s", return_type? return_type: "unknown");
|
||||
free (method_name);
|
||||
free (return_type);
|
||||
return r_strbuf_drain (sb);
|
||||
}
|
||||
|
||||
R_API int32_t *r2unity_get_type_index_table(R2UnityMetadata *meta, R2UMetadataSectionId id, size_t *count) {
|
||||
R_RETURN_VAL_IF_FAIL (meta && count, NULL);
|
||||
const bool compact_indices = (meta->version >= 35);
|
||||
|
||||
@@ -130,6 +130,12 @@ typedef struct {
|
||||
uint32_t token;
|
||||
} Il2CppFieldDefinition;
|
||||
|
||||
typedef struct {
|
||||
uint32_t nameIndex;
|
||||
uint32_t token;
|
||||
int32_t typeIndex;
|
||||
} Il2CppParameterDefinition;
|
||||
|
||||
typedef struct {
|
||||
uint32_t nameIndex;
|
||||
int32_t assemblyIndex;
|
||||
@@ -264,6 +270,9 @@ R_API bool r2unity_read_string_literal(R2UnityMetadata *meta, const Il2CppString
|
||||
R_API Il2CppTypeDefinition *r2unity_get_type_definitions(R2UnityMetadata *meta, size_t *count);
|
||||
R_API Il2CppMethodDefinition *r2unity_get_method_definitions(R2UnityMetadata *meta, size_t *count);
|
||||
R_API Il2CppFieldDefinition *r2unity_get_field_definitions(R2UnityMetadata *meta, size_t *count);
|
||||
R_API Il2CppParameterDefinition *r2unity_get_parameter_definitions(R2UnityMetadata *meta, size_t *count);
|
||||
R_API char *r2unity_type_name_from_index(R2UnityMetadata *meta, const Il2CppTypeDefinition *types, size_t type_count, int32_t type_index, bool fallback);
|
||||
R_API char *r2unity_method_signature(R2UnityMetadata *meta, const Il2CppMethodDefinition *method, const Il2CppTypeDefinition *owner, size_t owner_index, const Il2CppTypeDefinition *types, size_t type_count, const Il2CppParameterDefinition *parameters, size_t parameter_count, bool fallback);
|
||||
R_API int32_t *r2unity_get_type_index_table(R2UnityMetadata *meta, R2UMetadataSectionId id, size_t *count);
|
||||
R_API Il2CppImageDefinition *r2unity_get_images(R2UnityMetadata *meta, size_t *count);
|
||||
R_API int *r2unity_build_type_image_map(const Il2CppImageDefinition *images, size_t image_count, size_t type_count);
|
||||
|
||||
+101
-4
@@ -835,17 +835,32 @@ static RBinSymbol *new_symbol(const char *name, ut64 paddr, ut64 size, const cha
|
||||
if (!sym) {
|
||||
return NULL;
|
||||
}
|
||||
#if R2_ABIVERSION >= 138
|
||||
sym->attr.size = (ut32)R_MIN (size, UT32_MAX);
|
||||
sym->attr.flags = attr;
|
||||
sym->attr.lang = R_BIN_LANG_NONE;
|
||||
#else
|
||||
sym->size = (ut32)R_MIN (size, UT32_MAX);
|
||||
sym->type = type;
|
||||
sym->attr = attr;
|
||||
sym->ordinal = ordinal;
|
||||
sym->lang = R_BIN_LANG_NONE;
|
||||
#endif
|
||||
sym->type = type;
|
||||
sym->ordinal = ordinal;
|
||||
if (classname) {
|
||||
sym->classname = strdup (classname);
|
||||
}
|
||||
return sym;
|
||||
}
|
||||
|
||||
static void set_symbol_signature(RBinSymbol *sym, const char *name, const char *signature) {
|
||||
if (!sym || !sym->name || !name || !signature) {
|
||||
return;
|
||||
}
|
||||
free (sym->name->name);
|
||||
sym->name->name = strdup (name);
|
||||
r_bin_name_update (sym->name, signature);
|
||||
}
|
||||
|
||||
#if R2UNITY_BIN_VEC_ABI
|
||||
typedef RVecRBinSymbol R2UnitySymbolSink;
|
||||
|
||||
@@ -1016,6 +1031,8 @@ static bool symbols_fill(RBinFile *bf, R2UnitySymbolSink *ret) {
|
||||
|
||||
size_t method_count = 0;
|
||||
Il2CppMethodDefinition *methods = r2unity_get_method_definitions (meta, &method_count);
|
||||
size_t parameter_count = 0;
|
||||
Il2CppParameterDefinition *parameters = r2unity_get_parameter_definitions (meta, ¶meter_count);
|
||||
ut64 method_entry = r2unity_metadata_section_entry_size (meta, R2U_SEC_METHODS);
|
||||
Il2CppMetadataSection method_sec;
|
||||
r2unity_metadata_section (meta, R2U_SEC_METHODS, &method_sec);
|
||||
@@ -1036,12 +1053,29 @@ static bool symbols_fill(RBinFile *bf, R2UnitySymbolSink *ret) {
|
||||
classname = r2unity_type_fullname (meta, td, type_idx, R2U_NAME_FALLBACK_TYPE);
|
||||
}
|
||||
RBinSymbol *sym = new_symbol (name, method_sec.offset + i * method_entry, method_entry, R_BIN_TYPE_METH_STR, method_attr (methods[i].flags, mn), classname, ordinal++);
|
||||
if (sym) {
|
||||
char *signature = r2unity_method_signature (meta, &methods[i], td, type_idx,
|
||||
types, type_count, parameters, parameter_count, true);
|
||||
set_symbol_signature (sym, name, signature);
|
||||
free (signature);
|
||||
sym->rtype = r2unity_type_name_from_index (meta, types, type_count,
|
||||
methods[i].returnType, true);
|
||||
#if R2_ABIVERSION >= 138
|
||||
sym->attr.lang = R_BIN_LANG_CIL;
|
||||
sym->arg_count = methods[i].parameterCount
|
||||
+ ((methods[i].flags & 0x0010)? 0: 1);
|
||||
sym->cc_arg_count = sym->arg_count;
|
||||
sym->ret_count = sym->rtype && !strcmp (sym->rtype, "void")? 0: 1;
|
||||
sym->arg_prefix = "a";
|
||||
#endif
|
||||
}
|
||||
append_symbol (ret, sym);
|
||||
free (classname);
|
||||
free (mn);
|
||||
free (name);
|
||||
}
|
||||
|
||||
R_FREE (parameters);
|
||||
R_FREE (methods);
|
||||
R_FREE (types);
|
||||
R_FREE (asms);
|
||||
@@ -1087,7 +1121,11 @@ static RList *classes(RBinFile *bf) {
|
||||
if (klass) {
|
||||
klass->index = (int)i;
|
||||
klass->addr = type->offset;
|
||||
#if R2_ABIVERSION >= 138
|
||||
klass->attr.lang = R_BIN_LANG_NONE;
|
||||
#else
|
||||
klass->lang = R_BIN_LANG_NONE;
|
||||
#endif
|
||||
r_list_append (ret, klass);
|
||||
}
|
||||
free (name);
|
||||
@@ -1100,7 +1138,11 @@ static RList *classes(RBinFile *bf) {
|
||||
RBinClass *klass = r_bin_class_new (name, NULL, R_BIN_ATTR_NONE);
|
||||
klass->index = (int)i;
|
||||
klass->addr = obj->bgdb->tables[i].offset;
|
||||
#if R2_ABIVERSION >= 138
|
||||
klass->attr.lang = R_BIN_LANG_NONE;
|
||||
#else
|
||||
klass->lang = R_BIN_LANG_NONE;
|
||||
#endif
|
||||
r_list_append (ret, klass);
|
||||
free (name);
|
||||
}
|
||||
@@ -1115,6 +1157,10 @@ static RList *classes(RBinFile *bf) {
|
||||
Il2CppTypeDefinition *types = r2unity_get_type_definitions (meta, &type_count);
|
||||
size_t method_count = 0;
|
||||
Il2CppMethodDefinition *methods = r2unity_get_method_definitions (meta, &method_count);
|
||||
size_t parameter_count = 0;
|
||||
Il2CppParameterDefinition *parameters = r2unity_get_parameter_definitions (meta, ¶meter_count);
|
||||
size_t field_count = 0;
|
||||
Il2CppFieldDefinition *fields = r2unity_get_field_definitions (meta, &field_count);
|
||||
Il2CppMetadataSection type_sec;
|
||||
Il2CppMetadataSection method_sec;
|
||||
r2unity_metadata_section (meta, R2U_SEC_TYPE_DEFINITIONS, &type_sec);
|
||||
@@ -1125,16 +1171,48 @@ static RList *classes(RBinFile *bf) {
|
||||
for (size_t i = 0; types && i < type_count; i++) {
|
||||
char *ns = get_string (obj, types[i].namespaceIndex);
|
||||
char *tn = get_string (obj, types[i].nameIndex);
|
||||
char *base = r2unity_type_name_from_index (meta, types, type_count,
|
||||
types[i].parentIndex, false);
|
||||
char *fallback = NULL;
|
||||
if (!tn || !*tn) {
|
||||
fallback = r_str_newf ("type.%zu", i);
|
||||
}
|
||||
RBinClass *klass = r_bin_class_new ((tn && *tn)? tn: fallback, NULL, type_attr (types[i].flags));
|
||||
RBinClass *klass = r_bin_class_new ((tn && *tn)? tn: fallback, base, type_attr (types[i].flags));
|
||||
klass->index = (int)i;
|
||||
klass->addr = type_sec.offset + i * type_entry;
|
||||
klass->lang = R_BIN_LANG_NONE;
|
||||
#if R2_ABIVERSION >= 138
|
||||
klass->attr.lang = R_BIN_LANG_CIL;
|
||||
#else
|
||||
klass->lang = R_BIN_LANG_CIL;
|
||||
#endif
|
||||
if (ns && *ns) {
|
||||
#if R2_ABIVERSION >= 138
|
||||
klass->attr.ns = strdup (ns);
|
||||
#else
|
||||
klass->ns = strdup (ns);
|
||||
#endif
|
||||
}
|
||||
int field_start = types[i].fieldStart;
|
||||
int fields_in_type = types[i].field_count;
|
||||
for (int k = 0; fields && k < fields_in_type && field_start >= 0
|
||||
&& (size_t)(field_start + k) < field_count; k++) {
|
||||
size_t fi = (size_t)(field_start + k);
|
||||
char *field_name = get_string (obj, fields[fi].nameIndex);
|
||||
char *field_type = r2unity_type_name_from_index (meta, types, type_count,
|
||||
fields[fi].typeIndex, true);
|
||||
#if R2UNITY_BIN_VEC_ABI
|
||||
RBinField *field = RVecRBinField_emplace_back (&klass->fields);
|
||||
if (field) {
|
||||
field->name = r_bin_name_new (R_STR_ISNOTEMPTY (field_name)? field_name: "field");
|
||||
field->type = r_bin_name_new (R_STR_ISNOTEMPTY (field_type)? field_type: "unknown");
|
||||
#if R2_ABIVERSION >= 138
|
||||
field->attr.kind = R_BIN_FIELD_KIND_FIELD;
|
||||
field->attr.lang = R_BIN_LANG_CIL;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
free (field_type);
|
||||
free (field_name);
|
||||
}
|
||||
int start = types[i].methodStart;
|
||||
int count = types[i].method_count;
|
||||
@@ -1149,16 +1227,35 @@ static RList *classes(RBinFile *bf) {
|
||||
char *mname = r2unity_method_fullname (meta, &methods[mi], td, type_idx, R2U_NAME_WITH_PARAMS | R2U_NAME_FALLBACK_TYPE);
|
||||
char *raw = get_string (obj, methods[mi].nameIndex);
|
||||
RBinSymbol *sym = new_symbol (mname? mname: raw, method_sec.offset + mi * method_entry, method_entry, R_BIN_TYPE_METH_STR, method_attr (methods[mi].flags, raw), NULL, (int)mi);
|
||||
if (sym) {
|
||||
char *signature = r2unity_method_signature (meta, &methods[mi], td, type_idx,
|
||||
types, type_count, parameters, parameter_count, true);
|
||||
set_symbol_signature (sym, mname? mname: raw, signature);
|
||||
free (signature);
|
||||
sym->rtype = r2unity_type_name_from_index (meta, types, type_count,
|
||||
methods[mi].returnType, true);
|
||||
#if R2_ABIVERSION >= 138
|
||||
sym->attr.lang = R_BIN_LANG_CIL;
|
||||
sym->arg_count = methods[mi].parameterCount
|
||||
+ ((methods[mi].flags & 0x0010)? 0: 1);
|
||||
sym->cc_arg_count = sym->arg_count;
|
||||
sym->ret_count = sym->rtype && !strcmp (sym->rtype, "void")? 0: 1;
|
||||
sym->arg_prefix = "a";
|
||||
#endif
|
||||
}
|
||||
append_class_method (klass, sym);
|
||||
free (raw);
|
||||
free (mname);
|
||||
}
|
||||
r_list_append (ret, klass);
|
||||
free (base);
|
||||
free (fallback);
|
||||
free (tn);
|
||||
free (ns);
|
||||
}
|
||||
|
||||
R_FREE (fields);
|
||||
R_FREE (parameters);
|
||||
R_FREE (methods);
|
||||
R_FREE (types);
|
||||
return ret;
|
||||
|
||||
+45
-27
@@ -441,26 +441,8 @@ static bool enrich_reverse_pinvokes_native(RCore *core, R2UnityMetadata *meta, c
|
||||
return path && *path && r2unity_enrich_reverse_pinvokes_native (meta, path, &opts, items, count);
|
||||
}
|
||||
|
||||
static int type_definition_for_type_index(const Il2CppTypeDefinition *types, size_t type_count, int32_t type_index) {
|
||||
if (type_index >= 0) {
|
||||
for (size_t i = 0; i < type_count; i++) {
|
||||
if (types[i].byvalTypeIndex == type_index) {
|
||||
return (int)i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static char *type_name_from_index(R2UnityMetadata *meta, const Il2CppTypeDefinition *types, size_t type_count, int32_t type_index, bool fallback) {
|
||||
int idx = type_definition_for_type_index (types, type_count, type_index);
|
||||
if (idx >= 0) {
|
||||
return r2unity_type_fullname (meta, &types[idx], (size_t)idx, R2U_NAME_FALLBACK_TYPE);
|
||||
}
|
||||
if (fallback && type_index >= 0) {
|
||||
return r_str_newf ("type_index.%d", type_index);
|
||||
}
|
||||
return NULL;
|
||||
return r2unity_type_name_from_index (meta, types, type_count, type_index, fallback);
|
||||
}
|
||||
|
||||
static char *field_name_or_fallback(R2UnityMetadata *meta, const Il2CppFieldDefinition *field, size_t index) {
|
||||
@@ -832,6 +814,8 @@ static int cmd_symbols(RCore *core, char mode) {
|
||||
Il2CppTypeDefinition *types = r2unity_get_type_definitions (meta, &type_count);
|
||||
size_t method_count = 0;
|
||||
Il2CppMethodDefinition *methods = r2unity_get_method_definitions (meta, &method_count);
|
||||
size_t parameter_count = 0;
|
||||
Il2CppParameterDefinition *parameters = r2unity_get_parameter_definitions (meta, ¶meter_count);
|
||||
size_t img_count = 0;
|
||||
Il2CppImageDefinition *images = r2unity_get_images (meta, &img_count);
|
||||
|
||||
@@ -876,12 +860,16 @@ static int cmd_symbols(RCore *core, char mode) {
|
||||
if (!fullname) {
|
||||
continue;
|
||||
}
|
||||
char *signature = r2unity_method_signature (meta, m, td, type_idx,
|
||||
types, type_count, parameters, parameter_count, true);
|
||||
char *return_type = r2unity_type_name_from_index (meta, types, type_count,
|
||||
m->returnType, true);
|
||||
char *imgname = img? r2unity_get_string (meta, img->nameIndex): NULL;
|
||||
char flag_buf[1024];
|
||||
if (imgname && *imgname) {
|
||||
snprintf (flag_buf, sizeof (flag_buf), "sym.unity.%s.%s", imgname, fullname);
|
||||
snprintf (flag_buf, sizeof (flag_buf), "sym.unity.%s.%s.%zu", imgname, fullname, j);
|
||||
} else {
|
||||
snprintf (flag_buf, sizeof (flag_buf), "sym.unity.%s", fullname);
|
||||
snprintf (flag_buf, sizeof (flag_buf), "sym.unity.%s.%zu", fullname, j);
|
||||
}
|
||||
r_name_filter (flag_buf, -1);
|
||||
|
||||
@@ -890,6 +878,33 @@ static int cmd_symbols(RCore *core, char mode) {
|
||||
if (mode == 'j') {
|
||||
pj_o (pj);
|
||||
pj_ks (pj, "name", fullname);
|
||||
pj_kn (pj, "index", (ut64)j);
|
||||
pj_hex (pj, "token", m->token, 8);
|
||||
pj_string_or_null (pj, "signature", signature);
|
||||
pj_string_or_null (pj, "return_type", return_type);
|
||||
pj_kb (pj, "static", (m->flags & 0x0010) != 0);
|
||||
pj_ka (pj, "parameters");
|
||||
for (size_t k = 0; k < m->parameterCount; k++) {
|
||||
st64 pi = (st64)m->parameterStart + (st64)k;
|
||||
const Il2CppParameterDefinition *parameter = pi >= 0 && (ut64)pi < parameter_count
|
||||
? ¶meters[pi]: NULL;
|
||||
char *parameter_name = parameter? r2unity_get_string (meta, parameter->nameIndex): NULL;
|
||||
char *parameter_type = parameter
|
||||
? r2unity_type_name_from_index (meta, types, type_count, parameter->typeIndex, true)
|
||||
: NULL;
|
||||
pj_o (pj);
|
||||
pj_kn (pj, "index", k);
|
||||
if (parameter) {
|
||||
pj_ki (pj, "type_index", parameter->typeIndex);
|
||||
pj_hex (pj, "token", parameter->token, 8);
|
||||
}
|
||||
pj_string_or_null (pj, "name", parameter_name);
|
||||
pj_string_or_null (pj, "type", parameter_type);
|
||||
pj_end (pj);
|
||||
free (parameter_type);
|
||||
free (parameter_name);
|
||||
}
|
||||
pj_end (pj);
|
||||
pj_ks (pj, "flag", flag_buf);
|
||||
if (imgname) {
|
||||
pj_ks (pj, "image", imgname);
|
||||
@@ -903,11 +918,11 @@ static int cmd_symbols(RCore *core, char mode) {
|
||||
if (addr > 0x1000) {
|
||||
r_cons_printf (core->cons, "'@0x%" PFMT64x "'f %s\n", addr, flag_buf);
|
||||
if (imgname && *imgname) {
|
||||
r_cons_printf (core->cons, "'@0x%" PFMT64x "'CCu Method: [%s]%s%s %s\n", addr, imgname, *attrs? " ": "", attrs, fullname);
|
||||
r_cons_printf (core->cons, "'@0x%" PFMT64x "'CCu Method: [%s]%s%s %s\n", addr, imgname, *attrs? " ": "", attrs, signature? signature: fullname);
|
||||
} else if (*attrs) {
|
||||
r_cons_printf (core->cons, "'@0x%" PFMT64x "'CCu Method: %s %s\n", addr, attrs, fullname);
|
||||
r_cons_printf (core->cons, "'@0x%" PFMT64x "'CCu Method: %s %s\n", addr, attrs, signature? signature: fullname);
|
||||
} else {
|
||||
r_cons_printf (core->cons, "'@0x%" PFMT64x "'CCu Method: %s\n", addr, fullname);
|
||||
r_cons_printf (core->cons, "'@0x%" PFMT64x "'CCu Method: %s\n", addr, signature? signature: fullname);
|
||||
}
|
||||
listed++;
|
||||
}
|
||||
@@ -921,11 +936,11 @@ static int cmd_symbols(RCore *core, char mode) {
|
||||
imgname,
|
||||
*attrs? " ": "",
|
||||
attrs,
|
||||
fullname);
|
||||
signature? signature: fullname);
|
||||
} else if (*attrs) {
|
||||
comment = r_str_newf ("Method: %s %s", attrs, fullname);
|
||||
comment = r_str_newf ("Method: %s %s", attrs, signature? signature: fullname);
|
||||
} else {
|
||||
comment = r_str_newf ("Method: %s", fullname);
|
||||
comment = r_str_newf ("Method: %s", signature? signature: fullname);
|
||||
}
|
||||
if (comment) {
|
||||
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, comment);
|
||||
@@ -937,6 +952,8 @@ static int cmd_symbols(RCore *core, char mode) {
|
||||
|
||||
free (attrs);
|
||||
free (imgname);
|
||||
free (return_type);
|
||||
free (signature);
|
||||
free (fullname);
|
||||
}
|
||||
|
||||
@@ -956,6 +973,7 @@ static int cmd_symbols(RCore *core, char mode) {
|
||||
r2unity_native_result_fini (&native_result);
|
||||
R_FREE (type2img);
|
||||
R_FREE (images);
|
||||
R_FREE (parameters);
|
||||
R_FREE (methods);
|
||||
R_FREE (types);
|
||||
close_metadata (meta, buf);
|
||||
|
||||
Reference in new issue
Block a user