Unity引擎字符串内存布局

    Unity引擎的字符串有三种存储方式:

  • 堆 : 分配在堆上
  • 内嵌 : 一个栈上的内存数据。 默认25字节,可以放长度最多24的字符串。这个长度定义为STACK_LENGTH.  
  • 外部
    重点主要是前两种,这是一种优化方法,对于非常短的字符串,可以直接使用栈数据而不需要再次内存分配。C++伪代码看起来像这样:
 union
 {
     char stack_buffer[STACK_LENGTH];
     
     struct Data
     {
         char* data; // 8Bytes
         size_t capacity; // 8Bytes
         size_t length; // 8Bytes
         
         // align 8Bytes for Data  
         // or size of stack string length (STACK_LENGTH - length)
     } // 32Bytes

 } // 32Bytes
 
 uint8_t dataType; // 8Bytes, 指出存储方式,其中7个Bytes用于对齐
  
 {
    Id : 4Bytes
    Salt    : 4Bytes
    Index : 4Bytes
 }MemoryTag; // 12Bytes

      所以要逆向一个unity的C++字符串数据,首先定位地址。然后尝试找到dataType,其方式为:*(unit8_t*)(ptr + 0x20)。

  • 如果是0,那么字符串就是*(const char**)(ptr);
  • 如果是1,那么字符串就是(const char*)(ptr)。

      字符串长度也有两种方式存放。

  • 如果是1,那么长度以(STACK_LENGTH-length)的形式保存在stack_buffer[STACK_LENGTH]这个位置上,这个值不会超过一个字节。这种情况要获取字符串长度需要通过STACK_LENGTH减去该值得到。
  • 如果不是1,那么长度就是Union当中的length。

      除此之外,Unity还有一个类似于C++的string_view的东西,它将字符串以视图的形式传递,可以有效避免一些不必要的内存分配与拷贝。

{  
   const char* data;  
   size_t size;  
}  

      对于这种情况,对象地址就是字符串地址,其长度位于 ptr + 0x8的位置上。

 
posted @ 2024-07-31 15:17  bodong  阅读(20)  评论(0编辑  收藏  举报