内联汇编中jmp的地址出错

时间:2015-01-02 07:45:02

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

我的工作是

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

    这是我的代码:

    #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;
    }
    

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

    它似乎跳到某个地方,但不到我希望它跳跃的位置。

    我该如何解决?

1 个答案:

答案 0 :(得分:0)

撇开你想要做的奇怪事情......

你的问题是操作码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;
}