0% found this document useful (0 votes)
16 views19 pages

Tools & Opcodes

This document provides a guide on cracking .NET applications, emphasizing the importance of understanding Microsoft Intermediate Language (MSIL) and the tools required for decompiling and analyzing .NET assemblies. It introduces essential tools such as Reflector, ildasm, and Hex Workshop, and explains the significance of MSIL opcodes in the cracking process. The document serves as an educational resource for individuals interested in reverse engineering .NET applications.

Uploaded by

mikrotik.misagh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views19 pages

Tools & Opcodes

This document provides a guide on cracking .NET applications, emphasizing the importance of understanding Microsoft Intermediate Language (MSIL) and the tools required for decompiling and analyzing .NET assemblies. It introduces essential tools such as Reflector, ildasm, and Hex Workshop, and explains the significance of MSIL opcodes in the cracking process. The document serves as an educational resource for individuals interested in reverse engineering .NET applications.

Uploaded by

mikrotik.misagh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

Kurapica

.NET reversing Tips

Tools & OPCodes

Attention
Published for educational Purposes only
Welcome:-
Welcome to the wonderful world of cracking.

In this series of tutorials we will be targeting .net applications, If


You search the web you will find [if you are lucky] few tutorials on this topic,
although the .net technology has been around for a while now but the number of
applications developed with it is still nothing compared to those developed with
[old] languages like C++ or Delphi or VB.

Cracking is the art of removing or disabling copy protected coding from programs,
this manual will go into some detail on removing copy protection from programs.
If you feel offended by this, then I would suggest you stop here....

Introduction:-
Cracking .net applications is still a new topic, and it has any similarities with
classic cracking, but I think It's much easier than cracking native code
application, the ability to see the source code and what Functions are exactly
being used with detailed information about every line being executed is what
makes this easier, here no Soft-Ice or W32Dasm are needed, we may need soft-
ice some time later, I don't know, but there is a new workflow here, and it's
basically dependent upon decompiling the IL code of the targeted assembly and
analyzing the source code that tools like reflector can generate, so a good
understanding of any one of the new .NET languages is essential and can be a
great advantage for you.

Tools:-
Before we begin, you will need certain tools, I use some of them, but this doesn't
Mean we will need them all Here, just make sure that you have them and try to
learn how to use them...

1. Reflector : .NET assembly Decompiler

Reflector is a class browser for .NET components. It allows browsing and


Searching the Meta data, IL instructions, resources and XML documentation
Stored in a .NET assembly.

Think of it as W32Dasm, this is an essential tool to explore


The assembly code and resources and I think it's the best
Tool available for this purpose; you can download the latest version
From here "http://www.aisto.com/roeder/dotnet"

2. ildasm : Microsoft IL Disassembler

The MSIL Disassembler is a companion tool to the MSIL Assembler (Ilasm.exe).


Ildasm.exe takes a portable executable (PE) file that contains
Microsoft intermediate language (MSIL) code and creates a text
File suitable as input to Ilasm.exe.

Although Reflector can decompile a .net assembly into IL codes but


It won't show us the real byte of IL instructions in the assembly.
Ildasm has an option which reveals the Hex value of bytes that
Represent IL instructions in every method.

Take the "BLE" instruction for example:


It transfers control to a target instruction if the first value is
Less than or equal to the second value. [Like JLE in native code]
And its actual byte that you will see in a hex editor is "3E".

When you need to invert this jump you will need the actual bytes
Of the instruction "BGT" which Transfers control to a target
Instruction if the first value is greater than the second value.
And it's represented as "3D".

So you will need to replace the 3E with 3D in hex editor to get the job done....

Now look at this dump of some procedure from ildasm.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
.method public specialname instance class Scroller.Scroller/Title
get_Titles(object Index) cil managed
// SIG: 20 01 12 0C 1C
{
// Method begins at RVA 0xcd7c
// Code size 23 (0x17)
.maxstack 2
.locals init (class Scroller.Scroller/Title V_0)
IL_0000: /* 02 | */ ldarg.0
IL_0001: /* 7B | (04)00000D */ ldfld
IL_0006: /* 03 | */ ldarg.1
IL_0007: /* 28 | (0A)00005C */ call object
IL_000c: /* 6F | (0A)00005D */ callvirt instance object
IL_0011: /* 74 | (02)000003 */ castclass
Scroller.Scroller/Title
IL_0016: /* 2A | */ ret
} // end of method Scroller::get_Titles
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

