首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >精灵aarch64与sys_write

精灵aarch64与sys_write
EN

Stack Overflow用户
提问于 2022-11-22 11:49:40
回答 1查看 48关注 0票数 1

为了更好地理解ELF格式和ARM aarch64,我尝试在没有编译器的情况下创建精灵二进制文件,只需将字节与bash相对应。

威尔可以在这里看到我的努力:http://www.github.com/glaudiston/elf

我已经成功地实现了一个完全工作的精灵与sys_writesys_exit系统为x64

但是对于aarch64,它并不像我期望的那样起作用:

代码语言:javascript
复制
# cat make-elf.sh 
#!/bin/bash
#
# depends on:
# - elf_fn.sh (github.com/glaudiston/elf)
# - base64 (gnu-coreutils)
#

. elf_fn.sh

instructions="";
instructions="${instructions}\nwrite $(echo -en "hello world\n" | base64 -w0)";
instructions="${instructions}\nexit 3";
write_elf elf "${instructions}";

它产生:

代码语言:javascript
复制
$ xxd elf
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............
00000010: 0200 b700 0100 0000 7800 0100 0000 0000  ........x.......
00000020: 4000 0000 0000 0000 0000 0000 0000 0000  @...............
00000030: 0000 0000 4000 3800 0100 0000 0000 0000  ....@.8.........
00000040: 0100 0000 0500 0000 0000 0000 0000 0000  ................
00000050: 0000 0100 0000 0000 0000 0000 0000 0000  ................
00000060: 7800 0000 0000 0000 7800 0000 0000 0000  x.......x.......
00000070: 0000 0000 0000 0000 2000 80d2 010c 0058  ........ ......X
00000080: 8201 80d2 0808 80d2 0100 00d4 6000 80d2  ............`...
00000090: a80b 80d2 0100 00d4 6865 6c6c 6f20 776f  ........hello wo
000000a0: 726c 640a           
代码语言:javascript
复制
$ ./make-elf.sh 0 && ./elf; echo $?
3
$ cat elf | base64 -w0; echo
f0VMRgIBAQAAAAAAAAAAAAIAtwABAAAAeAABAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAOAABAAAAAAAAAAEAAAAFAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAeAAAAAAAAAB4AAAAAAAAAAAAAAAAAAAAIACA0gEMAFiCAYDSCAiA0gEAANRgAIDSqAuA0gEAANRoZWxsbyB3b3JsZAo=

它返回预期的退出代码,没有任何非法异常,但是sys_write调用没有打印任何内容。

隐藏所有ELF开销,我们有以下内容:

代码语言:javascript
复制
00000078:                     2000 80d2 010c 0058           ......X
00000080: 8201 80d2 0808 80d2 0100 00d4 6000 80d2  ............`...
00000090: a80b 80d2 0100 00d4 6865 6c6c 6f20 776f  ........hello wo
000000a0: 726c 640a                                rld.

退出呼叫正在按预期工作,所以我也可以隐藏它:

代码语言:javascript
复制
00000078:                     2000 80d2 010c 0058           ......X
00000080: 8201 80d2 0808 80d2 0100 00d4            ............    
00000090:                     6865 6c6c 6f20 776f          hello wo
000000a0: 726c 640a                                rld.

所以数据hello world.\n98位置开始。对于如何在这里进行sys_write调用,我感到非常困惑。在x64中,我可以设置为下一个数据地址,在本例中应该是65688(由PH_VADDR_V(65536) + ELF_HEADER_SIZE(64) + ELF_BODY_SIZE(32) (没有DATA_SECTION)组成)

对于输出fd,我在r0中用2000 80d2设置值1

对于数据地址,我使用的是010c,即0c01little endian表示--这个位:00001100000 00001最后5位是r1寄存器,用于数据地址。

考虑到这里只有11位,我使用了LDR (0058),但是我也尝试过MOV (这里是80d2)。没有成功

我尝试过从0到2048的任何值,其中它开始报告Illegal instruction和退出代码132

我认为aarch64可能不允许我在x64中使用的方法在没有标签数据部分的情况下打印数据。我将致力于创建它,但这只是一个猜测,我真的想了解为什么这个没有打印任何东西。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-22 14:55:33

因此,您的字符串位于绝对地址0x10098,您需要将该地址输入x1寄存器。

首先,LDR不是你想要的。顾名思义,它是来自内存的load (read)。您根本不希望指令访问内存,它只是想将值0x10098放入寄存器中。

MOV更接近,它将一个即时值写入寄存器,但问题是,即时限制在16位,而您需要17位。因为指令是32位,所以只有那么多位可以用于立即。我的猜测是,您溢出了这一点,并最终改变了操作码位,所以您编写了一个完全不同的指令。(不要猜测编码!)查查他们。这将向您显示16位的限制。)

要将任意的即时值输入寄存器,所需的方法是一系列MOV/MOVK指令,每次编写16位。在这里,你只需要两个:

代码语言:javascript
复制
   0:   d2801301    mov x1, #0x98                   // #152
   4:   f2a00021    movk    x1, #0x1, lsl #16

尽管我们使用的是一个额外的单词,字符串的地址也会发生变化,所以您必须相应地进行调整。

但是,对于特定的地址,AArch64提供了pc相对地址生成指令ADR/ADRP.它们允许您将当前值添加到程序计数器的当前值(即当前正在执行的指令的地址),并将结果写入寄存器。作为一种奖励,他们会为即时分配更多的数据(尽管你不再需要它们)。

在这里,我们可以使用ADR。其操作码在位31处为0,在位位为24-28时为10000 .目标寄存器是0-4位,我们需要00001.在29-30位时,立即得到它的低二位,在5-23位时得到较高的位。ADR指令将位于绝对地址0x1007c,我们需要0x10098,所以位移是0x1c = 0b11100。因此,我们想要的编码是

代码语言:javascript
复制
0 00 10000 0000000000000000111 00001 = 0x100000e1

一些一般性建议:

  • 首先尝试用汇编程序编写代码,这样您就可以学习指令集,并且能够集中精力尝试这些指令的功能,而不是在编码方式上陷入困境。如果您想稍后返回并手工进行编码,可以,但是有了汇编程序,您还可以检查您的工作。

  • 使用调试器单步执行程序.这将向你表明你的LDR给了你一个完全虚假的价值,可能是暗示它没有做你想做的事情。--

  • 使用strace查看程序的系统调用。这将向您显示(我想,我没有测试) write确实会被调用,但是地址是错误的。
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74532163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档