简单的栈溢出_hello_elf

本文介绍了简单的栈溢出漏洞利用,以_hello_elf为例,涵盖了基本知识、溢出点查找和目标指令定位。通过分析32位ELF文件,展示了如何利用栈溢出获取程序控制权,最终实现远程通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简单的栈溢出_hello_elf

原文地址:https://hvnt3r.top/2018/09/%E7%AE%80%E5%8D%95%E7%9A%84%E6%A0%88%E6%BA%A2%E5%87%BA-hello-elf/

最近哥们问了我一道PWN题,觉得比较有代表性而且难度较低,就记录下来以作栈溢出的示例,仅从新手角度分析,大牛绕过

题目地址:https://pan.baidu.com/s/1Gd6u_-pRWmPsRJdlnnNYKg

0x00 基本知识

首先,要进行栈溢出的漏洞利用要理解栈的基础结构以及在计算机内的存储方式,之前就有很多大佬写过相关的文章,我也没必要造轮子,就把链接放在这里吧,我是链接,这个是百度百科上比较通用的解答,如果觉得不清楚还可以自己查阅其他的文章

0x01 起手第一步

首先一般我拿到一个二进制文件的时候会先用file命令看一下文件的类型:

☁  1  file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=547379e1b7bd695a7546d2a3321e199c0474dfa9, not stripped

这里显示这是一个32位的ELF文件,其实对于新手来说IDA_Pro的一键f5还是挺方便的,我们先把文件放到IDA里看一下:

IDA的左侧显示了一些函数的信息,双击函数后再按F5键使IDA显示出伪C代码,这里说是伪C代码是因为这些代码严格意义上不算是C代码,只是IDA为了使程序显示更接近我们的逻辑顺序而显示的一种接近于C语言格式的代码,如果可以通过自己的判断来修复一些伪C代码中的逻辑或者变量名称,可以使得代码接近于源代码,但是我们这道题不涉及修复的知识。

随便翻看一下这些函数的内容,并在脑海中大致建立一个程序的逻辑框架,看到一个read函数,不知道此函数的作用怎么办,很简单,Linux下自带命令man可与查看函数的手册

在Linux终端下输入命令:

man read

此时终端会打印出关于read函数的信息:

内容很多,感兴趣的同学可以自己敲一下试试,而我们目前只需关注一下信息:

NAME
       read - read from a file descriptor

