![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-09-15 12:18 |
共 47,812 主题排行 / 349,917 发帖 / 今日 0 篇 / 48,268 会员排行 |
| DOS批处理 & 脚本技术(批处理室) » [原创]批处理搜索提取二进制文件小记 |
| 可打印版本 7,926 / 26 |
| 第1楼 无奈何 | 发表于 2006-11-25 05:54 |
| 荣誉版主 发帖 356 积分 1,338 | |
|
[原创]批处理搜索提取二进制文件小记 批处理搜索提取二进制文件小记
最近完成了一个批处理,功能是打开快捷方式(*.lnk)指向的文件所在的目录。其中使用到一些有意思的小技巧,这篇短文记录下一步步实现这个功能的过程,和大家一起分享一下。 我们首先要做的是先分析一下快捷方式的内容,为记事本创建两个快捷方式作为例子。第一个 notepad.lnk ,目标处填入 c:\WINDOWS\system32\notepad.exe ;第二个 notepad2.lnk ,目标处填入 %windir%\system32\notepad.exe 。我们知道快捷方式是以二进制文件的形式存在的,用任意一款十六进制编辑软件打开 notepad.lnk 与 notepad2.lnk 观察一下。提示一下部分编辑软件会打开指向的文件而不是快捷方式,但一般都有设置选项可以更改,具体软件的使用情况不做过多的说明。打开后会发现无论哪种方式建立的快捷方式都会找到一串字符 C:\WINDOWS\system32\notepad.exe ,现在要做的就是把这串字符提取出来。想想我们可以用到的命令好像只有 find 和 findstr 两个,两个命令都能够进行二进制文件的搜索,他们各有优缺点,find 会将搜到的二进制信息分行显示,findstr 会原样显示二进制信息,后者的强项是支持简单的正则表达式。我们利用两个命令的组合将所要的信息提取出来。 我们先看一下合法的文件与文件夹的全路径都会有哪些组合: c:\ c:\windows c:\windows\ c:\windows\explorer.exe D:\TeSt\.\ D:\TeSt\test1\test2 D:\TeSt\tEsT.txt.lnk D:\TeSt\tEsT (2).txt.lnk D:\TeSt\tEsT (3).txt.lnk 不存在 还有其他类似的组合,等等,哪怕最后一个看起来有些怪异仍是可能存在的。用 PERL 样式的正则表达式多行模式下可能需要这样描述“^(:\\)(.+?\\)*.*$”,但这个表达式不够严格,更好一点的应该这样写“^(:\\)((+\\)*)()*$”,如果不幸在一行上的话可能需要这样匹配“(:\\)(((?!:))*)”。我们在这里只是讨论一下完整路径名形式的特征,不多谈 PERL 正则表达式。回到我们的问题上来,不管那样的组合都会出现 “盘符:\” 这样字符组合,据此可以提取出我们想要的字串。先用 find 过滤一下,find ":" *.lnk ,观察一下结果会发现我们想要的字串在一行上,再用 findstr 二次过滤一下就 OK 了,find ":" *.lnk |findstr /r "^:" ,findstr 的 /r 参数表明搜索的字符串为一般表达式,“^”匹配行的开始,“”字符集表示匹配大小写的字母。重点谈一下 findstr 查找 “\” 字符,在其他的正则表达式中一般在字符前添加 “\”会脱掉元字符的特殊性,简单说就是两个 “\\” 表示一个 “\” 。而在 findstr 却要用四个代替一个,比如查找字符“D:\”需要这样来写 findstr "D:\\\\" ,如果查找多个连续的“\” 如:“D:\\\” 会把人搞晕的,另一个方法是利用字符集两个成表示一个,这个例子可以这样来写,findstr /r "D:" 。继续回到我们的问题,勤于思考的朋友会问,如果某快捷方式的路径为 “盘符:” 我们的查找会不会失败,这种情况是不会出现的,不信可建立一个快捷方式,目标位置填入 “C:” 会发现 widows 自动在后面添加上一个 “\”。 事实上还有一个命令会格式化二进制文件输出,就是 more ,如命令:more /s notepad.lnk |findstr /r "^:" ,会输出同样的效果,但是 more 非交互方式下不能应用于多文件,如命令:more /s *.lnk |findstr /r "^:" ,会一直等待用户的按键。非用 more 的不可情况是 find 无法完成第一遍过滤,比如搜索的是一个表达式没有简单的固定特征字符的情况。 最后给出我们的成果。可以放到 sendto 文件夹下,或命令行调用。
后记:我一直希望有更多的人了解批处理并对此感兴趣,尝试性的写一些小短文,发觉并不顺手,可能有些批处理知识的朋友看的会更累。效仿了一下 3742668 兄爱用的 mode 命令,让批处理错误提示更有趣了。 如果希望在快捷方式上直接右键打开目录的话,可以参考下面的注册表项修改一下。 |
|
| 第2楼 无奈何 | 发表于 2006-11-25 05:57 |
| 荣誉版主 发帖 356 积分 1,338 | |
|
非常抱歉,由于操作失误,不小心将帖子删除了,我重新发一遍,不幸的是相关讨论丢失了。
再次致歉,希望大家原谅。 |
|
| 第3楼 ccwan | 发表于 2006-11-25 06:03 |
| 金牌会员 发帖 1,160 积分 2,725 来自 河北廊坊 | |
|
版主勿忧,如果需要的话,我将讨论贴上来怎样?不过只有12楼,以后的灌水贴我没保存。(请看我签名)
|
|
| 第4楼 tao0610 | 发表于 2006-11-25 06:31 |
| 高级用户 发帖 218 积分 579 | |
|
楼上是传说中的备份数据库?
|
|
| 第5楼 无奈何 | 发表于 2006-11-25 06:34 |
| 荣誉版主 发帖 356 积分 1,338 | |
|
RE ccwan
非常感谢,兄整理一下贴上来吧,减少一点损失。 |
|
| 第6楼 ccwan | 发表于 2006-11-25 06:43 |
| 金牌会员 发帖 1,160 积分 2,725 来自 河北廊坊 | |
|
NO!
我只是每个帖子复制到文本文件中。不好意思,不太工整。 electronixtar 『第 2 楼』: 金牌会员 沙发,强贴留名 2006-10-26 06:37 lxmxn 『第 3 楼』: 银牌会员 呵呵,学习了。。 2006-10-26 06:42 electronixtar 『第 4 楼』: 金牌会员 请教无奈何兄:more 可以重定向输出一个二进制文件不? 2006-10-26 06:44 无奈何 『第 5 楼』: 版主 RE electronixtar 可以啊!只是一些不可显示字符也会被输出。 2006-10-26 06:58 electronixtar 『第 6 楼』: 金牌会员 斗胆提点建议呢, 第6句 改成 start "" explorer /select,/n,%%~fi 最后一句改成 start "title 提示!" cmd /c "mode con cols=30 lines=5 &for /l %%i in (5,-1,1) do cls &echo. 所选文件不是快捷方式!( %%i )&ping/n 2 127.1>nul" P.S. 我试了下 more %ComSpec% >a.exe,不行啊,而且我用了一个 596字节的标准exe做实验,生成了一个 930 字节的exe,而且PE结构被破坏了,没法运行了。 [ Last edited by electronixtar on 2006-10-26 at 07:26 AM ] 2006-10-26 07:16 无奈何 『第 7 楼』: 版主 Re electronixtar 不好意思,刚才出去一下。谢谢兄的第一条建议甚好,马上改。只是第二条没发现效果上有什么区别,还请指教。 more 不能从二进制文件中脱出嵌入的文件,因为数据会被重新解释并格式化。好像咱俩说的是两个方向,我提及的是从二进制文件中提取字符信息。 2006-10-26 09:21 3742668 『第 8 楼』: 版主 6F的 start "title 提示!" cmd /c "mode con cols=30 lines=5 &for /l %%i in (5,-1,1) do cls &echo. 所选文件不是快捷方式!( %%i )&ping/n 2 127.1>nul" 貌似应该理解为 start "提示" cmd /c "mode con cols=30 lines=5 &for /l %%i in (5,-1,1) do cls &echo. 所选文件不是快捷方式!( %%i )&ping/n 2 127.1>nul" 用start来指定标题而不在命令中指定标题. p.s:个人认为,所有磁盘上的文件都是以二进制存储的,所有都应该叫做二进制文件,大家讨论的应该是以二进制方式读取和保存文件. 2006-10-26 11:10 electronixtar 『第 9 楼』: 金牌会员 Quote: 貌似应该理解为 start "提示" 恩恩,我就是那个意思呢,Ctrl+C 太快了,呵呵 Quote: 所有都应该叫做二进制文件 通常所说的二进制文件就是指用记事本打开是乱码的文件,例如exe等,呵呵,叫习惯喽 [ Last edited by electronixtar on 2006-10-26 at 11:30 AM ] 2006-10-26 11:28 yfd11 『第 10 楼』: 初级用户 以前看了一个叫世界第一名的程序写的。 REM 将GIF,JPG等小于64Kb的文件转成十六进制格式。EXE的话要改名。 @echo off REM 获得常用信息 color 2f set ASCII=0123456789T %ASCII:~-1,1%itle=弱智制作QQ:%ASCII:~4,1%%ASCII:~-7,1%%ASCII:~1,1%%ASCII:~-6,1%%ASCII:~-7,1%%ASCII:~0,1%%ASCII:~-9,1%%ASCII:~3,1%%ASCII:~0,1% set/p file=请输入文件名: ::dir %file% ::下一行获得文件大小 ::for /F "usebackq tokens=3" %%i IN (`"dir /-c %file%|find "%file%""`) DO set z=%%i ::下一行获得文件大小另一方法 ::for /F %%I IN ("%file%") do set z=%%~zI ::echo 文件大小为%z%字节 REM 下面实现获得寄存器CX与BX值 echo r cx>temp1.txt echo.>>temp1.txt echo r bx>>temp1.txt echo,>>temp1.txt echo q >>temp1.txt echo;>>temp1.txt ::debug %file%<temp1.txt>temp2.txt for /F "usebackq tokens=2" %%i IN (`"debug %file%<temp1.txt|find "CX""`) DO set CX=%%i set CX0=%CX% for /F "usebackq tokens=2" %%i IN (`"debug %file%<temp1.txt|find "BX""`) DO set BX=%%i ::for /F "usebackq tokens=2" %%i IN (`"type temp2.txt|find "CX""`) DO set CX=%%i ::for /F "usebackq tokens=2" %%i IN (`"type temp2.txt|find "BX""`) DO set BX=%%i ::chcp 936 ::rem 活动代码页更改为 中文语言 ::echo CX的值是%CX% bx的值是%BX% ::pause ::for /F "usebackq tokens=2" %%i IN (`"echo H %CX% 100|debug|find /V "H %CX% 100""`) DO set BX=%%i REM 下面获得CX+100H的值 echo H %CX% 100>temp1.txt echo q>>temp1.txt for /F "skip=1 usebackq tokens=1" %%i IN (`"debug<temp1.txt|find "%CX:~-2%""`) DO set CX=%%i ::chcp 936 ::echo CX的值是%CX% bx的值是%BX% ::pause &rem 如果CX进位则BX+1 if %CX0:~0,2% LSS %CX:~0,2% goto :add1 echo H %BX% 1>temp1.txt echo q>>temp1.txt for /F "skip=1 usebackq tokens=1" %%i IN (`"debug<temp1.txt|find /v "H""`) DO set BX=%%i :add1 ::算了,BX不用了,反正输入的64k的有点不对,大文件如何读入Debug谁知道告诉我我的QQ是(441540230) REM 输出文件为了用中文文件名下面所以输出之前加chcp 936 echo D 100 %CX% 1>temp1.txt echo q>>temp1.txt chcp 936>nul 2>nul debug %file%<temp1.txt>输出.txt chcp 936>nul 2>nul REM 修改一下以后Debug可变回的文件 set j=1&&set/a CX1=0X%CX:~0,-1%-15 echo/>修改输出.txt &&rem 换行可以是.,;/[\]+等字符 echo 正在修改中......请等待。 ::echo cx1=%CX1% j=%j%&pause :Start for /F "delims= skip=%j% tokens=*" %%i in (输出.txt) do set t1=%%i && goto :Label :Label echo e %t1:~5,29% %t1:~35,-19% >>修改输出.txt if %j% == %CX1% goto :end set /a j+=1 goto :Start :end echo+>>修改输出.txt echo rcx>>修改输出.txt echo %CX0%>>修改输出.txt echo n 1%file%>>修改输出.txt echo w>>修改输出.txt echo q>>修改输出.txt REM 返回文件 echo set ASCII="<" >得到以前文件.bat echo debug%%ASCII:~1,1%%修改输出.txt >>得到以前文件.bat echo chcp 936>>得到以前文件.bat echo start 1%file%>>得到以前文件.bat echo 将修改输出.txt与得到以前文件.bat两个文件保存,要用只要双击bat文件即可 echo 完成操作,谢谢您使用.按任意键退出 &pause>nul 2>nul 2006-10-29 10:32 electronixtar 『第 11 楼』: 金牌会员 原来是debug做的 2006-10-29 10:57 lxmxn 『第 12 楼』: 银牌会员 10楼的帖子还不错,开头的标题设置还简单的加密了一下,呵呵。。。 p.s:你的签名是不是侵犯了 无奈何 兄的专利权哦??呵呵。不怕他把你开除"坛籍"啊?呵呵~~ |
|
| 第7楼 redtek | 发表于 2006-11-25 08:31 |
| 金牌会员 发帖 1,147 积分 2,902 | |
|
ccwan兄真是心细,幸好还有备份:)
|
|
| 第8楼 无奈何 | 发表于 2006-11-27 12:03 |
| 荣誉版主 发帖 356 积分 1,338 | |
|
谢谢 ccwan 兄将丢失的部分贴出来。
为了感谢,特制作了一个更方便的存贴脚本。 =========== 由于考虑到一些原因,我重新开了一个帖子,限定了浏览积分。 请到下面链接查看:http://www.cn-dos.net/forum/viewthread.php?tid=25130 我自己不能给自己评分,麻烦那位可以评分的版主或会员扣帮忙扣除这 9 点加分。 [ Last edited by 无奈何 on 2006-11-27 at 02:55 PM ] |
|
| 第9楼 electronixtar | 发表于 2006-11-27 23:43 |
| 铂金会员 发帖 2,672 积分 7,493 | |
|
再次强贴留名
|
|
| 第10楼 ccwan | 发表于 2006-11-28 04:31 |
| 金牌会员 发帖 1,160 积分 2,725 来自 河北廊坊 | |
|
回过头来再看,感觉还是超强!再顶一个。
|
|
| 第11楼 newaifi | 发表于 2007-02-24 06:43 |
| 初级用户 发帖 67 积分 154 | |
|
To:redtek
非常抱歉,因一时心情激动,鼠标不听使唤,扣除了redtek兄一点积分.纯熟失误,还望见谅. |
|
| 第12楼 slore | 发表于 2007-02-24 08:05 |
| 铂金会员 发帖 2,478 积分 5,212 | |
|
vbs直接可以对快捷方式操作.
|
|
| 第13楼 anqing | 发表于 2007-02-24 08:23 |
| 高级用户 发帖 413 积分 859 | |
|
为什么,我把qq的ink,拖进去,提示找不到文件呢?报错?
|
|
| 第14楼 qingfushuan | 发表于 2007-02-25 00:22 |
| 高级用户 发帖 327 积分 502 | |
为了看这个链接Originally posted by 无奈何 at 2006-11-26 11:03 PM: 看到这个时我才170分,专门到水区灌水2小时,挣到301分,就回来了 |
|
| 第15楼 skyearth | 发表于 2007-03-08 04:07 |
| 初级用户 发帖 13 积分 34 | |
|
不错,有价值
|
|
| 1 2 下一页 |
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |