AddressSanitizer 中的“影子字节”是什么?我应该如何解释它们?

2024-03-19

我正在调试 C 程序并且严重困惑当发现问题时,大约是 AddressSanitizer 输出的下半部分。让我们以此为例:

==33184==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000005 at pc 0x55f312fe2509 bp 0x7ffc99f5f5c0 sp 0x7ffc99f5f5b0
WRITE of size 1 at 0x602000000005 thread T0
    #0 0x55f312fe2508 in main /home/user/c/friends/main.c:20
    #1 0x7fa5ea0e9b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #2 0x55f312fe21c9 in _start (/home/user/c/friends/cmake-build-debug/friends+0x11c9)

0x602000000005 is located 11 bytes to the left of 5-byte region [0x602000000010,0x602000000015)
allocated by thread T0 here:
    #0 0x7fa5eb2b8b40 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb40)
    #1 0x55f312fe23f4 in main /home/user/c/friends/main.c:18
    #2 0x7fa5ea0e9b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/user/c/friends/main.c:20 in main

  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000:[fa]fa 05 fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==33184==ABORTING

这条线以上的所有内容,我理解: SUMMARY: AddressSanitizer: heap-buffer-overflow /home/user/c/friends/main.c:20 in main

我的问题涉及该行下方提供的数据。我读这个答案 https://stackoverflow.com/questions/59644114/addresssanitizer-heap-buffer-overflow-address-does-not-match-shadow-bytes-addre但它没有回答我的问题。 ASAN 显示的内存转储如下所示:

  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000:[fa]fa 05 fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  1. 带箭头的线想告诉我什么?我的假设是05之间出现的fas 指的是0x602000000005 is located 11 bytes to the left of 5-byte region“5 字节区域。”然而我还是很困惑,因为传说是这样说的fa意思是“堆离开红区”,但它看起来向右 of the 05 and在它的左边。为什么没有“堆右红区”?

  2. 在此示例中,ASAN 表示程序超出了 5 字节区域 11 字节,但它显示了更多内容fa比那。

  3. 是否有任何正确、详细的文档实际上解释了这些术语“heap left redzone”、“stack mid redzone”、“Global redzone”等的含义?我还没找到。

  4. 在这种情况下,什么是“影子字节/地址”?


AddressSanitizer 中的“影子字节”是什么?我应该如何解释它们?

