用dumpbin来查看dll导出了哪些函数(接口)。尤其是观察导出的那个类继承自模板(实例化了模板后再导出)

启动vs的“开发人员命令提示”

直接执行dumpbin,它会给出所有支持的选项:

给出dll的完整路径,可以将信息导出到文本文件:

D:\DevTools\VS2015>dumpbin /exports D:\123\test.dll >123123.txt

下面的代码

template <
    typename DerivedName, //signature,在类中不做使用。
    typename AbstractProduct, //接口
    typename ProductTypeKey, //key
    typename ...ArgTypes //其他参数
>
class GenericFactoryPro
{
protected:

    GenericFactoryPro() {}
    GenericFactoryPro(const GenericFactoryPro&) = delete; 
    GenericFactoryPro(GenericFactoryPro&&) = delete;
    GenericFactoryPro operator=(const GenericFactoryPro& other) = delete;

public:
    ~GenericFactoryPro() {}

    //具体产品注册类Register。使用内嵌类可明显简化设计
    template <typename ConcreteProduct>
    class Register
    {
    public:
        Register(const ProductTypeKey& key)
        {
            ...
        }
    private:
        inline static AbstractProduct* ConcreteProductCreator(ArgTypes... args)
        {
            ...
        }
    };

    bool Unregister(const ProductTypeKey& conp)
    {
        ...
    }

    std::shared_ptr<AbstractProduct> NewInstance(const ProductTypeKey& conp, ArgTypes... args)
    {
        ...
    }

    std::vector<ProductTypeKey> GetOrderedKeyVec()
    {
        ...
    }


    int GetSize()
    {
        ..
    }

    ProductTypeKey GetKey(unsigned n) 
    {
       ...
    }

    inline static GenericFactoryPro<DerivedName, AbstractProduct, ProductTypeKey, ArgTypes...>& GetSingletonInstance()
    {
        static GenericFactoryPro<DerivedName, AbstractProduct, ProductTypeKey, ArgTypes...> unique_generic_factory;
        return unique_generic_factory;
    }
};


struct EXPORT_attribute ECClassDefMgr123 : public GenericFactoryPro<ECClassDefMgr123, ECClassDef, ObjectType>
{
    //ECClassDefMgr() = delete;
    //~ECClassDefMgr() = delete;
};

