CSAPP - 反编译 string_length

这篇具有很好参考价值的文章主要介绍了CSAPP - 反编译 string_length。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

虽然先前已经把 phase_1 和 phase_2 做出来了, 但其实是参考了网络上的答案, 仅仅是大概知道了关键汇编代码。但其实并没有真的懂。为啥呢?因为很多模棱两可的地方是靠猜测的,而猜测是脆弱的。

重新看 phase_1, 第一个门槛是 string_length 函数。尝试逐句翻译回 C 代码。

前提条件: 知道 eax 存储返回值, 知道 rdi 存储函数第一个参数。使用Intel风格的汇编。

(gdb) disassemble string_length
Dump of assembler code for function string_length:
   0x000000000040131b <+0>:     cmp    BYTE PTR [rdi],0x0
   0x000000000040131e <+3>:     je     0x401332 <string_length+23>
   0x0000000000401320 <+5>:     mov    rdx,rdi
   0x0000000000401323 <+8>:     add    rdx,0x1
   0x0000000000401327 <+12>:    mov    eax,edx
   0x0000000000401329 <+14>:    sub    eax,edi
   0x000000000040132b <+16>:    cmp    BYTE PTR [rdx],0x0
   0x000000000040132e <+19>:    jne    0x401323 <string_length+8>
   0x0000000000401330 <+21>:    repz ret 
   0x0000000000401332 <+23>:    mov    eax,0x0
   0x0000000000401337 <+28>:    ret    
End of assembler dump.

尝试反汇编为 C 代码:
1)返回值类型:看到了对 eax 寄存器的操作。基本上是 int 类型。C代码为:

int string_length()
{
    ...
}

2)cmp BYTE PTR [rdi], 0x0: 这句是 rdi 寄存器里的值表示的内存地址里的值,和0作比较。用C代码表示为:

int string_length(const char* str)
{
    if (*str == '\0')
    {
        return 0;
    }
}
  1. je 0x401332 <string_length+23>: 和上一句连在一起的, return 0.
  2. mov rdx, rdi: 把函数第一个参数,赋值到一个新的变量里头,大概是:
int string_length(const char* str)
{
    if (*str == '\0')
    {
        return 0;
    }
    const char* ptr = str;
}
  1. add rdx, 0x1: 新赋值的变量加1:
int string_length(const char* str)
{
    if (*str == '\0')
    {
        return 0;
    }
    const char* ptr = str;
    ptr += 1;
}
  1. mov eax, edx: 把刚刚加1的变量,放到 eax 寄存器, 也就是和返回值有关系。没法直接写C代码。继续看。
  2. sub eax, edi: 让 eax 寄存器减掉 edi 寄存器。C代码:
int string_length(const char* str)
{
    if (*str == '\0')
    {
        return 0;
    }
    const char* ptr = str;
    ptr += 1;
    int ret = ptr - str;
    return ret;
}
  1. cmp BYTE PTR [rdx], 0x0: 把 rdx 寄存器里的值对应的内存地址处的值, 和0比较。看不出来C代码。继续看汇编.
  2. jne 0x401323 <string_length+8>: 如果刚刚的比较结果不相等,也就是说 [rdx] != 0, 那么跳转到 add rdx, 0x1 这句。代码:
int string_length(const char* str)
{
    if (*str == '\0')
    {
        return 0;
    }
    const char* ptr = str;
    int ret;
hello:
    ptr += 1;
    ret = ptr - str;
    if (*ptr != '\0')
    {
        goto hello;
    }
    return ret;
}
  1. repz ret: 没啥高深的,就是跳转到 ret

经过上面这段梳理,写出来的C代码很混乱。goto 和 if 的组合,基本上是等价于 while 循环:

int string_length(const char* str)
{
    if (*str == '\0')
    {
        return 0;
    }
    const char* ptr = str;
    int ret;

    do {
        ptr += 1;
        ret = ptr - str;
    } while (*ptr != '\0')
    return ret;
}

再进一步, 感觉 ret 的赋值做了重复计算, do while 也不如 while 直接:文章来源地址https://www.toymoban.com/news/detail-791302.html

int string_length(const char* str)
{
    if (*str == '\0')
    {
        return 0;
    }
    const char* ptr;
    for (ptr = str + 1; ptr != '\0'; ptr++);
    return ptr - str;
}

