uniref.mono.component

class uniref.mono.component.MonoAssembly(mono_injector: object, assembly: int)

MonoAssembly carries assembly reflection information.

dump_declaration(save_to: str, show_progress: bool = True) None

Dump all class declarations in the current assembly.

Parameters
  • save_to – output file path

  • show_progress – whether to show the progress bar

property handle: int

value as MonoAssembly*

property image: MonoImage

image corresponding to the assembly

class uniref.mono.component.MonoClass(mono_injector: object, image: Optional[int], klass: int, class_name: str = '', class_namespace: str = '')

MonoClass carries class reflection information.

property declaration: str

class declaration in C#

find_field(field_name: str) Optional[MonoField]

Find the field by its name.

Returns

MonoField instance if field is found, else None.

find_field_by_offset(offset: int) Optional[MonoField]

Find the field by its offset.

Returns

MonoField instance if field is found, else None.

find_method(method_name: str, param_count: int = -1) Optional[MonoMethod]

Find the method in the class.

If there are different overloads of a method in the same class, you can distinguish them by the number of parameters. This is what the param_count means.

Returns

MonoMethod instance if method is found, else None.

property flags: int

class flags

guess_instance_address(mem_writeable: bool = True) List[int]

Guess class instance address in memory.

Parameters

mem_writeable – the memory space where the class instance is located must be writable

Returns

a list of all class instance addresses guessed

property handle: int

value as MonoClass*

property image: object

image to which the class belongs (MonoImage)

property instance: int

class instance address

list_fields() List[MonoField]

List all fields in class.

list_methods() List[MonoMethod]

List all methods in class.

property name: str

class name

property namespace: str

class namespace

property parent: object

parent class (MonoClass)

set_instance(value: int) None

Set class instance address.

class uniref.mono.component.MonoField(mono_injector: object, klass: int, field: int, filed_name: str = '')

MonoField carries class property reflection information.

For MonoField objects, you can call the is_static method to determine whether the field is static (modified by the static keyword).

If it is a static field, there is no need to set the class instance, otherwise, the address of the class instance corresponding to the field needs to be set first.

Examples:

>>> ref = WinUniRef("TheForest.exe")
>>> PlayerStats = ref.find_class_in_image("Assembly-CSharp", "PlayerStats")
>>> Energy = PlayerStats.find_field("Energy")
>>> Energy.value
ValueError: Field Energy is not static, set instance address first
>>> Energy.instance = 0x12345678
>>> Energy.value
10.0
>>> Energy.value = 80.0
>>> Energy.value
80.0
>>> Energy.set_value(90.0)
>>> Energy.value
90.0

In addition, when you modify the value of the field, you need to use the correct Python type to assign the value according to the type of the field. The type mapping is shown in the table below.

C#

Python

System.Boolean

bool

System.SByte, System.Byte,

System.Int16, System.UInt16,

System.Int32, System.UInt32,

System.Int64, System.UInt64

int

System.Single, System.Double

float

System.String, System.Decimal

Not Editable

Else

int

property address: int

field address. Maybe 0 if it is static

property declaration: str

field declaration in C#

property flags: int

field flags

property handle: int

value as MonoClassField*

property instance: int

class instance address of the field

is_const() bool

Check if the field is const.

is_private() bool

Check if the field is private.

is_public() bool

Check if the field is public.

is_static() bool

Check if the field is static.

property klass: object

MonoClass instance of the field

property name: str

field name

property offset: int

field offset in the class

set_instance(value: int) None

Set class instance address of the field.

set_value(v: Any) None

Set field value.

property type_name: str

field type name

property value: Optional[Any]

field value

class uniref.mono.component.MonoImage(mono_injector: object, assembly: Optional[int], image: int, image_name: str = '', image_filename: str = '')

MonoImage carries image reflection information.

property assembly: object

the assembly to which the image belongs (MonoAssembly)

dump_declaration(save_to: str, show_progress: bool = True) None

