反汇编编程遇到的问题总结

反汇编编程遇到的问题总结

编写NtReadVirtualProcess反汇编代码的时候,遇到了一系列问题,记录一下,希望能给一些也是初入该领域的朋友带去帮助:

在此之前写过的几篇文章:

第五天 使用IDA反汇编系统NTReadVirtualMemory函数,模拟实现里边的部分函数

驱动与应用层简单消息通信总结

windows 编程ReadProcessMemory 使用中遇到的问题解决

总结的时候发现别人的一个博客,写的很好:

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
);
解释:

Process [in, out]

Pointer to the target process object. This parameter can be a PEPROCESS pointer returned byIoGetCurrentProcess orPsGetCurrentProcess.

ApcState [out]

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.

注意第二条,调用者必须开辟内存空间存储KAPC_STATE结构,无论是从非分页池还是从调用者自身的线程栈。

如果注意一下也会在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等修改。

看到一个朋友的博客,写的很详细:

Windows驱动中通过MDL实现用户态与核心态共享内存


你可能感兴趣的:(windows,操作系统,汇编)