如何找到 PIE 二进制文件的加载重定位?

2023-12-07

我需要获取正在运行的进程中堆栈的基地址。这将使我能够打印 addr2line 可以理解的原始堆栈跟踪(运行的二进制文件被剥离,但 addr2line 可以访问符号)。 我设法通过检查 elf header 来做到这一点argv[0]:我读取入口点并将其从中减去&_start:

#include <stdio.h>
#include <execinfo.h>
#include <unistd.h>
#include <elf.h>
#include <stdio.h>
#include <string.h>
void* entry_point = NULL;
void* base_addr = NULL;
extern char _start;

/// given argv[0] will populate global entry_pont
void read_elf_header(const char* elfFile) {
  // switch to Elf32_Ehdr for x86 architecture.
  Elf64_Ehdr header;
  FILE* file = fopen(elfFile, "rb");
  if(file) {
    fread(&header, 1, sizeof(header), file);
    if (memcmp(header.e_ident, ELFMAG, SELFMAG) == 0) {
        printf("Entry point from file: %p\n", (void *) header.e_entry);
        entry_point = (void*)header.e_entry;
        base_addr = (void*) ((long)&_start - (long)entry_point);
    }
    fclose(file);
  }
}

/// print stacktrace
void bt() {
    static const int MAX_STACK = 30;
    void *array[MAX_STACK];
    auto size = backtrace(array, MAX_STACK);
    for (int i = 0; i < size; ++i) {
        printf("%p ", (long)array[i]-(long)base_addr );
    }
    printf("\n");
}

int main(int argc, char* argv[])
{
    read_elf_header(argv[0]);
    printf("&_start = %p\n",&_start);
    printf("base address is: %p\n", base_addr);
    bt();

    // elf header is also in memory, but to find it I have to already have base address
    Elf64_Ehdr * ehdr_addr = (Elf64_Ehdr *) base_addr;
    printf("Entry from memory: %p\n", (void *) ehdr_addr->e_entry);

    return 0;
}

示例输出:

Entry point from file: 0x10c0
&_start = 0x5648eeb150c0
base address is: 0x5648eeb14000
0x1321 0x13ee 0x29540f8ed09b 0x10ea 
Entry from memory:  0x10c0

然后我就可以

$ addr2line -e a.out 0x1321 0x13ee 0x29540f8ed09b 0x10ea
/tmp/elf2.c:30
/tmp/elf2.c:45
??:0
??:?

如何在不访问的情况下获取基地址argv?我可能需要先打印痕迹main()(全局变量的初始化)。无法选择转向 ASLR 或 PIE。


如何在不访问 argv 的情况下获取基地址?我可能需要在 main() 之前打印痕迹

有以下几种方法:

  1. If /proc已安装(几乎总是如此),您可以从中读取 ELF 标头/proc/self/exe.
  2. 你可以使用dladdr1(),正如安蒂·哈帕拉的回答所示。
  3. 你可以使用_r_debug.r_map,它指向加载的ELF图像的链表。该列表中的第一个条目对应于a.out,及其l_addr包含您正在寻找的搬迁。该解决方案相当于dladdr1,但不需要链接libdl.

你能提供3的示例代码吗?

Sure:

#include <link.h>
#include <stdio.h>

extern char _start;
int main()
{
  uintptr_t relocation = _r_debug.r_map->l_addr;
  printf("relocation: %p, &_start: %p, &_start - relocation: %p\n",
         (void*)relocation, &_start, &_start - relocation);
  return 0;
}

gcc -Wall -fPIE -pie t.c && ./a.out
relocation: 0x555d4995e000, &_start: 0x555d4995e5b0, &_start - relocation: 0x5b0

2 和 3 的便携性相同吗?

我认为它们同样具有便携性:dladdr1是 Solaris 上也存在的 GLIBC 扩展。_r_debug早于 Linux,并且也可以在 Solaris 上运行(我没有实际检查过,但我相信它会)。它也可以在其他 ELF 平台上运行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何找到 PIE 二进制文件的加载重定位? 的相关文章

  • 具有多个谓词的 C++11 算法

    功能如std find if来自algorithmheader 确实很有用 但对我来说 一个严重的限制是我只能为每次调用使用 1 个谓词count if 例如给定一个像这样的容器std vector我想同时应用相同的迭代find if 多个
  • MSMQ接收和删除

    是否有任何选项可以在读取消息后将其从 MSMQ 中删除 比如 接收 删除可以作为原子操作运行吗 听起来您想查看下一条消息 然后在处理完成后接收它 Message message Queue Peek Queue ReceiveById me
  • DataGridView 列中的数字文本框

    我有一个DataGridView 我想要它的第一列或任何所需的列 其中有textboxes在其中 成为NUMERIC ONLY 我目前正在使用这段代码 private void dataGridViewItems EditingContro
  • 从时间列表中查找最接近的时间

    所以 这是场景 我有一个带有创建时间的文件 我想从该文件的创建时间最接近或相等的时间列表中选择一个时间 完成此操作的最佳方法是什么 var closestTime listOfTimes OrderBy t gt Math Abs t fi
  • make_shared<>() 中的 WKWYL 优化是否会给某些多线程应用程序带来惩罚?

    前几天我偶然看到这个非常有趣的演示 http channel9 msdn com Events GoingNative GoingNative 2012 STL11 Magic Secrets作者 Stephan T Lavavej 其中提
  • Elasticsearch 无法写入日志文件

    我想激活 elasticsearch 的日志 当我运行 elasticsearch 二进制文件时 我意识到我在日志记录方面遇到问题 无法加载配置 这是输出 sudo usr share elasticsearch bin elasticse
  • 在 Linux 上更快地分叉大型进程?

    在现代 Linux 上达到与 Linux 相同效果的最快 最好的方法是什么 fork execve combo 从一个大的过程 我的问题是进程分叉大约 500MByte 大 并且一个简单的基准测试只能从进程中实现约 50 个分叉 秒 比较最
  • 判断串口是普通COM还是SPP

    我正在寻找一种方法来确定 COM 是标准 COM 还是 SPP COM 也称为 COM 设备的电缆替换蓝牙适配器 我有一个可以在 USB COM gt USB 和蓝牙下工作的设备 并且蓝牙接口可以与 SPP 一起工作 我目前正在使用Syst
  • 提升mapped_file_source、对齐方式和页面大小

    我正在尝试在性能很重要的上下文中解析一些大小高达几百兆字节的文本文件 因此我使用 boostmapped file source 解析器期望源以空字节终止 因此我想检查文件大小是否是页面大小的精确倍数 如果是 则使用较慢的非内存映射方法 我
  • 如何增加ofstream的缓冲区大小

    我想增加 C 程序的缓冲区大小 以便它不会过于频繁地写入 默认缓冲区是 8192 字节 我尝试使用 pubsetbuf 将其增加到 200K 原始代码 ofstream fq fastq1 cstr ios out fastq1 is a
  • 如何设置消息队列的所有者?

    System Messaging MessageQueue 类不提供设置队列所有权的方法 如何以编程方式设置 MSMQ 消息队列的所有者 简短的答案是 p invoke 对 windows api 函数的调用MQSetQueueSecuri
  • 如何在新窗口中打开图像或pdf文件?

    我有一个 gridview 它包含文件名和文件路径 图像和 pdf 格式文件 其中我使用了模板字段 在该字段下放置了 1 个图像按钮 单击该图像按钮 即 查看 按钮 时 我想在新窗口中打开所选文件 这是我的代码 protected void
  • 是否可以在Linux上将C转换为asm而不链接libc?

    测试平台为Linux 32位 但也欢迎 Windows 32 位上的某些解决方案 这是一个c代码片段 int a 0 printf d n a 如果我使用 gcc 生成汇编代码 gcc S test c 然后我会得到 movl 0 28 e
  • 如何在 EF Core 2.1 中定义外键关系

    我的 DAL 使用 EF Core 2 1 这就是我的模型的样子 一名用户只能拥有一种角色 Role entity kind of master public class Role public int RoleId get set pub
  • 使用 Unity 在 C# 中发送 http 请求

    如何使用 Unity 在 C 中发送 HTTP GET 和 POST 请求 我想要的是 在post请求中发送json数据 我使用Unity序列化器 所以不需要 新的 我只想在发布数据中传递一个字符串并且能够 将 ContentType 设置
  • Android:ANT 构建失败,并显示 google-play-services-lib:“解析为没有项目的 project.properties 文件的路径”

    我正在尝试使用 ANT 构建我的应用程序 但在包含 google play services lib 库项目后 我惨遭失败 Step 1 我在 project properties 文件中设置了对库项目的引用 android library
  • 将日期时间显示为 MM/dd/yyyy HH:mm 格式 C#

    在数据库中 日期时间以 MM dd yyyy HH mm ss 格式存储 但是 我想以 MM dd yyyy HH mm 格式显示日期时间 我通过使用 String Format 进行了尝试 txtCampaignStartDate Tex
  • 不使用放置 new 返回的指针时的 C++ 严格别名

    这可能会导致未定义的行为吗 uint8 t storage 4 We assume storage is properly aligned here int32 t intPtr new void storage int32 t 4 I k
  • 在 C 中使用 #define 没有任何价值

    If a define没有任何价值地使用 例如 define COMMAND SPI 默认值是0吗 不 它的评估结果为零 从字面上看 该符号被替换为空 然而 一旦你有了 define FOO 预处理器条件 ifdef FOO现在将是真的 另
  • 是否可以使用 Dapper 流式传输大型 SQL Server 数据库结果集?

    我需要从数据库返回大约 500K 行 请不要问为什么 然后 我需要将这些结果保存为 XML 更紧急 并将该文件通过 ftp 传输到某个神奇的地方 我还需要转换结果集中的每一行 现在 这就是我正在做的事情 TOP 100结果 使用 Dappe

