首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法为Linux ELF二进制文件的函数提取常量和argc

无法为Linux ELF二进制文件的函数提取常量和argc
EN

Stack Overflow用户
提问于 2021-02-18 02:10:25
回答 1查看 96关注 0票数 0

我使用的是最新版本的angr (9,0,'gitrollling')。我得到了与angr版本(9,0,4663)相同的行为。

使用gcc 9.3.0,我为这个简单的C程序创建了一个ELF二进制文件:

代码语言:javascript
复制
float func3(float y) {
  float temp = 5.5; // expected angr to find this constant
  return y + temp;
}

int main(int argc, char *argv[]) {
  float ans;
  ans = func3(2.2); // expected angr to find this constant
}

然后,我使用angr来提取函数中的常量(即'func3‘和'main')以及函数的参数数量。不幸的是,我得到的常量(下面输出中的“const”)或"argc“的答案没有任何意义。我得到了:

代码语言:javascript
复制
name main const [8, 32, 8, 32, 18446744073709551596, 18446744073709551584, 0, 4202504, 4202504,
    8, 4198767, 128, 4198697, 18446744073709551612, 0, 8, 8, 128] argc -1 

name func3 const [8, 18446744073709551596, 4202500, 4202500, 18446744073709551612,
     18446744073709551596, 0, 18446744073709551612, 8, 8, 128] argc -1 

我的angr代码:

代码语言:javascript
复制
#!/usr/bin/env python3

import angr
from angrutils import *

def get_attributes(cfg, addr):
    if addr in cfg.kb.functions:
        func = cfg.kb.functions.get_by_addr(addr)
        if func:
            name = func.demangled_name
            if name != 'main' and name != 'func3':
                return # only care about these 2 funcs
            const = func.code_constants
            argc = len(func.arguments) if func.arguments else -1
            print('  name %s const %s argc %s ' % (name, const, argc))
    return

proj = angr.Project('simple', main_opts={'backend': 'elf'}, load_options={'auto_load_libs':False})
main = proj.loader.main_object.get_symbol('main')

start_state = proj.factory.blank_state(addr=main.rebased_addr)
start_state.stack_push(0x0)
with hook0(proj):
    cfg = proj.analyses.CFGFast()  # using CFGEmulated() also does not change the answer!
    #cfg = proj.analyses.CFGEmulated(fail_fast=False, starts=[main.rebased_addr], context_sensitivity_level=1, enable_function_hints=False, keep_state=True, enable_advanced_backward_slicing=False, enable_symbolic_back_traversal=False,normalize=True)

d=dict()
for src, dst in cfg.kb.functions.callgraph.edges():
    if not d.get(src):             # only need to do this once.
        src_attr = get_attributes(cfg, src)
        d[src] = True              # mark completed
    if not d.get(dst):             # only need to do this once.
        dst_attr = get_attributes(cfg, dst)
        d[dst] = True              # mark completed

我哪里错了?

EN

回答 1

Stack Overflow用户

发布于 2021-02-28 11:21:28

我没有使用angr的经验,但基于对为您的程序生成的程序集的检查,我对哪里出了问题有一些假设:

  1. func3没有副作用,而且main不使用ans的值,所以编译器可以完全消除对func3的调用,例如,在x86-64上,我在main上得到了以下代码:

main: movl $0,%eax ret

所以常量2.2很可能根本不在可执行文件中。

  1. 浮点常量通常必须发送到内存并通过引用加载,例如,在x86-64上,我为func3获得了以下程序集:

.section .text func3: addss .LC0(%rip),%xmm0 ret .section .rodata .LC0:.long 1085276160

在完全链接的可执行文件中,交叉引用.LC0成为相对偏移量:

1125: f3 0f 58 05 d7 0e 00 00 addss 0xed7(%rip),%xmm0 112d: c3 retqIt可能无法将此偏移量识别为要提取的常量,或者它只能提取此偏移量而不能提取它所引用的.rodata中的值。即使它可以取出.rodata中的值,它知道应该将该值解释为单精度浮点数而不是整数的唯一方法是,它是否解码了使用该值的指令。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66247619

复制
相关文章

相似问题

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