【问题标题】:Save CPU registers to variables in GCC将 CPU 寄存器保存到 GCC 中的变量
【发布时间】:2014-07-06 05:04:48
【问题描述】:

我想获取 EAX/EBX/ESP/EIP 等中的值并将它们保存在 C 变量中。例如:

int cEax;
asm("mov cEax,%eax"); ...

【问题讨论】:

  • 您需要提供更多详细信息:您使用的是什么编译器? 32位还是64位?最重要的是,您实际上想要完成什么?仅仅说“读取寄存器”并没有多大意义。查看您的“示例”,变量 cEax 当前可能位于 eax 寄存器中。让你的 asm 语句毫无意义。
  • 我想用 32 位 gcc 获取寄存器和标志。我想要打印寄存器(esp,eip,eax,...)
  • asm("movl $0x12, %ecx"); asm("":"=c"(ecx));
  • @user3808900 如果您找到了完成此任务所需的正确技术,为什么不将您的知识写下来并作为自我回答发布呢?这是允许和欢迎的。
  • 我要显示eip的值。这是我的问题。

标签: c gcc assembly x86 inline-assembly


【解决方案1】:

你可以用这个

register int eax asm("eax");
register int eax asm("ebx");
register int eax asm("esp");
//...
int cEax = eax;
int cEbx = ebx;
int cEsp = esp;
//...

您也可以像使用任何其他变量一样在表达式中使用这些寄存器,或者直接使用该寄存器的值而不分配给其他变量。

在没有内联汇编的情况下获取 eip 更加棘手,但在 gcc 中,您可以使用 __builtin_return_addresslabel as values 扩展名来获取它。

void* getEIP()
{
    return __builtin_return_address(0);
}

void *currentInstruction = getEIP();
currentAddr: void *nextInstruction = &&currentAddr;

如果你想要内联汇编你可以使用this page中的方式

【讨论】:

  • 在 x86_64 中使用 RIP 相对寻址来获取指令地址要容易得多
  • 嗨@LưuVĩnhPhúc,我已经编译了代码,但收到了这个错误。 user@linux:~/c$ gcc eip2.c eip2.c:9:28: error: initializer element is not constant void *currentInstruction = getEIP(); ^~~~~~ eip2.c:10:12: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘:’ token currentAddr: void *nextInstruction = &&currentAddr; ^ user@linux:~/c$
  • 您在这里使用register asm 只是因为或多或少的运气。 GCC 的 Local Register Variables 不支持您正在做的事情。唯一保证使用寄存器的点是作为扩展内联汇编模板的输入、输出、输入/输出操作数。根据文档此功能唯一受支持的用途是在调用扩展 asm(请参阅扩展 Asm)时为输入和输出操作数指定寄存器
猜你喜欢
  • 1970-01-01
  • 2015-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-04
  • 2021-03-25
相关资源
最近更新 更多