反汇编编程遇到的问题总结
编写NtReadVirtualProcess反汇编代码的时候,遇到了一系列问题,记录一下,希望能给一些也是初入该领域的朋友带去帮助:
在此之前写过的几篇文章:
总结的时候发现别人的一个博客,写的很好:
http://blog.csdn.net/fisher_jiang/article/details/4209112
001:形参的类型
一定一定要看清楚形参类型,因为在驱动中你写的反汇编代码将等于代替内核代码,就要考虑到栈,缓存位置等知识,稍不留神就会酿成灾难。
遇到不一样的类型,一定要向下找它的声明类型,切记弄一致。快捷键是Alt+G。
002:在这里最好不去写异常处理,这个对于新手来说比较难,我也暂时先放下,待解决。
003:由函数KeStackAttachProcess(...)和KeUnstackDetachProcess(...)引起的问题以及解决:
先说一下它的位置:
ReadProcessMemory--->NtReadVirtualMemory---->MmCopyVirtualMemory---->KeStackAttachProcess()
结构是:
VOID KeStackAttachProcess(
_Inout_ PRKPROCESS Process,
_Out_ PRKAPC_STATE ApcState
);
解释:
Pointer to the target process object. This parameter can be a PEPROCESS pointer returned byIoGetCurrentProcess orPsGetCurrentProcess.
An opaque pointer to a KAPC_STATE structure. The caller must allocate storage for this structure either from nonpaged pool or from the caller's own thread stack.
如果注意一下也会在IDA反汇编代码中看到帮助信息:
int __stdcall MiDoPoolCopy(......)
{
signed int v7;// edi@1
unsigned int v8;// ebx@7
signed int v9;//esi@20
char v11;//[sp+Ch] [bp-258h]@6
int v12;//[sp+20Ch] [bp-58h]@11
.............................
}
注意一下红色部分,之前没有这部分的知识,导致直接以为这里仅仅需要一个char 类型的就够了,其实不然,这个意思是告诉你,该部分需要提供258h-58h=200h大小的空间,由char v11来指向该地址,所以下边才有P = & v11;所以反汇编函数中应该声明char v11[512]而不是char v11,200h转化为10进制是512,切记,不然会发现memcpy的时候,P的地址被V19抵充了!!!经过这几天的痛苦努力,总结最大的就是参数类型,栈的存储方式,通信原理等等,很基本知识,却是很重要的知识,跟以前做的那种程序比,真的不一样,很棒!
004:通信再说一下,之前以为仅仅传递的是一个字符串那样的缓存,结果才发现,原来传递的参数多的话,可以自定义一个结构体,将需要的东西都存储到结构体中,传递过去的是一个指向缓存的指针,而指向可以自己任意,这样特别的方便,相当于应用层与你写的驱动层,对于你来说是透明的,把通信的中间设计好了,很棒的!
005:做完这个函数,用这个思路继续写一下分页的那个函数:
MiDoMappedCopy()
IDA中的反汇编代码第4、5个参数:
int v11;//[sp+64h][bp-64h]@7
unsigned int v12//[sp+7ch][bp-4ch]@7
同样的,64-4c=18转化为10进制是24,这正好是KeStackAttachProcess第二个参数里边指向的结构体KAPC_STATE:
typedef struct _KAPC_STATE
{
LIST_ENTRY ApcListHead[2];
PKPROCESS Process;
UCHAR KernelApcInProgress;
UCHAR KernelApcPending;
UCHAR UserApcPending;
} KAPC_STATE, *PKAPC_STATE;
里边的LIST_ENTRY是两个指针,也就是8字节:
typedef struct _LIST_ENTRY
{
PLIST_ENTRY Flink;
PLIST_ENTRY Blink;
} LIST_ENTRY, *PLIST_ENTRY;
所以KAPC_STATE就是8*2+4+3=23,还空着一个字节不知道是什么意思?希望有谁知道,跟大家分享一下,我感觉这个可能仅仅是为了对齐的。
回到主题,v12占用24字节,而函数中的KeStackAttachProcess里边调用该地址,所以反汇编出来后,v11就变成了:KAPC_STATE ApcState了。
006:直接使用反汇编代码,走到了MmMapLockedPagesSpecifyCache函数的时候蓝屏了,调试看下,发现里边的:
MmMapLockedPagesSpecifyCache(&MemoryDescriptorList, v7 , MmCached , (PVOID)v7 , v7 , HighPagePriority);出现了一个被忽视的问题,返汇编中所有的FALSE,NULL,0等等都是使用的v7=0,想法挺好,但是容易出现问题,详细看一下:
MemoryDescriptorList.Next = (Struct _MDL *)v7;
...................
MmProbeAndLockPages(&MemoryDescriptorList , AccessMode , (LOCK_OPERATION)v7);
这行结束后,原始为v7=0变成了v7=一个很大的数,就再也不是表示0了,后边MmMapLockedPagesSpecifyCache必然导致崩溃,方法就是别偷懒,把MmMapLockedPagesSpecifyCache里边的参数用FALSE,NULL等修改。
看到一个朋友的博客,写的很详细: