ssdt函数索引号_BUG:SSDT函数名获取SSDT函数号

ULONG GetFunctionId(char* FunctionName)

/*++

Routine Description:

[已删除,请勿再提任何无理要求。]

Arguments:

FunctionName - 导出的函数名.

Return Value:

函数的服务号的地址.

--*/

{

NTSTATUS ntstatus;

HANDLE hFile = NULL;

HANDLE hSection = NULL;

OBJECT_ATTRIBUTES object_attributes;

IO_STATUS_BLOCK io_status = { 0 };

PVOID baseaddress = NULL;

SIZE_T size = 0;

//模块基址

//        PVOID ModuleAddress = NULL;

//偏移量

ULONG dwOffset = 0;

PIMAGE_DOS_HEADER dos = NULL;

#ifdef _WIN64

PIMAGE_NT_HEADERS64 nt = NULL;

#else

PIMAGE_NT_HEADERS nt = NULL;

#endif

PIMAGE_DATA_DIRECTORY expdir = NULL;

PIMAGE_EXPORT_DIRECTORY exports = NULL;

ULONG addr;

ULONG Size;

PULONG functions;

PSHORT ordinals;

PULONG names;

ULONG max_name;

ULONG max_func;

ULONG i;

ULONG pFunctionAddress = 0;

ULONG ServiceId;

UNICODE_STRING DllName;

RtlInitUnicodeString(&DllName, L"\\SystemRoot\\system32\\ntdll.dll");

//初始化OBJECT_ATTRIBUTES结构

InitializeObjectAttributes(

&object_attributes,

&DllName,

OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,

NULL,

NULL);

//打开文件

ntstatus = ZwCreateFile(

&hFile,

FILE_EXECUTE | SYNCHRONIZE,

&object_attributes,

&io_status,

NULL,

FILE_ATTRIBUTE_NORMAL,

FILE_SHARE_READ,

FILE_OPEN,

FILE_NON_DIRECTORY_FILE |

FILE_RANDOM_ACCESS |

FILE_SYNCHRONOUS_IO_NONALERT,

NULL,

0);

if (!NT_SUCCESS(ntstatus))

{

KdPrint(("[GetFunctionAddress] error0\n"));

KdPrint(("[GetFunctionAddress] ntstatus = 0x%x\n", ntstatus));

return 0;

}

//创建区段

InitializeObjectAttributes(

&object_attributes,

NULL,

OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,

NULL,

NULL);

#ifndef SEC_IMAGE

#define SEC_IMAGE 0x1000000

#endif

ntstatus = ZwCreateSection(

&hSection,

SECTION_ALL_ACCESS,

&object_attributes,

0,

PAGE_EXECUTE,

SEC_IMAGE,

hFile);

if (!NT_SUCCESS(ntstatus))

{

KdPrint(("[GetFunctionAddress] error1\n"));

KdPrint(("[GetFunctionAddress] ntstatus = 0x%x\n", ntstatus));

return 0;

}

//映射区段到进程虚拟空间

ntstatus = ZwMapViewOfSection(

hSection,

NtCurrentProcess(), //ntddk.h定义的宏用来获取当前进程句柄

&baseaddress,

0,

1000,

0,

&size,

(SECTION_INHERIT)1,

MEM_TOP_DOWN,

PAGE_READWRITE);

if (!NT_SUCCESS(ntstatus))

{

KdPrint(("[GetFunctionAddress] error2\n"));

KdPrint(("[GetFunctionAddress] ntstatus = 0x%x\n", ntstatus));

return 0;

}

//得到模块基址

dwOffset = (ULONG)baseaddress;

//验证基址

//KdPrint(("[GetFunctionAddress] BaseAddress:0x%x\n", dwOffset));

dos = (PIMAGE_DOS_HEADER)baseaddress;

#ifdef _WIN64

nt = (PIMAGE_NT_HEADERS64)((ULONG)baseaddress + dos->e_lfanew);

#else

nt = (PIMAGE_NT_HEADERS)((ULONG)baseaddress + dos->e_lfanew);

#endif

expdir = (PIMAGE_DATA_DIRECTORY)(nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT);

addr = expdir->VirtualAddress;//数据块起始RVA

Size = expdir->Size;    //数据块长度

exports = (PIMAGE_EXPORT_DIRECTORY)((ULONG)baseaddress + addr);

functions = (PULONG)((ULONG)baseaddress + exports->AddressOfFunctions);

ordinals = (PSHORT)((ULONG)baseaddress + exports->AddressOfNameOrdinals);

names = (PULONG)((ULONG)baseaddress + exports->AddressOfNames);

max_name = exports->NumberOfNames;

max_func = exports->NumberOfFunctions;

for (i = 0; i < max_name; i++)

{

ULONG ord = ordinals[i];

if (i >= max_name || ord >= max_func)

{

return 0;

}

if (functions[ord] < addr || functions[ord] >= addr + Size)

{

if (strncmp((PCHAR)baseaddress + names[i], FunctionName, strlen(FunctionName)) == 0)

{

pFunctionAddress = (ULONG)((ULONG)baseaddress + functions[ord]);

break;

}

}

}

//KdPrint(("[GetFunctionAddress] %s:0x%x\n",FunctionName, pFunctionAddress));

ServiceId = *(PSHORT)(pFunctionAddress + 1);

//打印导出函数服务号

//KdPrint(("[GetServiceId] ServiceId:0x%x\n",ServiceId));

//卸载区段,释放内存,关闭句柄

ZwUnmapViewOfSection(NtCurrentProcess(), baseaddress);

ZwClose(hSection);

ZwClose(hFile);

return ServiceId;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值