Regarding the listening function on Gameguardian, my idea is to parse the symbol table of libil2cpp.so through the ELF file structure and parse out some il2cpp api functions in the native layer, such as il2cpp_method_get_name, and its ARM assembly segment is generally
LDR X0, [X0,#0x18]
~A8 RET
When many functions are called, the pointer of the function instance will be X0. When assembled by il2cpp_method_get_name, the function name string is read through the offset of 0x18.
Then we modify the function flow. Since many called functions will execute the assembly of this API function, we can write a unique tag value and actively tag ourselves when the function passes by. Then we can monitor which functions are called by searching for this tag value. call
LDR X10, [PC,#0xC]
STR X10, [X0,#0x40]
~A8 RET
983466571
We use the LDR instruction to load the tag 983466571 into the useless register X10, and then use the STR instruction to write the tag value to 0x40 of X0 (the function pointer, which is also the first bit of the function structure). Then when the function is called, When this API is executed, it actively exposes itself by writing the STR mark so that I can monitor it.
Of course, don’t forget to make up for it
LDR X0, [X0,#0x18]
~A8 RET
Otherwise it will cause the game to crash
The above are some of Shenmi’s ideas, and the gglua tool with this function has been written and can be used.