【发布时间】:2017-10-22 06:54:41
【问题描述】:
编辑:我想通过插入断点并比较断点前后的内存来测试系统。
我使用静态分析来获取 C 源代码位置列表和调试信息(即 dwarf)提供了 C 源代码和可执行文件中的机器指令之间的映射。
但问题是有许多机器指令映射到一行 C 源代码,我需要对它们全部进行测试。
要测试的机器指令是修改内存状态。
所以我想通过去掉不修改内存的指令来减少指令的数量。
例如,我有以下源代码test.c,我有line number 5。
2 int var1 = 10;
3 void foo() {
4 int *var2 = (int*)malloc(sizeof(int));
5 for(*var2=var1;;) {
6 /* ... */
7 }
8 }
需要明确的是,line number 5 访问全局内存 var1 和堆内存 *var2。
我用命令gcc -g test.c编译了上面的程序,结果是
(a.out)
00000000004004d6 <foo>:
4004d6: 55 push %rbp
4004d7: 48 89 e5 mov %rsp,%rbp
4004da: 48 83 ec 10 sub $0x10,%rsp
4004de: bf 04 00 00 00 mov $0x4,%edi
4004e3: e8 d8 fe ff ff callq 4003c0 <malloc@plt>
4004e8: 48 89 45 f8 mov %rax,-0x8(%rbp)
4004ec: 8b 15 1e 04 20 00 mov 0x20041e(%rip),%edx # 600910 <var2>
4004f2: 48 8b 45 f8 mov -0x8(%rbp),%rax
4004f6: 89 10 mov %edx,(%rax)
4004f8: eb fe jmp 4004f8 <foo+0x22>
和dwarfdump -l a.out 给我以下结果。
0x004004d6 [ 3, 0] NS uri: "/home/workspace/test.c"
0x004004de [ 4, 0] NS
0x004004ec [ 5, 0] NS
0x004004f8 [ 5, 0] DI=0x1
现在我知道,在 a.out 中,位置 0x4004ec、0x4004f2、0x4004f6 和 0xf004f8 映射到 C 源代码中的 line number 5。
但我想排除不访问(堆、全局或本地)内存的0x4004f8 (jmp)。
有谁知道如何只获取访问内存的指令?
【问题讨论】:
-
您想包含隐式内存操作数,例如用于 push/pop 和 call/ret 的堆栈吗? (还有
rep movs或rep stos,gcc 有时会内联。)英特尔语法反汇编可能很方便,因为所有显式内存操作数都包含ptr,如mov rax, qword ptr [rbp - 0x8],因此您可以进行文本搜索。 -
在 asm 源代码中,
<size> ptr语法不是必需的,但像objdump -drwC -Mintel这样的反汇编程序是明确的。在 AT&T 语法中,您也可以只查找()或裸符号名称作为操作数。哦,别忘了过滤掉lea指令。lea类似于 C 中的&运算符。它是使用内存操作数语法和机器编码的移位加法指令。 -
为什么你问?请编辑您的问题以激发它并改进它!
-
闻起来很像XY problem。如果你激发了你的问题并解释了你的总体目标,你会得到更好的答案。
-
我正在攻读博士学位,但我正面临一个困难的调试问题。
标签: c gcc assembly disassembly instructions