|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Pillar How do I cheat? Reputation: 0
Joined: 27 Feb 2024 Posts: 2
|
Posted: Tue Feb 27, 2024 10:18 pm Post subject: Mono Invoke Threading issue ? |
|
|
i have been working on a cheat table for valheim but i have been struggling with mono_invoke_method. here is a snippet
Code: |
function valheimMessage(text, stinger)
-- System.void(string text, bool playStinger)
local methodId = getMethod(msgHudClassAddr, "ShowBiomeFoundMsg")
local params = getParams(methodId)
local msgInstance = readPointer(m_messageHud)
local args = {}
table.insert(args, {type="string", value=text})
table.insert(args, {type="bool", value=stinger})
args[1].type=monoTypeToVartypeLookup[params.parameters[1].type]
args[2].type=monoTypeToVartypeLookup[params.parameters[2].type]
mono_invoke_method(domainAddr, methodId, msgInstance, args)
end
|
the function seems to work great but the game crashes at random call intervals. i looked into it and i dont know if this is true but i think its because the thread used to call the function is potentially unsafe. i looked into crash dumps and consistently it returned ExceptionCode: c0000409 (Security check failure or stack buffer overrun)
i think when the game calls the same function while im invoking it. it causes the stack to corrupt or something and game crashes.
Is there a work-around for this and if so i would like the snippet of what it looks like. If you need more info ill try to provide it.
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25298 Location: The netherlands
|
Posted: Wed Feb 28, 2024 12:44 am Post subject: |
|
|
only solution would be to call the method you're interested in from inside the thread that normally calls it.
use a code injection on a frequently called method only used by that thread
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
Pillar How do I cheat? Reputation: 0
Joined: 27 Feb 2024 Posts: 2
|
Posted: Thu Apr 11, 2024 10:08 am Post subject: Solved it. |
|
|
I followed your advice (Was having issues along the way) but I made a solution which could be useful for others so im gonna post my solution.
My comments might be off on what is happening with the registers but it works. Only issue i ran into was that the unity strings will eventually get removed by the garbage collector so if u spam 100 messages some messages might be gone by then.
Here is my Injection script
Code: |
define(address,MessageHud:UpdateMessage)
define(bytes,55 48 8B EC 48 81 EC 10 01 00 00)
[ENABLE]
assert(address,bytes)
alloc(newmem,$1000,MessageHud:UpdateMessage)
alloc(playBiomeMessage, $8)
alloc(biomeMessage, $8)
alloc(biomeMessageStinger, $4)
registerSymbol(playBiomeMessage)
registerSymbol(biomeMessage)
registerSymbol(biomeMessageStinger)
label(code)
label(return)
newmem:
code:
// our code
// determine whether to play message
cmp [playBiomeMessage], 1
jne @f
// Allocate space for my stack
sub rsp, 40
// Preserve old rax since it is gonna be overriden by the call
mov [rsp+32], rax
// push what i need for parameters
push rcx
push rdx
push r8
// rcx = messageHud instance, rdx = text (unityString), r8d = play stinger (bool)
mov rcx, [m_messageHud]
mov rdx, [biomeMessage]
mov r8d, [biomeMessageStinger]
call MessageHud::ShowBiomeFoundMsg
// Start cleaning up after call (must be reverse of push order)
pop r8
pop rdx
pop rcx
// clear all evidence of us
mov rax, [rsp+32]
add rsp, 40
// turn off play message (this symbol will be used in lua to trigger this function by turning it to 1)
mov [playBiomeMessage], 0
jmp @f
@@:
// original code
// recover stolen bytes from jmp
push rbp
mov rbp,rsp
sub rsp,40
// jump back and resume normal code flow
jmp return
playBiomeMessage:
dd 0
address:
jmp newmem
nop 6
return:
[DISABLE]
address:
db bytes
// push rbp
// mov rbp,rsp
// sub rsp,Player.m_zanim
dealloc(*)
unregistersymbol(*)
|
This is my invoking script that handles the symbols I created, populates them and then changes playMessage symbol to 1 which will then call the function
Code: |
{$lua}
if syntaxcheck then return end
[ENABLE]
local function getDomains()
return mono_enumDomains()
end
local function createUnityString(text)
local domain = getDomains()[0]
return mono_new_string(domain, text)
end
local function valheimStinger(text, stinger)
local biomeMessage = getAddress("biomeMessage")
local biomeStinger = getAddress("biomeMessageStinger")
local playBiomeMessage = getAddress("playBiomeMessage")
local dwUnityString = createUnityString(text)
assert(dwUnityString ~= 0)
writePointer(biomeMessage, dwUnityString)
writeByte(biomeStinger, stinger)
writeInteger(playBiomeMessage, 1)
end
valheimStinger("Wow it worked", 1)
[DISABLE]
|
Hope this helps anyone and ill try to reply to any questions about it (sorry in advance if i dont respond in a while)
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|