首页
社区
课程
招聘
[求助](有源码)居然把NtReadVirtualMemory换成ZwQuerySystemInformation就能编译了?
发表于: 2009-7-25 19:58 10291

[求助](有源码)居然把NtReadVirtualMemory换成ZwQuerySystemInformation就能编译了?

2009-7-25 19:58
10291
这是一个获取ZwQuerySystemInformation函数地址的例子.
怪了换成NtReadVirtualMemory就不行,真是奇怪。
还有

//获得函数在SSDT中的索引宏
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)

这个宏是怎么用的 传进的 _Function  应该是什么东西?

附不能编译的和能编译的:

不能编译:
#include "ntddk.h"

typedef unsigned long DWORD;
typedef DWORD * PDWORD;

typedef struct ServiceDescriptorEntry {
  unsigned int *ServiceTableBase;
  unsigned int *ServiceCounterTableBase; //仅适用于checked build版本
  unsigned int NumberOfServices;
  unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;


__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;

//获得SSDT基址宏
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]


PVOID *MappedSystemCallTable;

//获得函数在SSDT中的索引宏
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)

//调换自己的hook函数与原系统函数的地址
#define HOOK_SYSCALL(_Function, _Hook, _Orig ) \
_Orig = (PVOID) InterlockedExchange( (PLONG) &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)


typedef NTSTATUS (*NtReadVirtualMemory)
(
IN HANDLE               ProcessHandle,
  IN PVOID                BaseAddress,
  OUT PVOID               Buffer,
  IN ULONG                NumberOfBytesToRead,
  OUT PULONG              NumberOfBytesReaded OPTIONAL
);





VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
  DbgPrint("ROOTKIT: OnUnload called\n");

  

}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject, 
           IN PUNICODE_STRING theRegistryPath)
{       
      ULONG AAA;
  DbgPrint("ROOTKIT: Start\n");
  
  theDriverObject->DriverUnload = OnUnload; 

        
  
  AAA = SYSTEMSERVICE(NtReadVirtualMemory);
        
        DbgPrint("%08X\r\n",AAA);
  
        return STATUS_SUCCESS;
}




能编译:

#include "ntddk.h"

typedef unsigned long DWORD;
typedef DWORD * PDWORD;

typedef struct ServiceDescriptorEntry {
  unsigned int *ServiceTableBase;
  unsigned int *ServiceCounterTableBase; //仅适用于checked build版本
  unsigned int NumberOfServices;
  unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;


__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;

//获得SSDT基址宏
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]


PVOID *MappedSystemCallTable;

//获得函数在SSDT中的索引宏
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)

//调换自己的hook函数与原系统函数的地址
#define HOOK_SYSCALL(_Function, _Hook, _Orig ) \
_Orig = (PVOID) InterlockedExchange( (PLONG) &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)

NTSYSAPI
NTSTATUS
NTAPI ZwQuerySystemInformation(
                 IN ULONG SystemInformationClass,
                 IN PVOID SystemInformation,
                 IN ULONG SystemInformationLength,
                 OUT PULONG ReturnLength);


typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(
                       ULONG SystemInformationCLass,
                       PVOID SystemInformation,
                       ULONG SystemInformationLength,
                       PULONG ReturnLength
);

VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
  DbgPrint("ROOTKIT: OnUnload called\n");

  

}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject, 
           IN PUNICODE_STRING theRegistryPath)
{       
DWORD aaa;
  DbgPrint("ROOTKIT: Start\n");
  // 注册一个卸载的分发函数,与应用层沟通
  theDriverObject->DriverUnload = OnUnload; 

        
  
  aaa = SYSTEMSERVICE(ZwQuerySystemInformation);
        
        DbgPrint("%08X\r\n",aaa);
  
        return STATUS_SUCCESS;
}




可是我想获取的是NtReadVirtualMemory的地址

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (20)
雪    币: 952
活跃值: (1821)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
NtReadVirtualMemory没有导出。当然不行了
2009-7-25 20:35
0
雪    币: 44
活跃值: (133)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
Zw*函数的开始是mov eax,XXX XXX也就是索引(服务号)。
比如nt!ZwQuerySystemInformation:
80501ac0 b8ad000000      mov     eax,0ADh
这条指令5字节,后面4字节就是服务号,因此可以看到SYSCALL_INDEX中(PUCHAR)_Function+1),_Function是Zw*函数地址。
其实,这个SYSTEMSERVICE得到的就是相应的Nt*函数地址。
2009-7-25 21:43
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
4
NtReadVirtualMemory明明导出
2009-7-25 23:12
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
5
导出未导出
文档未文档可不是一个意思啊
2009-7-25 23:14
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
6
NtReadVirtualMemory导出未文档函数  可以直接用函数名做变量的
2009-7-25 23:16
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
7
未导出函数 函数名不可做变量使用 函数地址需要自己定位
ssdt中的导出函数,均可利用宏
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
获取函数地址
2009-7-25 23:17
0
雪    币: 246
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
[QUOTE=竹君;661120]未导出函数 函数名不可做变量使用 函数地址需要自己定位
ssdt中的导出函数,均可利用宏
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function...[/QUOTE]

竹君!能不能帮我修改一下。这么说的话我还是不知道应该怎么做!
2009-7-26 12:19
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
madaxian=马大仙?     

   其实最近你提的这些问题 网上早就有答案了  何不搜索一下?

#define SYSCALL_INDEX(_Function) *(PULONG) ((PUCHAR)_Function+1)
把上面的宏分成两部分理解
1 ((PUCHAR)_Function+1)   
Function是函数地址  把Function转换成字符指针   
+1是SSDT 函数的特性   可以获取SSDT对应服务号

