【问题标题】:ARM Assembly on using recv syscall关于使用 recv 系统调用的 ARM 程序集
【发布时间】:2019-06-28 14:13:54
【问题描述】:

我开始从https://azeria-labs.com/writing-arm-shellcode/ 学习ARM 汇编,我想练习从套接字接收数据。这是到目前为止我正在学习的代码 sn-p。测试是在移动设备上完成的。

网络客户端代码

    @socket syscall
    movw r7,#281
    mov r0,#2
    mov r1,#1
    sub r2,r2,r2
    svc #1
    mov r6,r0

    @connect syscall
    movw r7,#283
    adr r1,struct
    strb r2,[r1,#1]
    mov r2,#16
    mov r0,r6
    svc #1

    @recv syscall
    mov r0,r6
    mov r3, #100
    adr r1,to_receive
    mov r2,#receive_size
    movw r7,#291
    svc #1

    @write syscall
    mov r7,#4
    mov r0,#1
    adr r1,to_receive
    mov r2,#receive_size
    svc #1

    @exit with error code from last syscall
    mov r7,#1
    svc #1

    struct:
    .ascii "\x02\xff" @AF_INET
    .ascii "\x11\x5c" @port 4444
    .byte 127,0,0,1   @ip 127.0.0.1

    to_receive: .skip 40
    after_to_receive:
    .set receive_size, after_to_receive - to_receive

在网络连接的另一端,我将 nc 配置为侦听并将一些文本数据通过管道传输到成功的连接。

网络监听器(服务器)

toybox nc -Lp 4444 < file_to_send.txt

但是,我没有看到客户端控制台屏幕的任何输出。我怀疑 recv 系统调用没有接收到数据,或者我没有正确使用 write 系统调用。

我没有看到任何错误消息,所以我不确定我是否做得对。任何建议表示赞赏。

我已经单独确认将另一个nc进程连接到监听器将检索文本数据。

【问题讨论】:

  • 你能在这段代码上附加一个调试器并单步执行吗?或者运行strace ./a.out 来跟踪它所做的系统调用?在没有调试器的情况下开发 asm 就像试图构建一个机器人眼罩 - 你得到的通常是“不起作用”或“崩溃”,没有足够的信息来缩小原因。将错误的参数传递给系统调用不会导致错误消息,除非您手动编写错误处理代码,使write 系统调用打印错误消息!如果您传递了错误的地址,他们只会返回 -EFAULT,例如,甚至不会提高 SIGSEGV。
  • 嗨@PeterCordes 我忘了添加一行“movw r7, #291”来执行系统调用。添加它并在调试器中运行程序后,我看到 recv 系统调用返回一个非零值“0x1a”,根据手册页,它是接收到的字节数,我确认了要发送的字符数文本文件确实是 26,包括空字节。但是,当我使用调试器使用x/40x $pc 显示内存中的区域(to_receive 数组/缓冲区?)时,我看到它全为零,没有填充任何内容。所以似乎我在使用 recv 系统调用时做错了吗?
  • 是的,应该是字节数。但是x/40x $pc 在程序计数器之后转储内存,而不是静态缓冲区的内存。使用x &amp;to_receivex $r1 之类的。但是为什么recv 而不是来自套接字的简单read() 呢? 100(又名0x64)启用了哪些标志?另外,您的文本文件有一个0 字节?这很奇怪。通常文本文件在最后一行的末尾以换行符结束。仅当将字符串存储在内存中的隐式长度 C 字符串(不是显式长度文件)中时,您才会有一个 0 字节。
  • 嗨@PeterCordes 是的,阅读系统调用对我有用。我还意识到我给出了错误的标志值,再加上在执行 recv 系统调用之前我没有包含movw r7,#291,这可能是我的代码一开始就不起作用的原因。感谢您的帮助,至少现在我知道 read() 也以类似的方式工作。您的建议不是答案,所以我无法将您的评论标记为答案?
  • 您的评论中有一半需要回答的细节,所以您应该edit您的问题。但是,是的,如果解决了问题,我会发布答案。

标签: android assembly arm


【解决方案1】:

使用调试器(如 GDB)和/或strace ./a.out 跟踪您的程序进行的系统调用并找出问题所在。 asm 程序崩溃或静默什么都不做是很正常的,因为系统调用的错误参数通常会导致-EFAULT-EINVAL-ENOSYS,而不是引发 SIGSEGV 或类似的东西。但是除非您编写错误处理代码或使用strace,否则您不会知道哪个或为什么。

(OP 报告说,在这样做之后,很明显recv 电话号码缺少movw r7,#291。)


(在修复了调试/跟踪工具明显的错误之后):

使用x/40x $pc我看到它全为零,没有任何填充

$pc 是程序计数器,r15。你想要x &amp;to_receivex $r1 或其他东西来转储你传递给recv 的静态缓冲区中的内存。

是的,0x1a 返回值应该是字节数。

flags=100 (0x64) 也似乎很奇怪,但没有评论解释您想要哪些标志或为什么要用十进制写它们。

一开始你甚至不需要recv;你有一个连接的 TCP 套接字,可能不需要任何标志,所以你可以简单地从套接字 FD 中read()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-13
    • 2013-12-18
    • 2013-03-16
    • 2015-03-23
    • 1970-01-01
    • 1970-01-01
    • 2020-05-20
    • 2022-01-23
    相关资源
    最近更新 更多