liio
驱动小牛
驱动小牛
  • 注册日期2005-12-24
  • 最后登录2022-06-16
  • 粉丝4
  • 关注1
  • 积分24分
  • 威望343点
  • 贡献值0点
  • 好评度171点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:2777回复:8

自己写的GetProcAddress,驱动里用用..

楼主#
更多 发布于:2008-10-05 01:43

最近不好玩..
写了这个东西.

通过分析PE格式得到.

LPVOID
FindProcAddress(
                LPVOID hBaseAddress,
                PSTR strProcName,
                UINT ProcNameSize
                )
/*
    FindProcAddress:
        获取动态库的导出函数位于内存中的地址.

    版本:
        N/A

    描述:
        hBaseAddress:    动态库的基址
        strProcName:    函数名
        ProcNameSize:    函数名长度

    编写:
        Liio ,08/10
*/
{
    PIMAGE_DOS_HEADER        pDosHeader = (PIMAGE_DOS_HEADER) hBaseAddress;
    PIMAGE_FILE_HEADER        pNtHeader = NULL;
    PIMAGE_OPTIONAL_HEADER    pOptHeader = NULL;
    PIMAGE_EXPORT_DIRECTORY    pExpHeader = NULL;

    PSTR                    ModuleName = NULL;

    ULONG                    NumberOfFunctions = 0;
    ULONG                    Offset = 0;

    ULONG                    CurrentFunOffset = 0;
    PSTR                    CurrentFunName = NULL;

    ULONG                    CurrentFunAddressOffset = 0;
    ULONG                    CurrentFunAddress = 0;

    if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
    {
        // Is Not Real PE File.
        return NULL;
    }

    pNtHeader = (PIMAGE_FILE_HEADER) ((PUCHAR) hBaseAddress + (pDosHeader->e_lfanew + 4));
    pOptHeader = (PIMAGE_OPTIONAL_HEADER) ((PUCHAR)pNtHeader + sizeof(IMAGE_FILE_HEADER));
    if (pOptHeader->DataDirectory[0].VirtualAddress == 0)
    {
        // The Export Table is NULL.
        return NULL;
    }

    pExpHeader = (PIMAGE_EXPORT_DIRECTORY) ((PUCHAR)hBaseAddress + pOptHeader->DataDirectory[0].VirtualAddress);
    ModuleName = (PSTR) ((PUCHAR)hBaseAddress + pExpHeader->Name);

    NumberOfFunctions = pExpHeader->NumberOfFunctions;
    while(NumberOfFunctions)
    {
        NumberOfFunctions--;
        CurrentFunOffset = *(ULONG *) ((PUCHAR)hBaseAddress + (pExpHeader->AddressOfNames + (Offset * sizeof(ULONG))));
        CurrentFunName = (PSTR) ((PUCHAR)hBaseAddress + CurrentFunOffset);

        if(RtlCompareMemory(CurrentFunName ,strProcName,ProcNameSize) == ProcNameSize)
        {
            CurrentFunAddressOffset = *(ULONG *) ((PUCHAR)hBaseAddress + (pExpHeader->AddressOfFunctions + (Offset * sizeof(ULONG))));
            return ((PUCHAR)hBaseAddress + CurrentFunAddressOffset);
        }
        
        Offset++;
    }

    return NULL;
}
WQXNETQIQI
驱动大牛
驱动大牛
  • 注册日期2006-06-12
  • 最后登录2010-10-26
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望1076点
  • 贡献值0点
  • 好评度895点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2008-10-05 03:00
效率太低,用2叉搜索啊~
驱动开发者 呵呵
killvxk
论坛版主
论坛版主
  • 注册日期2005-10-03
  • 最后登录2014-04-14
  • 粉丝3
  • 关注1
  • 积分1082分
  • 威望2003点
  • 贡献值0点
  • 好评度1693点
  • 原创分2分
  • 专家分0分