ntdll!NtReadVirtualMemory:
7c92e2bb b8ba000000      mov     eax,0BAh
7c92e2c0 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92e2c5 ff12            call    dword ptr [edx]
7c92e2c7 c21400          ret     14h
7c92e2ca 90              nop

2  *(PULONG)  
然后 转换成ULONG指针  取这个ULONG指针的值    也就是获取上面的 0BAh

要用NtReadVirtualMemory的话  

你可以在R3 获取NTDLL 中 NtReadVirtualMemory函数地址 然后IO(PASSIVE_LEVEL级别)给R0的SYSTEMSERVICE宏  就可以获取当前SSDT 表NtReadVirtualMemory  函数的地址了
2009-7-26 15:23
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
10
不是不想帮你,你还是自己写下代码吧。不要下人家的代码在那修改。这样你根本学不到东西
2009-7-26 17:25
0
雪    币: 246
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
xacker! 我在r3直接获取 0BAh 然后传给驱动不是更方便么?
2009-7-26 18:05
0
雪    币: 612
活跃值: (996)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
NtReadVirtualMemory是未导出函数!导出或未导出看ntoskrnl.exe导出表就晓得了...用下面的GetDllFunctionAddress函数就可以获取到他的函数地址!

DWORD GetDllFunctionAddress(char* lpFunctionName, PUNICODE_STRING pDllName)
{
        HANDLE hThread, hSection, hFile, hMod;
        SECTION_IMAGE_INFORMATION sii;
        IMAGE_DOS_HEADER* dosheader;
        IMAGE_OPTIONAL_HEADER* opthdr;
        IMAGE_EXPORT_DIRECTORY* pExportTable;
        DWORD* arrayOfFunctionAddresses;
        DWORD* arrayOfFunctionNames;
        WORD* arrayOfFunctionOrdinals;
        DWORD functionOrdinal;
        DWORD Base, x, functionAddress;
        char* functionName;
        STRING        ntFunctionName, ntFunctionNameSearch;
        PVOID BaseAddress = NULL;
        SIZE_T size=0;
       
        OBJECT_ATTRIBUTES oa = {sizeof oa, 0, pDllName, OBJ_CASE_INSENSITIVE};
        IO_STATUS_BLOCK iosb;
       
        ZwOpenFile(&hFile, FILE_EXECUTE | SYNCHRONIZE, &oa, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
       
        oa.ObjectName = 0;
       
        ZwCreateSection(&hSection, SECTION_ALL_ACCESS, &oa, 0,PAGE_EXECUTE, SEC_IMAGE, hFile);
       
        ZwMapViewOfSection(hSection, NtCurrentProcess(), &BaseAddress, 0, 1000, 0, &size, (SECTION_INHERIT)1, MEM_TOP_DOWN, PAGE_READWRITE);
       
        ZwClose(hFile);
       
        hMod = BaseAddress;
       
        dosheader = (IMAGE_DOS_HEADER *)hMod;
       
        opthdr =(IMAGE_OPTIONAL_HEADER *) ((BYTE*)hMod+dosheader->e_lfanew+24);
       
        pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*) hMod + opthdr->DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress);
       
        arrayOfFunctionAddresses = (DWORD*)( (BYTE*)hMod + pExportTable->AddressOfFunctions);
       
        arrayOfFunctionNames = (DWORD*)( (BYTE*)hMod + pExportTable->AddressOfNames);
       
        arrayOfFunctionOrdinals = (WORD*)( (BYTE*)hMod + pExportTable->AddressOfNameOrdinals);
       
        Base = pExportTable->Base;
       
        RtlInitString(&ntFunctionNameSearch, lpFunctionName);
       
        for(x = 0; x < pExportTable->NumberOfFunctions; x++)
        {
                functionName = (char*)( (BYTE*)hMod + arrayOfFunctionNames[x]);
               
                RtlInitString(&ntFunctionName, functionName);
               
                functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1;
                functionAddress = (DWORD)( (BYTE*)hMod + arrayOfFunctionAddresses[functionOrdinal]);
                if (RtlCompareString(&ntFunctionName, &ntFunctionNameSearch, TRUE) == 0)
                {
                        ZwClose(hSection);
                        return functionAddress;
                }
        }
       
        ZwClose(hSection);
        return 0;
}
2009-7-26 18:52
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
    是的 你认为怎么方便就可以怎么做   

直接IO服务ID的话  把那个宏改一下就可以了
#define SYSTEMSERVICE(ID)  KeServiceDescriptorTable.ServiceTableBase[ ID]

BTW:   头像没见过... SASUKE么?
2009-7-26 20:09
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
14
无语了   说多少次了NtReadVirtualMemory是ntdll.dll导出函数  SSDT都有
2009-7-28 15:09
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
15
12楼代码真是大材小用
2009-7-28 15:10
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
16
自己解析NTDLL导出表取函数地址 这个函数也只有这个用途了  怎么能说大材小用呢  
如果是真正的未导出函数  PE的导出表里可找不到  

不过我等小菜 喜欢图简单 一般是用不上这个  能一句代码完事 就不用第二句   
哈哈
2009-7-28 16:21
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
17
ntdll.dll导出表咋看不到?
2009-7-28 18:02
0
雪    币: 612
活跃值: (996)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18
他说的是ntoskrnl.exe没导出.....
汗死,如果NtReadVirtualMemory是导出函数,你自己实验下用你说的那个宏看能不能获取.........
2009-7-28 20:39
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
19
ntdll导出了 有必要从ntoskrnl去取地址码?本来就是个SSDT HOOK
2009-7-28 20:42
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
20
没意义 此贴可结了
2009-7-28 20:43
0
雪    币: 612
活跃值: (996)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
21
....不然该怎么取,请教一下....
2009-7-28 20:45
0
游客
登录 | 注册 方可回帖
返回
//