首页
社区
课程
招聘
小菜问下获取未导出内核函数索引和地址的问题……
发表于: 2011-8-29 15:59 6394

小菜问下获取未导出内核函数索引和地址的问题……

2011-8-29 15:59
6394
因为内核函数在SSDT表和SSDT表中的索引可能会变化,所以尽可能的动态去获取索引,然后通过响应的表来获取其地址

网上为什么都用GetDllFunctionAddress来获取同名函数在ntdll.dll中的地址,然后用
SYSCALL_INDEX再来获取索引号,进而通过SSDT表来获得未导出内核函数的真实地址呢?

为什么不能直接通过ntkrnlpa.exe或者ntoskrnl.exe(貌似一共有四种可选内核文件)来直接获取未导出函数的真实地址呢,还要通过ntdll.dll中转??

#define SYSCALL_INDEX(_Function) *(PULONG) ((PUCHAR)_Function+1)


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; 
} 

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 53
活跃值: (29)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
说了是未导出啊,你怎么获取啊,特征码搜索?这个不准啊!

通过ntdll.dll,这个准确简单易用啊,居家旅行杀入必备啊!
2011-8-29 16:26
0
雪    币: 2
活跃值: (164)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
这样获得的Nt函数地址竟然跟windbg(u nt!NtOpenProcess)的地址不一样……

索引号:0x7a:
SSDT起始地址:0x8055d700:
地址:0x8055dea0:
入口地址:0xb223b9a8
函数名索引入口:0x805cc3fc


0: kd> u nt!NtCreateMutant
nt!NtCreateMutant:
80617d52 6a2c            push    2Ch
80617d54 6868e44d80      push    offset nt!ExpLuidIncrement+0x108 (804de468)
80617d59 e8224ef2ff      call    nt!_SEH_prolog (8053cb80)
80617d5e 33db            xor     ebx,ebx
80617d60 895dfc          mov     dword ptr [ebp-4],ebx
80617d63 64a124010000    mov     eax,dword ptr fs:[00000124h]
80617d69 8945d0          mov     dword ptr [ebp-30h],eax
80617d6c 8a8040010000    mov     al,byte ptr [eax+140h]


迷糊了……

    UNICODE_STRING str;
    RtlInitUnicodeString(&str,L"\\Device\\HarddiskVolume1\\Windows\\System32\\ntdll.dll");
    ULONG u1 = GetDllFunctionAddress("NtOpenProcess",&str);
    ULONG u2 = SYSCALL_INDEX(u1);
    KdPrint(("索引号:0x%x:\n",u2));
    KdPrint(("SSDT起始地址:0x%x:\n",KeServiceDescriptorTable.ServiceTableBase));
    KdPrint(("地址:0x%x:\n",KeServiceDescriptorTable.ServiceTableBase+u2*4));
    ULONG u3 = (ULONG)KeServiceDescriptorTable.ServiceTableBase+u2*4;
    ULONG u4 = *(ULONG*)u3;
    KdPrint(("入口地址:0x%x\n",u4));
    KdPrint(("函数名索引入口:0x%x\n",NtOpenProcess));
2011-8-29 17:03
0
雪    币: 2
活跃值: (164)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
结贴了,谢谢。

我再试试。
2011-8-29 18:05
0
游客
登录 | 注册 方可回帖
返回
//