-
Notifications
You must be signed in to change notification settings - Fork 0
ISIL Reference and Calling Conventions
This cheat sheet reference covers ISIL opcodes, CPU register conventions, and memory alignment rules used when disassembling IL2CPP binaries.
| Opcode | Description | Typical C# Equivalent |
|---|---|---|
Move dest, src |
Copy value or pointer from src into dest
|
var = x; |
Compare a, b |
Compare a and b (sets flags for conditional jumps) |
if (a == b) |
Jump line |
Unconditional jump to line
|
goto line; |
JumpIfEqual line |
Jump to line if previous Compare values were equal |
if (a == b) body |
JumpIfNotEqual line |
Jump to line if previous Compare values were not equal |
if (a != b) body |
JumpIfGreater line |
Jump to line if a > b
|
if (a > b) body |
JumpIfLess line |
Jump to line if a < b
|
if (a < b) body |
Call Target |
Invoke method Target
|
Target(); |
LoadElementAddress |
Calculate address of array element at index | array[index] |
LoadFieldAddress |
Calculate address of struct field | ref myStruct.field |
ShiftLeft / ShiftRight
|
Bitwise shift |
a << b / a >> b
|
And / Or / Xor
|
Bitwise AND, OR, XOR operations |
a & b, `a |
Return |
Exit current method | return; |
IL2CPP translates C# into C++ and compiles it with standard platform C++ compilers (MSVC, Clang, GCC). Understanding register usage lets you identify parameters and object references in ISIL.
-
rcx: Holds thethispointer for instance methods, or argument 1 for static methods. -
rdx: Argument 2 (or argument 1 for static methods). -
r8: Argument 3. -
r9: Argument 4. -
rax: Holds method return values. -
rbx: Callee-saved register. Compilers almost always copyrcxintorbxat method entry sorbxreliably points tothisthroughout the method body.
-
x0: Holdsthispointer / Argument 1 and holds return values. -
x1–x7: Arguments 2 through 8. -
x19–x28: Callee-saved registers (x19usually preservesthis).
When mapping [rbx + offset] memory accesses to C# class fields, fields are laid out in memory according to standard 64-bit alignment rules.
-
Object Header: Offsets
0x00–0x0F(0 to 15 bytes) hold vtable pointers and synchronization blocks. -
Base Class Fields: Monobehaviour / UnityEngine base fields occupy offsets up to
0x1F(16 to 31 bytes). -
First Custom Field: Always starts at offset 32 (
0x20).
| Type Size | Types | Alignment Requirement |
|---|---|---|
| 8 Bytes | Object references, string, UnityEvent, long, ulong, double, Pointers |
Must align to offsets divisible by 8 (32, 40, 48, 56, 64...) |
| 4 Bytes |
int, uint, float, Enums |
Must align to offsets divisible by 4 (32, 36, 40, 44...) |
| 2 Bytes |
short, ushort, char
|
Must align to offsets divisible by 2 (32, 34, 36...) |
| 1 Byte |
bool, byte, sbyte
|
Can sit at any byte offset (32, 33, 34...) |
Suppose a C# class has these fields in order:
public class Example : MonoBehaviour
{
public bool isReady; // Offset 32 (1 byte)
// 7 bytes padding inserted here to reach next 8-byte boundary!
public string title; // Offset 40 (8 bytes pointer)
public int count; // Offset 48 (4 bytes)
public bool isFinished; // Offset 52 (1 byte)
}Because string is an 8-byte pointer, it cannot sit at offset 33—the compiler inserts 7 padding bytes so title aligns to offset 40. That is why checking field order and alignment helps you calculate offsets matching [rbx + offset] instructions in ISIL.