SYNOPSIS
       #include <unistd.h>

       ssize_t read(int fd, void *buf,<
单击按键运行后输出以下信息: abort() was called at PC 0x403770d3 on core 0 --- 0x403770d3: lock_acquire_generic at D:/ESP32_2/Espressif/Espressif_V5.4.0/Espressif_IDF__PATH/v5.4/esp-idf/components/newlib/locks.c:133 Backtrace: 0x40375efd:0x3fca37e0 0x40383485:0x3fca3800 0x4038c079:0x3fca3820 0x403770d3:0x3fca3890 0x403771e9:0x3fca38c0 0x403772b3:0x3fca38e0 0x4209f533:0x3fca3910 0x4209f56f:0x3fca3950 0x4200b5e2:0x3fca3970 0x40377612:0x3fca3990 0x4037bd5d:0x3fca39c0 0x4037bdd2:0x3fca39e0 0x4037bb21:0x3fca3a00 0x420b14ec:0x3fcd70d0 0x42023c39:0x3fcd7100 0x42023c82:0x3fcd7120 0x42023d51:0x3fcd7150 0x4202899c:0x3fcd7190 0x42028f01:0x3fcd7230 0x4200b64d:0x3fcd7280 0x40383f1d:0x3fcd72b0 --- 0x40375efd: panic_abort at D:/ESP32_2/Espressif/Espressif_V5.4.0/Espressif_IDF__PATH/v5.4/esp-idf/components/esp_system/panic.c:454 0x40383485: esp_system_abort at D:/ESP32_2/Espressif/Espressif_V5.4.0/Espressif_IDF__PATH/v5.4/esp-idf/components/esp_system/port/esp_system_chip.c:92 0x4038c079: abort at D:/ESP32_2/Espressif/Espressif_V5.4.0/Espressif_IDF__PATH/v5.4/esp-idf/components/newlib/abort.c:38 0x403770d3: lock_acquire_generic at D:/ESP32_2/Espressif/Espressif_V5.4.0/Espressif_IDF__PATH/v5.4/esp-idf/components/newlib/locks.c:133 0x403771e9: _lock_acquire_recursive at D:/ESP32_2/Espressif/Espressif_V5.4.0/Espressif_IDF__PATH/v5.4/esp-idf/components/newlib/locks.c:162 0x403772b3: __retarget_lock_acquire_recursive at D:/ESP32_2/Espressif/Espressif_V5.4.0/Espressif_IDF__PATH/v5.4/esp-idf/components/newlib/locks.c:321 0x4209f533: _puts_r at /builds/idf/crosstool-NG/.build/xtensa-esp-elf/src/newlib/newlib/libc/stdio/puts.c:89 (discriminator 2) 0x4209f56f: puts at /builds/idf/crosstool-NG/.build/xtensa-esp-elf/src/newlib/newlib/libc/stdio/puts.c:129 (discriminator 1) 0x4200b5e2: encoder_event_handler at D:/ESP32_2/hello_world - 6-encoder/main/hello_world_main.c:124 0x40377612: button_isr_handler at D:/ESP32_2/hello_world - 6-encoder/main/bsp/encoder.c:44 0x4037bd5d: gpio_isr_loop at D:/ESP32_2/Espressif/Espressif_V5.4.0/Espressif_IDF__PATH/v5
最新发布
03-11
<think>嗯,用户这次遇到了一个abort()被调用的错误,导致程序崩溃。看起来错误发生在ESP32的项目里,尤其是和锁的获取有关。首先,我需要理解这个错误信息的具体含义。 用户提供的日志显示abort()在lock_acquire_generic函数中被调用,位于locks.c的第133行。回溯显示是从encoder_event_handler到button_isr_handler,再到gpio的中断处理。这说明问题可能出现在中断服务例程(ISR)中,特别是在处理按键事件时发生了锁的问题。 首先,ESP32的FreeRTOS要求ISR函数必须使用IRAM_ATTR,并且不能调用阻塞式的函数。如果button_isr_handler没有正确声明,或者在ISR中调用了不可用的函数(比如标准库的I/O操作),可能会导致锁的问题。比如,用户可能在ISR里用了printf或puts,这些函数内部会获取锁,而ISR中不允许这样做,导致abort。 接下来,查看代码中的encoder_event_handler函数,第124行调用了puts,这可能是在中断上下文中执行了非ISR安全的操作。同样,如果encoder.c的第44行的button_isr_handler没有正确使用中断安全函数,也可能引发锁的问题。 此外,另一个可能性是内存溢出或堆栈溢出,尤其是在中断处理中分配内存或使用大局部变量。但根据日志中的调用链,更可能的是锁的使用问题。 解决方法方面,首先检查button_isr_handler是否用了IRAM_ATTR修饰,并确保ISR中没有调用阻塞函数。替换puts为ESP_LOG类函数,使用中断安全的日志方法。检查是否有递归锁或死锁情况,确保所有锁操作成对出现。同时,调整堆栈大小和优化内存使用,防止溢出。 可能用户之前遇到过编译错误,已经解决了头文件的问题,现在遇到运行时错误。需要引导用户检查中断处理函数的正确性,避免在ISR中使用非安全函数,并正确使用日志系统。</think>$$abort()\ was\ called\ at\ PC\ 0x403770d3\ on\ core\ 0$$ 该错误表示程序在运行过程中触发了致命错误,导致系统调用`abort()`强制终止。结合回溯信息分析如下: --- ### 一、错误本质 1. **核心触发点** `lock_acquire_generic`函数中发生异常(位于`locks.c:133`),属于**多线程/中断场景下的资源竞争问题** 2. **关键线索** ```c Backtrace: ... encoder_event_handler -> button_isr_handler -> gpio_isr_loop ``` 错误链显示由GPIO中断处理程序(ISR)触发,最终在操作互斥锁时崩溃 --- ### 二、主要原因分析 #### 1. **中断服务程序(ISR)违规操作** - **违反FreeRTOS规则**:在中断上下文中调用了**不可重入函数**或**非ISR安全函数** - **典型违规操作**: - 在ISR中调用`malloc()`/`free()` - 使用标准I/O函数(如`printf`/`puts`,回溯显示调用了`_puts_r`) - 操作未标记`IRAM_ATTR`的中断处理函数 #### 2. **锁操作冲突** - **递归锁问题**:`_lock_acquire_recursive`表明可能存在重复加锁 - **优先级反转**:高优先级任务与中断服务程序争夺同一资源 #### 3. **内存越界** ```c encoder_event_handler at hello_world_main.c:124 ``` 可能涉及: - 缓冲区溢出 - 野指针操作 - 栈溢出(常见于中断嵌套场景) --- ### 三、解决步骤 #### 1. **检查中断服务程序** ```c // 确保ISR函数添加IRAM_ATTR修饰符 IRAM_ATTR void button_isr_handler(void* arg) { // 仅执行中断安全操作 } ``` #### 2. **替换非安全函数** ```diff - puts("message"); // 在ISR中调用危险 + ESP_DRAM_LOGI("TAG", "message"); // 使用ESP-IDF专用ISR安全日志 ``` #### 3. **验证锁操作** - 检查`encoder_config_t`结构体是否被多个任务/中断同时访问 - 使用临界区保护共享资源: ```c portENTER_CRITICAL_ISR(&spinlock); // 操作共享数据 portEXIT_CRITICAL_ISR(&spinlock); ``` #### 4. 内存问题排查 ```bash # 启用内存调试 idf.py menuconfig -> Component config -> Heap Memory Debugging -> Enable heap tracing ``` --- ### 四、高级调试建议 1. **反汇编定位** 通过PC地址`0x403770d3`结合`addr2line`工具精确定位: ```bash xtensa-esp32-elf-addr2line -pfiaC -e build/your_project.elf 0x403770d3 ``` 2. **锁状态监测** 启用FreeRTOS跟踪功能: ```c vTaskList(pcWriteBuffer); // 输出任务状态 uxTaskGetStackHighWaterMark(NULL); // 检查栈溢出 ``` 3. **中断延迟分析** 使用逻辑分析仪测量GPIO中断到回调函数的延迟,确认是否超过FreeRTOS的`configISR_STACK_SIZE`限制 --- ### 五、预防措施 1. **编码规范** ```c // 所有ISR函数必须遵循 static IRAM_ATTR void isr_handler(void* arg) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; // 仅调用xQueueSendFromISR类API portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } ``` 2. **静态检查配置** ```bash idf.py build -DCMAKE_EXPORT_COMPILE_COMMANDS=1 # 生成编译数据库 run-clang-tidy -checks='-*,esp-*' # 使用ESP-IDF专用规则检查 ``` 该问题需要结合具体业务逻辑分析,重点检查中断服务程序与共享资源的交互方式。建议优先使用`ESP-IDF`提供的线程安全API(如`atomic_compare_exchange_strong`)替代直接锁操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值