This is a piece of code in IL.

IL_0000 : Line number


02 : Actual byte of IL instructions in this line
ldarg.0 : IL instruction

Don't worry if you don't understand this code, we will talk about this more later...

The advantage of seeing the bytes that represent any IL instructions


comes when we want to nop a call or patch any part of the code.
We can also use the RVA value to calculate the offset of this method in the file
And I will explain both methods later.

You will find ildasm.exe in this folder after you install .Net framework SDK
"..\..\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\"
3. Hex workshop : Hex editor

I recommend this or any hex editor that can search for Unicode
Strings and locate a series of bytes.
Very easy to find on the web, just Google it!

4. CFF explorer : General PE files explorer

This is a great tool that will help us explore the contents of


Any PE file including metadata tables and resources inside
The assembly, you can download it from "www.pmode.com"

5. SNS remover : Strong Name signature remover

Some .net assemblies are signed with a digital signature to prevent


Any tampering or modification after the assembly is released, if
You modify any byte in a Strongly Named assembly then the .Net runtime
Will refuse to start that assembly, but there is a small utility called "SNS
remover"
That can be used to remove the signature field from the signed assembly.
By the way there is an option in CFF explorer that allows you to remove the
Strong Name signature from the .net assembly and rebuild the PE file again
But I prefer this small utility, you can download both from "www.pmode.com"

6. PEBrowse Professional : Disassembler/Debugger

A debugger and Disassembler for PE files that can disassemble and debug
.net assemblies too, It shows the IL instructions and their actual bytes,
You will be able to break on any JIT compiler event and this is cool!

With this debugger you can step through the .net IL instructions
And understand what's going in the background...
You can get it from "www.smidgeonsoft.com"

7. .Net Generic Unpacker : .Net assembly Unpacker

You will sometimes need this tool to dump the entire .net assembly
PE file, some protection software like ".Net reactor" will pack
Your .net assembly and will produce a non-MSIL PE file that will
Unpack your assembly and execute it from memory when launched, and
This technique is used to prevent any access to the IL code of the
Original assembly itself, but you can easily overcome this by using
A simple .net generic unpacker, you can download one from
"www.ntcore.com"

Finally:-
Sometimes you will see that "Reflector" won't be able to
Decompile some procedure or function into your favorite language like
C# or VB or Delphi, so you will have to familiarize yourself with
The IL instructions, and this is like learning the classic
Assembly language to crack native code applications, but you
Will see that IL is easier and faster to learn!
The Opcodes:-
This is the most important point of cracking, as you know the .net application
Represent their program instruction in MSIL format which stands for Microsoft
Intermediate language, your source code is not translated to native machine-code
when you compile it in visual studio RAD, but it's translated to this format which
will later be compiled into native code by JIT compiler, JIT stands for just-in-time
Compiler, meaning that only certain parts of your programs will be translated into
Native code and executed on demand.

This is a disassembly for a piece of code from ildasm.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
.method public specialname instance class Scroller.Scroller/Title
get_Titles(object Index) cil managed
// SIG: 20 01 12 0C 1C
{
// Method begins at RVA 0xcd7c
// Code size 23 (0x17)
.maxstack 2
.locals init (class Scroller.Scroller/Title V_0)
IL_0000: /* 02 | */ ldarg.0
IL_0001: /* 7B | (04)00000D */ ldfld
IL_0006: /* 03 | */ ldarg.1
IL_0007: /* 28 | (0A)00005C */ call
IL_000c: /* 6F | (0A)00005D */ callvirt
IL_0011: /* 74 | (02)000003 */ castclass
IL_0016: /* 2A | */ ret
} // end of method Scroller::get_Titles
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

This is the first line of this procedure:

IL_0000: /* 02 | */ ldarg.0

Line number Actual byte(s) IL instruction

Opcodes are representations of the Microsoft Intermediate Language (MSIL)


instructions.

If you are into cracking then you know what these instructions mean !

JMP JNE JLE NOP CALL etc...

MSIL Opcodes are different from native Opcodes designed for the Intel
Processors, for example after you know the offset of a CALL in a native code
program you open that program in a hex editor and overwrite the right number of
bytes that call that function or whatever with 90s which stands for NOP in native
machine code.

