中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [原创]批处理搜索提取二进制文件小记
« [1] [2] »
作者:
标题: [原创]批处理搜索提取二进制文件小记 上一主题 | 下一主题
无奈何
荣誉版主





积分 1338
发帖 356
注册 2005-7-15
状态 离线
『楼 主』:  [原创]批处理搜索提取二进制文件小记

批处理搜索提取二进制文件小记

        最近完成了一个批处理,功能是打开快捷方式(*.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 样式的正则表达式多行模式下可能需要这样描述“^([A-Za-z]:\\)(.+?\\)*.*$”,但这个表达式不够严格,更好一点的应该这样写“^([A-Za-z]:\\)(([^\\/:?*"<>|]+\\)*)([^\\/:?*"<>|])*$”,如果不幸在一行上的话可能需要这样匹配“([A-Za-z]:\\)(([^/:*?"<>|](?![A-Za-z]:))*)”。我们在这里只是讨论一下完整路径名形式的特征,不多谈 PERL 正则表达式。回到我们的问题上来,不管那样的组合都会出现 “盘符:\” 这样字符组合,据此可以提取出我们想要的字串。先用 find 过滤一下,find ":" *.lnk ,观察一下结果会发现我们想要的字串在一行上,再用 findstr 二次过滤一下就 OK 了,find ":" *.lnk |findstr /r "^[A-Za-z]:[\\]" ,findstr 的 /r 参数表明搜索的字符串为一般表达式,“^”匹配行的开始,“[A-Za-z]”字符集表示匹配大小写的字母。重点谈一下 findstr 查找 “\” 字符,在其他的正则表达式中一般在字符前添加 “\”会脱掉元字符的特殊性,简单说就是两个 “\\” 表示一个 “\” 。而在 findstr 却要用四个代替一个,比如查找字符“D:\”需要这样来写 findstr "D:\\\\" ,如果查找多个连续的“\” 如:“D:\\\” 会把人搞晕的,另一个方法是利用字符集两个成表示一个,这个例子可以这样来写,findstr /r "D:[\\][\\][\\]" 。继续回到我们的问题,勤于思考的朋友会问,如果某快捷方式的路径为 “盘符:” 我们的查找会不会失败,这种情况是不会出现的,不信可建立一个快捷方式,目标位置填入 “C:” 会发现 widows 自动在后面添加上一个 “\”。

        事实上还有一个命令会格式化二进制文件输出,就是 more ,如命令:more /s notepad.lnk |findstr /r "^[A-Za-z]:[\\]" ,会输出同样的效果,但是 more 非交互方式下不能应用于多文件,如命令:more /s *.lnk |findstr /r "^[A-Za-z]:[\\]" ,会一直等待用户的按键。非用 more 的不可情况是 find 无法完成第一遍过滤,比如搜索的是一个表达式没有简单的固定特征字符的情况。
        最后给出我们的成果。可以放到 sendto 文件夹下,或命令行调用。

  Quote:

  1. @echo off
  2. if "%~1" == "" goto :EOF
  3. ::检查扩展名是否是快捷方式文件
  4. if /i "%~x1" NEQ ".lnk" goto error
  5. for /f "delims=" %%i in ('find ":" "%~1" ^|findstr /r "^[A-z]:[\\]"') do (
  6. start %%~dpi
  7. )
  8. goto :EOF
  9. :error
  10. ::抛出错误提示窗口
  11. start cmd /c "title 提示!&mode con  cols=30 lines=5 &for /l %%i in (5,-1,1) do cls &echo. 所选文件不是快捷方式!( %%i )&ping/n 2 127.1>nul"
        无奈何发表于    2006-10-25  17:57

后记:我一直希望有更多的人了解批处理并对此感兴趣,尝试性的写一些小短文,发觉并不顺手,可能有些批处理知识的朋友看的会更累。效仿了一下 3742668 兄爱用的 mode 命令,让批处理错误提示更有趣了。
如果希望在快捷方式上直接右键打开目录的话,可以参考下面的注册表项修改一下。
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\lnkfile\shell]

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\lnkfile\shell\ShortcutOpen.cmd]
@="打开指向目录"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\lnkfile\shell\ShortcutOpen.cmd\command]
@="\"D:\\BAT\\ShortcutOpen.cmd\" \"%1\""




  ☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul

2006-11-25 05:54
查看资料  发送邮件  发短消息 网志  OICQ (105400208)  编辑帖子  回复  引用回复
无奈何
荣誉版主





积分 1338
发帖 356
注册 2005-7-15
状态 离线
『第 2 楼』:  

非常抱歉,由于操作失误,不小心将帖子删除了,我重新发一遍,不幸的是相关讨论丢失了。
再次致歉,希望大家原谅。



  ☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul

2006-11-25 05:57
查看资料  发送邮件  发短消息 网志  OICQ (105400208)  编辑帖子  回复  引用回复
ccwan
金牌会员




积分 2725
发帖 1160
注册 2006-9-23
来自 河北廊坊
状态 离线
『第 3 楼』:  

版主勿忧,如果需要的话,我将讨论贴上来怎样?不过只有12楼,以后的灌水贴我没保存。(请看我签名)



三人行,必有吾师焉。   学然后知不足,教然后知困,然后能自强也。
2006-11-25 06:03
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
tao0610
高级用户

朦胧的世界


积分 579
发帖 218
注册 2006-10-24
状态 离线
『第 4 楼』:  

楼上是传说中的备份数据库?




认识自己,降伏自己,改变自己
,才能改变别人!
2006-11-25 06:31
查看资料  发短消息 网志   编辑帖子  回复  引用回复
无奈何
荣誉版主





积分 1338
发帖 356
注册 2005-7-15
状态 离线
『第 5 楼』:  

RE ccwan
非常感谢,兄整理一下贴上来吧,减少一点损失。



  ☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul

2006-11-25 06:34
查看资料  发送邮件  发短消息 网志  OICQ (105400208)  编辑帖子  回复  引用回复
ccwan
金牌会员




积分 2725
发帖 1160
注册 2006-9-23
来自 河北廊坊
状态 离线
『第 6 楼』:  

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:你的签名是不是侵犯了 无奈何 兄的专利权哦??呵呵。不怕他把你开除"坛籍"啊?呵呵~~



三人行,必有吾师焉。   学然后知不足,教然后知困,然后能自强也。
2006-11-25 06:43
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
redtek
金牌会员





积分 2902
发帖 1147
注册 2006-9-21
状态 离线
『第 7 楼』:  

ccwan兄真是心细,幸好还有备份:)

   此帖被 -1 点积分    点击查看详情   
评分人:【 newaifi 分数: -1  时间:2007-2-24 06:40




    Redtek,一个永远在网上流浪的人……

_.,-*~'`^`'~*-,.__.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._,_.,-*~'`^`'~*-,._
2006-11-25 08:31
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
无奈何
荣誉版主





积分 1338
发帖 356
注册 2005-7-15
状态 离线
『第 8 楼』:  

谢谢 ccwan 兄将丢失的部分贴出来。
为了感谢,特制作了一个更方便的存贴脚本。

===========
由于考虑到一些原因,我重新开了一个帖子,限定了浏览积分。
请到下面链接查看:http://www.cn-dos.net/forum/viewthread.php?tid=25130

我自己不能给自己评分,麻烦那位可以评分的版主或会员扣帮忙扣除这 9 点加分。

[ Last edited by 无奈何 on 2006-11-27 at 02:55 PM ]

   此帖被 +9 点积分       点击查看详情   
评分人:【 lxmxn 分数: +9  时间:2006-11-27 13:18




  ☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul

2006-11-27 12:03
查看资料  发送邮件  发短消息 网志  OICQ (105400208)  编辑帖子  回复  引用回复
electronixtar
铂金会员





积分 7493
发帖 2672
注册 2005-9-2
状态 离线
『第 9 楼』:  

再次强贴留名




C:\>BLOG http://initiative.yo2.cn/
C:\>hh.exe ntcmds.chm::/ntcmds.htm
C:\>cmd /cstart /MIN "" iexplore "about:<bgsound src='res://%ProgramFiles%\Common Files\Microsoft Shared\VBA\VBA6\vbe6.dll/10/5432'>"
2006-11-27 23:43
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
ccwan
金牌会员




积分 2725
发帖 1160
注册 2006-9-23
来自 河北廊坊
状态 离线
『第 10 楼』:  

回过头来再看,感觉还是超强!再顶一个。



三人行,必有吾师焉。   学然后知不足,教然后知困,然后能自强也。
2006-11-28 04:31
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
newaifi
初级用户





积分 154
发帖 67
注册 2006-10-31
状态 离线
『第 11 楼』:  

To:redtek
非常抱歉,因一时心情激动,鼠标不听使唤,扣除了redtek兄一点积分.纯熟失误,还望见谅.

2007-2-24 06:43
查看资料  发短消息 网志   编辑帖子  回复  引用回复
slore
铂金会员





积分 5212
发帖 2478
注册 2007-2-8
状态 离线
『第 12 楼』:  

vbs直接可以对快捷方式操作.

   此帖被 +1 点积分     点击查看详情   
评分人:【 qinchun36 分数: +1  时间:2009-10-17 21:08


2007-2-24 08:05
查看资料  发短消息 网志   编辑帖子  回复  引用回复
anqing
高级用户




积分 859
发帖 413
注册 2006-8-14
状态 离线
『第 13 楼』:  

为什么,我把qq的ink,拖进去,提示找不到文件呢?报错?

2007-2-24 08:23
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
qingfushuan
高级用户





积分 502
发帖 327
注册 2006-12-30
状态 离线
『第 14 楼』:  为了看这个链接



  Quote:
Originally posted by 无奈何 at 2006-11-26 11:03 PM:
谢谢 ccwan 兄将丢失的部分贴出来。
为了感谢,特制作了一个更方便的存贴脚本。

===========
由于考虑到一些原因,我重新开了一个 ...

看到这个时我才170分,专门到水区灌水2小时,挣到301分,就回来了

2007-2-25 00:22
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
skyearth
初级用户





积分 34
发帖 13
注册 2006-7-20
状态 离线
『第 15 楼』:  

不错,有价值

2007-3-8 04:07
查看资料  发短消息 网志   编辑帖子  回复  引用回复
« [1] [2] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: