这是我的C程序...我试图打印出ESP、EBP和EIP。
#include <stdio.h>
int main() {
register int i asm("esp");
printf("%#010x <= $ESP\n", i);
int a = 1;
int b = 2;
char c[] = "A";
char d[] = "B";
printf("%p d = %s \n", &d, d);
printf("%p c = %s \n", &c, c);
printf("%p b = %d \n", &b, b);
printf("%p a = %d \n", &a, a);
register int j asm("ebp");
printf("%#010x <= $EBP\n", j);
//register int k asm("eip");
//printf("%#010x <= $EIP\n", k);
return 0;
}
我对ESP和EBP没有问题。
user@linux:~# ./memoryAddress
0xbffff650 <= $ESP
0xbffff654 d = B
0xbffff656 c = A
0xbffff658 b = 2
0xbffff65c a = 1
0xbffff668 <= $EBP
user@linux:~#
但是当我尝试添加EIP代码时,在编译它时出现了以下错误。
user@linux:~# gcc memoryAddress.c -o memoryAddress -g
memoryAddress.c: In function ‘main’:
memoryAddress.c:20:15: error: invalid register name for ‘k’
register int k asm("eip");
^
user@linux:~#
这段代码有哪些问题?
register int k asm("eip");
printf("%#010x <= $EIP\n", k);
是否可以通过C编程打印出EIP值?
如果是,请告诉我如何做到。
更新
我已在此处测试了代码...
user@linux:~/c$ lscpu
Architecture: i686
CPU op-mode(s): 32-bit
Byte Order: Little Endian
感谢@Antti Haapala和其他人的帮助。 代码可以工作...但是,当我将其加载到GDB中时,EIP值不同。
(gdb) b 31
Breakpoint 1 at 0x68f: file eip.c, line 31.
(gdb) i r $eip $esp $ebp
The program has no registers now.
(gdb) r
Starting program: /home/user/c/a.out
0x00000000 <= Low Memory Address
0x40055d <= main() function
0x4005a5 <= $EIP 72 bytes from main() function (start)
0xbffff600 <= $ESP (Top of the Stack)
0xbffff600 d = B
0xbffff602 c = A
0xbffff604 b = 2
0xbffff608 a = 1
0xbffff618 <= $EBP (Bottom of the Stack)
0xffffffff <= High Memory Address
Breakpoint 1, main () at eip.c:31
31 return 0;
(gdb) i r $eip $esp $ebp
eip 0x40068f 0x40068f <main+306>
esp 0xbffff600 0xbffff600
ebp 0xbffff618 0xbffff618
(gdb)
这里是新的代码。
#include <stdio.h>
#include <inttypes.h>
int main() {
register int i asm("esp");
printf("0x00000000 <= Low Memory Address\n");
printf("%p <= main() function\n", &main);
uint32_t eip;
asm volatile("1: lea 1b, %0;": "=a"(eip));
printf("0x%" PRIx32 " <= $EIP %" PRIu32 " bytes from main() function (start)\n",
eip, eip - (uint32_t)main);
int a = 1;
int b = 2;
char c[] = "A";
char d[] = "B";
printf("%#010x <= $ESP (Top of the Stack)\n", i);
printf("%p d = %s \n", &d, d);
printf("%p c = %s \n", &c, c);
printf("%p b = %d \n", &b, b);
printf("%p a = %d \n", &a, a);
register int j asm("ebp");
printf("%#010x <= $EBP (Bottom of the Stack)\n", j);
printf("0xffffffff <= High Memory Address\n");
return 0;
}
printf("%p\n", &main);
。 - Ped7gregister int j asm("ebp");
并不能保证变量j
中一定包含 EBP 的值,除非它被用作扩展内联汇编模板的输入(或输入/输出)限制条件。这里它能正常工作更像是偶然。GCC 文档特别指出了这一点。 - Michael Petch