文件的机器码(可执行文件)是什么?

4

我如何访问可执行文件的机器代码(二进制文件)?

细节

  • 我正在使用Ubuntu(Linux)系统
  • 我想访问.exe文件的机器代码(二进制文件),这些文件遵循PE格式
  • 我使用C语言进行实现
2个回答

6

使用带有选项-dobjdump进行反汇编。另一个有用的选项是-s,可获得文件转储。如果由于某种原因-d无法工作,您还可以尝试-D,这会强制objdump对文件进行反汇编,即使它看起来不包含机器代码。请参阅objdump的手册以获取更多详细信息。例如,要对PE可执行文件foo.exe进行反汇编和转储,请键入:

objdump -sd foo.exe

输出结果包含两个部分。第一部分如下所示:
Contents of section .text:
 401000 33c03905 28944200 0f9fc0c3 558bec51  3.9.(.B.....U..Q
 401010 568bf16a 01684410 4000c706 30024200  V..j.hD.@...0.B.
 401020 ff15b000 420085c0 75158d45 fc68c00e  ....B...u..E.h..
 401030 420050c7 45fc9070 4200e8cd bc01008b  B.P.E..pB.......
 401040 c65ec9c3 837c2404 0575056a 0158eb12  .^...|$..u.j.X..
 401050 ff052894 420033c0 833d2894 4200020f  ..(.B.3..=(.B...
 401060 9cc0c204 00568bf1 e8140000 00f64424  .....V........D$
 401070 08017407 56e88b6f 0000598b c65ec204  ..t.V..o..Y..^..
 401080 00558bec 516a0068 44104000 c7013002  .U..Qj.hD.@...0.
 401090 4200ff15 b0004200 85c07515 8d45fc68  B.....B...u..E.h
 4010a0 c00e4200 50c745fc 90704200 e85bbc01  ..B.P.E..pB..[..
 4010b0 00c9c3e8 48ffffff f6d81bc0 25044000  ....H.......%.@.
 4010c0 80c20c00 e837ffff fff6d81b c0250440  .....7.......%.@
 4010d0 0080c208 00558bec 568b7508 68c58240  .....U..V.u.h..@
 4010e0 00682072 4200ff75 0c8b4e40 68187242  .h rB..u..N@h.rB
 4010f0 00e8d771 00008bc8 e8e87100 008bc8e8  ...q......q.....

这是二进制文件各个部分的转储。第一列是此行的地址,接下来的四列以十六进制表示转储数据,最后一列将数据显示为ASCII字符,其中使用 . 代替不可打印字符。
第二部分如下:
00401000 <.text>:
  401000:   33 c0                   xor    %eax,%eax
  401002:   39 05 28 94 42 00       cmp    %eax,0x429428
  401008:   0f 9f c0                setg   %al
  40100b:   c3                      ret    
  40100c:   55                      push   %ebp
  40100d:   8b ec                   mov    %esp,%ebp
  40100f:   51                      push   %ecx
  401010:   56                      push   %esi
  401011:   8b f1                   mov    %ecx,%esi
  401013:   6a 01                   push   $0x1
  401015:   68 44 10 40 00          push   $0x401044
  40101a:   c7 06 30 02 42 00       movl   $0x420230,(%esi)
  401020:   ff 15 b0 00 42 00       call   *0x4200b0

这是二进制文件的反汇编。第一列显示当前地址,然后是十六进制表示的指令,最后是对应的助记符。请注意,此部分仅适用于标记为“包含可执行代码”的段(在PE文件的情况下,仅适用于文本段)。如果您不喜欢这种汇编语法(AT&T语法),请提供 -Mintel 以获得Intel语法输出:
00401000 <.text>:
  401000:   33 c0                   xor    eax,eax
  401002:   39 05 28 94 42 00       cmp    DWORD PTR ds:0x429428,eax
  401008:   0f 9f c0                setg   al
  40100b:   c3                      ret    
  40100c:   55                      push   ebp
  40100d:   8b ec                   mov    ebp,esp
  40100f:   51                      push   ecx
  401010:   56                      push   esi
  401011:   8b f1                   mov    esi,ecx
  401013:   6a 01                   push   0x1
  401015:   68 44 10 40 00          push   0x401044
  40101a:   c7 06 30 02 42 00       mov    DWORD PTR [esi],0x420230
  401020:   ff 15 b0 00 42 00       call   DWORD PTR ds:0x4200b0

另一个有用的工具是Agner Fog的objconv,它具有更适用于Windows二进制文件的选项,并且通常与objdump相比提供更详细的反汇编信息。

感谢您的回答。 - Arulx Z
我尝试使用“-s”来获取文件的转储,但没有成功。你能提供一个例子吗?很抱歉,我对shell还比较陌生。 - Arulx Z
@ArulxZ 只需使用 objdump -s foo.exe 命令即可以十六进制格式转储程序。你遇到了什么错误?你尝试了什么? - fuz
顺便说一下,当我尝试你的选项时,最后得到了一些奇怪格式的标记代码,就像这样 - 40dbe0 696c6567 65733e0d 0a20203c 72657175 ileges>.. <requ 40dbf0 65737465 64457865 63757469 6f6e4c65 estedExecutionLe 40dc00 76656c20 6c657665 6c3d2272 65717569 vel level="requi - Arulx Z
请参阅 objdump 的 man 手册以获取有关如何使用它的更多详细信息(man objdump)。 - fuz
显示剩余9条评论

5

源代码和机器码并不相同。

如果您已经安装了"binutils",您可以使用objdump

$ objdump --disassemble my-fantastic-program > my-fantastic-program.asm

这将会输出my-fantastic-program的汇编代码,无论这个程序是用什么语言编写的,都可以使用此方法。

>所在部分使用了shell命令的输出重定向,将结果保存到一个新文件中。


谢谢你的回答。我也编辑了问题! - Arulx Z
当我尝试将输出分组到文件中时,它会显示所有数据。然而,我只想要汇编代码。 - Arulx Z
@ArulxZ 如果你只想要汇编代码,可以尝试使用Agner Fog的工具,或者后处理objdump的输出以删除不需要的内容。 - fuz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接