[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

查询、复制可执行模块DLL依赖PDLL.EXE

本帖最后由 happy886rr 于 2017-5-12 10:43 编辑

下载:
这次编译的体积只有5KB,且不依赖任何多余DLL,是同类命令行工具中功能最强,速度最快,体积最小的。

下载pdll增强版:
增强版携带极为强悍之功能,可在32位系统下直接查看64位exe或dll文件的依赖关系和导入导出函数表,增强版用法源码不再贴出。

版本:
PDLL.EXE VERSION 1.0 (DLLS DEPEND ON TOOL, BY HAPPY)(外链图,随时失效)


摘要:
=====================================================
PDLL.EXE 查询、复制可执行模块DLL依赖。对EXE、DLL后缀的文件均可分析DLL依赖,并
且智能的分析DLL的必需性,有选择的复制依赖DLL到被查询文件目录。已兼容XP、WIN7、
WIN8.1等WIN系统,复制的兼容性可以达到在微小WINPE系统中正常运行。 代码做了非常
严密的逻辑判断,让依赖性分析更加智能。纯C语言书写,本工具不依赖任何DLL。
=====================================================

用法:
查询DLL依赖
PDLL     [要查询的可执行文件名]
复制DLL依赖
PDLL /C [要查询的可执行文件名]

演示一:
查看QQ.EXE的DLL依赖情况


演示二:
复制KERNEL32.DLL的底层API依赖


源码:
  1. /*
  2. CONSOLE DLLS DEPEND ON TOOL, COPYRIGHT@2017~2019 BY HAPPY, VERSION 1.0
  3. PDLL.EXE
  4. */
  5. #include <io.h>
  6. #include <stdio.h>
  7. #include <windows.h>
  8. //定义容器安全长度
  9. #define _SAFE_SIZE 512
  10. //系统必需DLL列表
  11. static LPCSTR SYSTEM_DLLS[]= {"aclui", "activeds", "adsldpc", "advapi32", "apphelp", "atl", "authz", "basesrv", "batmeter", "cabinet", "cfgmgr32", "clb", "comdlg32", "crypt32", "cryptdll", "cryptui", "csrsrv", "devmgr", "diskcopy", "dmdlgs", "dmdskmgr", "dmdskres", "dmintf", "dmocx", "dmutil", "dnsapi", "duser", "filemgmt", "fmifs", "gdi32", "hal", "halmacpi", "hhsetup", "ifsutil", "imagehlp", "imm32", "kdcom", "kernel32", "lpk", "lsasrv", "mfc42u", "mmcbase", "mmcndmgr", "mmcshext", "mpr", "msasn1", "msimg32", "msprivs", "msv1_0", "msvcp60", "msvcrt", "msvfw32", "mycomput", "ncobjapi", "netapi32", "ntdll", "ntdsapi", "ntmarta", "odbc32", "odbcbcp", "ole32", "oleacc", "oleaccrc", "oleaut32", "oledlg", "olepro32", "osuninst", "pdh", "powrprof", "psapi", "rpcrt4", "rpcss", "rsaenh", "rshx32", "samlib", "samsrv", "scesrv", "secur32", "setupapi", "shdocvw", "shell32", "shfolder", "shlwapi", "srvsvc", "stobject", "sxs", "uexfat", "ufat", "ulib", "umpnpmgr", "untfs", "urlmon", "user32", "userenv", "usp10", "uxtheme", "version", "wimgapi", "wininet", "winmm", "winsrv", "winsta", "wintrust", "ws2_32", "wsock32", NULL};
  12. //定义帮助说明
  13. #define HELP_INFORMATION "\
  14. pdll version 1.0 - Console DLLS depend on tool - Copyright (C) 2017-2019\n\
  15. Usage: pdll [options] [file] ...\n\
  16. \n\
  17. General options:\n\
  18.        List all depends on dlls name\n\
  19.   /C   Copy all depends on dlls to current file\n\
  20. \n\
  21. Official website:\n\
  22.        http://www.bathome.net/thread-44056-1-1.html\n"
  23. //字符串转大写
  24. LPCSTR LPCSTR2UPR(LPCSTR instr, LPSTR ostr)
  25. {
  26.     LPSTR cp=(LPSTR)instr, op=ostr;
  27.     while(*cp)
  28.     {
  29.         *op=('a'<=*cp && *cp<='z')?*cp-32:*cp, cp++, op++;
  30.     }
  31.     *op='\0';
  32.     return (LPCSTR)ostr;
  33. }
  34. //识别必需DLL
  35. int ItifyWords(LPCSTR strARGV)
  36. {
  37.     int i, SN;
  38.     for(SN=0; SYSTEM_DLLS[SN]; SN++)
  39.     {
  40.         LPSTR op=(LPSTR)strARGV, kp=(LPSTR)SYSTEM_DLLS[SN];
  41.         while(*op!='.' && *kp!='\0')
  42.         {
  43.             if( (('a'<= *op && *op<='z')?*op-32:*op) != (('a'<= *kp && *kp<='z')?*kp-32:*kp) )
  44.             {
  45.                 break;
  46.             }
  47.             op++, kp++;
  48.         }
  49.         if(*op=='.' && *kp=='\0')
  50.         {
  51.             return SN;
  52.         }
  53.     }
  54.     return -1;
  55. }
  56. //获取DLL依赖
  57. int GetDependDlls(HMODULE hMOD, LPCSTR pePATH, BOOL peMODE)
  58. {
  59.     IMAGE_DOS_HEADER* imageDosHeader = (IMAGE_DOS_HEADER*)hMOD;
  60.     IMAGE_OPTIONAL_HEADER * imageOptionalHeader = (IMAGE_OPTIONAL_HEADER*)((BYTE*)hMOD + imageDosHeader->e_lfanew +24);
  61.     IMAGE_IMPORT_DESCRIPTOR* imageImportDescriptor = (IMAGE_IMPORT_DESCRIPTOR*) ((BYTE*)hMOD + imageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
  62.     LPSTR  srcDllPath = (LPSTR)malloc(_SAFE_SIZE);
  63.     LPSTR  copyDllPath = (LPSTR)malloc(_SAFE_SIZE);
  64.     LPSTR  touprStrTain = (LPSTR)malloc(_SAFE_SIZE);
  65.     while(imageImportDescriptor->FirstThunk)
  66.     {
  67.         LPSTR dllNAME = (LPSTR)((BYTE*)hMOD + imageImportDescriptor->Name);
  68.         HMODULE hdMOD = LoadLibraryExA(dllNAME, NULL, DONT_RESOLVE_DLL_REFERENCES);
  69.         if(hdMOD != 0)
  70.         {
  71.             GetModuleFileNameA(hdMOD, srcDllPath, _SAFE_SIZE);
  72.         }
  73.         else
  74.         {
  75.             *srcDllPath='\0';
  76.         }
  77.         if(peMODE)
  78.         {
  79.             if(ItifyWords(dllNAME) == -1)
  80.             {
  81.                 sprintf(copyDllPath, "%s\\%s", pePATH, dllNAME);
  82.                 //判断DLL是否存在,不存在则复制
  83.                 if(_access(copyDllPath, F_OK) != 0)
  84.                 {
  85.                     if(*srcDllPath && CopyFileA(srcDllPath, copyDllPath, TRUE))
  86.                     {
  87.                         fprintf(stdout, "Copy... \"%s\" succeed\n", LPCSTR2UPR(dllNAME, touprStrTain));
  88.                     }
  89.                     else
  90.                     {
  91.                         fprintf(stdout, "Copy... \"%s\" failed\n", LPCSTR2UPR(dllNAME, touprStrTain));
  92.                     }
  93.                 }
  94.             }
  95.         }
  96.         else
  97.         {
  98.             if(strlen(dllNAME) >18)
  99.             {
  100.                 //打印API名称
  101.                 fprintf(stdout, "%s\n", LPCSTR2UPR(dllNAME, touprStrTain));
  102.             }
  103.             else
  104.             {
  105.                 //打印DLL名称
  106.                 fprintf(stdout, "%-16.16s ", LPCSTR2UPR(dllNAME, touprStrTain));
  107.                 //打印DLL路径
  108.                 fprintf(stderr, "%s\n", LPCSTR2UPR(srcDllPath, touprStrTain));
  109.             }
  110.         }
  111.         FreeLibrary(hdMOD);
  112.         imageImportDescriptor++;
  113.     }
  114.     free(srcDllPath);
  115.     free(copyDllPath);
  116.     free(touprStrTain);
  117.     return 0;
  118. }
  119. //MAIN主函数入口
  120. int main(int argc, char* argv[])
  121. {
  122.     //参数不足,抛出使用说明
  123.     if(argc <= 1)
  124.     {
  125.         fputs(HELP_INFORMATION, stdout);
  126.         return 1;
  127.     }
  128.     //获取查询模式
  129.     BOOL pdMODE = (stricmp(argv[1], "/C")==0) ?TRUE :FALSE;
  130.     //缺少必要参数,抛出错误
  131.     if(pdMODE && argc==2)
  132.     {
  133.         fputs("Needs executable file\n", stdout);
  134.         return 1;
  135.     }
  136.     //获取可执行文件名
  137.     LPSTR peFILE = (pdMODE) ?(LPSTR)argv[2] :(LPSTR)argv[1];
  138.     if(_access(peFILE, F_OK) != 0)
  139.     {
  140.         fprintf(stdout, "The file \"%s\" is not exists\n", peFILE);
  141.         return 1;
  142.     }
  143.     //仅装在DLL,而不初始化
  144.     HMODULE hMOD = LoadLibraryExA(peFILE, NULL, DONT_RESOLVE_DLL_REFERENCES);
  145.     if(hMOD == 0)
  146.     {
  147.         //加载模块失败,显示错误信息
  148.         fprintf(stderr, "Failed to load executable file \"%s\"\n", peFILE);
  149.         return 2;
  150.     }
  151.     //获取可执行文件路径
  152.     LPSTR lp = strrchr(peFILE, '\\');
  153.     LPSTR pePATH = (lp==NULL) ?(LPSTR)".\\" :(*lp='\0', peFILE);
  154.     //打印可执行文件名
  155.     //fprintf(stderr, "File Name: %s\n", peFILE);
  156.     //执行DLL依赖查询
  157.     GetDependDlls(hMOD, pePATH, pdMODE);
  158.     //释放装载模块
  159.     FreeLibrary(hMOD);
  160.     return 0;
  161. }
复制代码
附件: 您需要登录才可以下载或查看附件。没有帐号?注册
6

评分人数

回复 38# freesoft00
我的代码几乎都能用那个vc++2010精简版编译出来,参数、细节你都可以自己修改,从而调配出最佳的exe。

TOP

回复 37# happy886rr


    这个也ok了。

TOP

回复 36# freesoft00
那个编译器是VS里的,把/MD改为/MT就是会生成不依赖任何dll的单文件exe。

TOP

回复 29# happy886rr


    用你的源代码,使用你做的精简的vc编译通过,测试了ping2.exe的依存,因为它需要vc++运行库,系统中没有会弹出错误。
而你一楼给的编译好的pdll就没有问题。可以正确获取依存列表

TOP

回复 34# happy886rr


    噢,我是win10,那个是磁贴应用

TOP

本帖最后由 happy886rr 于 2017-5-12 16:50 编辑

回复 33# CrLf
最后那几个,我估计是软链接吧。但是我的win7提示的dll跟你的不一样。
pdll.exe C:\WINDOWS\System32\calc.exe
  1. SHELL32.DLL      FROM    C:\WINDOWS\SYSTEM32\SHELL32.DLL
  2. SHLWAPI.DLL      FROM    C:\WINDOWS\SYSTEM32\SHLWAPI.DLL
  3. GDIPLUS.DLL      FROM    C:\WINDOWS\WINSXS\X86_MICROSOFT.WINDOWS.GDIPLUS_6595B64144CCF1DF_1.1.7601.19061_NONE_72D6D48D86649709\GDIPLUS.DLL
  4. ADVAPI32.DLL     FROM    C:\WINDOWS\SYSTEM32\ADVAPI32.DLL
  5. OLEAUT32.DLL     FROM    C:\WINDOWS\SYSTEM32\OLEAUT32.DLL
  6. UXTHEME.DLL      FROM    C:\WINDOWS\SYSTEM32\UXTHEME.DLL
  7. OLE32.DLL        FROM    C:\WINDOWS\SYSTEM32\OLE32.DLL
  8. COMCTL32.DLL     FROM    C:\WINDOWS\WINSXS\X86_MICROSOFT.WINDOWS.COMMON-CONTROLS_6595B64144CCF1DF_5.82.7601.18837_NONE_EC86B8D6858EC0BC\COMCTL32.DLL
  9. NTDLL.DLL        FROM    C:\WINDOWS\SYSTEM32\NTDLL.DLL
  10. KERNEL32.DLL     FROM    C:\WINDOWS\SYSTEM32\KERNEL32.DLL
  11. USER32.DLL       FROM    C:\WINDOWS\SYSTEM32\USER32.DLL
  12. RPCRT4.DLL       FROM    C:\WINDOWS\SYSTEM32\RPCRT4.DLL
  13. WINMM.DLL        FROM    C:\WINDOWS\SYSTEM32\WINMM.DLL
  14. VERSION.DLL      FROM    C:\WINDOWS\SYSTEM32\VERSION.DLL
  15. GDI32.DLL        FROM    C:\WINDOWS\SYSTEM32\GDI32.DLL
  16. MSVCRT.DLL       FROM    C:\WINDOWS\SYSTEM32\MSVCRT.DLL
复制代码

TOP

本帖最后由 CrLf 于 2017-5-12 14:36 编辑

回复 32# happy886rr


    pdll.exe C:\WINDOWS\System32\calc.exe
得到结果:
SHELL32.DLL      FROM    C:\WINDOWS\SYSTEM32\SHELL32.DLL
KERNEL32.DLL     FROM    C:\WINDOWS\SYSTEM32\KERNEL32.DLL
MSVCRT.DLL       FROM    C:\WINDOWS\SYSTEM32\MSVCRT.DLL
ADVAPI32.DLL     FROM    C:\WINDOWS\SYSTEM32\ADVAPI32.DLL
API-MS-WIN-CORE-WINRT-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-STRING-L1-1-0.DLL
API-MS-WIN-CORE-WINRT-ERROR-L1-1-1.DLL
API-MS-WIN-CORE-SYNCH-L1-2-0.DLL
API-MS-WIN-CORE-PROCESSTHREADS-L1-1-2.DLL
API-MS-WIN-CORE-LIBRARYLOADER-L1-2-0.DLL

话说最后那几个 dll 是啥,全盘搜索都没有...
居然不影响运行

TOP

回复 31# CrLf
不错,不过没RVA地址,直接pdll /i calc.exe连用了哪个库的什么函数都能列出来,包括编号、虚拟地址。不过vs的调试工具,或者peid也带了这项功能。

TOP

By the way, Powershell 也可以查看 dll:
  1. Start-Process -PassThru calc.exe | Get-Process -Module
复制代码
和 tasklist /m 差不多,但 tasklist 不能保证百分百命中
这个用法得先打开进程
好处是炒鸡全面,可以看到系统自动引用的 dll,以及进程在运行中动态加载的 dll
用途不同,马克一下

TOP

回复 28# CrLf
已修复,直接PDLL 7Z64.exe即可。

TOP

回复 27# freesoft00
已经修复,请在一楼重新下载增强版。

TOP

回复 26# happy886rr


用 64 位 7z 做测试,也是用不了

不加 /i 运行报错
Failed to load executable file "Z:\7z64.exe"

加 /i 停止工作

所用 7z 程序:http://www.bathome.net/s/tool/?key=7z64

TOP

回复 26# happy886rr


还是不行呀。有错误。

TOP

本帖最后由 happy886rr 于 2017-5-11 22:55 编辑

回复 25# freesoft00
请使用/I 开关查看。
PDLL /I 文件名

因为是增强版,你不加/I开关还是默认引擎,加了/I开关就是超级引擎。

PDLL增强版,不仅包括了ldd32的全部代码,还新增200行新代码,用于改善性能,你看帮助信息,用法已经不同于之前的了。

TOP

返回列表