Ildasm.exe 的使用方法
示例:
在应用Ildasm.exe具体反编译代码之前,先附上MSDN对于用Ildasm.exe反编译的经典帮助。
然后我们用Ildasm.exe具体反编译经典的"Hello World"控制台程序的可执行文件,展现出来的视图为:
分析具体IL代码
1.MANIFEST清单:
MANIFEST是一个附加信息列表,主要包含程序集的一些属性,如程序集名称、版本号、哈希算法等;
2.ConsoleApplication1.Program类:
这才是我们介绍的主角。
首先是Program类: 代码为
.classprivateauto ansi beforefieldinit ConsoleApplication1.Program
extends [mscorlib]System.Object
{
}//end of class ConsoleApplication1.Program
1).class,表示Program是一个类。并且它继承自程序集—mscorlib的System.Object类;
2)private,表示访问权限;
3)auto,表示程序的内存加载全部由CLR来控制;
4)ansi,是为了在没有托管代码与托管代码之间实现无缝转换。这里主要指C、C++代码等;
5)beforefieldinit,是用来标记运行库(CLR)可以在静态字段方法生成后的任意时刻,来加载构造器(构造函数);
其次是 .ctor方法,代码为:
.methodpublichidebysig specialname rtspecialname
instancevoid.ctor() cil managed
{
//Code size 7 (0x7)
.maxstack8
IL_0000: ldarg.0
IL_0001: call instancevoid[mscorlib]System.Object::.ctor()
IL_0006: ret
}//end of method Program::.ctor
1)cil managed:表示其中为IL代码,指示编译器编译为托管代码;
2).maxstack:表示调用构造函数.otor期间的评估堆栈(Evaluation Stack) ;
3)IL_0000:标记代码行开头;
4)ldarg.0:表示转载第一个成员参数,在实例方法中指的是当前实例的引用;
5)call:call一般用于调用静态方法,因为静态方法是在编译期就确定的。而这里的构造函数.otor()也是在编译期就制定的。而另一指令callvirt则表示调用实例方法, 它是在运行时确定的,因为如前述,当调用方法的继承关系时,就要比较基类与派生类的同名函数的实现方法(virtual和new),以确定调用的函数所属的Method Table;
6)ret:表示执行完毕,返回;
最后是Main()方法,代码为:
.methodprivatehidebysigstaticvoidMain() cil managed
{
.entrypoint
//Code size 13 (0xd)
.maxstack8
IL_0000: nop
IL_0001: ldstr"Hello world"
IL_0006: callvoid[mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ret
}//end of method Program::Main
1) .entrypoint指令表示CLR加载程序时,是首先从.entrypoint开始的,即从Main方法作为程序的入口函数;
2)ldstr:表示将字符串压栈,在这里就是将"Hello World."压栈;
3)hidebysig:表示当把此类作为基类,存在派生类时,此方法不被继承,同上构造函数;
至此,我们对IL代码的一些指令有了了解。
IL指令说明
MSIL Instruction Set
Base Instructions
**Instruction** | **Description** | **Stack Transition** | |
1 | add | add two values, returning a new value | …, value1, value2à…, result |
2 |
add.ovf. |
add integer value with overflow check | …, value1, value2à…, result |
3 | and | bitwise AND | …, value1, value2à…, result |
4 | arglist | get argument list | …à…, argListHandle |
5 |
beq. |
branch on equal | …, value1, value2à… |
6 |
bge. |
branch on greater than or equal to | …, value1, value2à… |
7 |
bge.un. |
branch on greater/equal, unsigned or unordered | …, value1, value2à… |
8 |
bgt. |
branch on greater than | …, value1, value2à… |
9 |
bgt.un |
branch on greater than, unsigned or unordered | …, value1, value2à… |
10 |
ble. |
branch on less than or equal to | …, value1, value2à… |
11 |
ble..un |
branch on less/equal, unsigned or unordered | …, value1, value2à… |
12 |
blt. |
branch on less than | …, value1, value2à… |
13 |
blt.un. |
branch on less than, unsigned or unordered | …, value1, value2à… |
14 |
bne.un |
branch on not equal or unorded | …, value1, value2à… |
15 |
br. |
unconditional branch | …,à… |
16 | break | breakpoint instruction | …,à… |
17 |
brfalse. |
branch on false, null, or zero | …, valueà… |
18 |
brtrue. |
branch on non-false or non-null | …, valueà… |
19 | call | call a method | …, arg1, arg2 … argnà…, retVal (not always returned) |
20 | calli | indirect method call | …, arg1, arg2 … argn, ftnà…, retVal (not always returned) |
21 | ceq | compare equal | …, value1, value2à…, result |
22 | cgt | compare greater than | …, value1, value2à…, result |
23 | cgt.un | compare greater than, unsigned or unordered | …, value1, value2à…, result |
24 | ckfinite | check for a finite real number | …, valueà…, value |
25 | clt | compare less than | …, value1, value2à…, result |
26 | clt.un | compare less than, unsigned or unordered | …, value1, value2à…, result |
27 |
conv. |
data conversion | …, valueà…, result |
28 |
conv.ovf |
data conversion with overflow detection | …, valueà…, result |
29 |
conv.ovf. |
unsigned data conversion with overflow detection | …, valueà…, result |
30 | cpblk | copy data from memory to memory | …, destaddr, srcaddr, sizeà… |
31 | div | divide values | …, value1, value2à…, result |
32 | div.un | divide integer values, unsigned | …, value1, value2à…, result |
33 | dup | duplicate the top value of the stack | …, valueà…, value, value |
34 | endfilter | end filter clause of SEH | …, valueà… |
35 | endfinally | end the finally or fault clause of exception block | …à… |
36 | initblk | initialize a block of memory to a value | …, addr, value, sizeà… |
37 | jmp | jump to method | …à… |
38 |
ldarg. |
load argument onto the stack | …à…, value |
39 |
ldarga. |
load an argument address | …,à…, address of argument number *argNum* |
40 |
ldc. |
load numeric constant | …à…, num |
41 | ldftn | load method pointer | …à…, ftn |
42 |
ldind. |
load value indirect onto the stack | …, addrà…, value |
43 | ldloc | load local variable onto the stack | …à…, value |
44 |
ldloca. |
load local variable address | …à…, address |
45 | ldnull | load a null pointer | …à…, null value |
46 |
leave. |
exit a protected region of code | …,à |
47 | localloc | allocate space in the local dynamic memory pool | sizeàaddress |
48 | mul | multiply values | …, value1, value2à…, result |
49 |
mul.ovf |
multiply integer values with overflow check | …, value1, value2à…, result |
50 | neg | negate | …, valueà…, result |
51 | nop | no operation | …,à…, |
52 | not | bitwise complement | …, valueà…, result |
53 | or | bitwise OR | …, value1, value2à…, result |
54 | pop | remove the top element of the stack | …, valueà… |
55 | rem | compute the remainder | …, value1, value2à…, result |
56 | rem.un | compute integer remainder, unsigned | …, value1, value2à…, result |
57 | ret | return from method |
retValon callee evaluation stack (not always present)à
…, retValon caller evaluation stack (not always present) |
58 | shl | shift integer left | …, value, shiftAmountà…, result |
59 | shr | shift integer right | …, value, shiftAmountà…, result |
60 | shr.un | shift integer right, unsigned | …, value, shiftAmountà…, result |
61 | starg. | store a value in an argument slot | …, valueà…, |
62 | stind. | store value indirect from stack | …, addr, valà… |
63 | stloc | pop value from stack to local variable | …, valueà… |
64 | sub | substract numeric values | …, value1, value2à…, result |
65 | sub.ovf. | substract integer values, checking for overflow | …, value1, value2à…, result |
66 | switch | table switch on value | …, valueà…, |
67 | xor | bitwise XOR | ..., value1, value2à..., result |
Object Model Instructions
**Instruction** | **Description** | **Stack Transition** | |
1 | box | convert value type to object reference | …, valueTypeà…, obj |
2 | callvirt | call a method associated, a runtime, with an object | …, obj, arg1, … argNà…, returnVal (not always returned) |
3 | cast class | cast an object to a class | …, objà…, obj2 |
4 | cpobj | copy a value type | …, *destValObj, srcValObj*à…, |
5 | initobj | Initialize a value type | …,addrOfValObjà…, |
6 | isinst | test if an object is is an instance of a class or interface | …, objà…, result |
7 |
ldelem. |
load an element fo an array | …,array, indexà…, value |
8 | ldelema | load address of an element of an array | …, array, indexà…, address |
9 | ldfld | load field of an object | …,objà…, value |
10 | ldflda | load field address | …,objà…, address |
11 | ldlen | load the length of an array | …, arrayà…, length |
12 | ldobj | copy value type to the stack | …, addrOfValObjà…, valObj |
13 | ldsfld | load static field of a class | …,à…, value |
14 | ldsflda | load static field address | …,à…, address |
15 | ldstr | load a literal string | …,à…, string |
16 | ldtoken | load the runtime representation of metadata token | …à…, RuntimeHandle |
17 | ldvirtfn | load a virtual method pointer | … objectà…, ftn |
18 | mkrefany | push a typed reference on the stack | …, ptrà…, typedRef |
19 | newarr | Create a zero-base, on-dimensional array | …, *numElems*à…, *array* |
20 | newobj | create a new object | …, *arg1*, … *argN*à…, *obj* |
21 | refanytype | load the type out of a typed reference | …,TypedRefà…, type |
22 | refanyval | load the address out of a typed reference | …,TypedRefà…, address |
23 | rethrow | rethrow the current exception | …,à…, |
24 | sizeof | load the size in bytes of a value type | …,à…, size (4 bytes, unsigned) |
25 |
stelem. |
store an element of an array | …, *array*, *index*, *value*à…, |
26 | stfld | store into a field of an object | …, *obj*, *value*à…, |
27 | stobj | store a value type from the stack into memory | …, addr, valObjà…, |
28 | stsfld | store a static field of class | …, *val*à…, |
29 | throw | throw an exception | …, *object*à…, |
30 | unbox | convert boxed value type to its raw form |
转自:http://www.cnblogs.com/yangmingming/archive/2010/02/03/1662307.html
原文链接: https://www.cnblogs.com/scottckt/archive/2010/10/13/1850255.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/16096
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!