尝试对函数进行逆向工程

2023-12-11

我正在尝试更多地了解 x86 中的汇编。我这里有一个神秘的函数,我知道它返回一个int并采取int争论。 所以看起来像int mystery(int n){}。但是我无法弄清楚C 中的函数。大会是:

mov  %edi, %eax
lea  0x0(,%rdi, 8), %edi
sub  %eax, %edi
add  $0x4, %edi
callq < mystery _util >
repz retq

< mystery _util >
mov  %edi, %eax
shr  %eax
and  $0x1, %edi
and  %edi, %eax
retq

我不明白 lea 在这里做什么以及它可能具有什么样的功能。


汇编代码似乎是计算机生成的,并且可能是由 GCC 编译的,因为有一个repz retq在无条件分支之后(call)。还有迹象表明,因为没有尾部调用(jmp) 代替call当去mystery_util该代码是用-O1(更高的优化级别可能会内联该函数,但这里没有发生)。缺少帧指针和额外的加载/存储表明它不是用-O0

乘法x乘以 7 与相乘相同x乘以 8 并减去x。这就是下面的代码正在做的事情:

lea  0x0(,%rdi, 8), %edi
sub  %eax, %edi

LEA可以计算地址,但也可以用于简单的算术。内存操作数的语法是位移(基数、索引、标度)。比例尺可以是 1、2、4、8。计算公式是位移 + 基数 + 索引 * 比例尺。在你的情况下lea 0x0(,%rdi, 8), %edi实际上是 EDI = 0x0 + RDI * 8 或 EDI = RDI * 8。完整计算为 n * 7 - 4;

计算为mystery_util似乎只是

n &= (n>>1) & 1;

如果我把所有这些因素放在一起,我们就有一个函数mystery将 n * 7 - 4 传递给名为的函数mystery_util返回n &= (n>>1) & 1.

Since mystery_util返回单个位值(0 或 1) 这是合理的bool是返回类型。

我很好奇是否可以获得特定版本GCC优化级别 1 (-O1)来重现此汇编代码。我发现 GCC 4.9.x 会产生这个准确的汇编代码对于这个给定的C程序:

#include<stdbool.h>

bool mystery_util(unsigned int n)
{
    n &= (n>>1) & 1;
    return n;
}

bool mystery(unsigned int n)
{
    return mystery_util (7*n+4);
}

汇编输出为:

mystery_util:
        movl    %edi, %eax
        shrl    %eax
        andl    $1, %edi
        andl    %edi, %eax
        ret
mystery:
        movl    %edi, %eax
        leal    0(,%rdi,8), %edi
        subl    %eax, %edi
        addl    $4, %edi
        call    mystery_util
        rep ret

您可以使用此代码godbolt.


重要更新 - 不带 bool 的版本

我显然错误地解释了这个问题。我假设问这个问题的人自己确定了原型mystery was int mystery(int n)。我以为我可以改变这一点。根据一个相关问题一天后在 S​​tackoverflow 上询问,看来int mystery(int n)作为作业的一部分提供给您作为原型。这很重要,因为这意味着必须进行修改。

需要进行的更改与mystery_util。在要进行逆向工程的代码中有以下几行:

mov  %edi, %eax
shr  %eax