来自地址消毒算法 https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithmGitHub 上的页面(也可以从LLVM AddressSanitizer 页面 http://clang.llvm.org/docs/AddressSanitizer.html):

虚拟地址空间分为 2 个不相交的类:

  • 主应用程序内存 (Mem):该内存由常规应用程序代码使用。
  • 影子内存(Shadow):该内存包含影子值(或元数据)。影子和主应用内存之间存在对应关系。中毒主存中的一个字节意味着将一些特殊值写入相应的影子内存中。

因此,“影子字节”是描述程序可寻址内存状态的元数据。

如果我们看一下 asan 输出:

Shadow byte legend (one shadow byte represents 8 application bytes):

它告诉我们十六进制转储是影子内存,它描述了程序“真实”内存的状态。它跟踪哪些州?

  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  ...

因此,如果整个 8 字节线是可寻址的,则跟踪(或阴影)它的阴影字节应该具有值00。如果它是部分可寻址的,则影子字节将是01..07,这大概是行中可寻址字节的数量。

十六进制转储指向您的值是fa,或“堆左红区” - 大概这是堆分配周围的某种保护区,用于检测溢出。

来自同一链接:

运行时库取代了 malloc 和 free 函数。 malloc 区域(红色区域)周围的内存中毒了

更广泛地说,这个描述(在程序地址中)

0x602000000005 is located 11 bytes to the left of 5-byte region
  [0x602000000010,0x602000000015)

与所示的阴影贴图匹配:

=>0x0c047fff8000:[fa]fa 05 fa ...

假设自然对齐,

  • 影子字节0x0c047fff8000描述(或者,再次,影子)程序地址0x602000000000..0x602000000007其中包括您访问的地址
  • 下一个影子字节位于0x0c047fff8001描述程序地址0x602000000008..0x60200000000F
  • 两者都有价值fa,意思是“堆离开红区”
  • the next影子字节位于0x0c047fff8002描述程序地址0x602000000010..0x602000000007并且有价值05,意味着 5 个字节是可寻址的。这些是堆分配的 5 个字节。

所有这些都与您的错误部分一致did理解。

  1. 然而,我仍然很困惑,因为传说中 fa 的意思是“堆左红区”,但它似乎向右 of the 05 and在它的左边。为什么没有“堆右红区”?

    我不知道方向性在这里到底意味着什么。堆最初通常沿一个方向增长(传统上,随着堆栈向下增长而向上),但可以分段、释放、合并和重新分配。两个分配之间的间隔是“右”还是“左”,或者两者都存在,或者两者都不存在?我们需要知道的是,这是一个从未分配给用户的有毒堆区域。

    如果没有与堆栈左/中/右值相对应的方向,也许它应该只是“堆红区”。

  2. 在此示例中,ASAN 表示程序超出了 5 字节区域 11 字节,但它显示的 fas 远多于此。

    each fa代表八个字节,正如传说中所说。因此,如果您在分配之前访问了九到十五个字节的任何内容(模算术错误),它将显示在同一个影子字节中。如果您之前访问过一到八个字节,它会显示在next影子字节(就在05).

    剩下的fas 只是周围区域的地图,在这种情况下似乎没有帮助,但在其他情况下可能有用。

  3. 是否有任何正确、详细的文档实际上解释了这些术语“heap left redzone”、“stack mid redzone”、“Global redzone”等的含义?

    不知道。不过,它们似乎从用例中相当自然地遵循 - 你到达了红色区域 = 你访问了一个你不应该访问的地址。您始终可以只阅读代码,例如。asan_internal.h https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/asan/asan_internal.h定义了kAsanHeapLeftRedzoneMagic值,以及asan_allocator.cpp https://github.com/llvm/llvm-project/blob/master/compiler-rt/lib/asan/asan_allocator.cpp用它来毒害影子字节。

  4. 在这种情况下,什么是“影子字节/地址”?

    为了完整起见,影子字节是一个字节shadows一组八个通常可访问的程序字节,并跟踪有关它们的一些信息,这些信息对消毒程序有用。

    影子地址是影子字节的地址。

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

AddressSanitizer 中的“影子字节”是什么?我应该如何解释它们? 的相关文章

  • 访问私人成员[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 通过将类的私有成员转换为 void 指针 然后转换为结构来访问类的私有成员是否合适 我认为我无权修改包含我需要访问的数据成员的类 如果不道德 我
  • 获取按下的按钮的返回值

    我有一个在特定事件中弹出的表单 它从数组中提取按钮并将标签值设置为特定值 因此 如果您要按下或单击此按钮 该函数应返回标签值 我怎样才能做到这一点 我如何知道点击了哪个按钮 此时代码返回 DialogResult 但我想从函数返回 Tag
  • C++ 子字符串返回错误结果

    我有这个字符串 std string date 20121020 我正在做 std cout lt lt Date lt lt date lt lt n std cout lt lt Year lt lt date substr 0 4 l
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • Newtonsoft JSON PreserveReferences处理自定义等于用法

    我目前在使用 Newtonsoft Json 时遇到一些问题 我想要的很简单 将要序列化的对象与所有属性和子属性进行比较以确保相等 我现在尝试创建自己的 EqualityComparer 但它仅与父对象的属性进行比较 另外 我尝试编写自己的
  • 在 Visual Studio 2008 上设置预调试事件

    我想在 Visual Studio 中开始调试程序之前运行一个任务 我每次调试程序时都需要运行此任务 因此构建后事件还不够好 我查看了设置的 调试 选项卡 但没有这样的选项 有什么办法可以做到这一点吗 你唯一可以尝试的 IMO 就是尝试Co
  • C 预处理器库

    我的任务是开发源分析工具C程序 并且我需要在分析本身之前预处理代码 我想知道什么是最好的图书馆 我需要一些重量轻 便于携带的东西 与其推出自己的 为什么不使用cpp这是的一部分gcc suite http gcc gnu org onlin
  • Web API - 访问 DbContext 类中的 HttpContext

    在我的 C Web API 应用程序中 我添加了CreatedDate and CreatedBy所有表中的列 现在 每当在任何表中添加新记录时 我想填充这些列 为此目的我已经覆盖SaveChanges and SaveChangesAsy
  • 如何返回 json 结果并将 unicode 字符转义为 \u1234

    我正在实现一个返回 json 结果的方法 例如 public JsonResult MethodName Guid key var result ApiHelper GetData key Data is stored in db as v
  • 从路径中获取文件夹名称

    我有一些路c server folderName1 another name something another folder 我如何从那里提取最后一个文件夹名称 我尝试了几件事 但没有成功 我只是不想寻找最后的 然后就去休息了 Thank
  • 在 Mac 上使用 Eclipse 进行 C++ 调试器

    当我最终设置我的 mac 来使用 eclipse 后 我无法调试 我尝试通过谷歌寻求帮助 但没有一个答案对我有用 所以 我需要有人帮助我在 eclipse 上安装和使用 c c 调试器 我安装了 Xcode 5 0 感谢您的帮助 Roy 您
  • 当操作繁忙时,表单不执行任何操作(冻结)

    我有一个使用 C 的 WinForms 应用程序 我尝试从文件中读取一些数据并将其插入数据表中 当此操作很忙时 我的表单冻结并且无法移动它 有谁知道我该如何解决这个问题 这可能是因为您在 UI 线程上执行了操作 将文件和数据库操作移至另一个
  • C++ fmt 库,仅使用格式说明符格式化单个参数

    使用 C fmt 库 并给定一个裸格式说明符 有没有办法使用它来格式化单个参数 example std string str magic format 2f 1 23 current method template
  • 为什么 C# Math.Ceiling 向下舍入?

    我今天过得很艰难 但有些事情不太对劲 在我的 C 代码中 我有这样的内容 Math Ceiling decimal this TotalRecordCount this PageSize Where int TotalRecordCount
  • 为什么我收到“找不到编译动态表达式所需的一种或多种类型。”?

    我有一个已更新的项目 NET 3 5 MVC v2 到 NET 4 0 MVC v3 当我尝试使用或设置时编译出现错误 ViewBag Title财产 找不到编译动态表达式所需的一种或多种类型 您是否缺少对 Microsoft CSharp
  • Process.Start 阻塞

    我正在调用 Process Start 但它会阻止当前线程 pInfo new ProcessStartInfo C Windows notepad exe Start process mProcess new Process mProce
  • x86 上未对齐的指针

    有人可以提供一个示例 将指针从一种类型转换为另一种类型由于未对齐而失败吗 在评论中这个答案 https stackoverflow com questions 544928 reading integer size bytes from a
  • C 中的异或运算符

    在进行按位操作时 我在确定何时使用 XOR 运算符时遇到一些困难 按位与和或非常简单 当您想要屏蔽位时 请使用按位 AND 常见用例是 IP 寻址和子网掩码 当您想要打开位时 请使用包含或 然而 XOR 总是让我明白 我觉得如果在面试中被问
  • 限制C#中的并行线程数

    我正在编写一个 C 程序来生成并通过 FTP 上传 50 万个文件 我想并行处理4个文件 因为机器有4个核心 文件生成需要更长的时间 是否可以将以下 Powershell 示例转换为 C 或者是否有更好的框架 例如 C 中的 Actor 框
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我

随机推荐

  • NoSql DB 和 OO Db 有什么区别?

    NoSql DB 和 OO Db 有什么区别 NoSQL DB 通常是非规范化的 保存对象数据的副本来代替对象 而 OODB 是具有对象关系的规范化数据库 在 OODB 中 数据存储在对象中的一处 并链接 关系 到其他对象 由于上述非规范化
  • 自定义 MKAnnotation 按钮

    I d like to generate a custom annotation using MKAnnotation annotationView image UIImage named annotation this is to set
  • rmarkdown:手动指定pandoc路径?

    我有一个定期渲染的 rmarkdown 文档rmarkdown render 它在我的计算机 Windows 上运行良好 因为我安装了 RStudio 并且它自动设置了 pandoc 的路径 但是 当我尝试在我的服务器 RStudio 外部
  • 如何使用定时器动态调整帧大小?

    我正在尝试使用 Timer 对象动态调整窗口大小 但没有成功 我在构造函数中设置了面板的首选大小 这很好地设置了窗口的大小 尽管只有一次 程序初始化后首选大小会发生变化 但窗口大小保持不变 为什么 因为构造函数只初始化一次 因此不受大小变化
  • 如何在 AWS Glue 中设置多个 --conf 表参数?

    AWS Glue 的 stackoverflow 上的多个答案都说要设置 conf 表参数 但是 有时在一项作业中 我们需要在一项作业中设置多个 conf 键值对 我尝试了以下方法来设置多个 conf 值 所有这些都会导致错误 添加另一个名
  • 实现游程编码

    我编写了一个程序来执行游程编码 在典型情况下 如果文本是 AAAAAABBCDEEEEGGHJ 游程长度编码将使其 A6B2C1D1E4G2H1J1 但它为每个非重复字符添加了额外的 1 因为我用它压缩 BMP 文件 所以我想到了放置一个标
  • GPS 位置未正确检索

    我是 Android 开发新手 我了解 Android 活动生命周期 请看下面的代码 public class MyTest extends Activity Override public void onCreate Bundle sav
  • *.suo 文件中实际包含什么?

    我读过有关解决方案用户选项文件的 MSDN 文章 https msdn microsoft com en us library bb165909 aspx 解决方案用户选项文件用于存储用户首选项设置 并在 Visual Studio 保存解
  • 对具有相似名称的多组列使用相同的 mutate

    想象一下以下数据 data lt tribble a1 a2 b1 b2 c1 c2 32 32 50 12 12 50 48 20 55 43 10 42 对于 i 1 2 我想计算deltai ai ci ai bi ci ai 我明确
  • TCP/IP 套接字是原子的吗?

    据我了解 如果写入的数据量很小 则对 TCP IP 套接字的写入将是原子的 我所说的原子性是指接收者将接收所有数据或不接收任何数据 但是 如果写入的数据量很大 则它不是原子的 我对么 如果是的话 什么算大呢 谢谢 鲍勃 不 TCP 是一种字
  • Executor 和 ExecutorService 有什么区别? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我想知道 Executor 和 Ex
  • 在 BlackBerry 中单击事件期间更改 ButtonField 背景

    在 BlackBerry 中 如何更改ButtonField点击事件期间的背景颜色 例如 对于长按 背景颜色需要改变 对我来说 它采用默认颜色蓝色 如何改变呢 这是我们的自定义按钮字段 但它显示按钮单击事件的默认蓝色 public clas
  • 高效地从TextureView获取Bitmap

    我试图从一个TextureView 不幸的是尝试 textureView getBitmap 导致性能缓慢是否有更快的方法来获取位图 使用 NDK 是否更好 寻找实际例子 TextureView 接收 SurfaceTexture 上的帧
  • 当前对控制器类型 {1} 上的操作 {0} 的请求不明确

    我有两个动作 我想要我的路线 users and users id 与众不同 然而它给我带来了错误 是否可以在不手动创建的情况下实现这种事情every路线 我将有其他控制器将遵循类似的模式 并为所有这些控制器编写自定义路线 一般来说似乎是多
  • 请求网站时,Javascript 用户代理 (ajax) 与发送的用户代理不同

    我注意到我的手机 OnePlus 3 Android 8 0 0 上的 Chrome 64 0 3282 137 在请求网页时发送的用户代理与通过 ajax 发送的请求略有不同 该用户代理在请求网页时发送 Mozilla 5 0 Linux
  • 将字符串转换为 React JSX

    Goal 我想将包括 React 组件的字符串转换为功能齐全的 JSX 更简单的例子是这样的 Stack Overflow 上有很多解决方案 render let txt span b Hello World b span return d
  • 如何检查输入值是否在数组中(Powershell)

    InputArray a e i o u 1 2 3 4 5 UserInput Enter any value 我们如何检查 UserInput is in InputArray或不提示输入正确 Use the contains操作员 I
  • 在 r 中创建一个基于其他列自动递增的列

    我的数据框有客户 ID 产品和日期 我需要创建一个列 每次 customerID 或日期更改时都会生成交易 ID 我的数据框目前看起来像 客户 ID 产品 日期 23 abv 12 12 14 23 政府飞行服务处 12 12 14 18
  • 如何使用 Firebase Cloud Messaging 将推送通知发送到多个设备

    我正在寻找一种将推送消息从我的 Express JS 服务器传递到我的离子应用程序的方法 我发现GCM 使用 GCM 我可以传递传递令牌列表的消息 如下所示 sender send message registrationTokens de
  • AddressSanitizer 中的“影子字节”是什么?我应该如何解释它们?

    我正在调试 C 程序并且严重困惑当发现问题时 大约是 AddressSanitizer 输出的下半部分 让我们以此为例 33184 ERROR AddressSanitizer heap buffer overflow on address