到了这里,关于CSAPP - 反编译 string_length的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • UE4 Linux交叉编译Clang下载

    必需软件 操作系统 Ubuntu 20.04 (5.0), Ubuntu 22.04 (5.0.2+) 编译器 clang 13.0.1 IDE Visual Studio Code、CLion、QtCreator 推荐开发硬件 处理器 Intel四核处理器或AMD,2.5 GHz或更快 内存 32 GB RAM 显卡 NVIDIA GeForce 960 GTX或更高版本,带最新NVIDIA二进制驱动程序 显存RAM 8 GB或更高 RHI版本 Vulkan:  AMD(

    2024年02月09日
    浏览(44)
  • UE4.27 编译及打包HTML5相关资料

    https://docs.unrealengine.com/4.27/zh-CN/SharingAndReleasing/HTML5/GettingStarted/ UE4.27可以打包HTML5啦 https://github.com/Xi3Chen/UE4.27PackingH5DDoc https://blog.csdn.net/mrbaolong/article/details/131732174?spm=1001.2014.3001.5501

    2024年02月13日
    浏览(46)
  • 【UE4 C++】02-编译、生成当前的C++程序

    编译快捷键: Ctrl+F7  如果不使用快捷键,可以点击顶部菜单栏中的下拉按钮,然后选择自定义 点击添加命令  点击“生成”,选择编译“”,点击“确定” 此时可以看到顶部菜单栏多了一个用于编译的按钮 鼠标右键点击“VirtusCourse”,然后点击生成  生成结果如下    双

    2024年02月16日
    浏览(41)
  • VS2022(V17.6.4)编译UE4源码配置文件(源码包含自编译CEF)

    https://note.youdao.com/s/BwQ80dXk

    2024年02月08日
    浏览(37)
  • UE4无法编译项目。是否要在Visual Studio中打开

    一开始是没装Visual Studio。安装完成后想创建C++项目出现如下报错。 无法编译该项目。要在Visual Studio中打开它吗? Running E:/Epic Games/UE_4.27/Engine/Binaries/DotNET/UnrealBuildTool.exe Development Win64 -Project=\\\"E:/Epic Games/UE_4.27/UnrealProjects/我的项目4/我的项目4.uproject\\\" -TargetType=Editor -Progress -NoE

    2024年02月03日
    浏览(62)
  • 虚幻引擎UE4源码编译安装(x86,arm64平台)

    (1)关于运行Setup.sh脚本,mono报错,详情截图如下: 分析:不能执行二进制文件mono,根据错误提示找到源码中涉及到具体执行语句为: “mono Engine/Binaries/DotNET/GitDependencies.exe $ARGS”         GitDependencies.exe可执行文件的作用在线下载UE依赖库,而mono是跨平台.net运行环境,

    2024年02月06日
    浏览(94)
  • UE4_UE5源码编译及发布LinuxServer

    :::tip 情景内容 需要开发专用服务器 需要将Server发到云端Linux系统主机 需要关闭SSH,服务一直启用 需要使用UE4 ::: :::danger UE5.1补充内容 准备UE5.1 源码 准备VS2022 准备Linux交叉编译器-v20版本 ::: 1. Visual Studio 2019 1.1 下载 Visual Studio :::warning UE4 编译源码可以使用 VS2022 ,但就此博客

    2024年02月07日
    浏览(38)
  • UE4.27.2 源码使用 VS2022 编译时出现的错误的解决方法

    Fstring 的获得指针的函数是 nodiscard 的,但是目前这个表达式是可能 discard 的 https://forums.unrealengine.com/t/build-from-source-fails-with-errors-c4834-and-msb3073/1266696/4 我遇到的错误如下 这应该是说明 10.0.22621.0 是不适用的 我在网上看到了别人的解决办法是只保留 Win 10 的 SDK,不要 Win 11 的

    2024年02月07日
    浏览(61)
  • 关于UE4/UE5 无法正确使用VS2019进行编译运行(乱码报错)

            这是一个让我百思不得其解的问题,无论是上网查资料还是怎样去调整设置。总是感觉无法正确、彻底的解决。         通过学习,发现问题唯一的根源其实是VS的语言设置与你电脑系统的语言设置不兼容。我们只需要对系统的区域语言进行更改即可正常运行。如果

    2024年02月11日
    浏览(48)
  • ubuntu18.04源码编译安装carla0.9.13,关联UE4.26虚幻引擎账号

    参考博客:https://www.cnblogs.com/chenjian688/p/16624095.html 查看推荐显卡 找到recommended推荐的版本,本机是470版本。 本机是470版本 如果安装失败,需要在安装之前进行 sudo apt-get update 指令 同时为了避免UE和 CARLA 依赖项之间的兼容性问题,使用相同的编译器版本和 C++ runtime library来编

    2024年02月14日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包