【问题标题】:How to create hex-dump .bin file from powershell or cmd?如何从 powershell 或 cmd 创建 hex-dump .bin 文件?
【发布时间】:2017-05-16 20:30:29
【问题描述】:

主要目的是将十六进制编码的字符串或仅十六进制数据写入主 bin 文件,无论是否为十六进制转储。

使用 windows powershell 或 cmd,我们正在尝试创建一个 bin 文件,以便使用开源 srecord 执行脚本(如 srec_cat.exe)将其与主文件连接起来。

我们已经设法在 powershell 中以十六进制转储了一些东西,比如字符串左右:

“hello_world”将是:

PS C:\Users\user> echo hello_world | format-hex > output.bin

那个“bin”文件的内容是:

           Ruta:

           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   68 65 6C 6C 6F 5F 77 6F 72 6C 64                 hello_world

但是,上面的输出是字符串格式的,需要将其转储为 bin 类型文件。这是因为 srecord 的 srec_cat 工具需要以这种方式将数据写入(连接)到主 bin 文件的某个内存区域,这些内存区域将被闪存到设备中。

所需的输出类似于:

00000000: 68 65 6C 6C 6F 5F 77 6F 72 6C 64 00 00 00 00 00  #hello_world

再次,作为二进制类型文件。

非常感谢您的时间和关注!


第一次编辑:

因此,我们正在使用 Atmel Studio 制作一个适用于 SAMD21 设备的程序。通过 JTAG 与 SAM ICE 一起用于闪存和调试。编译的结果,因此为调试而挂载的最终可执行文件是 *.bin 文件。编码可能是UTF-8。

我正在尝试做的是将 ID、密钥等数据添加到最终固件 *.bin 文件的特定内存方向中,以便刷新。

利用 srec 工具,完成如下操作:

第一次转化:

srec_cat data_input_file.bin -o data_input_file.srec

第二次转换:

srec_cat main_file.bin -binary -o main_file.srec

特定内存区域的concat,这个命令是通用的(没有地址目标):

srec_cat data_input_file.srec main_file.srec -o final_firmware.bin

我不知道如何使用十六进制编码字符串创建这种二进制文件,从零地址开始,直到保存数据所需的空间。

借助 srec 工具,我们能够将这些数据放入所需的方向。


二次编辑

将使用的原始字节来源有两个。

第一个是 Atmel Studio 编译的 *.bin 结果,旨在闪存到我们正在使用的硬件设备中。

文件的内容,例如,Main_File_1.bin:

00000000: 30 30 30 30 09 66 66 20 66 65 20 36 38 20 30 30  #0000.ff fe 68 00
00000010: 20 36 35 20 30 30 20 36 63 20 30 30 20 20 36 63  # 65 00 6c 00  6c
00000020: 20 30 30 20 36 66 20 30 30 20 35 66 20 30 30 20  # 00 6f 00 5f 00
00000030: 37 37 20 30 30 20 20 20 2E 2E 68 2E 65 2E 6C 2E  #77 00   ..h.e.l.
00000040: 6C 2E 6F 2E 5F 2E 77 2E 0D 0A 30 30 31 30 09 36  #l.o._.w...0010.6
00000050: 66 20 30 30 20 37 32 20 30 30 20 36 63 20 30 30  #f 00 72 00 6c 00
00000060: 20 36 34 20 30 30 20 20 30 64 20 30 30 20 30 61  # 64 00  0d 00 0a
00000070: 20 30 30 20 20 20 20 20 20 20 20 20 20 20 20 20  # 00
00000080: 20 20 6F 2E 72 2E 6C 2E 64 2E 2E 2E 2E 2E 0D 0A  #  o.r.l.d......

同样,十六进制转储方式不是强制性的,十六进制转储用于视觉参考,我知道它可以是 Main_File_1.bin:

X"  ¡@  @  @                              @          @  @  @  @  @  @  e)  @  @  @  @  a/  q/  /  ‘/  ¡/  ±/  @  @  @  @  @  @  @  @  @  @  @  @  @  µL#x +ÑK +ÐH à ¿##p½Ø       ,h  µK +ÐHI à ¿Hh +ÐK + ИG½ÀF    ,h  Ü   ,h      µ  K˜GLú!‰  GK`ú!‰  GK`"K`½ÀFU>  E         à à0µKhJ %€!Ià ,ÐT`•`hBüÐ8öÒ0½   à àµKh + ИG½ÀFô   pµ‚° #J`¬%ep£p%p& !N°G% !°G' !°GK !Ya@"ZaYaZaKhBÐ
KhšÔ    K˜G"Kp¿ó_b¶  °p½ô   å*  €D Aà à     8µ (ÐM ¨G< ,úÑ8½ÀFM  µL #£a K˜G@#£a½€D A  µ„°K`¬ 
K˜G$#“ #c`##r#ãr !K˜GH! "K˜G  !K˜G°½ÀFô   Y*  m*  y  õ(  %)  µ (Ð  !K˜Gà  !K˜G½ÀF%)  E)  0µ‘°.L##p #cp£p©"Jp‹p
p )K˜G#xÙ    " )ÑZ  Ò&H!@!˜@aªp #S`“`tSt‘tÑtu$!ST   “
“€#[Ó`K“b#[BÓbKcKScK“aHIK˜G (ÑM,h K˜G#@#ƒ@K`*hÓi +üÑ"h#C#`K˜G K˜G   àú @²°0½¨  å*   D A      €–˜ ¬

上面的内容描述只是示例信息,不是实际的字节不能写入,只是理论上下文。

就像任何设备一样,主要目标是在每个硬件设备中写入 ID、频率、数据等。

我想到了本地 windows 机器中的一组 JSON 文件,它将读取内容,以便将其写入当前连接的设备,并准备好被刷写(此时不使用保险丝)。

那么,就像Data_File_1.json:

{
    'device_1_data' : {

        'device_uuid' : {
            'low_uuid' : '0x00000001',
            'high_uuid' : '0xABCD000A'
        },

        'key_1' : ['0x2E', '0x34', '0x72', '0x0A', '0x45', '0x57', '0x41', '0x17', '0x07', '0x52', '0xCA', '0x4C', '0x0D', '0x7B', '0x41', '0x57'],

        'module_data' : "0x387A3830",
        'frequency_0' : '390200000',
        'frequency_1' : '392100000',

        'generator_syncword' : '0xCF'

    }
}

该项目读取特定的内存地址以启动和运行,设置 ID 和工作所需的信息。因此,利用 JSON 文件保存的信息,需要将数据写入二进制文件,以便将其转换为 SREC,因此可以将其写入主二进制文件中 srecord 指定的内存地址工具。

所以它被配置为按原样读取信息。您可以注意到 JSON 包含十六进制数据,但 JSON 将数据保存为文本,因此需要将十六进制字符串视为十六进制,而整数需要转换为十六进制才能按预期适当写入已申请。

所以,就像Data_To_Be_Written_1.bin:

00000000:   01 00 CD AB 0A 00 00 00 2E 34 72 0A 45 57 41 17  #..Í«.....4r.EWA.
00000010:   07 52 CA 4C 0D 7B 41 57 30 38 7A 38 C0 FA 41 17  #.RÊL.{AW08z8ÀúA.
00000020:   A0 F8 5E 17                                      #ø^.

上面的数据是从 JSON 文件中获取的,所以,它是预期的,所以我们可以使用 SRecord 工具,以便将该数据写入包含项目的主二进制文件的内存地址,这将使硬件模块工作。


第三次修改(解决方案和总结):

非常感谢大家!

@AnsgarWiechers 的回答确实表明了获得预期的 *.bin 所需的条件。

如果我们以Data_File_1.json为例:

{
    'device_1_data' : {

        'device_uuid' : {
            'low_uuid' : '0x00000001',
            'high_uuid' : '0xABCD000A'
        },

        'key_1' : ['0x2E', '0x34', '0x72', '0x0A', '0x45', '0x57', '0x41', '0x17', '0x07', '0x52', '0xCA', '0x4C', '0x0D', '0x7B', '0x41', '0x57'],

        'module_data' : "0x387A3830",
        'frequency_0' : '390200000',
        'frequency_1' : '392100000',

        'generator_syncword' : '0xCF'

    }
}

接下来我们可以在powershell中进行如下操作:

