Intro to disassembly and CIL (Used in NET Reflector) opcode list

New Products

s810car

Advance Member
Dec 9, 2016
199
Been questioned about opcodes recently so thought this would make a good writeup.

This is a list of opcodes used in libraries/executables created for M$ .NET framework, prefaced by an introduction to assembly and some details for those wondering why its so dam hard to mod programs if you can understand and program in those languages. to skip to the good stuff without the college lecture PTSD you'll get from this head to the next post below. On the other hand, if you like the nerd stuff and want more, leave comments below (I will assume likes mean the chart not the boring stuff, which is what I expect anyways, I got bored of myself writing some of this up lol)

What is CIL?
Source: Wikipedia
Common Intermediate Language (CIL, pronounced either "sil" or "kil"), formerly called Microsoft Intermediate Language or MSIL, is the lowest-level human-readable programming language defined by the Common Language Infrastructure (CLI) specification and is used by the .NET Framework and Mono. Languages which target a CLI-compatible runtime environment compile to CIL, which is assembled into an object code that has a bytecode-style format. CIL is an object-oriented assembly language, and is entirely stack-based. Its bytecode is translated into native code or — most commonly — executed by a virtual machine.

Think of a program this way: You speak (or write) in a common language known by your own kind, humans. We have millions of ways to phrase things. Computers are electrical objects they know two things: working or not? yes or no? On or off? so basically is circuit receiving the electron flow or not. We understand this as binary code, where 1 = (On|True|Yes) and 0 = (Off|False|No). So how do we get these great graphic GUI phones with awesome games to mod into? We (humans) set up these on/off groups of circuits to mean something when put into sequences. For example I can say
Make a left at that turn
by, lets say, making a fist twice with my left hand, open both hands, then keep my right hand closed and open and close my left hand one last time. If you were taught that language you would understand those gestures entirely. This is exactly what we created in computers. We said ok this we understand (in this example, a letter in a word), so lets make this group of on/off pulses mean this part. So instead of hand gestures, we now have this many on/off (0|1) means this (the next letter in our example). We call this Binary language. In fact heres the same sentence in the above quote
01001101 01100001 01101011 01100101 00100000 01100001 00100000 01101100 01100101 01100110 01110100 00100000 01100001 01110100 00100000 01110100 01101000 01100001 01110100 00100000 01110100 01110101 01110010 01101110
(I will just say that each group is considered a single byte, not gonna break it down to byte/bit/nibble sh*t might as well go into making circuit boards lol I'll stick to the code part)
However, thats much harder for us to say, or even read esp long nights when the numbers just melt together, god forbid you have dyslexia. so how do we make these on/off pulses make sense to us? Simplify them. One way is to take groups and condense them into larger values that the computer can take a block and interpret it as the original value such as Hex(hexadecimal, or allowing us to use 0-15 in place of four on/off sectors, which we group in bytes. Why? again making circuits, don't care, google it, back to the code). Lets do the quote again
4d 61 6b 65 20 61 20 6c 65 66 74 20 61 74 20 74 68 61 74 20 74 75 72 6e
Now thats still hard to read, so we take groups again, and so on until we can say a simple thing in our millions+ word language, and the computer can repeat it simply for their 2 word language.

So lets apply this to what this thread is about. To get to this middle ground where humans can read what computers understand, we need to take the binary code and group in a way that we can understand what each group of 0s and 1s was instructed to do as an operation code, or opcode. If you're hardcore (or a masochist) break down the binary. If you want a little easier task, convert to hex and read those groups. Or, you can actually figure out, gee this would be nice if it was automated to find the info out, and try to find and understand that tool (not much faith there, still try to answer questions without saying "google it asshat" but i digress) These are disassemblers.
Disassemblers automatically start to go thru the binary of the file, get the hex equivalent, and the the corresponding opcode/operand of the bytes in question. Each byte is either an opcode, operand ie. data, or both. For example, in x86 architecture, moving the next byte of data I input into a register would be the MOV opcode taking 5 bits (binary 10110) and the register taking three (register=000-111) or in hex, B0-B7 depending on register. Moving the next word variable changes one bit (binary 10111 instead) and the same register options, so hex B8-BF. So you see, a simple 0-1 change can make that much difference and how we communicate becomes easier to understand.

So if computer only reads binary and a dissembler takes that and make it readable, whats the problem on changing instructions? You should be able to mod anything!!
Not quite.
Just like everything else in this world, we have choices. different brands breeds different fanboys, and each trying to add unique flavor to keep the market in their favor. So we have different architectures for different products, who have different opcodes, in different assemblies. Case in point, above example. Lets say your x86 built program has B1 in its binary which we just learned moves data into that registry, in this case, registry CL. Well in CIL (used in .NET so most .dll files and windows executables), this means SQUAT. Well it means something, but it may be a pointer, function address, w/e but couldn't say without more info.This is what our disassembler says about that byte as well, its amazing how some files disassemble very readable and some not so much. Worse, disassembling using the wrong framework would be useless to edit as too many instructions get mangled by misinterpretation. I have yet to ever see a file that gets 100% disassembled into 100% readable code. So we do the best we can with the info we got.

I will continue this segment in future tutes if enough interest in it, or I can stick to the sauce, no matters to me :) If you got this far thanks for reading!
 

s810car

Advance Member
Dec 9, 2016
199
The sauce
Source: Wikipedia
All comments are my addition to the info, if I'm incorrect on any, please clarify and I'll make the adjustment



Instruction Types
Base: performs universally compatible commands (conditionals, type conversions, arithmatic function. etc)
Object model: Allows for OOP, cast object types and refereences such as pointers,etc.
Prefix to Instruction: allows layering of another rule upon the following instruction

Order A-Z
0x58 add Add two values, returning a new value. Base instruction
0xD6 add.ovf Add signed integer values with overflow check. Base instruction
0xD7 add.ovf.un Add unsigned integer values with overflow check. Base instruction
// If you remember from school, signed means positive or negative, unsigned are positive numbersa ONLY, don't use a negative in an Unsigned integer

0xFE 0x00 arglist Return argument list handle for the current method. Base instruction

// branch is a form of jump, or goto, if arguement is true, branch to x, if not go to next line
0x3B beq <int32 (target)> Branch to target if equal. Base instruction
0x2E beq.s <int8 (target)> Branch to target if equal, short form. Base instruction
// so x == y
// short form requires 8bit integer, so bge.un if 32bit. this is the case with all x.s opcodes. for bge.un, un means unORDERED (floating point) not unsigned) so
// if one value is NaN, use bge.un, otherwise use bge. Equivalent function= (x == y ? branch : goto next line)
// this applies to all branch functions just replace == with different operand
0x3C bge <int32 (target)> Branch to target if greater than or equal to. Base instruction
0x2F bge.s <int8 (target)> Branch to target if greater than or equal to, short form. Base instruction
0x41 bge.un <int32 (target)> Branch to target if greater than or equal to (unsigned or unordered). Base instruction
0x34 bge.un.s <int8 (target)> Branch to target if greater than or equal to (unsigned or unordered), short form Base instruction
// x >= y
0x3D bgt <int32 (target)> Branch to target if greater than. Base instruction
0x30 bgt.s <int8 (target)> Branch to target if greater than, short form. Base instruction
0x42 bgt.un <int32 (target)> Branch to target if greater than (unsigned or unordered). Base instruction
0x35 bgt.un.s <int8 (target)> Branch to target if greater than (unsigned or unordered), short form. Base instruction
// x > y
0x3E ble <int32 (target)> Branch to target if less than or equal to. Base instruction
0x31 ble.s <int8 (target)> Branch to target if less than or equal to, short form. Base instruction
0x43 ble.un <int32 (target)> Branch to target if less than or equal to (unsigned or unordered). Base instruction
0x36 ble.un.s <int8 (target)> Branch to target if less than or equal to (unsigned or unordered), short form Base instruction
// x <= y
0x3F blt <int32 (target)> Branch to target if less than. Base instruction
0x32 blt.s <int8 (target)> Branch to target if less than, short form. Base instruction
0x44 blt.un <int32 (target)> Branch to target if less than (unsigned or unordered). Base instruction
0x37 blt.un.s <int8 (target)> Branch to target if less than (unsigned or unordered), short form. Base instruction
// x < y
0x40 bne.un <int32 (target)> Branch to target if unequal or unordered. Base instruction
0x33 bne.un.s <int8 (target)> Branch to target if unequal or unordered, short form. Base instruction
// x != y
0x38 br <int32 (target)> Branch to target. Base instruction
0x2B br.s <int8 (target)> Branch to target, short form. Base instruction
// jump/goto non conditional, just do it (Branch == true)
0x39 brfalse <int32 (target)> Branch to target if value is zero (false). Base instruction
0x2C brfalse.s <int8 (target)> Branch to target if value is zero (false), short form. Base instruction
// (x == false ? Branch : goto next line)
0x3A brinst <int32 (target)> Branch to target if value is a non-null object reference (alias for brtrue). Base instruction
0x2D brinst.s <int8 (target)> Branch to target if value is a non-null object reference, short form (alias for brtrue.s). Base instruction
// as example =
// Private x as Object
// put something into x
// (x != 0 ? Branch : goto next line)
0x39 brnull <int32 (target)> Branch to target if value is null. Base instruction
0x2C brnull.s <int8 (target)> Branch to target if value is null, short form. Base instruction
// (x === null ? Branch : goto next line)
0x3A brtrue <int32 (target)> Branch to target if value is non-zero (true). Base instruction
0x2D brtrue.s <int8 (target)> Branch to target if value is non-zero (true), short form. Base instruction
// (x != 0 ? Branch : goto next line)
0x39 brzero <int32 (target)> Branch to target if value is zero (alias for brfalse). Base instruction
0x2C brzero.s <int8 (target)> Branch to target if value is zero (alias for brfalse.s), short form. Base instruction
// (x == 0 ? Branch : goto next line) same as brfalse
// end of branch commands

0x8C box <typeTok> Convert a boxable value to its boxed form Object model instruction
0x79 unbox <valuetype> Extract a value-type from obj, its boxed representation. Object model instruction
0xA5 unbox.any <typeTok> Extract a value-type from obj, its boxed representation Object model instruction
// for Object programming, converts data of a single type (example int, float, w/e) into an object example Private x as Object
// won't be useful to modify in mods but would show how the data is stored in case you need to find and manipulat before boxed

0x01 break Inform a debugger that a breakpoint has been reached. Base instruction
// Important!! Use if youre debugging your mod to set breakpoints

0x28 call <method> Call method described by method. Base instruction
0x29 calli <callsitedescr> Call method indicated on the stack with arguments described by callsitedescr. Base instruction
0x6F callvirt <method> Call a method associated with an object. Object model instruction
// Calls are simply when a function is called, no brainwork there. callvirt applies this to a object function (objectX.DataIntoObject() for example)
// Calli best i can describe would be it calls the data from the object not the object itself (the end restult not the loaded object) maybe someone here
// can clarify better, its not going to be modded anyways you would have to go to the function itself if theres data to manipulate

0x74 castclass <class> Cast obj to class. Object model instruction
// Again beyond scope of modding, moving on

// cxx are compare or check commands, important to watch for since these will compare two arguments (very likely one you are modding) and pass true or false
// watch for these and make sure they will pass which value you need (true or false)
0xFE 0x01 ceq Push 1 (of type int32) if value1 equals value2, else push 0. Base instruction
0xFE 0x02 cgt Push 1 (of type int32) if value1 > value2, else push 0. Base instruction
0xFE 0x03 cgt.un Push 1 (of type int32) if value1 > value2, unsigned or unordered, else push 0. Base instruction
0xFE 0x04 clt Push 1 (of type int32) if value1 < value2, else push 0. Base instruction
0xFE 0x05 clt.un Push 1 (of type int32) if value1 < value2, unsigned or unordered, else push 0. Base instruction
0xC3 ckfinite Throw ArithmeticException if value is not a finite number. Base instruction
// this one may effect some errors you have, it throw an exception when your value is either NaN, or a floating point that is infinite such as 1/3 or pi
// end of compare commands

0xFE 0x16 constrained. <thisType> Call a virtual method on a type constrained to be type T Prefix to instruction
// used with callvirt usually, not needed to worry about in mods, provided you don't change any data's type, value is fine to alter

// conversions, can be important if you're possibly changing type, or making a number larger than the bits allow, IMPORTANT does not throw
// exceptions so if your alteration is buggy such as changing a float to an int you won't know except your mod wont work, use conv.ovf to
// error check
0xD3 conv.i Convert to native int, pushing native int on stack. Base instruction
0x67 conv.i1 Convert to int8, pushing int32 on stack. Base instruction
0x68 conv.i2 Convert to int16, pushing int32 on stack. Base instruction
0x69 conv.i4 Convert to int32, pushing int32 on stack. Base instruction
0x6A conv.i8 Convert to int64, pushing int64 on stack. Base instruction
0x76 conv.r.un Convert unsigned integer to floating-point, pushing F on stack. Base instruction
0x6B conv.r4 Convert to float32, pushing F on stack. Base instruction
0x6C conv.r8 Convert to float64, pushing F on stack. Base instruction
0xE0 conv.u Convert to native unsigned int, pushing native int on stack. Base instruction
0xD2 conv.u1 Convert to unsigned int8, pushing int32 on stack. Base instruction
0xD1 conv.u2 Convert to unsigned int16, pushing int32 on stack. Base instruction
0x6D conv.u4 Convert to unsigned int32, pushing int32 on stack. Base instruction
0x6E conv.u8 Convert to unsigned int64, pushing int64 on stack. Base instruction

// Conversions with error checks
0xD4 conv.ovf.i Convert to a native int (on the stack as native int) and throw an exception on overflow. Base instruction
0x8A conv.ovf.i.un Convert unsigned to a native int (on the stack as native int) and throw an exception on overflow. Base instruction
0xB3 conv.ovf.i1 Convert to an int8 (on the stack as int32) and throw an exception on overflow. Base instruction
0x82 conv.ovf.i1.un Convert unsigned to an int8 (on the stack as int32) and throw an exception on overflow. Base instruction
0xB5 conv.ovf.i2 Convert to an int16 (on the stack as int32) and throw an exception on overflow. Base instruction
0x83 conv.ovf.i2.un Convert unsigned to an int16 (on the stack as int32) and throw an exception on overflow. Base instruction
0xB7 conv.ovf.i4 Convert to an int32 (on the stack as int32) and throw an exception on overflow. Base instruction
0x84 conv.ovf.i4.un Convert unsigned to an int32 (on the stack as int32) and throw an exception on overflow. Base instruction
0xB9 conv.ovf.i8 Convert to an int64 (on the stack as int64) and throw an exception on overflow. Base instruction
0x85 conv.ovf.i8.un Convert unsigned to an int64 (on the stack as int64) and throw an exception on overflow. Base instruction
0xD5 conv.ovf.u Convert to a native unsigned int (on the stack as native int) and throw an exception on overflow. Base instruction
0x8B conv.ovf.u.un Convert unsigned to a native unsigned int (on the stack as native int) and throw an exception on overflow. Base instruction
0xB4 conv.ovf.u1 Convert to an unsigned int8 (on the stack as int32) and throw an exception on overflow. Base instruction
0x86 conv.ovf.u1.un Convert unsigned to an unsigned int8 (on the stack as int32) and throw an exception on overflow. Base instruction
0xB6 conv.ovf.u2 Convert to an unsigned int16 (on the stack as int32) and throw an exception on overflow. Base instruction
0x87 conv.ovf.u2.un Convert unsigned to an unsigned int16 (on the stack as int32) and throw an exception on overflow. Base instruction
0xB8 conv.ovf.u4 Convert to an unsigned int32 (on the stack as int32) and throw an exception on overflow. Base instruction
0x88 conv.ovf.u4.un Convert unsigned to an unsigned int32 (on the stack as int32) and throw an exception on overflow. Base instruction
0xBA conv.ovf.u8 Convert to an unsigned int64 (on the stack as int64) and throw an exception on overflow. Base instruction
0x89 conv.ovf.u8.un Convert unsigned to an unsigned int64 (on the stack as int64) and throw an exception on overflow. Base instruction
// end of conversions

0xFE 0x17 cpblk Copy data from memory to memory. Base instruction
// Useful with jmp to create code caves

0x70 cpobj <typeTok> Copy a value type from src to dest. Object model instruction //Not needed in modding

0x5B div Divide two values to return a quotient or floating-point result. Base instruction
0x5C div.un Divide two values, unsigned, returning a quotient. Base instruction
0x25 dup Duplicate the value on the top of the stack. Base instruction
// self explanitory

0xDC endfault End fault clause of an exception block. Base instruction
0xFE 0x11 endfilter End an exception handling filter clause. Base instruction
0xDC endfinally End finally clause of an exception block. Base instruction
// exception handlers, return the errors

0xFE 0x18 initblk Set all bytes in a block of memory to a given byte value. Base instruction
// sounds great at first for direct manipulation, but VERY error prone/dangerous, for modding i'd ignore

0xFE 0x15 initobj <typeTok> Initialize the value at address dest. Object model instruction
0x75 isinst <class> Test if obj is an instance of class, returning null or an instance of that class or interface. Object model instruction
// not for modding purpose

0x27 jmp <method> Exit current method and jump to the specified method. Base instruction
// again, think code caves

// load opcodes are one of the most important opcodes for modders and seem to be the most confusing esp. for new modders, i'll try to simplify as best
// as possible and I'm asking experience modders for their two cents which good info will be added here
0xFE 0x09 ldarg <uint16 (num)> Load argument numbered num onto the stack. Base instruction
0x02 ldarg.0 Load argument 0 onto the stack. Base instruction
0x03 ldarg.1 Load argument 1 onto the stack. Base instruction
0x04 ldarg.2 Load argument 2 onto the stack. Base instruction
0x05 ldarg.3 Load argument 3 onto the stack. Base instruction
0x0E ldarg.s <uint8 (num)> Load argument numbered num onto the stack, short form. Base instruction
// Load arguments set up the variable, ex (int x;) mistake many make is to change this. Don't do that. If a line says ldarg.0 leave it alone
// however pay attention to following lines, most likely you'll alter or put something there

0xFE 0x0A ldarga <uint16 (argNum)> Fetch the address of argument argNum. Base instruction
0x0F ldarga.s <uint8 (argNum)> Fetch the address of argument argNum, short form. Base instruction
// instead of loading a variable, loading the reference address (not (int x;), but (int* PointerX = &x;) instead)

0x20 ldc.i4 <int32 (num)> Push num of type int32 onto the stack as int32. Base instruction
0x16 ldc.i4.0 Push 0 onto the stack as int32. Base instruction
0x17 ldc.i4.1 Push 1 onto the stack as int32. Base instruction
0x18 ldc.i4.2 Push 2 onto the stack as int32. Base instruction
0x19 ldc.i4.3 Push 3 onto the stack as int32. Base instruction
0x1A ldc.i4.4 Push 4 onto the stack as int32. Base instruction
0x1B ldc.i4.5 Push 5 onto the stack as int32. Base instruction
0x1C ldc.i4.6 Push 6 onto the stack as int32. Base instruction
0x1D ldc.i4.7 Push 7 onto the stack as int32. Base instruction
0x1E ldc.i4.8 Push 8 onto the stack as int32. Base instruction
0x15 ldc.i4.m1 Push -1 onto the stack as int32. Base instruction
0x15 ldc.i4.M1 Push -1 onto the stack as int32 (alias for ldc.i4.m1). Base instruction
0x21 ldc.i8 <int64 (num)> Push num of type int64 onto the stack as int64. Base instruction
0x22 ldc.r4 <float32 (num)> Push num of type float32 onto the stack as F. Base instruction
0x23 ldc.r8 <float64 (num)> Push num of type float64 onto the stack as F. Base instruction
// Load values are pretty simple, in reality look at ldc.i4 <int32 (num)> which simply loads the value you put for <int32 (num)>, example ldc.i4 55
// puts 55 as the value. In other words ldc.i4.3 and ldc.id 3 are IDENTICAL (save for the space the opcode takes, if you need to keep the file a certain
// size for specific security checks you need to keep the line the same size, use the format your disassembler uses)
// these opcodes typically follow ldarg codes, alter the ldc code, not the ldarg

0x1F ldc.i4.s <int8 (num)> Push num onto the stack as int32, short form. Base instruction
// short version, ensure you fit as int8 instead of int32

0xA3 ldelem <typeTok> Load the element at index onto the top of the stack. Object model instruction
0x97 ldelem.i Load the element with type native int at index onto the top of the stack as a native int. Object model instruction
0x90 ldelem.i1 Load the element with type int8 at index onto the top of the stack as an int32. Object model instruction
0x92 ldelem.i2 Load the element with type int16 at index onto the top of the stack as an int32. Object model instruction
0x94 ldelem.i4 Load the element with type int32 at index onto the top of the stack as an int32. Object model instruction
0x96 ldelem.i8 Load the element with type int64 at index onto the top of the stack as an int64. Object model instruction
0x98 ldelem.r4 Load the element with type float32 at index onto the top of the stack as an F Object model instruction
0x99 ldelem.r8 Load the element with type float64 at index onto the top of the stack as an F. Object model instruction
0x9A ldelem.ref Load the element at index onto the top of the stack as an O. The type of the O is the same as the element type of the array pushed on the CIL stack. Object model instruction
0x91 ldelem.u1 Load the element with type unsigned int8 at index onto the top of the stack as an int32. Object model instruction
0x93 ldelem.u2 Load the element with type unsigned int16 at index onto the top of the stack as an int32. Object model instruction
0x95 ldelem.u4 Load the element with type unsigned int32 at index onto the top of the stack as an int32. Object model instruction
0x96 ldelem.u8 Load the element with type unsigned int64 at index onto the top of the stack as an int64 (alias for ldelem.i8). Object model instruction
// Load elements pertain to arrays, not single value variables (array[0],array[1],array[y] versus x)

0x8F ldelema <class> Load the address of element at index onto the top of the stack. Object model instruction
// so we have (int array[10]) then ldelema will pull (int* pointer = &array)

0x7B ldfld <field> Push the value of field of object (or value type) obj, onto the stack. Object model instruction
0x7C ldflda <field> Push the address of field of object obj on the stack. Object model instruction
// this is more important when it comes to arrays, basically ldelem for arrays = ldarg for single variables, so
// ldfld for array items such as array[0] value works like ldc.i4 for single values
// IMPORTANT reference needed as I am not 100% sure on this and it may be useful

0xFE 0x06 ldftn <method> Push a pointer to a method referenced by method, on the stack. Base instruction // Not needed for modding

0x4D ldind.i Indirect load value of type native int as native int on the stack Base instruction
0x46 ldind.i1 Indirect load value of type int8 as int32 on the stack. Base instruction
0x48 ldind.i2 Indirect load value of type int16 as int32 on the stack. Base instruction
0x4A ldind.i4 Indirect load value of type int32 as int32 on the stack. Base instruction
0x4C ldind.i8 Indirect load value of type int64 as int64 on the stack. Base instruction
0x4E ldind.r4 Indirect load value of type float32 as F on the stack. Base instruction
0x4F ldind.r8 Indirect load value of type float64 as F on the stack. Base instruction
0x50 ldind.ref Indirect load value of type object ref as O on the stack. Base instruction
0x47 ldind.u1 Indirect load value of type unsigned int8 as int32 on the stack Base instruction
0x49 ldind.u2 Indirect load value of type unsigned int16 as int32 on the stack Base instruction
0x4B ldind.u4 Indirect load value of type unsigned int32 as int32 on the stack Base instruction
0x4C ldind.u8 Indirect load value of type unsigned int64 as int64 on the stack (alias for ldind.i8). Base instruction
// shouldn't be needed, use ldc.i4 commands instead

0x8E ldlen Push the length (of type native unsigned int) of array on the stack. Object model instruction //not needed for modding unless debugging

0xFE 0x0C ldloc <uint16 (indx)> Load local variable of index indx onto stack. Base instruction
0x06 ldloc.0 Load local variable 0 onto stack. Base instruction
0x07 ldloc.1 Load local variable 1 onto stack. Base instruction
0x08 ldloc.2 Load local variable 2 onto stack. Base instruction
0x09 ldloc.3 Load local variable 3 onto stack. Base instruction
0x11 ldloc.s <uint8 (indx)> Load local variable of index indx onto stack, short form. Base instruction
0xFE 0x0D ldloca <uint16 (indx)> Load address of local variable with index indx. Base instruction
0x12 ldloca.s <uint8 (indx)> Load address of local variable with index indx, short form. Base instruction
// important when inside a function or class, think of ldloc like a local ldarg. you can use the same information for modifying, EXCEPT don't try
// to call that same variable outside the current function it'll either not do anything or pull an incorrent/different variable, which would be
// pretty hard to debug if you make that mistake

0x14 ldnull Push a null reference on the stack. Base instruction
// simply puts a null value, useful if theres an instance of ldarg you want to be null

0x71 ldobj <typeTok> Copy the value stored at address src to the stack. Object model instruction
// ex. int* value = &object.valuex given you would need to know the data at the address to be useful, not needed for "simple" mods. For advanced mods
// This is useful but if you're at that level this tut isn't useful except for reference

0x7E ldsfld <field> Push the value of field on the stack. Object model instruction
// ex. if you wanted your ldarg x to equal variableY you would go (ldsfld variableY) make sure the variable is accesible in the function youre altering

0x7F ldsflda <field> Push the address of the static field, field, on the stack. Object model instruction
// int value = &fieldx again more advanced, not needed for simple mods

0x72 ldstr <string> Push a string object for the literal string. Object model instruction
// Dim x as string = "Hello World" similar to ldsfld but insteal of a variables value you input a direct value. ldstr is useful if you need a
// non numeric output equivalent of ldc.i4

0xD0 ldtoken <token> Convert metadata token to its runtime representation. Object model instruction
0xFE 0x07 ldvirtftn <method> Push address of virtual method on the stack. Object model instruction
// not needed for the scope of this tut

0xDD leave <int32 (target)> Exit a protected region of code. Base instruction
0xDE leave.s <int8 (target)> Exit a protected region of code, short form. Base instruction
// really shouldn't see these in production code, usable to try to bypass try--catch loops but thats for experienced modders only

0xFE 0x0F localloc Allocate space from the local memory pool. Base instruction // hardcore modding, shouldn't need to go here
0xC6 mkrefany <class> Push a typed reference to ptr of type class onto the stack. Object model instruction // not needed for this tut

0x5A mul Multiply values. Base instruction
0xD8 mul.ovf Multiply signed integer values. Signed result shall fit in same size Base instruction
0xD9 mul.ovf.un Multiply unsigned integer values. Unsigned result shall fit in same size Base instruction
0x65 neg Negate value. Base instruction
// arithmatic functions

0x8D newarr <etype> Create a new array with elements of type etype. Object model instruction
0x73 newobj <ctor> Allocate an uninitialized object or value type and call ctor. Object model instruction
// just program in higher level code don't mess with this lol

0xFE 0x19 no. { typecheck, rangecheck, nullcheck }
The specified fault check(s) normally performed as part of the execution of the subsequent instruction can/shall be skipped. Prefix to instruction
// VERY interesting possibilities here, but you better REALLY understand the code you're working on, experienced only need apply

0x00 nop Do nothing (No operation). Base instruction // Filler code, useful for staying in the same memory range during modding

0x5F and Bitwise AND of two integral values, returns an integral value. Base instruction
0x66 not Bitwise complement (logical not). Base instruction
0x60 or Bitwise OR of two integer values, returns an integer. Base instruction
0x61 xor Bitwise XOR of integer values, returns an integer. Base instruction
// bitwise opcodes, google logical and/or/xor if you want info on this, useful for certain purposes, not simple modding esp. if no real sucurity or encryption on the apk

0x26 pop Pop value from the stack. Base instruction // Pop pulls data pushed onto the stack, simple

0xFE 0x1E readonly. Specify that the subsequent array address operation performs no type check at runtime, and that it returns a controlled-mutability managed pointer Prefix to instruction
0xFE 0x1D refanytype Push the type token stored in a typed reference. Object model instruction
0xC2 refanyval <type> Push the address stored in a typed reference. Object model instruction
// Not needed for this tut

0x5D rem Remainder when dividing one value by another. Base instruction
0x5E rem.un Remainder when dividing one unsigned value by another. Base instruction
arithmatic function

0x2A ret Return from method, possibly with a value. Base instruction
//end of function, may or may not send info back, don't put any code after ret

0xFE 0x1A rethrow Rethrow the current exception. Object model instruction // exception handling, easy to understand

0x62 shl Shift an integer left (shifting in zeros), return an integer. Base instruction
0x63 shr Shift an integer right (shift in sign), return an integer. Base instruction
0x64 shr.un Shift an integer right (shift in zero), return an integer. Base instruction
// quick change of int to float, altering the place value, and returning as int

0xFE 0x1C sizeof <typeTok> Push the size, in bytes, of a type as an unsigned int32. Object model instruction
// debugging uses otherwise not needed for modding

// Store opcodes look very useful at a glance, but it goes back to how easiest to alter data. Think about other tutes you've read
// how many told you to alter (for example) getAtk() vs putAtk() ? For webpages what are you allowed to alter client side in php (without
// hard server hacks) is it $_GET or $_POST? same idea here. The trick is you want to make the game GET its data it thinks it has for you (data you altered of course)
// versus you trying to force a different value on it which is prone to server checks, sanitizing, errors, etc.
// there will be cases where altering these work on weaker setup code (and believe me I wish modding was as simple as messing with store opcodes) but
// I don't need to repeat what every tute already says, focus on what works most of the time first before playing here
0xFE 0x0B starg <uint16 (num)> Store value to the argument numbered num. Base instruction
0x10 starg.s <uint8 (num)> Store value to the argument numbered num, short form. Base instruction
0xA4 stelem <typeTok> Replace array element at index with the value on the stack Object model instruction
0x9B stelem.i Replace array element at index with the i value on the stack. Object model instruction
0x9C stelem.i1 Replace array element at index with the int8 value on the stack. Object model instruction
0x9D stelem.i2 Replace array element at index with the int16 value on the stack. Object model instruction
0x9E stelem.i4 Replace array element at index with the int32 value on the stack. Object model instruction
0x9F stelem.i8 Replace array element at index with the int64 value on the stack. Object model instruction
0xA0 stelem.r4 Replace array element at index with the float32 value on the stack. Object model instruction
0xA1 stelem.r8 Replace array element at index with the float64 value on the stack. Object model instruction
0xA2 stelem.ref Replace array element at index with the ref value on the stack. Object model instruction
0x7D stfld <field> Replace the value of field of the object obj with value. Object model instruction
0xDF stind.i Store value of type native int into memory at address Base instruction
0x52 stind.i1 Store value of type int8 into memory at address Base instruction
0x53 stind.i2 Store value of type int16 into memory at address Base instruction
0x54 stind.i4 Store value of type int32 into memory at address Base instruction
0x55 stind.i8 Store value of type int64 into memory at address Base instruction
0x56 stind.r4 Store value of type float32 into memory at address Base instruction
0x57 stind.r8 Store value of type float64 into memory at address Base instruction
0x51 stind.ref Store value of type object ref (type O) into memory at address Base instruction
0xFE 0x0E stloc <uint16 (indx)> Pop a value from stack into local variable indx. Base instruction
0x0A stloc.0 Pop a value from stack into local variable 0. Base instruction
0x0B stloc.1 Pop a value from stack into local variable 1. Base instruction
0x0C stloc.2 Pop a value from stack into local variable 2. Base instruction
0x0D stloc.3 Pop a value from stack into local variable 3. Base instruction
0x13 stloc.s <uint8 (indx)> Pop a value from stack into local variable indx, short form. Base instruction
0x81 stobj <typeTok> Store a value of type typeTok at an address. Object model instruction
0x80 stsfld <field> Replace the value of field with val. Object model instruction
// end of store opcodes

0x59 sub Subtract value2 from value1, returning a new value. Base instruction
0xDA sub.ovf Subtract native int from a native int. Signed result shall fit in same size Base instruction
0xDB sub.ovf.un Subtract native unsigned int from a native unsigned int. Unsigned result shall fit in same size. Base instruction
// arithmatic function

0x45 switch <uint32, int32, int32 (t1..tN)> Jump to one of n values. Base instruction
0xFE 0x14 tail. Subsequent call terminates current method Prefix to instruction
0x7A throw Throw an exception. Object model instruction
0xFE 0x12 unaligned. (alignment) Subsequent pointer instruction might be unaligned. Prefix to instruction
0xFE 0x13 volatile. Subsequent pointer reference is volatile. Prefix to instruction
// Ok I got lazy but these last few aren't needed for modding really so look them up if interested
Order by Hex
0x00 nop Do nothing (No operation). Base instruction
0x01 break Inform a debugger that a breakpoint has been reached. Base instruction
0x02 ldarg.0 Load argument 0 onto the stack. Base instruction
0x03 ldarg.1 Load argument 1 onto the stack. Base instruction
0x04 ldarg.2 Load argument 2 onto the stack. Base instruction
0x05 ldarg.3 Load argument 3 onto the stack. Base instruction
0x06 ldloc.0 Load local variable 0 onto stack. Base instruction
0x07 ldloc.1 Load local variable 1 onto stack. Base instruction
0x08 ldloc.2 Load local variable 2 onto stack. Base instruction
0x09 ldloc.3 Load local variable 3 onto stack. Base instruction
0x0A stloc.0 Pop a value from stack into local variable 0. Base instruction
0x0B stloc.1 Pop a value from stack into local variable 1. Base instruction
0x0C stloc.2 Pop a value from stack into local variable 2. Base instruction
0x0D stloc.3 Pop a value from stack into local variable 3. Base instruction
0x0E ldarg.s <uint8 (num)> Load argument numbered num onto the stack, short form. Base instruction
0x0F ldarga.s <uint8 (argNum)> Fetch the address of argument argNum, short form. Base instruction
0x10 starg.s <uint8 (num)> Store value to the argument numbered num, short form. Base instruction
0x11 ldloc.s <uint8 (indx)> Load local variable of index indx onto stack, short form. Base instruction
0x12 ldloca.s <uint8 (indx)> Load address of local variable with index indx, short form. Base instruction
0x13 stloc.s <uint8 (indx)> Pop a value from stack into local variable indx, short form. Base instruction
0x14 ldnull Push a null reference on the stack. Base instruction
0x15 ldc.i4.m1 Push -1 onto the stack as int32. Base instruction
0x15 ldc.i4.M1 Push -1 onto the stack as int32 (alias for ldc.i4.m1). Base instruction
0x16 ldc.i4.0 Push 0 onto the stack as int32. Base instruction
0x17 ldc.i4.1 Push 1 onto the stack as int32. Base instruction
0x18 ldc.i4.2 Push 2 onto the stack as int32. Base instruction
0x19 ldc.i4.3 Push 3 onto the stack as int32. Base instruction
0x1A ldc.i4.4 Push 4 onto the stack as int32. Base instruction
0x1B ldc.i4.5 Push 5 onto the stack as int32. Base instruction
0x1C ldc.i4.6 Push 6 onto the stack as int32. Base instruction
0x1D ldc.i4.7 Push 7 onto the stack as int32. Base instruction
0x1E ldc.i4.8 Push 8 onto the stack as int32. Base instruction
0x1F ldc.i4.s <int8 (num)> Push num onto the stack as int32, short form. Base instruction
0x20 ldc.i4 <int32 (num)> Push num of type int32 onto the stack as int32. Base instruction
0x21 ldc.i8 <int64 (num)> Push num of type int64 onto the stack as int64. Base instruction
0x22 ldc.r4 <float32 (num)> Push num of type float32 onto the stack as F. Base instruction
0x23 ldc.r8 <float64 (num)> Push num of type float64 onto the stack as F. Base instruction
0x25 dup Duplicate the value on the top of the stack. Base instruction
0x26 pop Pop value from the stack. Base instruction
0x27 jmp <method> Exit current method and jump to the specified method. Base instruction
0x28 call <method> Call method described by method. Base instruction
0x29 calli <callsitedescr> Call method indicated on the stack with arguments described by callsitedescr. Base instruction
0x2A ret Return from method, possibly with a value. Base instruction
0x2B br.s <int8 (target)> Branch to target, short form. Base instruction
0x2C brfalse.s <int8 (target)> Branch to target if value is zero (false), short form. Base instruction
0x2C brnull.s <int8 (target)> Branch to target if value is null (alias for brfalse.s), short form. Base instruction
0x2C brzero.s <int8 (target)> Branch to target if value is zero (alias for brfalse.s), short form. Base instruction
0x2D brinst.s <int8 (target)> Branch to target if value is a non-null object reference, short form (alias for brtrue.s). Base instruction
0x2D brtrue.s <int8 (target)> Branch to target if value is non-zero (true), short form. Base instruction
0x2E beq.s <int8 (target)> Branch to target if equal, short form. Base instruction
0x2F bge.s <int8 (target)> Branch to target if greater than or equal to, short form. Base instruction
0x30 bgt.s <int8 (target)> Branch to target if greater than, short form. Base instruction
0x31 ble.s <int8 (target)> Branch to target if less than or equal to, short form. Base instruction
0x32 blt.s <int8 (target)> Branch to target if less than, short form. Base instruction
0x33 bne.un.s <int8 (target)> Branch to target if unequal or unordered, short form. Base instruction
0x34 bge.un.s <int8 (target)> Branch to target if greater than or equal to (unsigned or unordered), short form Base instruction
0x35 bgt.un.s <int8 (target)> Branch to target if greater than (unsigned or unordered), short form. Base instruction
0x36 ble.un.s <int8 (target)> Branch to target if less than or equal to (unsigned or unordered), short form Base instruction
0x37 blt.un.s <int8 (target)> Branch to target if less than (unsigned or unordered), short form. Base instruction
0x38 br <int32 (target)> Branch to target. Base instruction
0x39 brfalse <int32 (target)> Branch to target if value is zero (false). Base instruction
0x39 brnull <int32 (target)> Branch to target if value is null (alias for brfalse). Base instruction
0x39 brzero <int32 (target)> Branch to target if value is zero (alias for brfalse). Base instruction
0x3A brinst <int32 (target)> Branch to target if value is a non-null object reference (alias for brtrue). Base instruction
0x3A brtrue <int32 (target)> Branch to target if value is non-zero (true). Base instruction
0x3B beq <int32 (target)> Branch to target if equal. Base instruction
0x3C bge <int32 (target)> Branch to target if greater than or equal to. Base instruction
0x3D bgt <int32 (target)> Branch to target if greater than. Base instruction
0x3E ble <int32 (target)> Branch to target if less than or equal to. Base instruction
0x3F blt <int32 (target)> Branch to target if less than. Base instruction
0x40 bne.un <int32 (target)> Branch to target if unequal or unordered. Base instruction
0x41 bge.un <int32 (target)> Branch to target if greater than or equal to (unsigned or unordered). Base instruction
0x42 bgt.un <int32 (target)> Branch to target if greater than (unsigned or unordered). Base instruction
0x43 ble.un <int32 (target)> Branch to target if less than or equal to (unsigned or unordered). Base instruction
0x44 blt.un <int32 (target)> Branch to target if less than (unsigned or unordered). Base instruction
0x45 switch <uint32, int32, int32 (t1..tN)> Jump to one of n values. Base instruction
0x46 ldind.i1 Indirect load value of type int8 as int32 on the stack. Base instruction
0x47 ldind.u1 Indirect load value of type unsigned int8 as int32 on the stack Base instruction
0x48 ldind.i2 Indirect load value of type int16 as int32 on the stack. Base instruction
0x49 ldind.u2 Indirect load value of type unsigned int16 as int32 on the stack Base instruction
0x4A ldind.i4 Indirect load value of type int32 as int32 on the stack. Base instruction
0x4B ldind.u4 Indirect load value of type unsigned int32 as int32 on the stack Base instruction
0x4C ldind.i8 Indirect load value of type int64 as int64 on the stack. Base instruction
0x4C ldind.u8 Indirect load value of type unsigned int64 as int64 on the stack (alias for ldind.i8). Base instruction
0x4D ldind.i Indirect load value of type native int as native int on the stack Base instruction
0x4E ldind.r4 Indirect load value of type float32 as F on the stack. Base instruction
0x4F ldind.r8 Indirect load value of type float64 as F on the stack. Base instruction
0x50 ldind.ref Indirect load value of type object ref as O on the stack. Base instruction
0x51 stind.ref Store value of type object ref (type O) into memory at address Base instruction
0x52 stind.i1 Store value of type int8 into memory at address Base instruction
0x53 stind.i2 Store value of type int16 into memory at address Base instruction
0x54 stind.i4 Store value of type int32 into memory at address Base instruction
0x55 stind.i8 Store value of type int64 into memory at address Base instruction
0x56 stind.r4 Store value of type float32 into memory at address Base instruction
0x57 stind.r8 Store value of type float64 into memory at address Base instruction
0x58 add Add two values, returning a new value. Base instruction
0x59 sub Subtract value2 from value1, returning a new value. Base instruction
0x5A mul Multiply values. Base instruction
0x5B div Divide two values to return a quotient or floating-point result. Base instruction
0x5C div.un Divide two values, unsigned, returning a quotient. Base instruction
0x5D rem Remainder when dividing one value by another. Base instruction
0x5E rem.un Remainder when dividing one unsigned value by another. Base instruction
0x5F and Bitwise AND of two integral values, returns an integral value. Base instruction
0x60 or Bitwise OR of two integer values, returns an integer. Base instruction
0x61 xor Bitwise XOR of integer values, returns an integer. Base instruction
0x62 shl Shift an integer left (shifting in zeros), return an integer. Base instruction
0x63 shr Shift an integer right (shift in sign), return an integer. Base instruction
0x64 shr.un Shift an integer right (shift in zero), return an integer. Base instruction
0x65 neg Negate value. Base instruction
0x66 not Bitwise complement (logical not). Base instruction
0x67 conv.i1 Convert to int8, pushing int32 on stack. Base instruction
0x68 conv.i2 Convert to int16, pushing int32 on stack. Base instruction
0x69 conv.i4 Convert to int32, pushing int32 on stack. Base instruction
0x6A conv.i8 Convert to int64, pushing int64 on stack. Base instruction
0x6B conv.r4 Convert to float32, pushing F on stack. Base instruction
0x6C conv.r8 Convert to float64, pushing F on stack. Base instruction
0x6D conv.u4 Convert to unsigned int32, pushing int32 on stack. Base instruction
0x6E conv.u8 Convert to unsigned int64, pushing int64 on stack. Base instruction
0x6F callvirt <method> Call a method associated with an object. Object model instruction
0x70 cpobj <typeTok> Copy a value type from src to dest. Object model instruction
0x71 ldobj <typeTok> Copy the value stored at address src to the stack. Object model instruction
0x72 ldstr <string> Push a string object for the literal string. Object model instruction
0x73 newobj <ctor> Allocate an uninitialized object or value type and call ctor. Object model instruction
0x74 castclass <class> Cast obj to class. Object model instruction
0x75 isinst <class> Test if obj is an instance of class, returning null or an instance of that class or interface. Object model instruction
0x76 conv.r.un Convert unsigned integer to floating-point, pushing F on stack. Base instruction
0x79 unbox <valuetype> Extract a value-type from obj, its boxed representation. Object model instruction
0x7A throw Throw an exception. Object model instruction
0x7B ldfld <field> Push the value of field of object (or value type) obj, onto the stack. Object model instruction
0x7C ldflda <field> Push the address of field of object obj on the stack. Object model instruction
0x7D stfld <field> Replace the value of field of the object obj with value. Object model instruction
0x7E ldsfld <field> Push the value of field on the stack. Object model instruction
0x7F ldsflda <field> Push the address of the static field, field, on the stack. Object model instruction
0x80 stsfld <field> Replace the value of field with val. Object model instruction
0x81 stobj <typeTok> Store a value of type typeTok at an address. Object model instruction
0x82 conv.ovf.i1.un Convert unsigned to an int8 (on the stack as int32) and throw an exception on overflow. Base instruction
0x83 conv.ovf.i2.un Convert unsigned to an int16 (on the stack as int32) and throw an exception on overflow. Base instruction
0x84 conv.ovf.i4.un Convert unsigned to an int32 (on the stack as int32) and throw an exception on overflow. Base instruction
0x85 conv.ovf.i8.un Convert unsigned to an int64 (on the stack as int64) and throw an exception on overflow. Base instruction
0x86 conv.ovf.u1.un Convert unsigned to an unsigned int8 (on the stack as int32) and throw an exception on overflow. Base instruction
0x87 conv.ovf.u2.un Convert unsigned to an unsigned int16 (on the stack as int32) and throw an exception on overflow. Base instruction
0x88 conv.ovf.u4.un Convert unsigned to an unsigned int32 (on the stack as int32) and throw an exception on overflow. Base instruction
0x89 conv.ovf.u8.un Convert unsigned to an unsigned int64 (on the stack as int64) and throw an exception on overflow. Base instruction
0x8A conv.ovf.i.un Convert unsigned to a native int (on the stack as native int) and throw an exception on overflow. Base instruction
0x8B conv.ovf.u.un Convert unsigned to a native unsigned int (on the stack as native int) and throw an exception on overflow. Base instruction
0x8C box <typeTok> Convert a boxable value to its boxed form Object model instruction
0x8D newarr <etype> Create a new array with elements of type etype. Object model instruction
0x8E ldlen Push the length (of type native unsigned int) of array on the stack. Object model instruction
0x8F ldelema <class> Load the address of element at index onto the top of the stack. Object model instruction
0x90 ldelem.i1 Load the element with type int8 at index onto the top of the stack as an int32. Object model instruction
0x91 ldelem.u1 Load the element with type unsigned int8 at index onto the top of the stack as an int32. Object model instruction
0x92 ldelem.i2 Load the element with type int16 at index onto the top of the stack as an int32. Object model instruction
0x93 ldelem.u2 Load the element with type unsigned int16 at index onto the top of the stack as an int32. Object model instruction
0x94 ldelem.i4 Load the element with type int32 at index onto the top of the stack as an int32. Object model instruction
0x95 ldelem.u4 Load the element with type unsigned int32 at index onto the top of the stack as an int32. Object model instruction
0x96 ldelem.i8 Load the element with type int64 at index onto the top of the stack as an int64. Object model instruction
0x96 ldelem.u8 Load the element with type unsigned int64 at index onto the top of the stack as an int64 (alias for ldelem.i8). Object model instruction
0x97 ldelem.i Load the element with type native int at index onto the top of the stack as a native int. Object model instruction
0x98 ldelem.r4 Load the element with type float32 at index onto the top of the stack as an F Object model instruction
0x99 ldelem.r8 Load the element with type float64 at index onto the top of the stack as an F. Object model instruction
0x9A ldelem.ref Load the element at index onto the top of the stack as an O. The type of the O is the same as the element type of the array pushed on the CIL stack. Object model instruction
0x9B stelem.i Replace array element at index with the i value on the stack. Object model instruction
0x9C stelem.i1 Replace array element at index with the int8 value on the stack. Object model instruction
0x9D stelem.i2 Replace array element at index with the int16 value on the stack. Object model instruction
0x9E stelem.i4 Replace array element at index with the int32 value on the stack. Object model instruction
0x9F stelem.i8 Replace array element at index with the int64 value on the stack. Object model instruction
0xA0 stelem.r4 Replace array element at index with the float32 value on the stack. Object model instruction
0xA1 stelem.r8 Replace array element at index with the float64 value on the stack. Object model instruction
0xA2 stelem.ref Replace array element at index with the ref value on the stack. Object model instruction
0xA3 ldelem <typeTok> Load the element at index onto the top of the stack. Object model instruction
0xA4 stelem <typeTok> Replace array element at index with the value on the stack Object model instruction
0xA5 unbox.any <typeTok> Extract a value-type from obj, its boxed representation Object model instruction
0xB3 conv.ovf.i1 Convert to an int8 (on the stack as int32) and throw an exception on overflow. Base instruction
0xB4 conv.ovf.u1 Convert to an unsigned int8 (on the stack as int32) and throw an exception on overflow. Base instruction
0xB5 conv.ovf.i2 Convert to an int16 (on the stack as int32) and throw an exception on overflow. Base instruction
0xB6 conv.ovf.u2 Convert to an unsigned int16 (on the stack as int32) and throw an exception on overflow. Base instruction
0xB7 conv.ovf.i4 Convert to an int32 (on the stack as int32) and throw an exception on overflow. Base instruction
0xB8 conv.ovf.u4 Convert to an unsigned int32 (on the stack as int32) and throw an exception on overflow. Base instruction
0xB9 conv.ovf.i8 Convert to an int64 (on the stack as int64) and throw an exception on overflow. Base instruction
0xBA conv.ovf.u8 Convert to an unsigned int64 (on the stack as int64) and throw an exception on overflow. Base instruction
0xC2 refanyval <type> Push the address stored in a typed reference. Object model instruction
0xC3 ckfinite Throw ArithmeticException if value is not a finite number. Base instruction
0xC6 mkrefany <class> Push a typed reference to ptr of type class onto the stack. Object model instruction
0xD0 ldtoken <token> Convert metadata token to its runtime representation. Object model instruction
0xD1 conv.u2 Convert to unsigned int16, pushing int32 on stack. Base instruction
0xD2 conv.u1 Convert to unsigned int8, pushing int32 on stack. Base instruction
0xD3 conv.i Convert to native int, pushing native int on stack. Base instruction
0xD4 conv.ovf.i Convert to a native int (on the stack as native int) and throw an exception on overflow. Base instruction
0xD5 conv.ovf.u Convert to a native unsigned int (on the stack as native int) and throw an exception on overflow. Base instruction
0xD6 add.ovf Add signed integer values with overflow check. Base instruction
0xD7 add.ovf.un Add unsigned integer values with overflow check. Base instruction
0xD8 mul.ovf Multiply signed integer values. Signed result shall fit in same size Base instruction
0xD9 mul.ovf.un Multiply unsigned integer values. Unsigned result shall fit in same size Base instruction
0xDA sub.ovf Subtract native int from a native int. Signed result shall fit in same size Base instruction
0xDB sub.ovf.un Subtract native unsigned int from a native unsigned int. Unsigned result shall fit in same size. Base instruction
0xDC endfault End fault clause of an exception block. Base instruction
0xDC endfinally End finally clause of an exception block. Base instruction
0xDD leave <int32 (target)> Exit a protected region of code. Base instruction
0xDE leave.s <int8 (target)> Exit a protected region of code, short form. Base instruction
0xDF stind.i Store value of type native int into memory at address Base instruction
0xE0 conv.u Convert to native unsigned int, pushing native int on stack. Base instruction
0xFE 0x00 arglist Return argument list handle for the current method. Base instruction
0xFE 0x01 ceq Push 1 (of type int32) if value1 equals value2, else push 0. Base instruction
0xFE 0x02 cgt Push 1 (of type int32) if value1 > value2, else push 0. Base instruction
0xFE 0x03 cgt.un Push 1 (of type int32) if value1 > value2, unsigned or unordered, else push 0. Base instruction
0xFE 0x04 clt Push 1 (of type int32) if value1 < value2, else push 0. Base instruction
0xFE 0x05 clt.un Push 1 (of type int32) if value1 < value2, unsigned or unordered, else push 0. Base instruction
0xFE 0x06 ldftn <method> Push a pointer to a method referenced by method, on the stack. Base instruction
0xFE 0x07 ldvirtftn <method> Push address of virtual method on the stack. Object model instruction
0xFE 0x09 ldarg <uint16 (num)> Load argument numbered num onto the stack. Base instruction
0xFE 0x0A ldarga <uint16 (argNum)> Fetch the address of argument argNum. Base instruction
0xFE 0x0B starg <uint16 (num)> Store value to the argument numbered num. Base instruction
0xFE 0x0C ldloc <uint16 (indx)> Load local variable of index indx onto stack. Base instruction
0xFE 0x0D ldloca <uint16 (indx)> Load address of local variable with index indx. Base instruction
0xFE 0x0E stloc <uint16 (indx)> Pop a value from stack into local variable indx. Base instruction
0xFE 0x0F localloc Allocate space from the local memory pool. Base instruction
0xFE 0x11 endfilter End an exception handling filter clause. Base instruction
0xFE 0x12 unaligned. (alignment) Subsequent pointer instruction might be unaligned. Prefix to instruction
0xFE 0x13 volatile. Subsequent pointer reference is volatile. Prefix to instruction
0xFE 0x14 tail. Subsequent call terminates current method Prefix to instruction
0xFE 0x15 initobj <typeTok> Initialize the value at address dest. Object model instruction
0xFE 0x16 constrained. <thisType> Call a virtual method on a type constrained to be type T Prefix to instruction
0xFE 0x17 cpblk Copy data from memory to memory. Base instruction
0xFE 0x18 initblk Set all bytes in a block of memory to a given byte value. Base instruction
0xFE 0x19

no. {
typecheck,
rangecheck,
nullcheck
}

The specified fault check(s) normally performed as part of the execution of the subsequent instruction can/shall be skipped. Prefix to instruction
0xFE 0x1A rethrow Rethrow the current exception. Object model instruction
0xFE 0x1C sizeof <typeTok> Push the size, in bytes, of a type as an unsigned int32. Object model instruction
0xFE 0x1D refanytype Push the type token stored in a typed reference. Object model instruction
0xFE 0x1E readonly. Specify that the subsequent array address operation performs no type check at runtime, and that it returns a controlled-mutability managed pointer

Hopefuly by the end of this you can better read the assembly instructions in .NET Reflector or dnspy. What to do with that info is up to you.
 
Last edited: