vfsfitvnm / frida-il2cpp-bridge

A Frida module to dump, trace or hijack any Il2Cpp application at runtime, without needing the global-metadata.dat file.

Home Page:https://github.com/vfsfitvnm/frida-il2cpp-bridge/wiki

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Il2Cpp.String::content may write out of bounds

axhlzy opened this issue · comments

Il2Cpp.api.stringGetChars(this).writeUtf16String(value ?? "");

It seems that you should not directly write the memory in this way. You have modified the length of the string here, and the content has also been extended, which will cause the memory of the latter part to be overwritten.

Yeah, correct, thanks for noticing. I should allocate a new string in case its length increases.

However, there's another place in the code base where it might end up writing more bytes than it should: can you spot it? 😝

not yet ...
but It seems that this function can be used to modify the length of the original string

il2cpp_string_new_len

1689325570468

Uhm, it looks like the Il2CppString struct should stay immutable:

typedef struct Il2CppString
{
    Il2CppObject object;
    int32_t length;
    Il2CppChar chars[0];
} Il2CppString;

Il2CppString* String::NewSize(int32_t len)
{
    if (len == 0)
        return Empty();

    Il2CppString *s;
    IL2CPP_ASSERT(len >= 0);
    size_t size = (sizeof(Il2CppString) + ((len + 1) * 2));

    s = reinterpret_cast<Il2CppString*>(Object::AllocatePtrFree(size, il2cpp_defaults.string_class));

    s->length = len;
    s->chars[len] = 0;

    return s;
}

In other words, we can't grow the string without reallocating the whole memory, and Il2Cpp.String::handle is immutable as well.
Now, we all agree the following snippet:

const s = Il2Cpp.string("hello");
s.content = "a longer content";

ends up writing to unallocated memory, potentially causing debug nightmares, and it should be prohibited.

However, writing a shorter string should be completely fine, so we could either:

  1. Make Il2Cpp.String::content read only;
  2. Keep Il2Cpp.String::content as it is and:
    1. Warn the user if a write out of bounds is about to occur;
    2. Add Il2Cpp.String::contentUnsafe for those who feel lucky.

Il2cppString is actually equivalent to this class (mscorlib System.String), so you can directly use the methods under this class to modify String

SUB -> mscorlib.System.String

System.String.Concat(cs_string* left, cs_string* right)
System.String.CreateString(char* array, int start, int length)
System.String.FastAllocateString(int length)
System.String.Substring(cs_string* this, int start, int length)
System.String.Replace(cs_string* original, cs_string* old, cs_string* new)

These methods return a new string!

I eventually decided to leave things as they are (I simply added an @unsafe marker to the setter docstring), as one might not care at all of this discouraged pattern.

However, I will take care of updating the documentation so that it's clear overwriting the string content may write out of bounds.