S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

hook未导出native api的好办法

Posted on 2009-11-04 11:39 S.l.e!ep.¢% 阅读(371) 评论(0)  编辑 收藏 引用 所属分类: RootKit
				
						昨天写的那个 
hook ssdt的驱动,用的是硬编码的办法,这样在不同的系统中由于NtShutdownSystem的服务号都不相同,所以在不同的操作系统上代码都要做修改,这个比较不爽.今天听老大PJF说有避免硬编码的方法,google了下,发现下面的文章,代码稍微改了改,用在我的驱动中,果然好使.文章贴在下面:
-------------------------------------------------------------------------------------------
from http://www.rootkit.com

Hardcoding the positions seems a poor solution, since it means after a new service pack, the rootkit may no longer work and become discovered.

As I have found the code on this site extremely helpful, I think it is only fair that I return the favour ;-)

I have implemented the method described in previous posts, whereby I have mapped a view of ntdll.dll into the process space of whoever loads the driver initially, and then retrieve the required function positions directly from the dll.

This was relatively simple to do, and only requires knowledge of the pe file format, and a few undocumented apis.

Using the function pasted below, when hooking you simply do as follows:


RtlInitUnicodeString(&dllName, L"\\Device\\HarddiskVolume1\\Windows\\System32\\ntdll.dll");
functionAddress = GetDllFunctionAddress(functionName, &dllName);
position = *((WORD*)(functionAddress+1));
    
g_OriginalZwCreateProcessEx = (ZWCREATEPROCESSEX)(KeServiceDescriptorTable.ServiceTableBase[position]);


and here's the function 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;

    //_asm int 3;
    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);

    // now we can get the exported functions, but note we convert from RVA to address
    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; // always need to add base, -1 as array counts from 0
        // this is the funny bit.  you would expect the function pointer to simply be arrayOfFunctionAddresses[x]...
        // oh no... thats too simple.  it is actually arrayOfFunctionAddresses[functionOrdinal]!!
        functionAddress = (DWORD)( (BYTE*)hMod + arrayOfFunctionAddresses[functionOrdinal]);
        if (RtlCompareString(&ntFunctionName, &ntFunctionNameSearch, TRUE) == 0) 
        {
            ZwClose(hSection);
            return functionAddress;
        }
    }

    ZwClose(hSection);
    return 0;
}

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理