# JSON processing.
$json = Get-Content 'C:\<path to json file>\device_data.json' -Raw | ConvertFrom-Json

现在我们已经让 json 对象工作了,我们继续开始获取数据。

首先,获取 UUID。并声明要用于连接第一个字节值的字节数组。

注意这里,如果你知道这里的解决方法或最佳编程实践,那将是很棒的,我从这个开始,所以,我通过阅读和编码来得出以下内容-去。

# Process the whole UUID from the two JSON fields.

[int64] $device_uuid = [int64] ($json.device_1_data.device_uuid.low_uuid + (($json.device_1_data.device_uuid.high_uuid).split('x')[1]))

$device_uuid_byte_array = [BitConverter]::GetBytes($device_uuid)

# Final Byte array for first target address.

[byte[]] $final_byte_array = $device_uuid_byte_array

在上面,我利用了带有 int 值的 BitConverter 函数。首先用高低地址做一个String concat,可以注意到连接的顺序,因为powershell处理的字节序,所以,为了得到下面的字节顺序01 00 CD AB 0A 00 00 00,powershell需要类似"0x00000001ABCD0001" 的字符串,不喜欢 0xABCD00100000001

然后它将值转换为整数,其结果是7177306113。并利用该功能:

[BitConverter]::getBytes(7177306113)

我们可以得到它的字节值数组。所以它可以被连接起来,或者在这种情况下,是字节数组的起始值,它将位于二进制文件的内容中。

接下来是 JSON 的键字符串字节数组的串联。

# Now process the key byte array from JSON.
[int[]] $key_1_value = [int[]] $json.device_1_data.key_1
[byte[]] $key_1_byte_array = [byte[]][int[]]$key_1_value

$final_byte_array += $key_1_byte_array

现在,可以继续使用module_data JSON 字段。

[int64] $module_data = [int64] $json.device_1_data.module_data

$module_data_byte_array = [BitConverter]::GetBytes($module_data)

$final_byte_array += $module_data_byte_array

然后是频率:

[int] $frequency_0 = [int] $json.device_1_data.frequency_0
[byte[]]$frequency_0_byte_array = [BitConverter]::getBytes($frequency_0)
$final_byte_array += $frequency_0_byte_array

[int] $frequency_1 = [int] $json.device_1_data.frequency_1
[byte[]] $frequency_1_byte_array = [BitConverter]::getBytes($frequency_1)
$final_byte_array += $frequency_1_byte_array

最后是同步词:

[int] $generator_syncword = [int] $json.device_1_data.generator_syncword

$syncword_byte_array = [BitConverter]::GetBytes($generator_syncword)

$final_byte_array += $syncword_byte_array

一旦我们在字节数组中获取并连接了所有内容,我们就可以执行管道操作来了解我们正在获取的内容。

这将是 powershell 的初步输出:

