首页
社区
课程
招聘
驱动枚举dll,ZwQueryVirtualMemory总是返回内存访问违法?、大牛们求解呀
发表于: 2013-3-6 14:00 3453

驱动枚举dll,ZwQueryVirtualMemory总是返回内存访问违法?、大牛们求解呀

2013-3-6 14:00
3453
//////////////////////////////////////////////////////////////////////////
// Dll.c

#include "precomp.h"
#include "Dll.h"


NTSTATUS EnumDllByZwQueryVirtualMem(ULONG ulPid)
{
  NTSTATUS status=0;
  MEMORY_BASIC_INFORMATION mem_info = {0};
  MEMORY_SECTION_NAME mem_secName;

  HANDLE hProcess;
  OBJECT_ATTRIBUTES obj;
  CLIENT_ID cid;
  PEPROCESS  pEproc;

  int      retLen;
  ULONG    index=0;
  PRKAPC_STATE pApcStatus;

  ULONG *systemCallTable = (ULONG*)KeServiceDescriptorTable.KiServiceTable;
  MyZwQueryVirtualMemory ZwQueryVirtualMemory = (MyZwQueryVirtualMemory)( systemCallTable[0xB2] );
  
  cid.UniqueProcess = (HANDLE)ulPid;
  cid.UniqueThread = NULL;
  InitializeObjectAttributes(&obj, NULL, 0, NULL, NULL);

  status = PsLookupProcessByProcessId( (HANDLE)ulPid, &pEproc);
  if ( !NT_SUCCESS(status) )
  {
    KdPrint(("cannot get process eprocess, ERROR CODE = %08X\n", status));
    status = STATUS_UNSUCCESSFUL;
    return status;
  }

  pApcStatus = (PRKAPC_STATE)ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC_STATE), 'pApc');
  if (pApcStatus)
  {
    KeStackAttachProcess(pEproc, pApcStatus);
    KdPrint(("已切换到目标进程上下文\n"));
  }

  //获取进程句柄
  status = ZwOpenProcess(&hProcess, PAGE_READWRITE, &obj, &cid);
  if ( !NT_SUCCESS(status) )
  {
    KdPrint(("cannot get process handle, ERROR CODE = %08X\n", status));
    status = STATUS_UNSUCCESSFUL;
    return status;
  }
  KdPrint(("hProcess= %X\n", hProcess));

  do 
  {
    //查询内存 ;这里为何返回状态为访问违法呢???
    status=ZwQueryVirtualMemory( hProcess,
                  (PULONG)index,
                  MemoryBasicInformation,
                  &mem_info,
                  sizeof(mem_info),
                  NULL );
    if ( !NT_SUCCESS(status) )
    {
      DbgPrint("cannot query memory, ERROR CODE = %08X\n", status);

      KeUnstackDetachProcess(pApcStatus);
      ExFreePoolWithTag(pApcStatus,'pApc');
      status = STATUS_SUCCESS;
      return status;
    }

    if ( status >= 0 )
    {
      KdPrint(("ZwQueryVirtualMemory 成功!\n"));

      //判断"内存节.类型"是否是 "映像/模块"类型
      if (mem_info.Type == MEM_IMAGE)
      {
        //判断模块所占内存范围
        if ( (DWORD)mem_info.AllocationBase == index )
        {
          //查询内存节名
          status=ZwQueryVirtualMemory( hProcess,
                        (PULONG)index,
                        MemorySectionName,
                        &mem_secName,
                        sizeof(mem_secName),
                        NULL );
          if ( status >= 0 )
          {
            KdPrint(("Address:%08X \t ModuleName:%ws\n", index, mem_secName.SectionFileName.Buffer));
          }
        }
      }
    }

    index += 0x1000;
  } while (index < 0x80000000);

  KeUnstackDetachProcess(pApcStatus);
  ExFreePoolWithTag(pApcStatus,'pApc');
  status = STATUS_SUCCESS;
  return status;
}


头文件:
//////////////////////////////////////////////////////////////////////////
// Dll.h

#ifndef _DLL_H_
#define _DLL_H_


// #define MAX_PATH     256
// 
// typedef struct _DLL_INFO
// {
//   CHAR  pszPath[MAX_PATH];
//   ULONG  ulBase;
//   ULONG  ulSize;
// }DLL_INFO, *PDLL_INFO;


#define MEM_IMAGE    0x1000000
#define PROCESS_QUERY_INFORMATION          (0x0400) 

typedef unsigned long       DWORD;

typedef enum _MEMORY_INFORMATION_CLASS 
{
  MemoryBasicInformation,
  MemoryWorkingSetList,
  MemorySectionName
}MEMORY_INFORMATION_CLASS;

typedef struct _MEMORY_BASIC_INFORMATION {
  PVOID BaseAddress;
  PVOID AllocationBase;
  DWORD AllocationProtect;
  SIZE_T RegionSize;
  DWORD State;
  DWORD Protect;
  DWORD Type;
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;

typedef struct
{
  UNICODE_STRING SectionFileName;
  WCHAR       NameBuffer[ANYSIZE_ARRAY];
} MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME;

#pragma pack(1)
typedef struct ServiceDescriptorEntry
{
  DWORD *KiServiceTable;
  DWORD *CounterBaseTable;
  DWORD *nSystemCalls;
  DWORD *KiArgumentTable;
}SDE, *PSDE;
#pragma pack()

typedef struct ServiceDescriptorTable
{
  SDE ServiceDescriptor[4];
} SDT;

__declspec(dllimport) SDE KeServiceDescriptorTable;

typedef NTSTATUS
(NTAPI *MyZwQueryVirtualMemory)(
                IN HANDLE ProcessHandle,
                IN PVOID BaseAddress,
                IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
                OUT PVOID MemoryInformation,
                IN ULONG MemoryInformationLength,
                OUT PULONG ReturnLength OPTIONAL
                );

NTSTATUS EnumDllByZwQueryVirtualMem( ULONG ulPid );

//////////////////////////////////////////////////////////////////////////
#endif

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 8865
活跃值: (2379)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
2
你的PrevMode是KernelMode么~!!
2013-3-6 17:01
0
雪    币: 17
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
大哥,小弟很菜。在驱动程序中运行调用函数时,难道当前线程结构的PreviousMode不是KernelMode模式的?
2013-3-6 18:45
0
游客
登录 | 注册 方可回帖
返回
//