如何直接重用`.rodata`、`.data`和`.bss`部分的转储内容?

逆向工程 拆卸 部件 纳姆
2021-07-04 11:03:54

好的,所以基本上我想在 Linux 32 位上重新使用来自 ELF 的转储.rodata databss部分的内容

转储命令:

objdump -s -j .text elf_binary
objdump -s -j .rodata elf_binary
objdump -s -j .data elf_binary

对于该.bss部分,我准备重新使用00000000其中一些与该bss部分具有相同大小的部分。

当我nasm以这种方式汇编程序中重新使用它时,它工作正常

.section rodata
S_label1: db 0x01
         db 0x02
         ....  
.section data
        db 0x01
S_label2:  db 0x02
         ....
.section bss
S_label3: db 0x00
         db 0x00
         ....

nasm -f elf test.s

但基本上我的问题是:

如何在gas汇编程序中重用这些转储的部分

基本上gas有不同的组装风格,显然数据部分表示不同......

我试了好几次还是找不到解决办法..

我是否清楚地展示了我的问题..?谁能给我一些帮助?

========更新==========

所以基本上我想重新使用从另一个二进制文件转储rodata databss部分。

例如,这是rodata部分的内容

03000000 01000200 0a0a556e 736f7274
65642061 72726179 2069733a 20200020
25642000 0a0a536f 72746564 20617272
61792069 733a2020 00

我可以通过这种方式重新使用它:

label1: 
db 0x03
db 0x00
db 0x00
db 0x00
label2: 
db 0x01
db 0x00
db 0x02
db 0x00
.....

mov eax, label1      // of course I will guarantee that I use it correctly
....

基本上nasm,我可以很容易地以上述方式重用它们,但我的问题是,如何以类似的方式重用gas(或直接使用gcc

是否可以?

2个回答

作为汇编程序员,我会说它gas很少用于汇编外部代码。调用的任务gas通常留给编译器,而gas现实生活中必须处理的大部分程序集要么inlined在内部C要么C++代码中,要么来自编译器。但是,我相信Dean ElsnerJay Fenlanson和他的朋友们撰写的这份文件是我在相当长一段时间内设法依赖的最佳参考资料。多次更新,涵盖2.19.51版本。

简单的方法是使用GCC我会说:

  //Just to avoid make a point :]
  typedef unsigned char byte;

  //
  byte lbl1[] = { 0x03, 0x00, 0x00, 0x00, ... }, 
       lbl2[] = { 0x01, 0x00, 0x02, 0x00, ... };

  //I prefer Intel syntax rather than AT&T, it's somehow cleaner !
  __asm__("intel_syntax noprefix                 ;"
          "mov eax, %0                           ;"
          "mov ebx, %1                           ;"
          "att_syntax prefix                     ;"
          :                        //output
          : "r" (lbl1), "r" (lbl2) //input
          : "%eax", "%ebx");       //clobber

好吧,如果您想专注于汇编代码(这是我手动优化代码时的做法),这是一个不错的方法。

现在,让我稍微解释一下。首先,您有两个包含检索数据的数组,没什么特别的。然后你得到汇编代码。如果您不熟悉inlined程序集,我会向您推荐链接,不过我将简要介绍一下我的代码。__asm__指令允许您在代码中的任何位置插入汇编指令。首先我告诉汇编器我将使用 Intel 的语法(寄存器没有 % 前缀,...),然后我将寄存器 %0 的内容移入eax,然后将 %1 的内容移入ebx(%0 是指针对于LBL1,%1是指针LBL2)。然后,我将其余参数切换到 AT&T 语法。第一个您可以指定输出变量。第二次之后您可以指定输入。在这里我通过LBL1LBL2,我用“R”让编译器手柄寄存器分配。如果您知道自己在做什么,则可以指定寄存器。在最后一个之后您必须声明代码中使用的寄存器,以便编译器释放它们并将它们用于剩余的代码生成步骤。

感谢@yaspr 的出色回答。

所以在这篇文章中我问的是

如何重用.rodata .data.bss节的内容?

这是我的回答:

一旦你转储了这些部分的所有内容,你就可以快速走这条路,我使用一个 hello world 代码来演示它:

.section .text
.globl  main
main:
push   %ebp
mov    %esp,%ebp
and    $0xfffffff0,%esp
sub    $0x20,%esp
fldl   S_80484f0     // lift the conceret address into symbol
fstpl  0x18(%esp)
fldl   0x18(%esp)
fstpl  0x4(%esp)
movl   $S_80484e0,(%esp) // lift the conceret address into symbol
call   printf
leave
ret
nop
nop
nop

.section .rodata

S_80484e0:
.long 0x6c6c6568
.long 0x6f77206f
.long 0x20642c72
.long 0x000a6625

S_80484f0:
.long 0x00000000
.long 0x40240000

致@yaspr 关于 AT&T 与英特尔风格的对比:

很明显,Intel 的风格比 AT&T 清晰得多:)

然而,在我目前正在努力的项目中,我发现nasm在一堆 GNU 工具(objdump objcopy ld和其他工具)中 使用它可能不是很容易

恕我直言,尽管objdump可以拆卸Intel风格,但我仍然遇到一堆问题/不清楚的问题,特别是在比较了objdumpIDAPro