In MSIL the NOP is represented by 00 not 90, so it's important here to list the
Opcodes For MSIL with their actual byte values now, we won't need to use them
all when We crack a program, most of the time we will be using the NOP
instruction and inverting Jumps to get the job done.

I will mark the important Opcodes in cracking in gray and orange colors so try to
focus on them.
Opcodes list

OPCODE What It does Actual bytes

Adds two values and pushes the result onto the


Add 58
evaluation stack.
Adds two integers, performs an overflow check,
Add_Ovf and pushes the result onto the evaluation D6
stack.
Adds two unsigned integer values, performs an
Add_Ovf_Un overflow check, and pushes the result onto the D7
evaluation stack.
Computes the bitwise AND of two values and
And 5F
pushes the result onto the evaluation stack.

Returns an unmanaged pointer to the argument


Arglist FE 00
list of the current method.

Transfers control to a target instruction if


Beq 3B
two values are equal.

Transfers control to a target instruction


Beq_S 2E
(short form) if two values are equal.
Transfers control to a target instruction if
Bge the first value is greater than or equal to the 3C
second value.
Transfers control to a target instruction
Bge_S (short form) if the first value is greater than 2F
or equal to the second value.
Transfers control to a target instruction if
the the first value is greater than the second
Bge_Un 41
value, when comparing unsigned integer values
or unordered float values.
Transfers control to a target instruction
(short form) if if the the first value is
Bge_Un_S greater than the second value, when comparing 34
unsigned integer values or unordered float
values.
Transfers control to a target instruction if
Bgt the first value is greater than the second 3D
value.
Transfers control to a target instruction
Bgt_S (short form) if the first value is greater than 30
the second value.
Transfers control to a target instruction if
the first value is greater than the second
Bgt_Un 42
value, when comparing unsigned integer values
or unordered float values.
Transfers control to a target instruction
(short form) if the first value is greater than
Bgt_Un_S 35
the second value, when comparing unsigned
integer values or unordered float values.
Transfers control to a target instruction if
Ble the first value is less than or equal to the 3E
second value.
Transfers control to a target instruction
Ble_S (short form) if the first value is less than or 31
equal to the second value.
Transfers control to a target instruction if
the first value is less than or equal to the
Ble_Un 43
second value, when comparing unsigned integer
values or unordered float values.
Transfers control to a target instruction
(short form) if the first value is less than or
Ble_Un_S equal to the second value, when comparing 36
unsigned integer values or unordered float
values.

Transfers control to a target instruction if


Blt 3F
the first value is less than the second value.

Transfers control to a target instruction


Blt_S (short form) if the first value is less than 32
the second value.
Transfers control to a target instruction if
the first value is less than the second value,
Blt_Un 44
when comparing unsigned integer values or
unordered float values.
Transfers control to a target instruction
(short form) if the first value is less than
Blt_Un_S 37
the second value, when comparing unsigned
integer values or unordered float values.
Transfers control to a target instruction when
Bne_Un two unsigned integer values or unordered float 40
values are not equal.
Transfers control to a target instruction
Bne_Un_S (short form) when two unsigned integer values 33
or unordered float values are not equal.

Converts a value type to an object reference


Box 8C
(type O).

Unconditionally transfers control to a target


Br 38
instruction.

Signals the Common Language Infrastructure


Break (CLI) to inform the debugger that a break point 01
has been tripped.
Transfers control to a target instruction if
Brfalse value is false, a null reference (Nothing in 39
Visual Basic), or zero.
Transfers control to a target instruction if
Brfalse_S 2C
value is false, a null reference, or zero.

Transfers control to a target instruction if


Brtrue 3A
value is true, not null, or non-zero.
Transfers control to a target instruction
Brtrue_S (short form) if value is true, not null, or 2D
non-zero.
Unconditionally transfers control to a target
Br_S 2B
instruction (short form).

Calls the method indicated by the passed method


Call 28
descriptor.

Calls the method indicated on the evaluation


Calli stack (as a pointer to an entry point) with 29
arguments described by a calling convention.
Calls a late-bound method on an object, pushing
Callvirt 6F
the return value onto the evaluation stack.

Attempts to cast an object passed by reference