板凳#
发布于:2008-10-05 13:08
MmGetXXX很好用~
没有战争就没有进步 X3工作组 为您提供最好的军火
liio
驱动小牛
驱动小牛
  • 注册日期2005-12-24
  • 最后登录2022-06-16
  • 粉丝4
  • 关注1
  • 积分24分
  • 威望343点
  • 贡献值0点
  • 好评度171点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2008-10-05 15:30
....
对对对。。
回头再写个2叉叉的搜索放上来

MmGetSystemRoutineAddress貌似只能返回Hal.dll等里导出的地址?
boywhp
驱动中牛
驱动中牛
  • 注册日期2007-08-09
  • 最后登录2015-04-24
  • 粉丝2
  • 关注0
  • 积分1105分
  • 威望515点
  • 贡献值0点
  • 好评度254点
  • 原创分1分
  • 专家分0分
地下室#
发布于:2008-10-05 21:04
友情客串 不过貌似我也是这样干的 2分法没有必要吧 哈哈
该函数又不是经常要调用的,我的原则是只优化最需要优化的地方,其他越简单越好
boywhp
驱动中牛
驱动中牛
  • 注册日期2007-08-09
  • 最后登录2015-04-24
  • 粉丝2
  • 关注0
  • 积分1105分
  • 威望515点
  • 贡献值0点
  • 好评度254点
  • 原创分1分
  • 专家分0分
5楼#
发布于:2008-10-05 21:05
哇靠 !!!!我啥时候变成驱动肿瘤啊???
  幸福啊 兴奋啊 种牛啊
可耻的拼音输入法
nevergone
驱动牛犊
驱动牛犊
  • 注册日期2007-08-27
  • 最后登录2014-10-13
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望49点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2008-10-05 22:25
偶也实现过一个
用的是2叉
嘿嘿
tiamo
VIP专家组
VIP专家组
  • 注册日期2002-02-26
  • 最后登录2018-01-09
  • 粉丝17
  • 关注4
  • 积分50分
  • 威望142点
  • 贡献值1点
  • 好评度40点
  • 原创分2分
  • 专家分15分
  • 原创先锋奖
  • 社区居民
7楼#
发布于:2008-10-06 04:44
没有处理forwarder么....


//
    // check for a forwarder.
    //
    if(ThunkEntry->u1.Function > reinterpret_cast<ULONG>(ExportDirectory) && ThunkEntry->u1.Function < Add2Ptr(ExportDirectory,ExportSize,ULONG))
    {
        CHAR ForwardDllName[10];
        RtlCopyMemory(ForwardDllName,reinterpret_cast<PVOID>(ThunkEntry->u1.Function),sizeof(ForwardDllName));

        *strchr(ForwardDllName,'.')                        = '\0';

        //
        // should load the referenced DLL here, just return failure for now.
        //
        PLDR_DATA_TABLE_ENTRY DataTableEntry            = 0;
        if(!BlCheckForLoadedDll(ForwardDllName,&DataTableEntry))
            return EINVAL;

        ULONG TargetExportSize                            = 0;
        PVOID Temp                                        = RtlImageDirectoryEntryToData(DataTableEntry->DllBase,TRUE,IMAGE_DIRECTORY_ENTRY_EXPORT,&TargetExportSize);
        PIMAGE_EXPORT_DIRECTORY TargetExportDirectory    = static_cast<PIMAGE_EXPORT_DIRECTORY>(Temp);
        if(!TargetExportDirectory)
            return EINVAL;

        IMAGE_THUNK_DATA ThunkData;
        UCHAR Buffer[128];
        PCHAR ImportName                                = strchr(reinterpret_cast<PCHAR>(ThunkEntry->u1.Function),'.') + 1;

......................
liio
驱动小牛
驱动小牛
  • 注册日期2005-12-24
  • 最后登录2022-06-16
  • 粉丝4
  • 关注1
  • 积分24分
  • 威望343点
  • 贡献值0点
  • 好评度171点
  • 原创分0分
  • 专家分0分
  • 社区居民
8楼#
发布于:2008-10-06 06:53
写得匆忙。。
谢谢大家的提醒。。
转发输出确实没有处理。
有时间补上后再发上来
游客

返回顶部