逆向-beginners之scanf

本文详细解析了不同架构(如x86、x64、arm和arm64)下函数运行时栈帧结构,重点讲解了EBP和ESP的作用,以及参数传递方式。
摘要由CSDN通过智能技术生成

#include <stdio.h>

int main()
{
    int x;

    printf("Enter x:\n");
    scanf("%d", &x);
    printf("you entered %d...\n", x);

    return 0;    
}

#if 0

/*
 * x86
 */
    在函数运行期间,EBP一直指向当前的栈帧(stack frame)。这样,函数即可能过EBP+offset的方式访问本地变量、以及外部传入的函数参数。

    ESP也可以用来访问本地变量,获取函数所需的运行参数。不过ESP的值经常变化,用起来并不方便。函数在启动之初就会利用EBP保存ESP的
    值。这就是为了确保在函数运行期间保证EBP存储的原始ESP值固定不变。

    在32位系统里,典型的栈帧(stack frame)结构如下:

        ...            ...
        EBP-8        局部变量#2
        EBP-4        局部变量#1
        EBP            ESP的值
        EBP+4        返回地址
        EBP+8        函数参数#1, IDA标记为arg_0
        EBP+C        函数参数#2, IDA标记为arg_4
        EBP+10        函数参数#3, IDA标记为arg_8
        ...            ...

    lea
        load effective address,将源操作数(第二个参数)给出的效地址(offset)传送到目的寄存器(第一个参数)之中。

/*
 * x64
 */
    由于这个程序的参数较少,编译器会直接使用寄存器传递参数。

/*
 * arm
 */
    scan函数同样要借助指针传递返回值。

/*
 * arm64
 */
    add x1, x29, 28        # 分配局部变量 x 的存储空间。

#endif

#if 0
/*
 * intel
 */