Castclass 74
to the specified class.
Compares two values. If they are equal, the
integer value 1 (int32) is pushed onto the
Ceq FE 01
evaluation stack; otherwise 0 (int32) is pushed
onto the evaluation stack.
Compares two values. If the first value is
greater than the second, the integer value 1
Cgt (int32) is pushed onto the evaluation stack; FE 02
otherwise 0 (int32) is pushed onto the
evaluation stack.
Compares two unsigned or unordered values. If
the first value is greater than the second, the
Cgt_Un integer value 1 (int32) is pushed onto the FE 03
evaluation stack; otherwise 0 (int32) is pushed
onto the evaluation stack.
Throws ArithmeticException if value is not a
Ckfinite C3
finite number.
Compares two values. If the first value is less
than the second, the integer value 1 (int32) is
Clt FE 04
pushed onto the evaluation stack; otherwise 0
(int32) is pushed onto the evaluation stack.
Compares the unsigned or unordered values
value1 and value2. If value1 is less than
Clt_Un value2, then the integer value 1 (int32) is FE 03
pushed onto the evaluation stack; otherwise 0
(int32) is pushed onto the evaluation stack.
Converts the value on top of the evaluation
Conv_I D3
stack to natural int.

Converts the value on top of the evaluation


Conv_I1 67
stack to int8, then extends (pads) it to int32.
Converts the value on top of the evaluation
Conv_I2 stack to int16, then extends (pads) it to 68
int32.

Converts the value on top of the evaluation


Conv_I4 69
stack to int32.

Converts the value on top of the evaluation


Conv_I8 6A
stack to int64.
Converts the signed value on top of the
Conv_Ovf_I evaluation stack to signed natural int, D4
throwing OverflowException on overflow.
Converts the signed value on top of the
evaluation stack to signed int8 and extends it
Conv_Ovf_I1 B3
to int32, throwing OverflowException on
overflow.
Converts the unsigned value on top of the
evaluation stack to signed int8 and extends it
Conv_Ovf_I1_Un 82
to int32, throwing OverflowException on
overflow.
Converts the signed value on top of the
evaluation stack to signed int16 and extending
Conv_Ovf_I2 B5
it to int32, throwing OverflowException on
overflow.
Converts the unsigned value on top of the
evaluation stack to signed int16 and extends it
Conv_Ovf_I2_Un 83
to int32, throwing OverflowException on
overflow.
Converts the signed value on top of the
Conv_Ovf_I4 evaluation tack to signed int32, throwing B7
OverflowException on overflow.
Converts the unsigned value on top of the
Conv_Ovf_I4_Un evaluation stack to signed int32, throwing 84
OverflowException on overflow.
Converts the signed value on top of the
Conv_Ovf_I8 evaluation stack to signed int64, throwing B9
OverflowException on overflow.
Converts the unsigned value on top of the
Conv_Ovf_I8_Un evaluation stack to signed int64, throwing B9
OverflowException on overflow.
Converts the unsigned value on top of the
Conv_Ovf_I_Un evaluation stack to signed natural int, 85
throwing OverflowException on overflow.
Converts the signed value on top of the
Conv_Ovf_U evaluation stack to unsigned natural int, D5
throwing OverflowException on overflow.
Converts the signed value on top of the
evaluation stack to unsigned int8 and extends
Conv_Ovf_U1 B4
it to int32, throwing OverflowException on
overflow.
Converts the unsigned value on top of the
evaluation stack to unsigned int8 and extends
Conv_Ovf_U1_Un 86
it to int32, throwing OverflowException on
overflow.
Converts the signed value on top of the
evaluation stack to unsigned int16 and extends
Conv_Ovf_U2 B6
it to int32, throwing OverflowException on
overflow.
Converts the unsigned value on top of the
evaluation stack to unsigned int16 and extends
Conv_Ovf_U2_Un 87
it to int32, throwing OverflowException on
overflow.
Converts the signed value on top of the
Conv_Ovf_U4 evaluation stack to unsigned int32, throwing B8
OverflowException on overflow.
Converts the unsigned value on top of the
Conv_Ovf_U4_Un evaluation stack to unsigned int32, throwing 88
OverflowException on overflow.
Converts the signed value on top of the
Conv_Ovf_U8 evaluation stack to unsigned int64, throwing BA
OverflowException on overflow.
Converts the unsigned value on top of the
Conv_Ovf_U8_Un evaluation stack to unsigned int64, throwing 89
OverflowException on overflow.
Converts the unsigned value on top of the
Conv_Ovf_U_Un evaluation stack to unsigned natural int, 8B
throwing OverflowException on overflow.
Converts the value on top of the evaluation
Conv_R4 6B
stack to float32.