Dump all class declarations in the current image.

Parameters
  • save_to – output file path

  • show_progress – whether to show the progress bar

property filename: str

image filename

find_class(class_path: str) MonoClass

Find the class in the image.

Returns

MonoClass instance if class is found, else None.

property handle: int

value as MonoImage*

list_classes() List[MonoClass]

List all classes in the image.

property name: str

image name

class uniref.mono.component.MonoMethod(mono_injector: object, klass: int, method: int, method_name: str = '')

MonoMethod carries class method reflection information.

For MonoMethod objects, you can call the is_static to determine whether the method is static (modified by the static keyword).

If it is a static method, there is no need to set the class instance, otherwise, the address of the class instance corresponding to the method needs to be set first.

Examples:

>>> ref = WinUniRef("TheForest.exe")
>>> PlayerStats = ref.find_class_in_image("Assembly-CSharp", "PlayerStats")
>>> SetCold = PlayerStats.find_method("SetCold")
>>> hex(SetCold.address)
'0x6e673b0'
>>> SetCold(args=(1,))
ValueError: Not a static method, set class instance first
>>> SetCold.instance = 0x12345678
>>> SetCold(args=(1,))

You can call a MonoMethod object like a Python function, passing the argument tuple via args. The args tuple requires that the elements in it are all of type int, and currently does not support parameters of types such as float / str.

For 32-bit applications, you need to additionally specify the type of function calling convention. The supported types are as follows:

CALL_TYPE_CDECL
CALL_TYPE_STDCALL
CALL_TYPE_THISCALL
CALL_TYPE_FASTCALL

Please set the function calling convention under the correct analysis result, otherwise the program may crash.

Examples:

from uniref import *

ref = WinUniRef("game.exe")
TestClass = ref.find_class_in_image("Assembly-CSharp", "TestClass")
TestClass.instance = 0x12345678
TestMethod = TestClass.find_method("TestMethod")
TestMethod(args=(1, 2), call_type=CALL_TYPE_CDECL)
property address: int

method machine code address

property declaration: str

method declaration in C#

property flags: int

method flags

property handle: int

value as MonoMethod*

property instance: int

class instance address of the method

is_private() bool

Check if the method is private.

is_public() bool

Check if the method is public.

is_static() bool

Check if the method is static.

is_virtual() bool

Check if the method is virtual.

property klass: object

MonoClass instance of the method

property name: str

method name

native_nop(offset: int, size: int) NativePatch

NOP method machine code.

Parameters
  • offset – offset from the beginning of the function

  • size – nop size in bytes

Returns

NativePatch instance

native_patch(offset: int, code: str) NativePatch

Patch method machine code.

Parameters
  • offset – offset from the beginning of the function

  • code – can be str or bytes

Returns

NativePatch instance

When the code parameter is of bytes type , the specified offset of the method will be modified to the given byte array.

When the code parameter is of str type, it will be regarded as assembly code and translated into machine code before patching. The assembly engine is keystone .

Meanwhile, you can enable and disable this patch through the NativePatch instance returned by the function.

Examples:

from uniref import *

ref = WinUniRef("game.exe")
TestClass = ref.find_class_in_image("Assembly-CSharp", "TestClass")
TestMethod = TestClass.find_method("TestMethod")

patch_1 = TestMethod.native_patch(0x222, b'H\xc7\xc0\x01\x00\x00\x00')  # mov rax, 1

asm = "mov rax, 1; mov rbx, 2; add rax, rbx"
patch_2 = TestMethod.native_patch(0x333, asm)

# disable patch
patch_1.disable()
patch_2.disable()

# enable again
patch_1.enable()
patch_2.enable()
property offset: int

method machine code offset relative to the module base (only for IL2CPP)

property return_type_name: str

method return type name

set_instance(value: int) None

Set class instance address of the method.

property signature: str

method signature

property size: int

method size. Maybe -1 if app uses IL2CPP