PS C:\Users\user> $final_byte_array | format-hex

               Ruta:

               00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

    00000000   01 00 CD AB 01 00 00 00 2E 34 72 0A 45 57 41 17  ..Í«.....4r.EWA.
    00000010   07 52 CA 4C 0D 7B 41 57 30 38 7A 38 C0 FA 41 17  .RÊL.{AW08z8ÀúA.
    00000020   A0 F8 5E 17 CF 00 00 00                           ø^.Ï...

现在我们可以将该字节数组发送到扩展名为 *.bin 的文件中,但由于数据是以字节为单位写入的,因此使用 SRecord 工具的进一步步骤不会有任何问题。

# File storage
[IO.File]::WriteAllBytes('C:\<path desired to save>\input_file.bin', $final_byte_array)

一旦我们有了文件,我们就可以使用 srec_cat.exe,为了说明的目的,假设我们在 srec_cat.exe 所在的某个目录位置使用 CMD,如以及我们刚刚创建的input_file.bin

>srec_cat input_file.bin -binary -o srec_input_file.srec

如果我们打开文件srec_input_file.srec,它将显示如下内容:

S0220000687474703A2F2F737265636F72642E736F75726365666F7267652E6E65742F1D
S12300000100CDAB010000002E34720A455741170752CA4C0D7B415730387A38C0FA4117D5
S10B0020A0F85E17CF000000F8
S5030002FA

然后,我们可以使用 hex-dump 再次对其进行转换,以查看我们是否获得了与之前在 powershell 输出中看到的相同的字节值:

>srec_cat srec_input_file.srec -o hex_input_file.bin -hex-dump

如果我们打开hex_input_file.bin,我们可以看到:

00000000: 01 00 CD AB 01 00 00 00 2E 34 72 0A 45 57 41 17  #..M+.....4r.EWA.
00000010: 07 52 CA 4C 0D 7B 41 57 30 38 7A 38 C0 FA 41 17  #.RJL.{AW08z8@zA.
00000020: A0 F8 5E 17 CF 00 00 00                          # x^.O...

我们可以使用这个文件来连接它的偏移量,假设我们打算从位置0x1A010写入它,我们这样做:

>srec_cat srec_input_file.srec -offset 0x1A010 -o srec_input_file_offset.srec

我们得到类似的东西:

S0220000687474703A2F2F737265636F72642E736F75726365666F7267652E6E65742F1D
S22401A0100100CDAB010000002E34720A455741170752CA4C0D7B415730387A38C0FA411723
S20C01A030A0F85E17CF00000046
S5030002FA

然后我们通过以下方式对其进行审核:

>srec_cat srec_input_file_offset.srec -o hex_input_file_offset.bin -hex-dump

然后打开看看:

0001A010: 01 00 CD AB 01 00 00 00 2E 34 72 0A 45 57 41 17  #..M+.....4r.EWA.
0001A020: 07 52 CA 4C 0D 7B 41 57 30 38 7A 38 C0 FA 41 17  #.RJL.{AW08z8@zA.
0001A030: A0 F8 5E 17 CF 00 00 00                          # x^.O...

之后,我们用0xFF 填充srec_input_file_offset.srec 的空字节:

>srec_cat.exe srec_input_file_offset.srec -fill 0xFF 0x0001A030 0x0001A040 -output final_srec_input_file.srec

最后,只将final_srec_input_file.srec 附加到主 bin 文件的 srec 中。

假设我们没有转换main_file.bin

>srec_cat main_file.bin -binary -o main_file.srec

然后我们把所有东西放在一起:

>srec_cat main_file.srec srec_input_file_offset.srec -o final_file.bin -binary

就是这样。再次感谢一切。非常欢迎反馈和建议。

亲切的问候。

【问题讨论】:

  • 你认为什么是“二进制文件”?请退后一步,描述您要解决的实际问题,而不是您认为的解决方案。你需要这个做什么?
  • 我需要它来将一些密钥、ID 和一些数据写入最终的 *.bin 文件,该文件旨在闪存到硬件设备中。我将二进制类型文件视为 srecord 工具可以使用的 *.bin 文件。
  • 只是文本还是不可打印的字符?哪种编码?数据结构如何?
  • 您需要了解设备的内存布局。就像为 intel cpu 烧写 spi flash rom 一样,您需要知道闪存映射。例如,可能 4kbytes 映射到 0xfffffff0。所以你写到那个偏移量。这只是内存映射。我也认为 windows .bin 与该格式无关。想想一个例子是固件的.spi。 github.com/espressif/esptool/wiki/Firmware-Image-Format 然后有图像以闪存程序员期望的无序方式格式化数据。
  • 除非您指定“二进制”输入文件应该具有的格式/结构,否则任何人都不太可能为您提供帮助。

标签: powershell cmd hex bin


【解决方案1】:

certutil 可以同时做到:从二进制文件创建一个十六进制(转储)文件,从一个十六进制编码文件创建一个二进制文件:

certutil -f -encodeHex out.bin out.txt >nul
certutil -f -decodeHex hex.txt out.bin >nul

要从批处理创建二进制文件,请参见此处:
https://www.dostips.com/forum/viewtopic.php?f=3&t=5326

对于二进制文件的十进制转储:
comp File1 File2 /D /m
(类似于 powershell 中的gc -encoding byte File1

对于二进制文件的十六进制转储:
fc /b File1 File2
(类似于 powershell 中的gc -encoding byte File1 |% {write-host ("{0:X2}" -f $_)}

注意:File2 是一个参考文件,与 File1 没有相似的字符。
如果不确定,则解决方法是用 0x20 填充 File2,然后在第二次比较中用 0x00 填充 File2 并用 0x20 替换缺失的字符(在第一次比较中)
提示: 检查偏移地址。

在 Win 10 x64 上测试

【讨论】:

  • certutil -encodeHex -v InFile OutFile 工作得很好。
【解决方案2】:

将数据字节写入文件非常简单。获取一些数据,将其转换为字节数组,然后将该数组写入文件:

$s = 'some text'
$b = [byte[]][char[]]$s
[IO.File]::WriteAllBytes('C:\path\to\output.bin', $b)

但是,如果您写入文件的字节布局不正确,无论您尝试做什么,这都对您没有任何帮助。在上面的示例中,尽管扩展名为 .bin,但您仍然得到一个 ASCII 文本文件(扩展只是用于将一组文件与特定程序相关联)。


编辑:鉴于更新问题中的示例输入和输出数据,您需要将整数值(以十六进制和十进制表示法)写入具有不同字节顺序的字节序列并对齐数据。

下面是一个帮助您入门的示例:

function Get-Bytes([uint32]$val) {
  [BitConverter]::GetBytes($val)
}

$json  = Get-Content 'C:\path\to\input.json' -Raw | ConvertFrom-Json
$bytes = @()

# convert UUID and append to byte array
$bytes += $json.device_1_data.device_uuid.PSObject.Properties | ForEach-Object {
  $v = Get-Bytes $_.Value
  if ($v[2] -ne 0 -or $v[3] -ne 0) {
    $v[2, 3, 0, 1]
  } else {
    $v[0, 1]
  }
}

# fill missing bytes with zero values to align next sequence
$bytes += [byte[]]0 * (8 - $bytes.Count)

# convert key_1 and append to byte array
$bytes += $json.device_1_data.key_1 | ForEach-Object { [byte][uint32]$_ }

...
...   # continue for the rest of the data, adjust byte order as required
...

[IO.File]::WriteAllBytes('C:\path\to\output.bin', $bytes)

【讨论】:

  • 我实际上正在进行数据类型转换,以便适当地编写信息,所以这确实会有所帮助。使用 [IO.File]::WriteAllBytes('C:\path\to\output.bin', $b) 的硬编码字节数组的输出文件在使用 Srecord 工具时确实可以正常工作。现在我对二进制文件以及如何编写它们有了更多的了解。将尝试在编辑时发布的代码,稍后再回来。谢谢!我会试试这个并且会
【解决方案3】:

man page 告诉我:

可以使用 srec_cat(1) 读写二进制文件。

(对 SRecord 没有个人经验,)我认为这意味着您可以使用输入文件 原样,使用其 原始字节 -无需十六进制转储和重新格式化;您只需要在命令行上使用选项-binary 跟随其文件名。

这假定您的输入文件使用所需的字符编码;如果不是,请先转换它,例如使用iconv,甚至是Get-Content -Encoding ... / Set-Content -Encoding ... 组合。

可接受的输入格式描述为hereAscii-Hex 的格式与Format-Hex 生成的格式相似,但需要进行重要的调整。


一般来说,请注意,诸如Format-Hex 创建的表示本身总是文本,而不是“二进制”。
它们以文本方式描述一系列字节值,这允许它们表示任意数据,包括二进制(非文本)数据。

【讨论】:

  • 当然是文本。好的,所以,我不知道如何将原始字节写入二进制文件。十六进制转储仅用于视觉参考,最后我们将仅使用原始二进制文件。不能使用iconv因为我们使用的是windows环境。我正在记录自己,以了解如何使用 get-content... / set-content 组合。尝试硬编码带有 *.hex 和 *.bin 扩展名的 ascii hex 文件,但 srec_cat 工具无法识别内容,因此它会忽略它。目前正在阅读您在此处发布的所有内容,非常感谢。
  • @GJntN 这就是为什么我一直告诉你,你需要告诉我们该文件的内容需要是什么样的。
  • @GJntN:添加到 Ansgar 的评论中:这些原始字节的来源是什么,为什么该来源需要转换?
  • 我将添加另一个编辑以添加您要求的信息。非常感谢您的跟进。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-10
  • 2013-07-07
  • 2021-07-06
  • 1970-01-01
  • 2012-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多