随机推荐

  • 如何使用 mechanize 库执行 HEAD 请求?

    我知道如何使用 httplib 执行 HEAD 请求 但我必须对该站点使用 mechanize 本质上 我需要做的是从标头 文件名 中获取值 而不实际下载文件 有什么建议我可以如何实现这一点吗 Mechanize 本身仅发送 GET 和 P
  • 在 OfficeJS 中,您可以检索绑定对象的范围吗?

    针对 Word Online 但任何针对 Excel PPT 的指示也会有所帮助 本质上 是否可以将绑定对象内的文本视为范围 因此 能够选择全部并将插入符移动到开头 结尾 我设想代码具有以下效果 Office select myBindin
  • 如何从 python 中的另一个 .py 文件访问全局变量?

    我创建了两个文件 当我运行时a py 结果是 1 1 这是正确的 然而 运行b py 结果是没有 我如何获取请求的值b py a py requests def set value global requests requests 1 1
  • 创建一个大的虚拟文件

    我是这个社区的新手 也是 iOS 开发的新手 我希望有人能帮助我解决一些小问题 目前我正在为自己编写一个小应用程序 它应该创建一个非常大的虚拟文件 其中包含虚拟数据或单词或任何使它变大的东西 原因是 我想单击一个按钮 应用程序应该生成一个
  • 使用另一个 data.table 中的值更新 data.table 中的值

    我有一个包含大约 2500 万行的数据集 我正在获取这些行的子集并执行一个运行良好的函数 但是 我接下来需要做的是用新值更新原始数据集中的值 同时保留其余值 我确信这很简单 但我就是无法理解它 这是我正在处理的事情的简化版本 require
  • 无需 AJAX 将 JSON 文件从 jQuery 发送到 PHP

    所以 我是 javascript jquery 的新手 但我已经使用 PHP 足够长的时间了 我知道如何使用 PHP 从输入中获取数据 这非常简单 但是当尝试使用 jQuery 执行相同操作时 如何操作却超出了我的想象 现在我有这个脚本 还
  • JavaScript 中的 PMT

    我正在尝试编写与 EXCEL PMT 函数等效的代码 在 JavaScript 中 公式如下所示 function PMT ir np pv fv ir interest rate per month np number of period
  • nextTriggerDate() 不返回“预期”值,是否有其他方法来获取重复本地通知的下一个触发日期?

    在我的应用程序中 我允许用户安排重复的本地通知 我遇到的问题 基于环顾四周的任何其他问题 是 nextTriggerDate 始终将其返回值基于当前时间而不是安排通知的时间 我看到了在通知的 userInfo 中存储 日期 值的建议 但从通
  • ASP.NET Core 2.0 MVC - 如何从视图编译中排除某些文件夹?

    这是场景 我使用这段代码https iamrufio com 2017 09 08 rendering emails with razorviewengine in net core 2 0 感谢作者 将视图呈现为字符串 用于电子邮件 但是
  • 为什么 Borland 会在不同的 C 文件中使用同一对象的多个定义进行编译,而 GCC 却不会?

    我正在研究全局变量的行为 到目前为止 我认为全局变量的多重定义是一种非法的方式 并且必须得到一个错误 但是我从 Borland C C 编译器得到了意想不到的结果 而 GCC 给了我预期的结果 Code test1 c include
  • 为什么 FirebaseAuth.getInstance().getCurrentUser() 在 android 中返回 null 值

    我正在关注使用firebase发送图像的代码 我已经配置了 firebase 存储 url 数据库 url 数据库规则 true sha1 将 google services json 放置在应用程序文件夹中 但是当我调试代码时 it 用户
  • Apache Airflow 仅向列表中的第一个人发送 SLA 未命中电子邮件

    我使用 Apache Airflow 我希望它能够在 SLA 未命中时发送电子邮件通知 我将电子邮件地址存储为气流变量 并且我有一个 dag 其任务之一使用 EmailOperator 发送电子邮件 问题来了 因为当我向所有收件人运行发送邮
  • 如何在 geo URI Intent 启动的地图中显示标记?

    我有一个应用程序 我想通过启动具有特定地理坐标的 Google 地图来显示不同的位置 一次一个 由用户输入选择 我目前正在使用这个 当然具有真实的纬度和经度值 Intent intent new Intent Intent ACTION V
  • 如何为每个列名添加后缀(或前缀)?

    我想添加 x每个列名称的后缀 如下所示 featuresA myPandasDataFrame columns values x 我该怎么做呢 另外 如果我想添加x 作为后缀 解决方案会如何变化 以下是我认为添加后缀的最好方法 df df
  • 与菜单元素中的右“左三角形”对齐

    我构建 HTML CSS JS 菜单 并希望将箭头向右对齐以指出该元素是子菜单 我的问题是 在 Firefox 中 三角形 符号 显示在下一行而不是当前行 铬在两种情况下都表现良好 BTS中存在与我的情况类似的错误 https bugzil
  • JAI:如何从多页 TIFF 图像容器中提取单页输入流?

    我有一个将 PDF 文档转换为图像的组件 每页一张图像 由于该组件使用转换器生成内存中图像 因此它会对 JVM 堆造成严重影响 并且需要一些时间才能完成转换 我正在尝试提高转换过程的整体性能 并找到了一个具有 JNI 绑定的本机库来将 PD
  • jQuery CSS 悬停

    我有一个 CSS 菜单 当鼠标悬停在它上面时设置父 li 的颜色 它是子 ul 子菜单 基本上 当您将鼠标悬停在菜单上时 它会改变颜色并保持这种状态 直到您将鼠标移开菜单及其子菜单 看起来很好 我添加了一些 jQuery 代码来更改菜单项的
  • 如何让一个视图知道另一个视图的变化?

    假设您正在制作一个音乐库应用程序 您有一个包含流派列表的视图 另一个显示所选流派的内容 当用户单击列表上的流派时 其他视图中的内容应相应更新 为了最大限度地减少依赖性 最好的方法是什么 除了绘制各个流派的视图之外 我还没有找到任何其他地方可
  • Java数组的克隆方法

    Java 中的 clone 方法在数组上使用时到底返回什么 它是否返回一个新数组 其中包含从原始数组复制的数据 Ex int a 1 2 3 int b a clone 当 的时候clone方法在数组上调用 它返回对新数组的引用 该新数组包
  • 如何找到 PIE 二进制文件的加载重定位?

    我需要获取正在运行的进程中堆栈的基地址 这将使我能够打印 addr2line 可以理解的原始堆栈跟踪 运行的二进制文件被剥离 但 addr2line 可以访问符号 我设法通过检查 elf header 来做到这一点argv 0 我读取入口点