在Linux中我们可以做到
echo -n -e '\x66\x6f\x6f' > test.txt
将HEX值写入文件。
如何在Windows批处理中完成此操作?
答案 0 :(得分:7)
我假设您希望能够在\ x00到\ xFF范围内编写所有可能的二进制字节。不幸的是,纯批次并没有提供一种简单的机制来实现这一点。
但是有很多选择并不太难。
!=ExitCodeASCII!
动态变量 !=ExitCodeASCII!
动态变量报告最近运行的外部命令的返回码的ASCII值。但它仅限于从\ x20到\ x7E的ASCII码。
我使用延迟扩展,这样我就不用担心毒药了。
返回特定错误代码的最简单机制是使用cmd /c exit N
,其中N必须是十进制值。如果要传入十六进制值,则必须先将值转换为十进制。
Windows批处理使用0xNN表示法指定十六进制值。正如其他人所说,您可以使用set /a val=0x66
进行转换。另一种选择是使用for /l %%N in (0x66 1 0x66) do ...
,这样做的好处是您不需要定义一个中间环境变量来保存该值。
@echo off
setlocal enableDelayedExpansion
set "str="
for %%H in (0x66 0x6f 0x6f) do (
for /l %%N in (%%H 1 %%H) do cmd /c exit %%N
set "str=!str!!=ExitCodeASCII!"
)
>test.txt echo(!str!
优点:
缺点:
FORFILES命令支持0xNN语法,因此它可以生成大多数字符。但字符串必须通过CMD / C,因此它不能用于生成\ 0x00,\ 0x0A或\ 0x0D。 (我没有经过测试,但我相信所有其他价值观都有效,前提是毒药字符被适当引用或逃脱)
@echo off
forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(0x660x6f0x6f"
优点:
缺点:
CERTUTIL支持-decodeHex动词,它可以读取十六进制值并直接写入文件
@echo off
>temp.txt echo(66 6f 6f 0d 0a
certutil -f -decodehex temp.txt test.txt >nul
del temp.txt
优点:
缺点:
在批处理脚本中嵌入和执行JScript非常容易。 JScript具有解释许多转义序列的本机能力,包括\ xNN。但是,\ xNN转义序列实际上映射到Unicode代码点,因此某些高阶字节代码不会映射到正确的字符值。高阶字节的结果可能因机器的默认字符集而异。
下面我定义一个:jWrite子例程,它可以写入带有嵌入转义序列的行。如果要编写没有换行符的字符串,只需将J WriteLine
更改为Write
。
@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment
:: -------- Batch code --------------
@echo off
call :jWrite "\x66\x6f\x6f" >test.txt
exit /b
:jWrite
cscript.exe //E:JScript //nologo "%~f0" %1
exit /b
:: --------- JScript code -----------*/
WScript.StdOut.WriteLine(eval('"'+WScript.Arguments.Unnamed(0)+'"'));
优点:
\\
,\t
,\r
,\n
等。\x22
缺点:
只要您的机器默认为Windows-1252,编写一些JScript代码来正确解释所有\ xNN代码以提供正确的字节并不困难。如果您的命令会话的活动代码页也与Windows 1252匹配,那么您可以在普通文本中自由混合。
@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment
:: -------- Batch code --------------
@echo off
call :jWrite "\x66\x6f\x6f"
call :jWrite "Hello\nworld\x80"
exit /b
:jWrite
cscript.exe //E:JScript //nologo "%~f0" %1
exit /b
:: --------- JScript code -----------*/
WScript.StdOut.WriteLine(WScript.Arguments.Unnamed(0).replace(
/\\(\\|b|f|n|r|t|v|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4})/g,
function($0,$1) {
switch ($1.toLowerCase()) {
case 'x80': return '\u20AC';
case 'x82': return '\u201A';
case 'x83': return '\u0192';
case 'x84': return '\u201E';
case 'x85': return '\u2026';
case 'x86': return '\u2020';
case 'x87': return '\u2021';
case 'x88': return '\u02C6';
case 'x89': return '\u2030';
case 'x8a': return '\u0160';
case 'x8b': return '\u2039';
case 'x8c': return '\u0152';
case 'x8e': return '\u017D';
case 'x91': return '\u2018';
case 'x92': return '\u2019';
case 'x93': return '\u201C';
case 'x94': return '\u201D';
case 'x95': return '\u2022';
case 'x96': return '\u2013';
case 'x97': return '\u2014';
case 'x98': return '\u02DC';
case 'x99': return '\u2122';
case 'x9a': return '\u0161';
case 'x9b': return '\u203A';
case 'x9c': return '\u0153';
case 'x9d': return '\u009D';
case 'x9e': return '\u017E';
case 'x9f': return '\u0178';
default: return eval('"'+$0+'"');
}
}
));
优点:
\\
,\t
,\r
,\n
等。\x22
缺点:
我的JREPL.BAT utility最初设计用于对文本文件执行正则表达式搜索和替换操作。但它有一些选项可以让它轻松编写带有嵌入式转义序列的字符串,并且无论机器使用什么默认字符集,它都可以为所有字节代码提供正确的结果。
如果您的机器默认使用任何单字节字符集,那么您可以安全地使用以下所有可能的转义序列,从\ x00到\ xFF,您可以在正常文本和转义序列中自由混合。
call jrepl $ "\x66\x6f\x6f" /s "=" /x /o test.txt
/s "="
选项将未定义的环境变量指定为输入源,将其解释为空字符串。第一个$
参数匹配空字符串的结尾。第二个"\x66\x6f\x6f"
参数指定替换值。 /x
选项在替换字符串中启用转义序列,/o test.txt
选项指定输出文件。
如果要附加到test.txt,请添加/APP
选项。
如果你想要\ n行结束而不是\ r \ n,(Unix风格而不是Windows),那么添加/U
选项
如果您不想要任何新的行终止符,请添加/M
选项。
最后,如果您的机器没有默认为单字节字符集,您仍然可以通过为输出格式指定单字节字符集(如Windows-1252)来强制所有转义序列的正确结果。但是,如果指定的字符集与命令会话的活动代码页不匹配,则只保证转义序列有效 - 某些正常的文本字符可能会产生错误的结果。
call jrepl $ "\x66\x6f\x6f" /s "=" /x /o "test.txt|Windows-1252"
优点:
\\
,\t
,\r
,\n
等。\x22
或\q
缺点:
答案 1 :(得分:0)
要写入“十六进制值到文件”:
toMap(t -> t.to, t -> t,
(x, y) -> y, () -> new EnumMap<>(Phase.class))));
要使用所有值从批处理创建二进制文件,请参见此处:
https://www.dostips.com/forum/viewtopic.php?f=3&t=5326
set a=.
for /l %a in (0,1,255) do (
set /a dec=%a >nul
call cmd /c exit /b !dec!
set hex=!=exitcode!
set a=!a! !hex:~-2!
)
echo %a:~2% > file.txt
可以同时执行以下操作:从二进制文件创建十六进制文件,并从十六进制编码文件创建二进制文件:
certutil
要从CMD写入具有给定(已解码)十六进制值字节的二进制文件:
certutil -f -decodeHex hex.txt out.bin >nul
certutil -f -encodeHex out.bin out.txt >nul
如果您刚写完可打印的字符(从0x20到0x7E),那么set data="66 6F 6F"
echo Dim File : Set File = CreateObject("Scripting.FileSystemObject").CreateTextFile("test.txt") > tmp.vbs
echo data = %data% >> tmp.vbs
echo data = Split (data) >> tmp.vbs
echo for each x in data >> tmp.vbs
echo File.write chr("&H" ^& x) >> tmp.vbs
echo next >> tmp.vbs
echo File.Close >> tmp.vbs
cscript //nologo tmp.vbs
是一个好/更快的(批处理)解决方案。