【问题标题】:Error with address for jmp in inline assembly内联汇编中 jmp 的地址错误
【发布时间】:2015-01-02 07:45:02
【问题描述】:

我做的是

  1. 获取ExitProcess的地址
  2. 为操作码腾出空间
  3. 修改空间中的操作码
  4. 执行__asm__ ("jmp %%ecx"::"c"(opcode));修改的操作码

这是我的代码:

#include <windows.h>
#include <stdio.h>
int main()
{
  char addr[4];
  *(int*)addr = GetProcAddress(GetModuleHandle("kernel32.dll"),"ExitProcess");

  //push 0 == 0x6a 0x00
  //call ExitProcess == 0xe8 0xd8 0x79 0xa2 0x75
  char opcode[400] = {0x6a, 0x00, 0xe8,addr[0], addr[1],addr[2],addr[3]};
  __asm__ ("jmp %%ecx" ::"c"(opcode));


  //never be here
  printf("never get here");
  getchar();
  return 0;
}

我希望程序正常退出,但程序因分段错误而终止。

它似乎跳转到某个地方,但没有跳转到我希望它跳转的位置。

我该如何解决这个问题?

【问题讨论】:

  • 你有没有用调试器检查它跳转到哪里?
  • 不能通过调用jmp来调用函数。必须先设置堆栈帧和相应的寄存器。
  • @thang 感谢您的评论。但我想我没有跳转到 ExitProcess 而是跳转到调用 ExitProcess 的地方
  • @MohitJain gdb 说asm之前的eip是0x4016ce;在 asm 是 0x28fd2c 之后,我没有得到我必须纠正的内容
  • 你不能跳转到操作码。那不在代码空间中。为什么不直接调用ExitProcess?这个问题的动机是什么?这看起来像是 X-Y 问题 (meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。

标签: c assembly x86 segmentation-fault inline-assembly


【解决方案1】:

把你想做的奇怪的事情放在一边……

您的问题是操作码 e8 是相对跳转。因此,您需要考虑存储它的地址。可能是这样的:

更新:每 taeyun,请考虑 x 的长度。

#include <windows.h>
#include <stdio.h>

#pragma pack(1)

struct mfoo {
  unsigned char x[3] = {0x6a, 0x00, 0xe8};
  void *addr;
} foo;

int main()
{
  unsigned char *a = (unsigned char *)GetProcAddress(GetModuleHandle("kernel32.dll"),"ExitProcess");
  foo.addr = (void *)(a - sizeof(foo) - (unsigned char *)foo.x);

  __asm__ ("jmp *%%ecx" ::"c"(&foo));


  //never be here
  printf("never get here");
  getchar();
  return 0;
}

【讨论】:

  • 经过几次修正,它可以工作了!多谢。 foo.x 的地址必须是 +7
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-23
  • 2019-03-17
  • 2013-03-25
  • 1970-01-01
  • 2017-02-02
相关资源
最近更新 更多