【问题标题】:Extract RegExp string from binary in windows batch从Windows批处理中的二进制文件中提取RegEx字符串
【发布时间】:2012-10-29 23:33:24
【问题描述】:

一个小问题困扰了我好几天。我正在尝试从 *.exe 二进制文件中提取我可以用正则表达式定义的字符串,例如“1.01.01.00T123”这样的文本到环境变量中以供进一步使用。
我用

找到了字符串
findstr /i [0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9][T][0-9][0-9][0-9] name.exe>outp.bin

现在它是我的字符串,用更小的二进制格式,可能是 200 字节。然后我试图在“for / f”中使用 findstr 的输出,但是我应该为二进制文件使用什么分隔符,没有任何保证。即使是点和空白也可以来来去去。
类似的东西:

for /f "tokens=1,2,3,4* delims=^." %%a in ('findstr /i [0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]T[0-9][0-9][0-9] name.exe') do (
echo %%a
echo %%b
echo %%c
echo %%d
)

它只工作了一半——第一个太长了,最后一部分“xxTxxx”不是这个定义的标记。此外,点也可能出现在二进制文件中,而不仅仅是在我的字符串中。
我想到了通过始终剪切第一个字节来缩短循环中的 outp.bin,然后检查我的字符串是否位于 outp.bin 的开头。但是还没有找到方法来做到这一点。有可能吗?
有什么方法可以让我将正则表达式结果复制到变量中变得不那么复杂?
我希望错过了标准命令外壳中正则表达式的一些神奇命令。

【问题讨论】:

    标签: for-loop batch-file binary cmd findstr


    【解决方案1】:

    使用纯批处理几乎不可能完成您想要的操作,因为您的二进制文件可能包含空字节并且批处理无法处理空字节。但是使用VBS或JScript和正则表达式可以很容易地解决这个问题。

    这是一个非常粗略的 VBS 解决方案,还有很大的改进空间。但它有效。

    findStr.vbs

    Set myRegExp = New RegExp
    myRegExp.IgnoreCase = True
    myRegExp.Global = True
    myRegExp.Pattern = "\d\.\d\d\.\d\d\.\d\dT\d\d\d"
    Set matches = myRegExp.Execute(WScript.StdIn.ReadAll())
    For Each match In matches
      WScript.StdOut.WriteLine(match.value)
    Next
    

    使用 CSCRIPT 调用脚本并将输入重定向到您的 exe 文件。

    <name.exe cscript //nologo findStr.vbs
    

    您可以通过 FOR /F 使用批处理来处理结果。

    for /f "delims=" %%A in ('^<name.exe cscript //nologo findStr.vbs') do echo %%A
    


    更新 - 2015-08-26

    您可以使用JREPL.BAT 轻松解决这个问题 - 一个纯脚本的正则表达式处理实用程序(混合 JScript/batch),它可以在从 XP 开始的任何 Windows 机器上本地运行。完整的文档嵌入在脚本中。

    以下仅列出在文件中找到的值。请注意,/M 选项是必需的,因为 exe 中可能存在空字节。

    call jrepl "\d\.\d\d\.\d\d\.\d\dT\d\d\d" $0 /jmatch /m /f name.exe
    

    要捕获变量中的值(或最后一个值,如果有多次出现):

    for %%A in (
      'jrepl "\d\.\d\d\.\d\d\.\d\dT\d\d\d" $0 /jmatch /m /f name.exe'
    ) do set "str=%%A"
    

    【讨论】:

    • 另一种选择可能是使用strings 提取可打印字符并将其输出通过管道传输到findstr
    • @dbenham,非常感谢!我已经放弃了干净的 shell 脚本,你的 vbs 做得很好!像一个魅力一样工作,我将在我的 cmd 脚本中打包 vbs 行,然后将 >>echo 我一个临时 vbs 脚本文件,并对我讨厌的二进制文件做一些事情。顺便说一句,“几乎不可能”是什么意思? :-)
    • @AnsgarWiechers,谢谢!请说,“使用字符串”是什么意思?进展如何?而且,即使我只能向我展示可打印的字符,我也不能保证除了我的 RegExp-String 之外的单一结果,实际上是这样。我想出的唯一方法是将我的二进制剪辑总是缩短一个字节,然后查看“findstr / b”是否带来任何积极的结果。然后,如果它从末端缩短其余部分,然后使用“findstr /e”查看。但不知何故,我还没有找到削减一字节专业迭代的方法。
    • @AnsgarWiechers,对不起,这对我来说不是一个非常聪明的问题。 :-) 你发布了一个链接 :-) 我现在看到了。
    • @sangesi - “几乎不可能”我的意思是纯原生批处理可能是可能的,但这需要英勇的努力,大量的代码,而且可能会很慢。我能想到的唯一可以处理 nul 字节的命令是 CERTUTIL -DUMP 和 FC /B,但是当使用其他脚本语言更容易时,我不想围绕这些命令构建解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    相关资源
    最近更新 更多