EDI是第一个参数。SHR是逻辑右移。编译器只会生成这个如果EDI was an unsigned int(或同等学历)。int是一个有符号类型,将生成SAR(算术右移)。这意味着参数为mystery_util必须unsigned int(因此返回值可能是unsigned int。这意味着代码将如下所示:

unsigned int mystery_util(unsigned int n)
{
    n &= (n>>1) & 1;
    return n;
}

int mystery(int n)
{
    return mystery_util (7*n+4);
}

mystery现在有你的教授给出的原型(bool被删除),我们使用unsigned int对于参数和返回类型mystery_util。为了使用 GCC 4.9.x 生成此代码,我发现您需要使用-O1 -fno-inline。该代码可以在godbolt。汇编输出与使用的版本相同bool.

如果你使用unsigned int mystery_util(int n)你会发现它并不能完全输出我们想要的:

mystery_util:
        movl    %edi, %eax
        sarl    %eax          ; <------- SAR (arithmetic shift right) is not SHR
        andl    $1, %edi
        andl    %edi, %eax
        ret
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尝试对函数进行逆向工程 的相关文章

随机推荐

  • AngularJs 中的迭代 ng-repeat 仅 X 次

    我如何使用 ng repeat 之类的for在 JavaScript 中 example div Text div 我想用 ng repeat 迭代 4 次 但我该怎么做呢 Angular 带有一个 limitTo limit 过滤器 它支
  • 导入数据时遇到错误字符 (ASCII 0)

    我正在尝试导入一些数据并收到错误 遇到错误字符 ASCII 0 我尝试导入的文件位于http commondatastorage googleapis com snksales dimdistributor csv 无法理解如何解决这个问题
  • 在Python中组合嵌套的for循环

    假设我有一个以下形式的嵌套循环 for i in List1 for j in List2 DoSomething i j 是否可以按如下方式进行 for i j in combine List1 List2 DoSomething i j
  • Application.Quit() 在 Android 上不起作用

    我试图让应用程序在您按 Android 手机的后退 返回键时自行退出 我尝试将此代码放入附加到所有场景中存在的游戏对象的脚本的更新中 因为DontDestroyOnLoad if Input GetKeyDown KeyCode Escap
  • Tensorflow,恢复特定设备中的变量

    也许我的问题有点天真 但我确实在张量流文档中没有找到任何内容 我有一个训练有素的张量流模型 它的变量被放置在 GPU 中 现在我想恢复这个模型并使用CPU进行测试 如果我通过 tf train Saver restore 执行此操作 如示例
  • .net4 的新 no pia 功能的优点是什么 [部署 PIA]

    我可能只是在这里遗漏了一些东西 但是 当我为 Excel 互操作编写一些代码时 它是这样的 我添加了对 Excel Com 库的引用 VS 创建一个 PIA Microsoft Office Interop Excel 通过 tlbimp
  • 在css中创建十字图像水印[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我的需要是创建一个如图所示的十字图像 Div 1 没有固定的高度 有时会有所不同
  • 如何在 Qt Designer 中创建圆形按钮

    我正在使用 Qt Designer 作为 GUI 创建器来开发 Python 项目 我尝试创建一个圆形按钮 但只有QPushButton 这是一个正方形 我还尝试将单击事件绑定到圆形图像 但我不知道该怎么做 您应该能够使用样式表获得圆形按钮
  • C 中的位摆弄 - 计数位

    我想计算一个非常大的位向量 即 100 000 位 中设置的位 我当前正在做的是使用指向 char 的指针 即 char cPtr 来指向位数组的开头 我然后 1 look at each element of the array i e
  • Google Docs Apps 脚本中的字数统计功能

    Google Apps 脚本中是否有一种方法可以从 Google 文档返回字数统计 假设我正在写一份对字数有特定限制的报告 它非常精确 准确地显示了 1 8k 2k 个单词 是的 这不仅仅是一个案例 而是很多 在 Microsoft Off
  • silverlight 4 中的可序列化属性

    那么 silverlight 4 中是否有 Serialized 属性呢 我在互联网上得到了一些令人困惑的答复 当我尝试在代码中使用它时 出现命名空间错误 这些是我的包含内容 using System using System Compon
  • 在 Xcode 7 中发现意外的 Mach-O 标头代码:0x72613c21

    我有一个使用 ObjC 动态框架的 Swift 项目 该框架必须与我的项目链接并嵌入到我的项目中 项目在设备上运行正常 提交到App Store时 验证时出现错误 Found an unexpected Mach O header code
  • 将 32 位 COM DLL 注册到 64 位 Windows 7

    我有一个 32 位 COM 组件 DLL 这个 DLL 是用 Delphi 编写的 它是一个 Win32 DLL 我想在 NET 平台上的 Visual C 项目中使用这个 DLL 我无法在项目中添加对此 DLL 的引用 我尝试在 Wind
  • AudioConverterFillComplexBuffer 返回 -50 (paramErr)

    我正在尝试将 PCM 32 位浮动音频流转换为 ALAC 我找到了一些可以构建的工作示例 但我自己的代码不断从 AudioConverterFillComplexBuffer 获取 50 paramErr 看到这段代码 我的眼睛都红了 我看
  • header() 不会自动重定向到另一个索引页

    当我点击登录时 它不会自动将我重定向到 home php 我必须刷新页面才能重定向我 我猜第一个 header 工作正常 因为它响应页面刷新 不起作用的是 if 语句中的第二个 header 我究竟做错了什么 非常感谢你的帮助 登录 php
  • .NET 和 C++ 应用程序之间的 IPC

    是否有用于 NET 应用程序和本机 C 应用程序之间的进程间通信 IPC 的库 可以使用Socket进行简单的通信 它位于操作系统中 因此您不需要任何新的库 详细信息在C 套接字 and C 套接字 如果进程间通信始终在同一台计算机上完成
  • 自定义组件控件不断重新创建

    我是 Firemonkey 自定义控件的新手 很抱歉 如果这是一个平庸的问题或重复的问题 但我被困住了 无法弄清楚 这是我的自定义控件的代码 unit swScheduler interface uses System SysUtils S
  • 如何显示每天的事件?

    我有一个事件页面 我需要在其中显示每天的事件 我已经做到了这一点 所以我正在进步 数据库有3个表 fairdays eventtypes events fairdays id fairdaydate 日期时间 daycolor 描述 eve
  • UIAutomator 与 espresso 一起运行

    我目前正在测试一个应设置为默认启动器的应用程序 我已经有一套了Espresso测试正在运行 但仅当用户之前选择我的应用程序作为启动器时它们才有效 向用户显示的用于选择启动器的对话框无法通过Espresso 因为它位于应用程序本身之外 然而
  • 尝试对函数进行逆向工程

    我正在尝试更多地了解 x86 中的汇编 我这里有一个神秘的函数 我知道它返回一个int并采取int争论 所以看起来像int mystery int n 但是我无法弄清楚C 中的函数 大会是 mov edi eax lea 0x0 rdi 8