会看到类似这样的导出信息,

         10    9 005EDEA8 ?$TSS0@?1??GetSingletonInstance@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@SAAEAV2@XZ@4HA = ?$TSS0@?1??GetSingletonInstance@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@SAAEAV2@XZ@4HA (int `public: static class GenericFactoryPro<struct ECClassDefMgr123,struct ECClassDef,struct ObjectType> & __cdecl GenericFactoryPro<struct ECClassDefMgr123,struct ECClassDef,struct ObjectType>::GetSingletonInstance(void)'::`2'::$TSS0)

         18   11 00001E79 ??0?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@IEAA@XZ = @ILT+3700(??0?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@IEAA@XZ)

        304  12F 0001203A ??1?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA@XZ = @ILT+69685(??1?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA@XZ)

       1224  4C7 000089C7 ?GetKey@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA?AUObjectType@@I@Z = @ILT+31170(?GetKey@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA?AUObjectType@@I@Z)

       1262  4ED 0000CDBF ?GetOrderedKeyVec@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA?AV?$vector@UObjectType@@V?$allocator@UObjectType@@@std@@@std@@XZ = @ILT+48570(?GetOrderedKeyVec@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA?AV?$vector@UObjectType@@V?$allocator@UObjectType@@@std@@@std@@XZ)

       1308  51B 0000CCD9 ?GetSingletonInstance@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@SAAEAV1@XZ = @ILT+48340(?GetSingletonInstance@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@SAAEAV1@XZ)

       1316  523 000106E5 ?GetSize@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAAHXZ = @ILT+63200(?GetSize@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAAHXZ)

       1554  611 000059B6 ?NewInstance@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA?AV?$shared_ptr@UECClassDef@@@std@@AEBUObjectType@@@Z = @ILT+18865(?NewInstance@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA?AV?$shared_ptr@UECClassDef@@@std@@AEBUObjectType@@@Z)

       1788  6FB 00014623 ?Unregister@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA_NAEBUObjectType@@@Z = @ILT+79390(?Unregister@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA_NAEBUObjectType@@@Z)

       2348  92B 005EDE78 ?unique_generic_factory@?1??GetSingletonInstance@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@SAAEAV2@XZ@4V2@A = ?unique_generic_factory@?1??GetSingletonInstance@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@SAAEAV2@XZ@4V2@A (class GenericFactoryPro<struct ECClassDefMgr123,struct ECClassDef,struct ObjectType> `public: static class GenericFactoryPro<struct ECClassDefMgr123,struct ECClassDef,struct ObjectType> & __cdecl GenericFactoryPro<struct ECClassDefMgr123,struct ECClassDef,struct ObjectType>::GetSingletonInstance(void)'::`2'::unique_generic_factory)

为什么上面的GenericFactoryPro要加第一个参数呢?

首先,继承自GenericFactoryPro主要是为了生成一个单例,添加的第一个参数并没有用在实际代码中,主要是为了将导出的函数名保持唯一性。如果不唯一的话就会出现有意思的事,见:http://t.csdnimg.cn/BXdie

比如:

A.dll里这样定义:

template <
    typename AbstractProduct, //接口
    typename ProductTypeKey=std::wstring, //key
    typename ...ArgTypes //其他参数
>
class GenericFactory
{
protected:

    GenericFactory() {}
    GenericFactory(const GenericFactory&) = delete; 
    GenericFactory(GenericFactory&&) = delete;
    GenericFactory operator=(const GenericFactory& other) = delete;

public:
    ~GenericFactory() {}

    //具体产品注册类Register。使用内嵌类可明显简化设计
    template <typename ConcreteProduct>
    class Register
    {
    public:
        Register(const ProductTypeKey& key)
        {
            GenericFactory::GetSingletonInstance().m_OrderedKeyVec.push_back(key);
            GenericFactory::GetSingletonInstance().m_mapConFactory.emplace(key, ConcreteProductCreator);
        }
    private:
        inline static AbstractProduct* ConcreteProductCreator(ArgTypes... args)
        {
            ...
        }
    };

    bool Unregister(const ProductTypeKey& conp)
    {
        ...
    }

    std::shared_ptr<AbstractProduct> NewInstance(const ProductTypeKey& conp, ArgTypes... args)
    {
       ...
    }

    std::vector<ProductTypeKey> GetOrderedKeyVec()
    {
        ..
    }


    int GetSize()
    {
        ...
    }

    ProductTypeKey GetKey(unsigned n) 
    {
       ...
    }

    inline static GenericFactory<AbstractProduct, ProductTypeKey, ArgTypes...>& GetSingletonInstance()
    {
        static GenericFactory<AbstractProduct, ProductTypeKey, ArgTypes...> unique_generic_factory;
        return unique_generic_factory;
    }
};

struct EXPORT_attribute ECClassDefMgr123 : public GenericFactory<ECClassDef, ObjectType>
{
    //ECClassDefMgr() = delete;
    //~ECClassDefMgr() = delete;
};

struct EXPORT_attribute ECClassDefMgr456 : public GenericFactoryPro<ECClassDef, ObjectType>
{
    //ECClassDefMgr() = delete;
    //~ECClassDefMgr() = delete;
};

B.dll里这样使用

void fun()
{
    auto& fac1 = ECClassDefMgr123::GetSingletonInstance();
    auto& fac2 = ECClassDefMgr456::GetSingletonInstance();
    if(&fac1==&fac2)
    {
        std::cout<<"wc, 地址相同,它俩指向了同一个单例!";
    }
}

会发现,虽然类名不一样(一个是ECClassDefMgr123,一个是ECClassDefMgr456),但它们最后指向的单例是同一个。因为它们用的是同一个导出的static变量:unique_generic_factory

导出名称类似:

?unique_generic_factory@?1??GetSingletonInstance@?$GenericFactoryPro@@UECClassDef@@UObjectType@@$$V@@SAAEAV2@XZ@4V2@A = ?unique_generic_factory@?1??GetSingletonInstance@?$GenericFactoryPro@@UECClassDef@@UObjectType@@$$V@@SAAEAV2@XZ@4V2@A (class GenericFactoryPro<struct ECClassDef,struct ObjectType> `public: static class GenericFactoryPro<struct ECClassDef,struct ObjectType> & __cdecl GenericFactoryPro<struct ECClassDef,struct ObjectType>::GetSingletonInstance(void)'::`2'::unique_generic_factory)

  • 15
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
DLL函数查看器是一款DLL函数查看工具,直接把DLL文件拖入列表查看即可。 1.将本程序快捷方式放入系统 "SendTo" 目录后,就可以右键文件"发送到"实现文件快速查看 2.按粘帖键(Ctrl+V)将剪辑板中字符串在列表中匹配查找 3.关于参数量的问题,由于猜解方法过于简单对于部分函数未从当前函数返回,而是"JMP"到别的函数 所以猜解可能会有错误,需要结合已知函数库或反汇编查看,另此方法对于cdecl调用函数无效 4.关于反汇编视图的"到首返回"如果勾选即表示仅反汇编到头一个RETN为止,否者将按照"DisAsm_MaxLine" 所指定的行数.生效方法参见说明细则12~13. 5.将PEID userdb.txt 放置到程序目录下可以实现查壳 6.如果将易语言API伴侣DATA下文件复制到本目录,可获得已知函数信息.这首先要感谢API伴侣的作者 7.在目录下建立 "ViewApi.cfg" ,设置信息将写入配置文件可方便放入优盘等移动存储器中使用 程序启动时会优先读取配置文件,如果文件不纯在则会访问注册表 8.如果你觉得这个美化窗口很浪费资源,可以打开注册表修改如下项值即可关闭 [HKEY_CURRENT_USER\Software\ViewApiList] "UI"=dword:00000000 9.如果你觉得反汇编影响了效率,可以打开注册表修改如下项值即可关闭 [HKEY_CURRENT_USER\Software\ViewApiList] "DisAsm"=dword:00000000 10.如果想关闭查壳功能可以删除userdb.txt或注册表如下设置 [HKEY_CURRENT_USER\Software\ViewApiList] "CheckShell"=dword:00000000 11.在线查询接口可在注册表如下位置修改,{searchTerms}为保留关键字被作为替换函数名 [HKEY_CURRENT_USER\Software\ViewApiList] "WebSearch"="http://www.baidu.com/s?wd={searchTerms}&ie=utf-8" 12.是否仅反汇编到头一个返回,1.表示是,0表示否 [HKEY_CURRENT_USER\Software\ViewApiList] "DisAsm_Retn"=dword:00000001 13.反汇编最大行数,即表示当前地址向后的长度,与函数实际长度无关.是否生效需要根据"DisAsm_Retn"设置 [HKEY_CURRENT_USER\Software\ViewApiList] "DisAsm_MaxLine"=dword:000003e8 键盘快捷键说明: TAB(SHIFT+TAB) -- 视图焦点切换 CTRL+S -- 视图切换 CTRL+F -- 文字搜索 F3 -- 搜索下一个 CTRL+A -- 项目全选 CTRL+C -- 复制选中项目函数名称/汇编代码 CTRL+V -- 将剪辑板中的字符在视图中匹配搜索 ALT+← -- 反汇编视图上一次跳转的后退 ALT+→ -- ... 前进 Application -- 弹出右键菜单(右WIN键和右CTRL键中间的那个键)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值