Coopyy / Unturned-External-Base

simple external base (kinda) that sets local admin so you can use freecam & in game esp (thanks nelson) + no recoil & spread
16 stars 3 forks source link

Read String #9

Closed italoseara closed 6 months ago

italoseara commented 6 months ago

hey, i don't know if you are still active, but i'm kinda new to game hacking (i've been coding for a lot of time tho), i've been able to use your base really well, but i don't know get a string, i believe it is because a string in C# is different than the C++ String. How would you do that?

Coopyy commented 6 months ago

good question simplified unity string struct is as follows

class System_String
{
    char _pad[0x10];
public:
    int size; // 0x10
    wchar_t buffer[1024]; // 0x14
};

you can check with reclass as well, it will show you the string in memory

italoseara commented 6 months ago

Good to know you are still here! I managed to get it in the end by just analyzing and understanding your code. It's a bit overcomplicated because i was 2.5 hours into this problem, so i wasn't thinking right. Here is my code:

class String
{
public:
    uint32_t length()
    {
        return Memory::read<uint32_t>(THISPTR + 0x10);
    }

    char* c_str()
    {
        uint32_t len = length();

        char *str = new char[len + 1];
        for (uint32_t i = 0; i < len; i++)
        {
            char16_t c = Memory::read<char16_t>(THISPTR + 0x14 + (i * 2));
            str[i] = c;
        }
        str[len] = '\0';

        return str;
    }

    string to_string()
    {
        return c_str();
    }
};

I believe the c_str function can be replaced with one simple call to read_widechar, but i didn't manage to understand how it worked.

Coopyy commented 6 months ago

Good to know you are still here! I managed to get it in the end by just analyzing and understanding your code. It's a bit overcomplicated because i was 2.5 hours into this problem, so i wasn't thinking right. Here is my code:

class String
{
public:
  uint32_t length()
  {
      return Memory::read<uint32_t>(THISPTR + 0x10);
  }

  char* c_str()
  {
      uint32_t len = length();

      char *str = new char[len + 1];
      for (uint32_t i = 0; i < len; i++)
      {
          char16_t c = Memory::read<char16_t>(THISPTR + 0x14 + (i * 2));
          str[i] = c;
      }
      str[len] = '\0';

      return str;
  }

  string to_string()
  {
      return c_str();
  }
};

I believe the c_str function can be replaced with one simple call to read_widechar, but i didn't manage to understand how it worked.

for using read_widechar (which i'd recommend), something like this will work:

class String
{
public:
    uint32_t length()
    {
        return Memory::read<uint32_t>(THISPTR + 0x10);
    }

    string to_string()
    {
        return read_widechar(THISPTR + 0x14, length() * 2 + 1);
    }

    char* c_str()
    {
        return to_string().c_str();
    }
};
italoseara commented 6 months ago

Can you explain why it wouldn't be recommended?

Coopyy commented 6 months ago

i would recommend read_widechar i wouldn't recommend your method as it is reading more than it needs to (can just read whole buffer) and has a memory leak with char *str = new char[len + 1];

italoseara commented 6 months ago

sorry, my head is dizzy from trying to debug my own code, lol, thank you for the help! If i get stuck on something, can i ask for your help again?

Coopyy commented 6 months ago

yep, feel free to ask, ill answer when I can get to it

italoseara commented 6 months ago

Ok. Thanks a lot