首页
论坛
专栏
课程

[系统底层] [求助]ZwQuerySystemInformation

2016-10-13 15:43 2601

[系统底层] [求助]ZwQuerySystemInformation

2016-10-13 15:43
2601
本菜鸟想想自己 做个进程管理工具,

ZwQuerySystemInformation 按网上一些教程 编译出来可以正常运行,

但是写成 dll文件 用其他程序调用就出问题 

这是原始代码

#include <stdio.h>
#include <Windows.h>

typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)
(
  IN ULONG  SystemInformationClass,
  OUT PVOID  SystemInformation,
  IN ULONG  Length,
  OUT PULONG  ReturnLength
);

typedef unsigned long DWORD;

typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY
{
    ULONG Unknow1;
    ULONG Unknow2;
    ULONG Unknow3;
  ULONG Unknow4;
    PVOID Base;
    ULONG Size;
    ULONG Flags;
    USHORT Index;
    USHORT NameLength;
    USHORT LoadCount;
    USHORT ModuleNameOffset;
    char ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;

typedef struct _SYSTEM_MODULE_INFORMATION
{
    ULONG Count;//内核中以加载的模块的个数
    SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation;

BOOLEAN EnumKM(char *HighlightDrvName)
{
    ULONG NeedSize, i, ModuleCount, HLed=0, BufferSize = 0x5000;
    PVOID pBuffer = NULL;
  PCHAR pDrvName = NULL;
    NTSTATUS Result;
    PSYSTEM_MODULE_INFORMATION pSystemModuleInformation;
    do
    {
        //分配内存
        pBuffer = malloc( BufferSize );
        if( pBuffer == NULL )
            return 0;
        //查询模块信息
        Result = ZwQuerySystemInformation( 11, pBuffer, BufferSize, &NeedSize );
        if( Result == 0xC0000004L )
        {
            free( pBuffer );
            BufferSize *= 2;
        }
        else if( Result<0 )
        {
            //查询失败则退出
            free( pBuffer );
            return 0;
        }
    }
    while( Result == 0xC0000004L );
    pSystemModuleInformation = (PSYSTEM_MODULE_INFORMATION)pBuffer;
  //获得模块的总数量
    ModuleCount = pSystemModuleInformation->Count;
  //遍历所有的模块
    for( i = 0; i < ModuleCount; i++ )
  {
    if((ULONG64)(pSystemModuleInformation->Module[i].Base) > (ULONG64)0x8000000000000000)
    {
      pDrvName = pSystemModuleInformation->Module[i].ImageName+pSystemModuleInformation->Module[i].ModuleNameOffset;
      printf("0x%llx\t%s",(ULONG64)pSystemModuleInformation->Module[i].Base,pDrvName);
      if( _stricmp(pDrvName,HighlightDrvName)==0 )
      {
        printf("\t\t<--------------------");
        HLed=1;
      }
      printf("\n");
    }
  }
  if(HLed==0)
    printf("\n[%s] NOT FOUND!",HighlightDrvName);
  free(pBuffer);
  return 1;
}

int main()
{  
  ZwQuerySystemInformation=(ZWQUERYSYSTEMINFORMATION)GetProcAddress(LoadLibraryW(L"ntdll.dll"),"ZwQuerySystemInformation");
  EnumKM("disk.sys");
  getchar();
  return 0;
}

这是导出 后的dll

#include <stdio.h>
#include <Windows.h>
#include <stdlib.h>
extern "C" __declspec(dllexport) BOOLEAN EnumKM(char *HighlightDrvName);//这句有问题 吗?
typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)
(
  IN ULONG  SystemInformationClass,
  OUT PVOID  SystemInformation,
  IN ULONG  Length,
  OUT PULONG  ReturnLength
);

typedef unsigned long DWORD;

typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY
{
    ULONG Unknow1;
    ULONG Unknow2;
    ULONG Unknow3;
  ULONG Unknow4;
    PVOID Base;
    ULONG Size;
    ULONG Flags;
    USHORT Index;
    USHORT NameLength;
    USHORT LoadCount;
    USHORT ModuleNameOffset;
    char ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;

typedef struct _SYSTEM_MODULE_INFORMATION
{
    ULONG Count;//内核中以加载的模块的个数
    SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation;

BOOLEAN EnumKM(char *HighlightDrvName)
{
    ULONG NeedSize, i, ModuleCount, HLed=0, BufferSize = 0x5000;
    PVOID pBuffer = NULL;
  PCHAR pDrvName = NULL;
    NTSTATUS Result;
    PSYSTEM_MODULE_INFORMATION pSystemModuleInformation;
  ZwQuerySystemInformation=(ZWQUERYSYSTEMINFORMATION)GetProcAddress(LoadLibraryW(L"ntdll.dll"),"ZwQuerySystemInformation");
    do
    {
        //分配内存
        pBuffer = malloc( BufferSize );
        if( pBuffer == NULL )
            return 0;
        //查询模块信息
        Result = ZwQuerySystemInformation( 11, pBuffer, BufferSize, &NeedSize );
        if( Result == 0xC0000004L )
        {
            free( pBuffer );
            BufferSize *= 2;
        }
        else if( Result<0 )
        {
            //查询失败则退出
            free( pBuffer );
            return 0;
        }
    }
    while( Result == 0xC0000004L );
    pSystemModuleInformation = (PSYSTEM_MODULE_INFORMATION)pBuffer;
  //获得模块的总数量
    ModuleCount = pSystemModuleInformation->Count;
  //遍历所有的模块
    for( i = 0; i < ModuleCount; i++ )
  {
    if((ULONG64)(pSystemModuleInformation->Module[i].Base) > (ULONG64)0x8000000000000000)
    {
      pDrvName = pSystemModuleInformation->Module[i].ImageName+pSystemModuleInformation->Module[i].ModuleNameOffset;
      printf("0x%llx\t%s",(ULONG64)pSystemModuleInformation->Module[i].Base,pDrvName);
      if( _stricmp(pDrvName,HighlightDrvName)==0 )
      {
        printf("\t\t<--------------------");
        HLed=1;
      }
      printf("\n");
    }
  }
  if(HLed==0)
    printf("\n[%s] NOT FOUND!",HighlightDrvName);
  free(pBuffer);
  return 1;
}

这是调用 Dll 的  EXE

#include <stdio.h>
#include <Windows.h>
int main()
{
  typedef BOOLEAN EKM(char*);

  HMODULE hdll=LoadLibrary(L"testdll.dll");
  if(hdll==NULL)
  {
    printf("载入模块失败\n");
  }
  EKM* EnumKM=(EKM*)GetProcAddress(hdll,"EnumKM");
  if(EnumKM==NULL)
  {
    printf("定位符合失败\n");
  }
  EnumKM("disk.sys\n");
}

有好心人 指教一些 

[公告]安全测试和项目外包请将项目需求发到看雪企服平台:https://qifu.kanxue.com

最新回复 (4)
hzqst 3 2016-10-13 17:44
2
0
nt6以上的系统需要管理员权限+SeDebugPrivilege才能枚举进程
云栖小镇 2016-10-13 19:17
3
0
这个代码运行是正常的,问题是我想做成动态库,给其他程序调用,应该是函数压栈 方式出问题,调用报错
hzqst 3 2016-10-13 19:57
4
0
typedef NTSTATUS (*NTAPI ZWQUERYSYSTEMINFORMATION)
(
  IN ULONG  SystemInformationClass,
  OUT PVOID  SystemInformation,
  IN ULONG  Length,
  OUT PULONG  ReturnLength
);

这样就行了
云栖小镇 2016-10-14 14:48
5
0
好我试试
游客
登录 | 注册 方可回帖
返回