2.9 怎么找出cmd.exe所有的内部命令 https://scz.617.cn/windows/201510160925.txt D: scz 2015-10-16 09:25 起因是想确认mklink是cmd.exe内部命令。"where.exe mklink"表明mklink不在PATH 中,直接执行mklink有帮助信息输出,这样就间接证明mklink是cmd.exe内部命令。 但如何找出cmd.exe所有的内部命令?显然前述办法不适用,有个鸡蛋问题。本以为 "cmd.exe /?"会给出内部命令列表,实际不完整,只看到: del/erase color cd/chdir md/mkdir prompt pushd popd set setlocal endlocal if for call shift goto start assoc ftype 至少mklink不在上述列表中。现在的问题已经与原始需求无关,变成单纯的找出 cmd.exe所有的内部命令。 用IDA反汇编cmd.exe,看到符号_JumpTable,这里好像是一个结构数组,前两个成员 可能如下: struct { char *cmdname; // 内部命令名 void *cmdfunc; // 内部命令对应的处理函数 .... }; 从此处依序得到一张列表: DIR ERASE DEL TYPE COPY CD CHDIR RENAME REN ECHO SET PAUSE DATE TIME PROMPT MD MKDIR RD RMDIR PATH GOTO SHIFT CLS CALL VERIFY VER VOL EXIT SETLOCAL ENDLOCAL TITLE START DPATH KEYS MOVE PUSHD POPD ASSOC FTYPE BREAK COLOR MKLINK FOR IF REM CMDEXTVERSION ERRORLEVEL DEFINED EXIST NOT 但我觉得上IDA也太那个了,不至于拍死个苍蝇还得引爆核弹。 一般上网请教,以扯淡回复为主,不会让你获得知识增长。这类回复要么文不对题, 你在问A,TA在说B;要么告诉你,你out了,地球人都知道,但实际上你在请教时已 将这些所谓out的东西排除在外;要么假设你是SB,给你一些更SB的答案,此时以比 拼智商下限为主要目的。 运气好的时候会有某个ID给一个指向性较强的回复,去年一个SysWOW64相关的问题, InsideStack就是这种ID。 尽管历史经验如此不堪,仍然节操满满地上网请教。这次"黑真他妈黑"(原谅我,是 TA粗俗,不是我)提到help命令。help给出的命令列表里包含MKLINK,包含大多数IDA 看到的结果,但也不完整,比如有PATH没有DPATH。更要命的是,help列表里有太多 外部命令,比如ATTRIB、XCOPY等。不过help还是不错的,把常用命令列在那儿了, "help mklink"比直接mklink显得文明礼貌些。话说自MS-DOS 5.0之后,我再没有用 过help命令,都忘记它的存在了。 这个问题可能没有完美解决方案。我最后的尝试是用sysinternals的strings: > strings.exe -q -u cmd.exe | findstr /I mklink MKLINK 不必IDA,直接strings快速看一眼,对付着用吧。其实这个奇葩需求并不真实存在, 只是碰上了,就琢磨了一下。 D: scz 2022-04-07 11:28 前面可能是Win7的情况,今天看了一眼Win10的cmd.exe,符号_JumpTable不见了。 IDA反汇编cmd.exe,在Strings中搜"ERASE",交叉引用定位到.rdata中某个结构数组, 该结构可能这样定义 -------------------------------------------------------------------------- #pragma pack(1) struct DispatchTable { wchar_t *cmdname; // +0x0 内部命令名 void *cmdfunc; // +0x8 内部命令对应的处理函数 unsigned char unknown[0x10]; // +0x10 // +0x20 }; #pragma pack() -------------------------------------------------------------------------- 可以得到一些内部命令,数量上与Win7无差别。"TYPE"对应函数eType。