00000000000011a9 <main>:
    11a9:    f3 0f 1e fa              endbr64 
    11ad:    55                       push   %rbp
    11ae:    48 89 e5                 mov    %rsp,%rbp
    11b1:    48 83 ec 10              sub    $0x10,%rsp
    11b5:    64 48 8b 04 25 28 00     mov    %fs:0x28,%rax
    11bc:    00 00 
    11be:    48 89 45 f8              mov    %rax,-0x8(%rbp)
    11c2:    31 c0                    xor    %eax,%eax
    11c4:    48 8d 3d 39 0e 00 00     lea    0xe39(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
    11cb:    e8 b0 fe ff ff           callq  1080 <puts@plt>        // puts()
    11d0:    48 8d 45 f4              lea    -0xc(%rbp),%rax        // rax=rbp-0xc
    11d4:    48 89 c6                 mov    %rax,%rsi        // rsi=rax
    11d7:    48 8d 3d 2f 0e 00 00     lea    0xe2f(%rip),%rdi        # 200d <_IO_stdin_used+0xd>    // rdi="%d"
    11de:    b8 00 00 00 00           mov    $0x0,%eax
    11e3:    e8 c8 fe ff ff           callq  10b0 <__isoc99_scanf@plt>    // scanf(rdi, rsi)
    11e8:    8b 45 f4                 mov    -0xc(%rbp),%eax        // eax=x
    11eb:    89 c6                    mov    %eax,%esi        // esi=eax
    11ed:    48 8d 3d 1c 0e 00 00     lea    0xe1c(%rip),%rdi        # 2010 <_IO_stdin_used+0x10>    // rdi="you entered %d...\n"
    11f4:    b8 00 00 00 00           mov    $0x0,%eax
    11f9:    e8 a2 fe ff ff           callq  10a0 <printf@plt>    // printf(rdi, esi)
    11fe:    b8 00 00 00 00           mov    $0x0,%eax
    1203:    48 8b 55 f8              mov    -0x8(%rbp),%rdx
    1207:    64 48 33 14 25 28 00     xor    %fs:0x28,%rdx
    120e:    00 00 
    1210:    74 05                    je     1217 <main+0x6e>
    1212:    e8 79 fe ff ff           callq  1090 <__stack_chk_fail@plt>
    1217:    c9                       leaveq 
    1218:    c3                       retq   
    1219:    0f 1f 80 00 00 00 00     nopl   0x0(%rax)


/*
 * arm
 */
00000000004005fc <main>:
  4005fc:    a9be7bfd     stp    x29, x30, [sp, #-32]!
  400600:    910003fd     mov    x29, sp
  400604:    90000000     adrp    x0, 400000 <_init-0x468>
  400608:    911bc000     add    x0, x0, #0x6f0
  40060c:    97ffffb1     bl    4004d0 <puts@plt>        // puts
  400610:    910073a1     add    x1, x29, #0x1c            // x1 = x29+0x1c
  400614:    90000000     adrp    x0, 400000 <_init-0x468>
  400618:    911c0000     add    x0, x0, #0x700            // x0="you entered %d...\n"
  40061c:    97ffffb1     bl    4004e0 <__isoc99_scanf@plt>    // scanf(x0, x1)
  400620:    b9401fa1     ldr    w1, [x29, #28]
  400624:    90000000     adrp    x0, 400000 <_init-0x468>
  400628:    911c2000     add    x0, x0, #0x708
  40062c:    97ffffb1     bl    4004f0 <printf@plt>
  400630:    52800000     mov    w0, #0x0                       // #0
  400634:    a8c27bfd     ldp    x29, x30, [sp], #32
  400638:    d65f03c0     ret
  40063c:    00000000     .inst    0x00000000 ; undefined


#endif
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 很抱歉,我是一名AI语言模型,无法进行安装操作。但是,我可以提供一些安装ROS Academy for Beginners的指导: 1. 首先,确保你的计算机已经安装了ROS(Robot Operating System)。 2. 在终端中输入以下命令,下载ROS Academy for Beginners: ``` git clone https://github.com/qboticslabs/ros-academy-for-beginners.git ``` 3. 进入下载的文件夹: ``` cd ros-academy-for-beginners ``` 4. 运行安装脚本: ``` ./install.sh ``` 5. 安装完成后,你可以在终端中输入以下命令,启动ROS Academy for Beginners: ``` roslaunch academy academy.launch ``` 希望这些指导能够帮助你安装ROS Academy for Beginners。如果你遇到了任何问题,可以在ROS社区中寻求帮助。 ### 回答2: 首先,安装ROS的前提是已经安装好了Ubuntu操作系统,推荐使用Ubuntu 18.04。可以从Ubuntu的官网上下载系统镜像并且安装。 其次,在安装ROS之前,需要先添加ROS的软件源,这里以Melodic版本为例。打开终端,输入以下命令,添加ROS的软件源: ``` sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' ``` 由于ROS的安装需要与ubuntu操作系统的软件进行整合,为了确保最佳匹配,需要先运行以下命令进行更新: ``` sudo apt update sudo apt upgrade ``` 然后是ROS的安装,运行以下命令: ``` sudo apt install ros-melodic-desktop-full ``` 该命令会安装ROS桌面完整版,其中包含许多常用的软件包和工具。安装完成后,可以通过以下命令检查ROS的版本: ``` rosversion -d ``` 接下来,还需配置ROS环境变量。在终端中输入: ``` echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc source ~/.bashrc ``` 安装ROS的最后一步是安装ROS初始工作区(catkin工作区)。打开终端,输入以下命令: ``` mkdir -p ~/catkin_ws/src cd ~/catkin_ws/ catkin_make ``` 这个命令创建一个名为catkin_ws的文件夹,并在其中创建一个src文件夹,用于存放ROS软件包源代码。 最后,我们可以安装ros-academy-for-beginners这个包,这个包可以用于学习ROS的基础知识,包括ROS的概念、练习和示例等等。在终端输入以下命令: ``` cd ~/catkin_ws/src git clone https://github.com/OTL/ros-academy-for-beginners.git cd ~/catkin_ws catkin_make ``` 至此,ros-academy-for-beginners的安装就完成了。如果想要使用该软件包内的示例和练习程序,可以查看ros-academy-for-beginners中的README文件,然后通过以下命令运行: ``` roslaunch ros_academy_publisher publisher.launch ``` ### 回答3: ROS(机器人操作系统)是一种流行的开源软件框架,它可以帮助开发人员为机器人软件构建底层、中间层、以及可视化的应用程序。ROS Academy for Beginners是一个为初学者提供ROS学习和实践的平台,这个平台包含了一系列的教程,如基础知识、机器人操作、感知和导航等。 在安装ROS Academy for Beginners之前,首先需要准备以下工具: 1. 一个ROS Kinetic(或更高版本)的Ubuntu操作系统。 2. 一个支持VirtualBox或VMware的虚拟机管理软件。 3. 一个ROS学习环境的Ubuntu虚拟机镜像文件。 下面是安装ROS Academy for Beginners的步骤: 1. 在VirtualBox(或其他虚拟机软件)中创建一台新的虚拟机。请确保选择Ubuntu x64的版本。 2. 启动Ubuntu虚拟机,并使用管理员权限运行Terminal。 3. 输入以下命令,添加ROS Kinetic的存储库以及密钥: $ sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' $ sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116 4. 更新存储库并安装ROS Kinetic Desktop Full: $ sudo apt-get update $ sudo apt-get install ros-kinetic-desktop-full 5. 安装ROS依赖项: $ sudo apt-get install python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential 6. 初始化rosdep: $ sudo rosdep init $ rosdep update 7. 设置ROS环境变量: $ echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc $ source ~/.bashrc 8. 下载ROS Academy for Beginners虚拟机镜像: $ wget https://s3-us-west-2.amazonaws.com/ros-academy/ROS-Academy-For-Beginners.ova 9. 启动VirtualBox软件,选择“File” -> “Import Appliance”,并选择已下载的ROS Academy for Beginners虚拟机镜像文件。 10. 等待虚拟机导入完成后,启动ROS Academy for Beginners虚拟机,并按照教程开始学习ROS! 希望这些步骤可以帮助您安装ROS Academy for Beginners。如果您在安装过程中遇到任何问题,请参考ROS官方文档或社区论坛,寻求帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值