Converts the value on top of the evaluation


Conv_R8 6C
stack to float64.

Converts the unsigned integer value on top of


Conv_R_Un 76
the evaluation stack to float32.

Converts the value on top of the evaluation


Conv_U stack to unsigned natural int, and extends it E0
to natural int.
Converts the value on top of the evaluation
Conv_U1 stack to unsigned int8, and extends it to D2
int32.
Converts the value on top of the evaluation
Conv_U2 stack to unsigned int16, and extends it to D1
int32.
Converts the value on top of the evaluation
Conv_U4 stack to unsigned int32, and extends it to 6D
int32.
Converts the value on top of the evaluation
Conv_U8 stack to unsigned int64, and extends it to 6E
int64.

Copies a specified number bytes from a source


Cpblk FE 17
address to a destination address.
Copies the value type located at the address of
an object (type &, * or natural int) to the
Cpobj 70
address of the destination object (type &, * or
natural int).
Divides two values and pushes the result as a
Div floating-point (type F) or quotient (type 5B
int32) onto the evaluation stack.
Divides two unsigned integer values and pushes
Div_Un 5C
the result (int32) onto the evaluation stack.

Copies the current topmost value on the


Dup evaluation stack, and then pushes the copy onto 25
the evaluation stack.
Transfers control from the filter clause of an
Endfilter exception back to the Common Language FE 11
Infrastructure (CLI) exception handler.
Transfers control from the fault or finally
clause of an exception block back to the Common
Endfinally DC
Language Infrastructure (CLI) exception
handler.
Initializes a specified block of memory at a
Initblk specific address to a given size and initial FE 18
value.
Initializes all the fields of the object at a
Initobj specific address to a null reference or a 0 of FE 15
the appropriate primitive type.
Tests whether an object reference (type O) is
Isinst 75
an instance of a particular class.

Exits current method and jumps to specified


Jmp 27
method.

Loads an argument (referenced by a specified


Ldarg FE 09
index value) onto the stack.

Load an argument address onto the evaluation


Ldarga FE 0A
stack.

Load an argument address, in short form, onto


Ldarga_S 0F
the evaluation stack.

Loads the argument at index 0 onto the


Ldarg_0 02
evaluation stack.

Loads the argument at index 1 onto the


Ldarg_1 03
evaluation stack.

Loads the argument at index 2 onto the


Ldarg_2 04
evaluation stack.

Loads the argument at index 3 onto the


Ldarg_3 05
evaluation stack.

Loads the argument (referenced by a specified


Ldarg_S 0E
short form index) onto the evaluation stack.

Pushes a supplied value of type int32 onto the


Ldc_I4 20
evaluation stack as an int32.

Pushes the integer value of 0 onto the


Ldc_I4_0 16
evaluation stack as an int32.

Pushes the integer value of 1 onto the


Ldc_I4_1 17
evaluation stack as an int32.

Pushes the integer value of 2 onto the


Ldc_I4_2 18
evaluation stack as an int32.

Pushes the integer value of 3 onto the


Ldc_I4_3 19
evaluation stack as an int32.
Pushes the integer value of 4 onto the
Ldc_I4_4 1A
evaluation stack as an int32.

Pushes the integer value of 5 onto the


Ldc_I4_5 1B
evaluation stack as an int32.

Pushes the integer value of 6 onto the


Ldc_I4_6 1C
evaluation stack as an int32.

Pushes the integer value of 7 onto the


Ldc_I4_7 1D
evaluation stack as an int32.

Pushes the integer value of 8 onto the


Ldc_I4_8 1E
evaluation stack as an int32.

Pushes the integer value of -1 onto the


Ldc_I4_M1 15
evaluation stack as an int32.

Pushes the supplied int8 value onto the


Ldc_I4_S 1F
evaluation stack as an int32, short form.

Pushes a supplied value of type int64 onto the


Ldc_I8 21
evaluation stack as an int64.

Pushes a supplied value of type float32 onto


Ldc_R4 22
the evaluation stack as type F (float).

Pushes a supplied value of type float64 onto


Ldc_R8 23
the evaluation stack as type F (float).

Loads the address of the array element at a


