Mo cuishle

导航

IDA反汇编深度总结(转载)

1,[eax]的歧义(其中eax指向SourceString):到底是*SourceString还是SourceString所处的结构的第一个偏移的结构。这个应该根据语境来,比如[eax]赋给的值的结构和第一偏移结构匹配,就是后面一种可能;反之就是第一种可能。
2,IDA翻译的代码不一定是完全正确的,比如入口函数它会翻译为DriverEntry(int,PUNICODE_STRING SourceString)。所以翻译的时候还是要坚持原则,能肯定的就不一定非要完全照抄IDA的结果。
3,PUNICODE_STRING和UNICODE_STRING的选择:如果出现DiskperfRegistryPath.Length或DiskperfRegistry.Buffer则必定是UNICODE_STRING.首先我们知道指针哪有长度和缓存呢。我们可以根据这样去记忆。其次,这明显就是UNICODE_STRING的结构,可以查到。
4,局部变量和全局变量:关于一个新的变量,我们到底怎么去判断是前者还是后者呢。如果在函数中显视出现,则判定它为全局变量。如果是局部变量,则会根据偏移量制造出来。
5.关于头文件,我们可以在全部翻译完成读C代码的时候查看函数的DDK。看他们都定义在哪些头文件里面。
6,函数后面的eax。我们都知道,函数执行之后返回值放在eax寄存器里面。有时候不要脑子死掉了,看到eax就去找前面显视放进去的数据。不要犯这种低级的错误。
7,offset:它也是地址的标志,不要只记住lea而忘了这个offset。
8,在if语句里面,如果IDA直译是if(a=0)那么我们应该翻译成if(a!=0)。
9,循环语句:我们都知道循环语句的初始化是在大方框的上面那一行代码。我们如果不太确定这行代码是不是初始化,可以先把他直译出来,不放到循环体里面。等到翻译出了判断式的条件语句,再回过头看下这行代码是不是该循环体的初始化语句。
10,PDRIVER_DISPATCH 定义为:PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1] 。
关于MajorFunction我们要注意两个方面:首先,MajorFunction数组是指针形式的,如果DriverObject->MajorFunction赋值给某一个变量,那么我们应该定义成PDRIVER_DISPATCH *变量名的形式。其次,MajorFunction是四个字节的,也就是说MajorFunction[a]到
MajorFunction[a+1]其实增加了四个字节。
11,+4真的就是+4吗???这个问题其实接着上面的问题。我们应该对数据的大小有个了解,当碰到
ULONG时+1就是+1,但是当碰到上面的数据结构的时候,+4就不是+4了。
12,在DriverEntry中0就是STATUS_SUCCESS。
13,另类函数调用:一般的函数调用是通过把参数压栈;现在的函数调用是通过ecx和edx调用,其中第一个参数是ecx,第二个参数是edx,其他的参数还是通过压栈实现。
14,数据结构1注释:IRP+60h为=Irp->Tail.Overlay.CurrentStackLocation。那么它赋予的变量的结构是
PIO_STACK_LOCATION。[IRP+60h]-24h就是IoGetNextIrpStackLocation(Irp),当然了,这个值被赋予的值还是PIO_STACK_LOCATION类型的。
15,数据结构2注释:DeviceExtension+24h的结构是:DeviceExtension->DiskCounters。
DeviceExtension+34h的结构是:DeviceExtension->CountersEnabled。
DeviceExtension+54h的结构是:DeviceExtension->PhysicalDeviceNameBuffer[0]。
以上结论都市错误的,因为DeviceExtension是根据用户自己定义的。
16,或结构的if选择:如果有很多if,并且有一个分支是指向同一个地址,那么这个结构可能就是或结构的if分支。这个时候就不能取反了,而是按IDA翻译的结构直接写出来。
17,mov esi,[ebp+a]
mov ecx,XXX
mov edi,[ebp+b]
rep movsd
正确的翻译方法是:*b=*a;
18,add eax,4
到底是eax加4还是eax的结构偏移4位呢。该怎么判断呢?
如果eax是整型的,当然是加4了;如果是别的struct结构,当然是后面哪种情况了。
19,数据结构3注释:IO_STACK_LOCATION+4h的结构是parameters数组,该数组的第一个元素是Read。
IO_STACK_LOCATION+0Ch的结构是也是parameters数组,该偏移量的值是DeviceIoControl.IoControlCode。以上说的是不正确的,因为Parameters是union结构。
20,分支结构中间反汇编什么时候停:在一条分支结构中,不需要全部反汇编到文件结尾。如果另一条分支和这条分支会在某一个地址相遇,就在这里停止。也就是在某一个地址分开,在某一个地址有相遇,就选择一个写就好了,不需要两个都写。
20,IO_STATUS_BLOCK的第一个偏移量是Status。
21,status中的各种情况的值:
0C0000001h:STATUS_UNSUCCESSFUL
22,数据结构4注释:AssociatedIrp+0h的结构是AssociatedIrp数组,该元素的第一个偏移是:SystemBuffer。
23,mov ecx,XXX1
xor eax,eax
mov edi,XXX2
rep stosd
该代码应该翻译成:RtlZeroMomery(XXX2,XXX1);
24,循环体:一般说在循环方框的前面代码即是循环体的初始化。如果出现0赋值某变量,那么应该要注意下该变量是不是循环体的变量。
25,函数的参数:不时说有几个push就有多少个参数,因为有些参数占两个PUSH。怎么看:看看有没有两个PUSH压入的参数类型相同,但是只是数值差4。
26,确定局部变量:找到一些系统的函数,查看DDK,然后就可以确定有些未知变量的类型了。包括函数值的类型也可以去查了,如果返回值是放在一个未知变量里面的。
27,如果在同一个函数里面有两个相同类型的相同变量,那么他们可能一个是大局部变量,另一个是小局部变量。比如小局部变量位于case语句里面。
28,case语句:如果对于同一个变量,比如var_1C有不同的选择分支,那么极可能是case语句。对于这类语句,IDA怎么翻译就怎么翻译,不需要对判断条件求反。
29,ExAllocatePoolWithTag的返回值的buffer,它的类型是PCHAR。
30,MajorFunction[]的结构:38h
+34h:Unload
+38h:IRP_MJ_CTREATE
+40h:IRP_MJ_CLOSE
+70h:IRP_MJ_DEVICE_CONTROL
+80h:IRP_MJ_CLEANUP
31,status各值的含义:
0C000000Dh:STATUS_INVALID_PARAMETER
0C0000023h: STATUS_BUFFER_TOO_SMALL
0C0000120h: STATUS_CANCELLED
0C0000001h: STATUS_UNSUCCESSFUL
103h: STATUS_PENDING
32,continue的使用(循环中的continue):假设A点是循环的开始,到B点后跳回A点,沿着A到B的选择的另一分支到达C点,又跳回A点。则B点是一个continue.
33,while语句循环:while的条件判断是在循环方框里面的顶部。
34,DeviceExtensin->Flags 4:DO_BUFFERED_IO。
35,IofCompleteRequest(x,x)的标准式是:IoCompleteRequest(Irp, IO_NO_INCREMENT);
36,返回基地址:CONTAINING_RECORD(IN PCHAR Address,//现在的地址
IN TYPE Type,//返回的类型
IN PCHAR Field//现在的地址在返回类型中的偏移
);
一般这个适用于对一偏移结构出现sub。
37,Irp->AssociatedIrp.SystemBuffer的返回值是PINPUT_DATA类型的值。

posted on 2014-03-30 15:16  Mo cuishle  阅读(3998)  评论(0编辑  收藏  举报