与PE导出表解析功能地址 [英] Resolve Function Address with PE Export Table

查看:320
本文介绍了与PE导出表解析功能地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人都可以解释我如何正确地从PE图像获取函数的地址,然后调用一个委托,它的功能? 我找到了一个好片code google搜索周围的负载出口从DLL库,但只得到函数名出来吧......所以我修改,如下所示:

Can anyone explain me how to properly obtain a function address from a PE image and then call that function with a delegate? I found a good piece code googling around that loads exports from a DLL library, but it only get function names out of it... so I modified it as follows:

[DllImport("ImageHlp", CallingConvention = CallingConvention.Winapi), SuppressUnmanagedCodeSecurity]
public static extern bool MapAndLoad(string imageName, string dllPath, out LOADED_IMAGE loadedImage, bool dotDll, bool readOnly);

public static IntPtr CustomGetProcAddress(string modulePath, string moduleProc)
{
    LOADED_IMAGE loadedImage;

    if (MapAndLoad(modulePath, null, out loadedImage, true, true))
        return GetAddr(loadedImage, moduleProc);
    else
        return IntPtr.Zero;
}

private static IntPtr GetAddr(LOADED_IMAGE loadedImage, string moduleProc)
{
    var hMod = (void*)loadedImage.MappedAddress;

    if (hMod != null)
    {
        uint size;
        var pExportDir = (IMAGE_EXPORT_DIRECTORY*)ImageDirectoryEntryToData(
            (void*)loadedImage.MappedAddress,
            false,
            IMAGE_DIRECTORY_ENTRY_EXPORT,
            out size);

        uint* pFuncNames = (uint*)RvaToVa(loadedImage, pExportDir->AddressOfNames);
        ushort* pFuncOrdinals = (ushort*)RvaToVa(loadedImage, pExportDir->AddressOfNameOrdinals);
        uint* pFuncAddr = (uint*)RvaToVa(loadedImage, pExportDir->AddressOfFunctions);

        for (uint i = 0; i < pExportDir->NumberOfNames; i++)
        {
            uint funcNameRva = pFuncNames[i];

            if (funcNameRva != 0)
            {
                char* funcName = (char*)RvaToVa(loadedImage, funcNameRva);
                string name = Marshal.PtrToStringAnsi((IntPtr)funcName);
                _exports.Add(name);

                if (name == wantedFunction)
                    return addr = new IntPtr(*(uint*)(pFuncAddr + (*pFuncOrdinals * 4)));
            }
        }
    }

    return IntPtr.Zero;
}

我敢肯定,我的报价接近的解决方案......但我总是AccessViolationException(当我使用错误的指针)或InvalidFunctionPointerInDelegate和PInvokeStackImbalance(当我尝试转换指针使用Marshal.GetDelegateForFunctionPointer和委托然后执行它)。 我什么都试过,但我不能让它工作(我已经拿出我正在寻找使用调用LoadLibrary和GetProcAddress函数的正确的地址...所以我可以比较的结果,但我不希望使用这些功能)。

I'm sure I'm quote close to the solution... but I always get AccessViolationException (when I use wrong pointers) or InvalidFunctionPointerInDelegate and PInvokeStackImbalance (when I try to cast the pointer to a delegate using Marshal.GetDelegateForFunctionPointer and then execute it). I tried everything but I can't make it work (I already pulled out the correct address of the function I'm looking for using LoadLibrary and GetProcAddress... so I can compare the results, but I don't want to use those functions).

我发现了另一个例子,但我不知道它可以做我在找什么: <一href="http://www.rohitab.com/discuss/topic/39366-c-loadlibary-from-byte/page__k__bb2fe024f8a71424996db6d9af08c1fc__settingNewSkin__19" rel="nofollow">http://www.rohitab.com/discuss/topic/39366-c-loadlibary-from-byte/page_k_bb2fe024f8a71424996db6d9af08c1fc_settingNewSkin_19

I found another example, but I'm not sure it can do what I'm looking for: http://www.rohitab.com/discuss/topic/39366-c-loadlibary-from-byte/page_k_bb2fe024f8a71424996db6d9af08c1fc_settingNewSkin_19

推荐答案

您不能这样做。该 MapAndLoad ImageHlp 库函数只加载PE文件到内存中的数据文件,以便它可以检查。它不会在所有的Windows加载程序的逻辑运行并当它加载DLL使它可执行文件(RVA的修正,等等)。

You can't do that. The MapAndLoad and function from the ImageHlp library only loads a PE file into memory as a data file so it can be examined. It does not run through all of the logic of the Windows loader does when it loads a DLL to make it executable (RVA fixups, etc.).

如果您想要加载DLL,按名称查找功能,并得到一个可调用的指针指向它,您可以使用调用LoadLibrary GetProcAddress的。其中,设计这些功能做的正是你在找什么要做。

If you want to load a DLL, find a function by name, and get an callable pointer to it, you use LoadLibrary and GetProcAddress. Those functions where designed to do exactly what you are looking trying to do.

这篇关于与PE导出表解析功能地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