Ldelema specified array index onto the top of the 8F
evaluation stack as type & (managed pointer).
Loads the element with type natural int at a
Ldelem_I specified array index onto the top of the 97
evaluation stack as a natural int.
Loads the element with type int8 at a specified
Ldelem_I1 array index onto the top of the evaluation 90
stack as an int32.
Loads the element with type int16 at a
Ldelem_I2 specified array index onto the top of the 92
evaluation stack as an int32.
Loads the element with type int32 at a
Ldelem_I4 specified array index onto the top of the 94
evaluation stack as an int32.
Loads the element with type int64 at a
Ldelem_I8 specified array index onto the top of the 96
evaluation stack as an int64.
Loads the element with type float32 at a
Ldelem_R4 specified array index onto the top of the 98
evaluation stack as type F (float).
Loads the element with type float64 at a
Ldelem_R8 specified array index onto the top of the 99
evaluation stack as type F (float).
Loads the element containing an object
reference at a specified array index onto the
Ldelem_Ref 9A
top of the evaluation stack as type O (object
reference).
Loads the element with type unsigned int8 at a
Ldelem_U1 specified array index onto the top of the 91
evaluation stack as an int32.
Loads the element with type unsigned int16 at a
Ldelem_U2 specified array index onto the top of the 93
evaluation stack as an int32.
Loads the element with type unsigned int32 at a
Ldelem_U4 specified array index onto the top of the 94
evaluation stack as an int32.

Finds the value of a field in the object whose


Ldfld 7B
reference is currently on the evaluation stack.
Finds the address of a field in the object
Ldflda whose reference is currently on the evaluation 7C
stack.
Pushes an unmanaged pointer (type natural int)
Ldftn to the native code implementing a specific FE 06
method onto the evaluation stack.
Loads a value of type natural int as a natural
Ldind_I 4D
int onto the evaluation stack indirectly.

Loads a value of type int8 as an int32 onto the


Ldind_I1 46
evaluation stack indirectly.

Loads a value of type int16 as an int32 onto


Ldind_I2 48
the evaluation stack indirectly.

Loads a value of type int32 as an int32 onto


Ldind_I4 4A
the evaluation stack indirectly.

Loads a value of type int64 as an int64 onto


Ldind_I8 4C
the evaluation stack indirectly.

Loads a value of type float32 as a type F


Ldind_R4 4E
(float) onto the evaluation stack indirectly.

Loads a value of type float64 as a type F


Ldind_R8 4F
(float) onto the evaluation stack indirectly.
Loads an object reference as a type O (object
Ldind_Ref reference) onto the evaluation stack 50
indirectly.
Loads a value of type unsigned int8 as an int32
Ldind_U1 47
onto the evaluation stack indirectly.

Loads a value of type unsigned int16 as an


Ldind_U2 49
int32 onto the evaluation stack indirectly.

Loads a value of type unsigned int32 as an


Ldind_U4 4B
int32 onto the evaluation stack indirectly.
Pushes the number of elements of a zero-based,
Ldlen one-dimensional array onto the evaluation 8E
stack.
Loads the local variable at a specific index
Ldloc FE 06
onto the evaluation stack.

Loads the address of the local variable at a


Ldloca FE 0D
specific index onto the evaluation stack.
Loads the address of the local variable at a
Ldloca_S specific index onto the evaluation stack, short 12
form.
Loads the local variable at index 0 onto the
Ldloc_0 06
evaluation stack.

Loads the local variable at index 1 onto the


Ldloc_1 07
evaluation stack.

Loads the local variable at index 2 onto the


Ldloc_2 08
evaluation stack.

Loads the local variable at index 3 onto the


Ldloc_3 09
evaluation stack.

Loads the local variable at a specific index


Ldloc_S 11
onto the evaluation stack, short form.

Pushes a null reference (type O) onto the


Ldnull 14
evaluation stack.

Copies the value type object pointed to by an


Ldobj 71
address to the top of the evaluation stack.

Pushes the value of a static field onto the


Ldsfld 7E
evaluation stack.

Pushes the address of a static field onto the


Ldsflda 7F
evaluation stack.

Pushes a new object reference to a string


Ldstr 72
literal stored in the metadata.
Converts a metadata token to its runtime
Ldtoken representation, pushing it onto the evaluation D0
stack.
Pushes an unmanaged pointer (type natural int)
to the native code implementing a particular
Ldvirtftn FE 07
virtual method associated with a specified
object onto the evaluation stack.
Exits a protected region of code,
Leave unconditionally tranferring control to a DD
specific target instruction.
Exits a protected region of code,
Leave_S unconditionally tranferring control to a target DE
instruction (short form).
Allocates a certain number of bytes from the
local dynamic memory pool and pushes the
Localloc FE 0F
address (a transient pointer, type *) of the
first allocated byte onto the evaluation stack.
Pushes a typed reference to an instance of a
Mkrefany C6
specific type onto the evaluation stack.

