mirror of
https://github.com/radareorg/r2unity.git
synced 2026-11-07 06:36:00 -10:00
Reject v24.0 metadata instead of silently decoding wrong offsets
This commit is contained in:
1 parent
b276df7e87
commit
a4e6446d16
3 files changed
+54
-2
No files matched your search
@@ -119,12 +119,16 @@ if (version < 24 || version > 31) return NULL;
|
||||
if (version < 27) header_size = sizeof (v24);
|
||||
else if (version < 29) header_size = sizeof (v27);
|
||||
else header_size = sizeof (v29); /* 29, 30, 31 */
|
||||
/* After normalizing header fields, reject v24.0 via image-stride probe. */
|
||||
if (version == 24 && is_v24_0 (meta)) return NULL;
|
||||
```
|
||||
|
||||
| Wire version | Status | Reality |
|
||||
|--------------|-----------------------------------|--------------------------------------------------------------------------------------------|
|
||||
| 16, 19, 20 | Rejected | Pre-Unity-5.5 builds, effectively extinct. |
|
||||
| 21, 22, 23 | Rejected | Unity 5.3 – 5.5 IPAs exist but are rare. |
|
||||
| 24.0 | Rejected after sub-version probe | On-disk `version` is 24 for both v24.0 and v24.1+. The parser probes image-row stride (32 B vs 40 B) and rejects v24.0 with an explicit error; TypeDefinition/MethodDefinition/ImageDefinition rows would otherwise decode at wrong offsets. |
|
||||
| 24.1 – 24.5 | Accepted via `_v24` header struct | Row decoders target the v24.1+ strides. |
|
||||
| 27 | Accepted via `_v27` header struct | Header correct. Row decoders still assume the v24.1+ layout; v27.2 RGCTX widening not handled (only affects RGCTX which is unused). |
|
||||
| 29 | Accepted via `_v29` header struct | Header correct. Method rows decoded as 32 B. Reverse-P/Invoke BLOB path is the only v29-specific code. |
|
||||
| 30 | Accepted | Never shipped on disk; dead slot, safe. |
|
||||
|
||||
+6
-2
@@ -917,9 +917,13 @@ Unity-release → wire-version → sub-version mapping.
|
||||
`Il2CppMethodDefinition`, aligning with ECMA-335's return-value
|
||||
param-row model.
|
||||
|
||||
r2unity's current acceptance band is **v24..v31**, with dedicated
|
||||
r2unity's current acceptance band is **v24.1..v31**, with dedicated
|
||||
handling only for the v24.1+ table strides and the v31
|
||||
`returnParameterToken` insertion.
|
||||
`returnParameterToken` insertion. Since the on-disk `version` field is
|
||||
`24` for both v24.0 and v24.1+, the parser probes the image-row stride
|
||||
(32 B on v24.0, 40 B on v24.1+) and rejects v24.0 explicitly to avoid
|
||||
silent mis-decoding of TypeDefinition/MethodDefinition/ImageDefinition
|
||||
rows.
|
||||
|
||||
## 5. How the parser is wired in r2unity
|
||||
|
||||
|
||||
@@ -14,6 +14,43 @@ R_API bool r2unity_is_debug (void) {
|
||||
}
|
||||
|
||||
|
||||
/* Detect v24.0 vs v24.1+ (both land on disk as version==24).
|
||||
*
|
||||
* At v24.1 the ImageDefinition row grew by 8 bytes (added
|
||||
* customAttributeStart/Count), so imagesSize is a multiple of 40 on v24.1+
|
||||
* and 32 on v24.0. When imagesSize is divisible by both (a multiple of 160),
|
||||
* probe the 4 bytes at offset 40: under v24.1+ that is row 1's nameIndex
|
||||
* (a valid string-pool offset); under v24.0 it is mid-row.
|
||||
*
|
||||
* Fixing row layouts for v24.0 (larger TypeDefinition, MethodDefinition,
|
||||
* ImageDefinition) is tracked separately; reject for now so decoders don't
|
||||
* silently return wrong offsets. */
|
||||
static bool is_v24_0 (R2UnityMetadata *meta) {
|
||||
ut64 ioff = meta->header.v24.imagesOffset;
|
||||
ut64 isize = meta->header.v24.imagesSize;
|
||||
if (!isize) {
|
||||
return false;
|
||||
}
|
||||
bool div40 = (isize % 40) == 0;
|
||||
bool div32 = (isize % 32) == 0;
|
||||
if (div40 && !div32) {
|
||||
return false;
|
||||
}
|
||||
if (div32 && !div40) {
|
||||
return true;
|
||||
}
|
||||
if (isize >= 44) {
|
||||
ut8 probe[4];
|
||||
if (r_buf_read_at (meta->buf, ioff + 40, probe, 4) == 4) {
|
||||
uint32_t name_idx = r_read_le32 (probe);
|
||||
if (name_idx < (uint32_t) meta->stringSize) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
R_API R2UnityMetadata *r2unity_parse_metadata (RBuffer *buf) {
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
@@ -97,6 +134,13 @@ R_API R2UnityMetadata *r2unity_parse_metadata (RBuffer *buf) {
|
||||
meta->typeDefinitionsOffset = meta->header.v29.typeDefinitionsOffset;
|
||||
meta->typeDefinitionsSize = meta->header.v29.typeDefinitionsSize;
|
||||
}
|
||||
if (meta->version == 24 && is_v24_0 (meta)) {
|
||||
R_LOG_ERROR ("v24.0 metadata (Unity 5.6..2018.2) not supported: "
|
||||
"TypeDefinition/MethodDefinition/ImageDefinition row layouts "
|
||||
"differ from v24.1+ and would silently decode wrong offsets");
|
||||
r2unity_free_metadata (meta);
|
||||
return NULL;
|
||||
}
|
||||
meta->strings = r_buf_new_slice (buf, meta->stringOffset, meta->stringSize);
|
||||
meta->string_literals = r_buf_new_slice (buf, meta->stringLiteralOffset, meta->stringLiteralSize);
|
||||
if (g_debug) {
|
||||
|
||||
Reference in new issue
Block a user