【问题标题】:How to disassemble a shellcode into assembly instruction? [duplicate]如何将 shellcode 反汇编成汇编指令? [复制]
【发布时间】:2017-06-27 13:41:18
【问题描述】:

是否有一些工具可以将原始十六进制反汇编成汇编指令?例如:假设我们有 \xeb\x1d 根据this 在线反汇编程序反汇编成 jmp 0x1f。那么有一些离线工具吗?我试过 ndisasm 它没有给我正确的输出。

ndisam -b32foo 给我:

输出:

00000000  5C                pop esp<br>
00000001  7833              js 0x36<br>
00000003  315C7865          xor [eax+edi*2+0x65],ebx<br>
00000007  620A              bound ecx,[edx]

应该是 jmp 0x1f。 我也试过像这样的objdump:

objdump -D -b binary -mi386 -M intel foo

输出:

00000000 <.data>:<br>
   0:   5c                      pop    esp <br>
   1:   78 33                   js     0x36 <br>
   3:   31 5c 78 65             xor    DWORD PTR [eax+edi*2+0x65],ebx<br>
   7:   62 0a                   bound  ecx,QWORD PTR [edx]<br>

所以你能告诉我一些将原始十六进制代码反汇编成汇编语言的工具吗?

我也尝试过 gdb,但我想要更灵活的东西。

【问题讨论】:

  • 字节 5c 78 65 5c 78 31 64 0a 是字符串 \xeb\x1d(以换行符结尾)的表示形式,这是您在键入 echo '\xeb\x1d' &gt;foo 时得到的。你想反汇编字节 eb 1d,好像你误解了 "\xeb\x1d" 的意思。
  • 另外注意eb 1djmp .+0x1f,即跳转到的地址是相对于跳转指令所在地址的。根据这条指令反汇编的位置,绝对跳转目标会发生变化!
  • @specializt 这正是反汇编的意思!将机器代码翻译回助记符。唯一涉及的猜测是指令开始的位置(以防 ISA 没有明确说明)以及对于某些 ISA,使用的是哪个指令集。
  • 维基百科的文章同时试图深入过于简单化。这行:“例如,x86 汇编程序在两个二进制代码之间任意选择,用于像 MOV AX,BX 这样简单的事情。如果原始代码使用其他选择,则原始代码根本无法在任何给定条件下复制时间点。” 是荒谬的。如果MOV AX, BX有两种可能的编码,那么无论在十六进制转储中找到哪一种,都会反汇编为MOV AX, BX这是原始指令
  • @CodyGray 维基百科的那篇文章需要一些认真的工作。他们实际上将文章过于复杂,以至于它实际上没有多大意义。即使是相对/绝对跳转的反汇编示例也没有任何意义。无论是绝对的还是相对的,都是编码的一部分。几乎就像不了解 x86 的人试图编写那样。

标签: assembly x86 disassembly shellcode


【解决方案1】:

正如 cmets 所建议的,您的问题是您已将字符串 \xeb\x1d 作为 ASCII 输出到您尝试反汇编的文件中。你可能做过类似的事情:

echo '\xeb\x1d' >foo

您可以这样做,但您需要告诉echo 解释转义字符\。这可以通过-e 选项来完成。

您会希望它不要使用 -n 选项在末尾附加换行符。这在 ECHO 手册页中有记录:

  -n     do not output the trailing newline
  -e     enable interpretation of backslash escapes

这可能有效:

echo -ne '\xeb\x1d' >foo

使用NDISASM反汇编字节:

ndisasm -b32 foo

现在应该产生:

00000000  EB1D              jmp short 0x1f

不使用中间文件(如foo),您可以将ECHO 输出通过管道传输到NDISASM 并以这种方式对其进行反汇编。此行将采用 shell 代码字符串并输出反汇编代码:

echo -ne '\xeb\x1d' | ndisasm -b32 -

需要最后的 - 告诉 NDISASM 从标准输入而不是显式文件中反汇编输入。

我们现在已经彻底改变了 IT 行业! ;-)

【讨论】:

  • 哦,我明白了,谢谢。
  • 另一种更方便的方法是在 shellcode 的开头和结尾声明两个全局符号 - 分别称为 PIC_START 和 PIC_END。使用 gcc -c shellcode.s 编译程序集。不要有 main() 或 _start() 符号。然后,用 extern unsigned char *PIC_START; 编写一个简单的 c 程序; unsigned char *PIC_END,调用它 main.c 并给它一个带有 unsigned char *ptr 的 main,它从 PIC_START 开始并迭代你的 shellcode,一次一个字节(或者你想这样做)并使用 print 语句比如 printf("\\x%.02x", *ptr);
  • 你可以让这个互动吗?
猜你喜欢
  • 2011-08-06
  • 1970-01-01
  • 2011-12-29
  • 2021-04-04
  • 1970-01-01
  • 2011-04-28
  • 1970-01-01
  • 2014-12-31
  • 2013-02-06
相关资源
最近更新 更多