|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
ApacheTech Newbie cheater Reputation: 0
Joined: 26 Jun 2020 Posts: 14
|
Posted: Fri Jun 26, 2020 12:02 pm Post subject: [Help] Two questions regarding Mono Features (CE 7.1) |
|
|
First of all, is is possible to programmatically disable Mono Features? I can use
Code: | LaunchMonoDataCollector(); |
to Enable them, but I'd like to Disable them programmatically as well. The reason for this is because the game I am programming against hangs on Exit, if the library is still injected.
My second question is a bit more specific. I'm trying to invoke a method that has a parameter for a System.Action callback. In dnSpy, I can see that this method is almost always called with "null" as the callback, but I seem to be unable to send "null", "nil", "0", or any other form of nullified value to the method via CE because it expects a Type of System.Action.
This is the method signature from dnSpy:
Code: |
public void SetNotification(string text, Action callback = null)
{
// Do stuff.
}
|
No matter what I try, I receive this error in return:
Quote: | Error:C:\Program Files\Cheat Engine 7.1\autorun\monoscript.lua:1683: attempt to index a nil value (global 'monopipe') |
How do you pass a null value to an invoked method?
|
|
Back to top |
|
|
blankTM Cheater Reputation: 0
Joined: 03 May 2020 Posts: 49
|
Posted: Fri Jun 26, 2020 12:23 pm Post subject: Re: [Help] Two questions regarding Mono Features (CE 7.1) |
|
|
Close mono:
Code: |
monopipe.OnTimeout() |
No need to pass in the second parameter
|
|
Back to top |
|
|
ApacheTech Newbie cheater Reputation: 0
Joined: 26 Jun 2020 Posts: 14
|
Posted: Fri Jun 26, 2020 2:57 pm Post subject: |
|
|
Thank you for that. I've added:
Code: |
[DISABLE]
{$lua}
-- Clean the registered symbols.
for k, v in pairs(aPointerList) do
unregisterSymbol(k);
end
-- Close Mono Features.
if (monopipe) then
monopipe.OnTimeout();
end
{$asm}
|
to the script and it works fine.
As for the second part, I've added an overload for the method, for testing, and recompiled the library.
Code: |
public void SetNotification(string text)
{
this.SetNotification(text, null);
}
|
Using this, I'm at least able to get some feedback. For some reason now, when I try to invoke this, even via the GUI, I get this error:
Quote: | parameter 1: "Hello World" is not a valid value |
Even though the value type is "string".
To do this programmatically, I've adapted the "my_mono_invoke_method" example from the wiki:
Code: |
--- </summary>
--- Wrapper to safely invoke mono methods within Cheat Engine.
--- </summary>
function InvokeMethod(domain, method, args, instanceAddress)
local c=mono_method_getClass(method);
local instance;
if (instanceAddress == nil) then
instance = mono_class_findInstancesOfClassListOnly(domain,c);
instance = instance[1];
else
instance = instanceAddress;
end
local params = mono_method_get_parameters(method)
if #args ~= #params.parameters then
print('ERROR:InvokeMethod : wrong length of args');
return
end
local i;
local args_t={};
for i=1, #params.parameters do
args_t[i] = {};
args_t[i].type = monoTypeToVartypeLookup[params.parameters[i].type];
args_t[i].value = args[i];
end
if method==nil or method==0 then
print('ERROR:InvokeMethod : method==0');
return;
end
if instance==nil or instance==0 then
print('ERROR:InvokeMethod : instance==0');
return;
end
local r=mono_invoke_method(domain, method, instance, args_t);
return r;
end
|
I'm using this within a script:
Code: |
{$lua}
--NB: SingletonPrefab<Backbone>.instance.gameUI.notificationBox.SetNotification(SS.Get("expandFillInDisabled"), null);
function Test()
local methodId = mono_findMethod('', 'NotificationBox', 'SetNotification');
local instanceId = getAddress('[[[["mono.dll"+00265110]+BD0]+60]+E8]+0');
print(string.format("Method ID: %X", methodId));
print(string.format("Instance ID: %X", instanceId));
InvokeMethod('', methodId, {"Hello World!"}, instanceId);
end
{$asm}
[ENABLE]
{$lua}
Test();
memrec.OnActivate = function(memrec, preState, curState)
if (not preState) and curState then
local t = createTimer()
t.Interval = 100;
t.OnTimer = function(t)
t.destroy();
memrec.Active = enabled;
end
end
return true;
end
{$asm}
[DISABLE]
{$lua}
{$asm}
// EOF
|
But, I always get back the error:
Quote: |
Error:C:\Program Files\Cheat Engine 7.1\autorun\monoscript.lua:1683: attempt to index a nil value (global 'monopipe')
|
and it shuts the pipe down.
|
|
Back to top |
|
|
blankTM Cheater Reputation: 0
Joined: 03 May 2020 Posts: 49
|
Posted: Fri Jun 26, 2020 5:16 pm Post subject: |
|
|
This method returns an instance array
There may be multiple instances of this class
Code: |
instance = mono_class_findInstancesOfClassListOnly(domain,c) |
For specific tests, you need to right-click the method and select the options in the figure
Description: |
|
Filesize: |
40.99 KB |
Viewed: |
4888 Time(s) |
|
|
|
Back to top |
|
|
ApacheTech Newbie cheater Reputation: 0
Joined: 26 Jun 2020 Posts: 14
|
Posted: Fri Jun 26, 2020 5:28 pm Post subject: |
|
|
I have the correct instance. Invoking other methods within that instance works fine. I've tested methods that take Boolean, and Integer parameters, as well as methods with no parameters. It's only Strings and complex types that I have difficulties with.
Description: |
|
Filesize: |
17.13 KB |
Viewed: |
4886 Time(s) |
|
|
|
Back to top |
|
|
blankTM Cheater Reputation: 0
Joined: 03 May 2020 Posts: 49
|
Posted: Fri Jun 26, 2020 6:36 pm Post subject: |
|
|
You can try to get an instance of type System.Action and pass the instance pointer to the second parameter
Specifically, you can also use DNSpy analysis or CE breakpoint debugging to obtain the System.Action pointer
|
|
Back to top |
|
|
ApacheTech Newbie cheater Reputation: 0
Joined: 26 Jun 2020 Posts: 14
|
Posted: Fri Jun 26, 2020 9:31 pm Post subject: |
|
|
blankTM wrote: | You can try to get an instance of type System.Action and pass the instance pointer to the second parameter
Specifically, you can also use DNSpy analysis or CE breakpoint debugging to obtain the System.Action pointer |
That would be ok if I wanted a callback. I could create a new Action, and redirect to it. But, I specifically want to send NULL as a parameter, which should be a valid input.
|
|
Back to top |
|
|
blankTM Cheater Reputation: 0
Joined: 03 May 2020 Posts: 49
|
Posted: Fri Jun 26, 2020 10:33 pm Post subject: |
|
|
Error location mono_method_get_parameters method error
Can you successfully call it after decompiling with dnspy
|
|
Back to top |
|
|
ApacheTech Newbie cheater Reputation: 0
Joined: 26 Jun 2020 Posts: 14
|
Posted: Sat Jun 27, 2020 7:07 pm Post subject: |
|
|
I've changed out "mono_method_get_parameters " for "mono_method_getSignature".
My invocation functions now read:
Code: |
--- <summary>
--- Returns a string array that contains the substrings in the
--- specified input string, delimited by elements of a specified
---- string, with an optional limit to the number of results.
--- </summary>
string.split = function(str, del, limit)
local t = {};
local fpat = "(.-)" .. del;
local last_end = 1;
local s, e, cap = str:find(fpat, 1);
while s do
if s ~= 1 or cap ~= "" then
table.insert(t, cap);
end
last_end = e+1;
s, e, cap = str:find(fpat, last_end);
if limit ~= nil and limit <= #t then
break;
end
end
if last_end <= #str then
cap = str:sub(last_end);
table.insert(t, cap);
end
return t;
end
--- <summary>
--- Wrapper to safely invoke Mono methods within Cheat Engine.
--- </summary>
function InvokeMethod(domain, method, args, instanceAddress)
local c=mono_method_getClass(method);
local instance;
if (instanceAddress == nil) then
instance = mono_class_findInstancesOfClassListOnly(domain,c);
instance = instance[1];
else
instance = instanceAddress;
end
local params = string.split(mono_method_getSignature(method),',');
if #args ~= #params then
print('ERROR:InvokeMethod : Invalid Parameter Signature.');
print(string.format('ERROR:InvokeMethod : Expected: %d', #params));
print(string.format('ERROR:InvokeMethod : Actual: %d', #args));
return
end
local i;
local args_t={};
for i=1, #params do
args_t[i] = {};
args_t[i].type = monoTypeToVartypeLookup[params[i].type];
args_t[i].value = args[i];
end
if method==nil or method==0 then
print('ERROR:InvokeMethod : method==0');
return;
end
if instance==nil or instance==0 then
print('ERROR:InvokeMethod : instance==0');
return;
end
local r=mono_invoke_method(domain, method, instance, args_t);
return r;
end
|
This still doesn't allow me to pass NULL as a parameter. I've tested passing random valid Action instances, and it CTDs both the application, and Cheat Engine, every time. I need to pass NULL to the application as a parameter.
I can't even see an option for a NULL parameter within monoscript.lua.
Code: |
MONO_TYPE_END = 0x00 -- End of List
MONO_TYPE_VOID = 0x01
MONO_TYPE_BOOLEAN = 0x02
MONO_TYPE_CHAR = 0x03
MONO_TYPE_I1 = 0x04
MONO_TYPE_U1 = 0x05
MONO_TYPE_I2 = 0x06
MONO_TYPE_U2 = 0x07
MONO_TYPE_I4 = 0x08
MONO_TYPE_U4 = 0x09
MONO_TYPE_I8 = 0x0a
MONO_TYPE_U8 = 0x0b
MONO_TYPE_R4 = 0x0c
MONO_TYPE_R8 = 0x0d
MONO_TYPE_STRING = 0x0e
MONO_TYPE_PTR = 0x0f -- arg: <type> token
MONO_TYPE_BYREF = 0x10 -- arg: <type> token
MONO_TYPE_VALUETYPE = 0x11 -- arg: <type> token
MONO_TYPE_CLASS = 0x12 -- arg: <type> token
MONO_TYPE_VAR = 0x13 -- number
MONO_TYPE_ARRAY = 0x14 -- type, rank, boundsCount, bound1, loCount, lo1
MONO_TYPE_GENERICINST= 0x15 -- <type> <type-arg-count> <type-1> \x{2026} <type-n> */
MONO_TYPE_TYPEDBYREF = 0x16
MONO_TYPE_I = 0x18
MONO_TYPE_U = 0x19
MONO_TYPE_FNPTR = 0x1b -- arg: full method signature */
MONO_TYPE_OBJECT = 0x1c
MONO_TYPE_SZARRAY = 0x1d -- 0-based one-dim-array */
MONO_TYPE_MVAR = 0x1e -- number */
MONO_TYPE_CMOD_REQD = 0x1f -- arg: typedef or typeref token */
MONO_TYPE_CMOD_OPT = 0x20 -- optional arg: typedef or typref token */
MONO_TYPE_INTERNAL = 0x21 -- CLR internal type */
MONO_TYPE_MODIFIER = 0x40 -- Or with the following types */
MONO_TYPE_SENTINEL = 0x41 -- Sentinel for varargs method signature */
MONO_TYPE_PINNED = 0x45 -- Local var that points to pinned object */
MONO_TYPE_ENUM = 0x55 -- an enumeration */
monoTypeToVartypeLookup={}
monoTypeToVartypeLookup[MONO_TYPE_BOOLEAN]=vtByte
monoTypeToVartypeLookup[MONO_TYPE_CHAR]=vtString
monoTypeToVartypeLookup[MONO_TYPE_I1]=vtByte
monoTypeToVartypeLookup[MONO_TYPE_U1]=vtByte
monoTypeToVartypeLookup[MONO_TYPE_I2]=vtWord
monoTypeToVartypeLookup[MONO_TYPE_U2]=vtWord
monoTypeToVartypeLookup[MONO_TYPE_I4]=vtDword
monoTypeToVartypeLookup[MONO_TYPE_U4]=vtDword
monoTypeToVartypeLookup[MONO_TYPE_I8]=vtQword
monoTypeToVartypeLookup[MONO_TYPE_U8]=vtQword
monoTypeToVartypeLookup[MONO_TYPE_R4]=vtSingle
monoTypeToVartypeLookup[MONO_TYPE_R8]=vtDouble
monoTypeToVartypeLookup[MONO_TYPE_STRING]=vtPointer --pointer to a string object
monoTypeToVartypeLookup[MONO_TYPE_PTR]=vtPointer
monoTypeToVartypeLookup[MONO_TYPE_BYREF]=vtPointer
monoTypeToVartypeLookup[MONO_TYPE_CLASS]=vtPointer
monoTypeToVartypeLookup[MONO_TYPE_FNPTR]=vtPointer
monoTypeToVartypeLookup[MONO_TYPE_GENERICINST]=vtPointer
monoTypeToVartypeLookup[MONO_TYPE_ARRAY]=vtPointer
monoTypeToVartypeLookup[MONO_TYPE_SZARRAY]=vtPointer
|
Is this an oversight?
ADDENDUM:
Even with adding my own overload, removing the need to send a NULL parameter, it's saying that a string is not a valid input for a string parameter. Am I missing something very basic here, or has something gone very wrong with CE?
Description: |
|
Filesize: |
22.25 KB |
Viewed: |
4746 Time(s) |
|
|
|
Back to top |
|
|
blankTM Cheater Reputation: 0
Joined: 03 May 2020 Posts: 49
|
Posted: Sat Jun 27, 2020 10:14 pm Post subject: |
|
|
Maybe you should analyze the Action instance structure
Then use createMemoryStream to create an empty structure passed to the second parameter
Description: |
|
Filesize: |
22.67 KB |
Viewed: |
4733 Time(s) |
|
Description: |
|
Filesize: |
38.63 KB |
Viewed: |
4733 Time(s) |
|
|
|
Back to top |
|
|
ApacheTech Newbie cheater Reputation: 0
Joined: 26 Jun 2020 Posts: 14
|
Posted: Sun Jun 28, 2020 8:12 am Post subject: |
|
|
Passing NULL as a parameter is an extremely common occurrence. Is there really no way to do it in CE?
|
|
Back to top |
|
|
Ahmed Jihad How do I cheat? Reputation: 0
Joined: 06 Jan 2024 Posts: 9
|
Posted: Mon Jan 08, 2024 1:53 pm Post subject: |
|
|
ApacheTech wrote: | I have the correct instance. Invoking other methods within that instance works fine. I've tested methods that take Boolean, and Integer parameters, as well as methods with no parameters. It's only Strings and complex types that I have difficulties with. |
Hi please I need you answer in the following questions what is the ASM code to do this invoke???
|
|
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
|
|