Mono related lua invoke or asm call C# System.String constructor

Want Cheat Engine to do something specific and no idea how to do that, ask here. (From simple scripts to full trainers and extensions)
Post Reply
peddroelm
Cheater
Cheater
Posts: 40
Joined: Fri Apr 05, 2019 9:15 am
Reputation: 14

Mono related lua invoke or asm call C# System.String constructor

Post by peddroelm »

I'm trying to add some extra feedback to some Character Info panels for a game that uses IL2CPP ( this would've probably taken 5 minutes with DNSPY otherwise ) ...

Image

Managed to get the parameters of interest calling a mono function that supplies them from ASM ( I'm calling a AOB signature of the function )


// Try call_1
lea r9,[rbp+30] // orig
lea r8,[rbp-50] // orig
mov edx,0000005
mov rcx,rdi
call AOB_BM_f_CharacterInformationsTooltip_getStatInformations

//SAVE [rbp+30] COURAGE !!
mov edx, [rbp+30]
mov [CbtUI_Hover_Courage_Agility_Params], edx // Courage

// Try call_2
lea r9,[rbp+30] // orig
lea r8,[rbp-50] // orig
mov edx,0000001
mov rcx,rdi
call AOB_BM_f_CharacterInformationsTooltip_getStatInformations

//SAVE [rbp+30] AGILITY !!
mov edx, [rbp+30]
mov [CbtUI_Hover_Courage_Agility_Params+4], edx // Agility


those parameters get to lua and I can make lua print this string in console when hovering units in combat


function CbtUI_Hover_Courage_Agility(params)

local Courage = readInteger(params)
local Agility = readInteger(params+0x4)
local CharacterInformationsTooltip = readQword(params+0x100)

local Character = readQword(CharacterInformationsTooltip + 0x160)
local Character_Level = readInteger( readQword(Character + 0x138) +0x40)

print(string.format("LvL:%2d Courage:%2d Agility:%2d", Character_Level, Courage, Agility))
-- sample lua console output
-- LvL: 5 Courage: 9 Agility:14
-- LvL: 3 Courage:30 Agility: 9
-- LvL: 3 Courage:30 Agility: 9

end


But of course I don't want this string in the lua console.. I want it to the

CharacterInformationsTooltip.m_characterLevel(textmeshpro).m_text.Value

to display seamlessly in game when hovering combat units

Image

And here I'm kid of stuck ... I could SIMPLY OVERWRITE CharacterInformationsTooltip.m_characterLevel(textmeshpro).m_text.Value with a Shorter or equal string ..
I can get its address :
UnicodeStringAddr = readQword( readQword( readQword(CharacterInformationsTooltip + 0x90) + 0xC8) + 0x14)

Problem is my string WILL BE LONGER ! (high risk of overwritting stuff ..)

The game does call TMPro.TMP_Text.set_text before ..

// SIMPLER TO INVOKE IN LUA ??

//CALL TMPro.TMP_text.set_text

// R9 or Rax used for calling setText of object using virtual function table

// arguments
// RCX ptr to TextMeshPro object that displays Unit LvL string
// RDX ptr SYSTEM.String object with my unicode string
// R8 get loaded offset of setText addr + 0x8

// call qword ptr [R9+530] // r9 = [[rsi + 90]] where RSI pointer to the CharacterInformationsTooltip
// [RSI+90] ptr to TextMeshPro object that displays Unit LvL string


Problem1
how do I call a constructor of System.String in ASM ? (randomly dig trough traces till I stumble upon an example ? Build c# project and see how the constructor call translates into ASM ? ) ..
To make the string.object argument to be able to call settext from ASM.

Problem2
is it simpler to mono invoke this set text from lua ? (doubt) ..
The parameter is a unicode string which I have.. Do I really need to go digging for functions/method ids when I can easily access the actual function address from my injection point ?

If I put a breakpoint when the hover window is active to get the function settext function addr could I invoke it from LUA engine for test purpose while the game is frozen for test purpose ? Doesn't sound right .. Will probably need to attempt the monoinvokes from my lua script that concatenates the string ..and crash crash crash :) ...

EDIT
Problem3
Simpler still ?
- make a mock? string object struct to pass as argument and see if it works


0 copy the addr pointer from an actual string.object I have access to (should be common for all system.string objects ?)
0x10 put strlen
0x14 put the unicode str

pass address of this struct in rdx , call set text and pray :))

peddroelm
Cheater
Cheater
Posts: 40
Joined: Fri Apr 05, 2019 9:15 am
Reputation: 14

Re: Mono related lua invoke or asm call C# System.String constructor

Post by peddroelm »

What I call an Absolute WIN :P

Image
Image

The UI in this game doesn't auto rescale/ resize with sting length .. Sigh .. Will have to live with shortened string C%2d A%2d

Solution 3 was it ..

fakeSystemString:
dq 0 // vtable ptr
dq 0 // 0
dd 0 // 4 byte strlen
dq 1 // utf-16 string hopefully shorter than 7x10
dq 2
dq 3
dq 4
dq 5
dq 6
dq 7
dq 8
dq 9
dq 10


local str = string.format("LvL:%2d Courage:%2d Agility:%2d", Character_Level, Courage, Agility)

local m_textTextMesh = readQword(CharacterInformationsTooltip + 0x90)
local SystemStringVtable = readQword(readQword(m_textTextMesh + 0xC8))

writeQword(FakeSystemString, SystemStringVtable)
writeInteger(FakeSystemString+0x10, string.len(str) )
writeString(FakeSystemString+0x14 , str, 1)


and set text asm call
// call qword ptr [R9+530] // r9 = [[rdi + 90]] where RDI pointer to the CharacterInformationsTooltip
// [RDI+90] ptr to TextMeshPro object that displays Unit LvL string

mov rcx, [rdi+90] // CharacterInformationsTooltip.m_characterLevel textmeshpro
mov rdx, fakeSystemString
mov r9, [rcx]
mov r8, [r9+538]
call qword ptr [r9+530]



EDIT:
Just occurred to me that the CharacterInformationsTooltip.m_characterDescription HAS ROOM FOR for example 238! characters of pure fluff text ! .. I CAN replace that with A LOT of useful hidden STATS !
Image
description text NOT shown when buffs/debuffs/status effects in play :( .. Maybe I can do something bout that ..

User avatar
Strigger
Expert Cheater
Expert Cheater
Posts: 85
Joined: Wed Sep 07, 2022 6:43 am
Reputation: 164

Re: Mono related lua invoke or asm call C# System.String constructor

Post by Strigger »

hey thanks for posting your solution, i'm trying to read and write string in il2cpp game, the game itself is obfuscated so i can't use mono dissect to find which variable i'm looking for, atleast your fake string gave me an idea, thanks again

Post Reply

Who is online

Users browsing this forum: praisebrad