Multiplies two values and pushes the result on


Mul 5A
the evaluation stack.
Multiplies two integer values, performs an
Mul_Ovf overflow check, and pushes the result onto the D8
evaluation stack.
Multiplies two unsigned integer values,
Mul_Ovf_Un performs an overflow check, and pushes the D9
result onto the evaluation stack.
Negates a value and pushes the result onto the
Neg 65
evaluation stack.

Pushes an object reference to a new zero-based,


Newarr one-dimensional array whose elements are of a 8D
specific type onto the evaluation stack.
Creates a new object or a new instance of a
Newobj value type, pushing an object reference (type 73
O) onto the evaluation stack.
Fills space if opcodes are patched. No
Nop meaningful operation is performed although a 90
processing cycle can be consumed.
Computes the bitwise complement of the integer
Not value on top of the stack and pushes the result 66
onto the evaluation stack as the same type.
Compute the bitwise complement of the two
Or integer values on top of the stack and pushes 60
the result onto the evaluation stack.
Removes the value currently on top of the
Pop 26
evaluation stack.

Retrieves the type token embedded in a typed


Refanytype FE 1D
reference.

Retrieves the address (type &) embedded in a


Refanyval C2
typed reference.

Divides two values and pushes the remainder


Rem 5D
onto the evaluation stack.

Divides two unsigned values and pushes the


Rem_Un 5E
remainder onto the evaluation stack.
Returns from the current method, pushing a
return value (if present) from the caller's
Ret 2A
evaluation stack onto the callee's evaluation
stack.

Rethrow Rethrows the current exception. FE 1A


Shifts an integer value to the left (in zeroes)
Shl by a specified number of bits, pushing the 62
result onto the evaluation stack.
Shifts an integer value (in sign) to the right
Shr by a specified number of bits, pushing the 63
result onto the evaluation stack.
Shifts an unsigned integer value (in zeroes) to
Shr_Un the right by a specified number of bits, 64
pushing the result onto the evaluation stack.
Pushes the size, in bytes, of a supplied value
Sizeof FE 1C
type onto the evaluation stack.

Stores the value on top of the evaluation stack


Starg FE 0B
in the argument slot at a specified index.
Stores the value on top of the evaluation stack
Starg_S in the argument slot at a specified index, 10
short form.
Replaces the array element at a given index
Stelem_I with the natural int value on the evaluation 9B
stack.
Replaces the array element at a given index
Stelem_I1 9C
with the int8 value on the evaluation stack.

Replaces the array element at a given index


Stelem_I2 9D
with the int16 value on the evaluation stack.

Replaces the array element at a given index


Stelem_I4 9E
with the int32 value on the evaluation stack.

Replaces the array element at a given index


Stelem_I8 9F
with the int64 value on the evaluation stack.

Replaces the array element at a given index


Stelem_R4 A0
with the float32 value on the evaluation stack.

Replaces the array element at a given index


Stelem_R8 A1
with the float64 value on the evaluation stack.

Replaces the array element at a given index


Stelem_Ref with the object ref value (type O) on the A2
evaluation stack.
Replaces the value stored in the field of an
Stfld 7D
object reference or pointer with a new value.

Stores a value of type natural int at a


Stind_I DF
supplied address.

Stores a value of type int8 at a supplied


Stind_I1 52
address.

Stores a value of type int16 at a supplied


Stind_I2 53
address.
Stores a value of type int32 at a supplied
Stind_I4 54
address.

Stores a value of type int64 at a supplied


Stind_I8 55
address.

Stores a value of type float32 at a supplied


Stind_R4 56
address.

Stores a value of type float64 at a supplied


Stind_R8 57
address.

Stores a object reference value at a supplied


