与SSDT有关,但本质应该是C++指针有关问题

与SSDT有关,但本质应该是C++指针问题
一般SSDT HOOK的代码如下
#pragma pack(1)
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;
#pragma pack()

extern "C" ServiceDescriptorTableEntry KeServiceDescriptorTable; 

现在已经验证如下代码(HOOK1)能够成功HOOK:
ULONG index = *(PUCHAR)((PUCHAR)ZwOpenProcess+1);
ULONG ulBaseAddr = *(KeServiceDescriptorTable.ServiceTableBase);
PULONG SSDT_NTOpenProcess = (PULONG)(ulBaseAddr + index*4); 
OldZwOpenProcess = (ZWOPENPROCESS)(*SSDT_NTOpenProcess) ;
*SSDT_NTOpenProcess = (unsigned long)NewZwOpenProcess;

index就是表索引,用SB代替KeServiceDescriptorTable.ServiceTableBase,那么HOOK1代码里通过对SB使用*取值获得表地址。

但很多SSDT HOOK的代码并不是这么计算的,而是用一个这样的宏#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[*(PUCHAR)((PUCHAR)_function+1)]

该宏的中心应该是通过对SB[index]来获得表元素。


我的问题是不能理解SB既可以*SB取得表地址,又可以SB[index]获得表元素。想做一个简单的模拟都不成功,比如int Table[3] = {1,2,3};PUING pt = Table;那么pt[x]可以取表元素没有错,但*pt则不是表地址。如果是二级指针的话,*能得到表地址,但[]却不是表元素。

------解决方案--------------------
一级的时候*p 是不可以取到地址的!
------解决方案--------------------
按照C++的语法标准,SB[index] 和 *(SB + index) 是等价的,也就是说后者的SB表示的就是表地址,如果再按照你的说法,*SB也取得表地址,那么 *SB == SB,这个表达式成立的唯一情况就是SB[0]元素的值(也就是 *SB )刚好等于SB表地址