【问题标题】:crafting direct jump in visual studio在视觉工作室中制作直接跳转
【发布时间】:2013-06-05 04:47:55
【问题描述】:

我想在 Visual Studio 中直接跳转。因为 Visual Studio 使用的 MASM 不支持像 jmp 0x12345678 这样的直接跳转,所以我想用它的操作码来制作这个跳转。我的代码是这样的

//0xEA = jmpf, 0x11223344 = jump target, 0x002e = code segment
unsigned char jmpf[] = {0xEA,0x44,0x33,0x22,0x11,0x2E,0x00};

//make stack executable (because of DEP)
DWORD oldprotect;
DWORD error;
VirtualProtect(&jmpf,7,PAGE_EXECUTE_READWRITE,&oldprotect);

unsigned int addr = (unsigned int)jmpf;

_asm{
    mov eax, addr
    jmp eax
}

跳转反汇编成这样:

EA 44 33 22 11 2E 00         jmp  002E:11223344 

但如果我执行此跳转,则会在读取地址 0xFFFFFFFF 时引发访问冲突异常。我不确定这个跳转与 0xFFFFFFFF 有什么关系。

我从http://ref.x86asm.net/coder32.html(命名为jmpf)获得了OP代码,从http://www.c-jump.com/CIS77/CPU/x86/lecture.html获得了代码段寄存器的编号。

有人可以帮我编码直接跳转吗?谢谢!

【问题讨论】:

  • 如果你想直接跳转到一个已知的硬编码地址而不用汇编魔法,你也可以使用((void (*)(void))0x11223344)();
  • 这组装成 mov eax,11223344h; mov esi,esp;调用 eax;没有直接跳转:(
  • 为什么必须使用直接跳转?为什么不能只使用寄存器或内存间接跳转?

标签: c assembly visual-studio-2012 x86


【解决方案1】:

要在 Visual Studio 中直接跳转,您可以先将绝对目标地址存储在变量中,然后在 asm 中使用它:

unsigned int target = 0x11223344;
__asm {
    jmp target
}

这将编译成这样:

69044B7C  - FF25 E4330669       JMP DWORD PTR DS:[test.690633E4]

这还允许您在编译时指定目标地址和变量。

至于直接跳跃...我认为没有。您提到的 0xea 是操作系统不允许您使用的一大步。但是,如果您确实需要对地址进行硬编码,则可以使用以下解决方法进行跳转:

__asm {
    push 0x11223344
    ret
}

【讨论】:

  • 你的意思是你不必担心它是相对的?
  • @paulm 抱歉,有一些虚假信息。现已更正!
  • 但这是一个内存间接跳转。我需要直接跳转目标地址作为操作码的一部分。
  • @user2252343 我不认为有这样的指令。您在帖子中提到的那个使用段寄存器,操作系统将禁止您使用它(例外)。另一种选择是“0xE9”跳转,这是一个相对跳转。
  • hm x86 真的没有像 jmp 0x11223344 这样的东西吗?这真的让我吃惊。
猜你喜欢
  • 1970-01-01
  • 2011-04-19
  • 2018-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多