extern和_declspec(dllimport)的区别
写shadow ssdt hook的时候出现一个比较奇怪的错误,看下面的代码:
#include "ntddk.h"
#pragma pack(1)
typedef struct _SystemServiceTable
{
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char* ParamTableBase;
} SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE;
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
SYSTEM_SERVICE_TABLE ntoskrnl;
SYSTEM_SERVICE_TABLE win32k;
SYSTEM_SERVICE_TABLE table3;
SYSTEM_SERVICE_TABLE table4;
} SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;
#pragma pack()
SERVICE_DESCRIPTOR_TABLE KeSystemServiceDescriptorTable;
``````<span style="text-decoration: underline;">```_declspec(dllimport) ```PSYSTEM_SERVICE_TABLE KeServiceDescriptorTable;</span>
_declspec(dllimport) KeAddSystemServiceTable(ULONG, ULONG, ULONG, ULONG, ULONG);
SYSTEM_SERVICE_TABLE* GetServiceDescriptorShadowTableAddress()
{
unsigned char *check = (unsigned char*)KeAddSystemServiceTable;
int i;
SYSTEM_SERVICE_TABLE *rc = 0;
DbgPrint("KeAddSystemServiceTable: 0x%p\n", check);
DbgPrint("KeServiceDescriptorTable: 0x%p\n", KeServiceDescriptorTable);
for (i=0; i<100; i++)
{
__try
{
rc = *(SYSTEM_SERVICE_TABLE**)check;
if (!MmIsAddressValid(rc)
|| (rc == KeServiceDescriptorTable)
|| (memcmp(rc, KeServiceDescriptorTable, sizeof (*rc)) != 0))
{
if (MmIsAddressValid(rc))
DbgPrint("Something: %08x\n", rc);
check ++;
rc = 0;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
rc = 0;
}
if (rc) break;
}
DbgPrint("Ans: %08x\n", rc);
return rc;
}
void Unload(PDRIVER_OBJECT driver)
{
DbgPrint("Unload!\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING szReg)
{
DbgPrint("DriverEntry\n");
GetServiceDescriptorShadowTableAddress();
driver-> DriverUnload = Unload;
return STATUS_SUCCESS;
}
总是得不到正确的地址,看出来是哪里错了嘛?
加下划线的那一行,我用了dllimport,实际上_declspec(dllimport)导入的是导出变量的值,而这里需要的是导出变量的地址,所以需要用extern。改掉之后就可以找到KeServiceDescriptorTableShadow的地址了。