Stind_Ref 51
address.
Pops the current value from the top of the
Stloc evaluation stack and stores it in a the local FE 0E
variable list at a specified index.
Pops the current value from the top of the
Stloc_0 evaluation stack and stores it in a the local 0A
variable list at index 0.
Pops the current value from the top of the
Stloc_1 evaluation stack and stores it in a the local 0B
variable list at index 1.
Pops the current value from the top of the
Stloc_2 evaluation stack and stores it in a the local 0C
variable list at index 2.
Pops the current value from the top of the
Stloc_3 evaluation stack and stores it in a the local 0D
variable list at index 3.
Pops the current value from the top of the
Stloc_S evaluation stack and stores it in a the local 13
variable list at index (short form).
Copies a value of a specified type from the
Stobj evaluation stack into a supplied memory 81
address.
Replaces the value of a static field with a
Stsfld 80
value from the evaluation stack.

Subtracts one value from another and pushes the


Sub 59
result onto the evaluation stack.
Subtracts one integer value from another,
Sub_Ovf performs an overflow check, and pushes the DA
result onto the evaluation stack.
Subtracts one unsigned integer value from
Sub_Ovf_Un another, performs an overflow check, and pushes DB
the result onto the evaluation stack.

Switch Implements a jump table. 45

Performs a postfixed method call instruction


such that the current method's stack frame is
Tailcall FE 14
removed before the actual call instruction is
executed.
Throws the exception object currently on the
Throw 7A
evaluation stack.
Indicates that an address currently atop the
evaluation stack might not be aligned to the
Unaligned natural size of the immediately following FE 12
ldind, stind, ldfld, stfld, ldobj, stobj,
initblk, or cpblk instruction.
Converts the boxed representation of a value
Unbox 79
type to its unboxed form.
Specifies that an address currently atop the
evaluation stack might be volatile, and the
Volatile results of reading that location cannot be FE 13
cached or that multiple stores to that location
cannot be suppressed.
Computes the bitwise XOR of the top two values
Xor on the evaluation stack, pushing the result 61
onto the evaluation stack.

What lies beneath?

These are some of the obstacles that you will face when you crack any Assembly;
I will try to explain some of them here, for more information on any of them just
Google it.

1. Obfuscation:

It's the process of changing the method and classes names to non-
readable
Characters to make harder for us to find the "IsLicensed" function, yes;
It can make the job harder for you but believe me it's not that hard to
trace
Through the code even when it's obfuscated.
The solution here is using bookmarks in reflector to help you keep your
Sanity when moving between methods and a I suggest a paper and a pen
too,
Cracking demands patience. No patience, no cracking.

2. Encoded Strings:

This is ugly, It reminds me of old times when I was waiting for W32Dasm
to
Finish disassembling to see if there is any "Invalid Serial Number" in
String references, but with encoding strings you won't see any clear
Text wandering around to tell you what this particular function does.
The most common way to hide strings is encoding them and then saving
the
Entire encoded stream as a binary .net resource, and whenever some
string is
Needed, A function is called to get that string from encoded stream and
It will return the original string, the point that makes this technique weak
Is that it has to be fast in decoding to keep the program running fast or
At least not much slower than it used to do when strings were clear and
Retrieved quickly without decoding, most decoding functions use byte
Shifting and reordering to decode strings, and believe me they are easy
To find and reverse, as soon as you find the decoder you can reverse it
And write your own decoder, this will help you reveal most strings
Through the code quickly, Later I will show you how to reverse the
Decoding function used in commercial applications.

3. Strong Name signature:

A digital signature enables authentication of digital documents, text or


data. It is used to prove that the author of the data is the expected one,
and that the data has not been tampered with. To create a digital
signature, public-key cryptography is used. Typically, a digital signature is
created by first hashing the data to be signed into a 160-bit value, which
is then encrypted using the unique Private Key held only by the party that
is signing the data. Anyone holding the Public Key that corresponds to the
Private Key can then use it to authenticate the author of the data and also
to ensure that the data has not been altered since it was signed.

This is a primitive technique used to protect .net assemblies from any


Tampering or modification after the assembly is released to the public.
When you start an exe application built with .net, it will be checked
By the run-time for string name signature, if it exists then the digital
Signature is verified, if verification fails then this means that the
Assembly has been modified after it was released and the runtime
Will refuse to load it!

How can you defeat this?

You can find detailed explanations about how the Strong Name Signature
works and its implementation over the internet.
We won't reinvent the wheel, read in the tools section to find the answer.

THE END
Last words:-

That's all for now…

See you soon and I hope you enjoy this tutor.

Best wishes,

Kurapica

Monday, June 26, 2006

You might also like