美文网首页Windows客户端开发
【Windows】你所不知道的Rundll32

【Windows】你所不知道的Rundll32

作者: mercurygear | 来源:发表于2016-12-12 16:16 被阅读23次

    很多时候我们用rundll32.exe作为宿主来运行dll的某个函数,每次都是潦草的搬一段代码完事。
    这次有个dll需要导出给rundll32运行的函数,就先找了下资料,汇总了一下相关的知识点。

    用法

    rundll32.exe <dllname>,<entrypoint> <optional arguments>
    <dllname>最好给完整路径,且注意路径中不能有空格、逗号和引号,所以最好把路径转成短文件名来避免出现非法字符
    <dllname>和<entrypoint>之间用,隔开,不能有空格,<entrypoint>和<optional arguments>之间必须有空格
    <optional arguments>这部分rundll32不会解析,而是作为<entrypoint>的第三个参数传递过去

    导出函数

    我们先来看下导出函数的原型
    void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
    首先容易被忽略的一个知识点就是认为导出函数就是上面这样的MBCS编码的(第三个参数可见),但是现在大多数情况下,我们都是使用Unicode编码了,难道是因为这是历史原因吗?
    当然不是,其实是可以导出Unicode版本的,我们先来看下rundll32是如何找到这个导出函数的:

    1. 给函数名加上W后缀,用GetProcAddress找(可见首先找的就是Unicode版本)
    2. 如果1没找到,那么加上A后缀找
    3. 如果2也没找到,那么就用原名字找

    从上面的三个查找步骤,我们可以知道,如果我们要导出Unicode版本的,那么就得导出类似EntryPointW这样的函数名,且第三个参数为LPWSTR,然后使用的时候,要用rundll32 abc.dll,EntryPoint <传递的命令参数>
    这样才能正确工作。
    而如果导出函数是带A后缀,或者不带后缀的话,rundll32就会视为这个是MBCS编码的导出函数了。

    总结

    从上面的描述,可以知道,如果我们导出Unicode版本的函数,在使用的时候就要注意去掉W后缀
    一旦有了这种潜规则,给别人使用的时候,就很容易出问题,所以一般情况下,还是建议导出不带后缀的MBCS版本

    相关文章

      网友评论

        本文标题:【Windows】你所不知道的Rundll32

        本文链接:https://www.haomeiwen.com/subject/flimmttx.html