直接调用在ASM /跳不使用相关性(86) [英] Directly call/jump in ASM without using relevance(x86)

查看:241
本文介绍了直接调用在ASM /跳不使用相关性(86)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注入一个C ++ DLL到游戏,我想钩一个函数来我自己的一些code的。由于DLL每次都映射到不同的位置,这将是更容易有直接跳转和调用。同时,由于这是一个挂钩,我不想改变堆栈或寄存器,当我回去的功能。

I'm injecting a c++ DLL into a game and I'd like to hook a function to some of my own code. Since the DLL is mapped to a different location each time, It would be easier to have direct jumps and calls. Also, because this is a hook I don't want to change the stack or registers for when I go back to the function.

我宣布一个char *存储ASM,让我有一个指向它(的char * ASM =\\ X00)。
如果你能提供十六进制,那会救我一些时间。

I declare a char* to store the Asm so that I will have a pointer to it.(char* asm="\x00";) If you could provide hex, that would save me some time.

香港专业教育学院尝试和跳跃,但我想我只是不明白如何将这些工作。当我用他们,我注意到,我现在已经在运行一个冒号。

Ive tried using FF and EA for the calls and jumps but I guess I just don't understand how those work. When I used them I noticed that I now had a colon in the operation.

JMP FAR FWORD PTR DS:[00000000]

这没有工作,它仍然没有工作后,我试图用一个指针跳跃位置。

This didn't work and it still didn't work after I tried to use a pointer to the jump location.

下面是之前我开始尝试不同的方法,我用汇编:

Here's the assembly that I was using before I started trying different methods:

01270000    50              PUSH EAX
01270001    57              PUSH EDI
01270002    E8 E9CC1BFF     CALL fwound.0042CCF0
01270007    5F              POP EDI
01270008    58              POP EAX
01270009    50              PUSH EAX                      //replacements
0127000A    8D4C24 7C       LEA ECX,DWORD PTR SS:[ESP+7C] //
0127000E  - E9 36D11BFF     JMP fwound.0042D149

我做了使用奥利该块,因此它知道在当时所需的相关跳跃/调用。

I made that block using Olly, therefore it knew the relevant jumps/calls needed at the time.

之后,ASM是在内存中,然后我必须在函数写在两个操作(替换)跳转到这个位置。

After that Asm is in the memory, I then have to write over two operations(which are replaced) in the function to jump to this location.

所以,我怎么能解决我的ASM块使用直接跳转和调用?

So, How could I fix my Asm block to use direct jumps and calls?

推荐答案

您可以code像这样(GCC式/ AT& T公司汇编语法):

You can code it like this (gcc-style / AT&T assembly syntax):

    jmp    *.Ltgtaddr
.Ltgtaddr:  .long absoluteAddrOfFunctionToCall

这组装成10个字节(在32位x86)的 - FF 25 与32位内存操作数的绝对JMP,那么这四个字节与下列字的地址,其次是内容,然后是你的code的(绝对)的目标地址。

This assembles into ten bytes (on 32bit x86) - ff 25 for the absolute jmp with 32bit memory operand, then the four bytes with the address of the following word, followed by the contents which then is the (absolute) target address of your code.

编辑:我已经与编译和测试更新,例如下面的部分。

I've updated the section below with a compiled and tested example.

您可以从C源$ C ​​$ C,动态地创建这样一个蹦床。示例源(32位需要86,作为练习留给读者如何蹦床转换为64位):

You can, from C sourcecode, dynamically create such a trampoline. Example source (requires 32bit x86, left as an exercise to the reader how to convert the trampoline to 64bit):

#include <sys/mman.h>
#include <stdio.h>

void oneWay(char *str, int arg)
{ printf("string is \"%s\", int is %d\n", str, arg); }

void otherWay(char *str, int arg)
{ printf(str, arg); printf("\n"); }

void *trampGen(void *tgtAddr)
{
    char *trampoline = mmap(NULL, 10, PROT_EXEC | PROT_WRITE | PROT_READ,
        MAP_PRIVATE | MAP_ANON, -1, 0);
    trampoline[0] = (char)0xff; trampoline[1] = (char)0x25;
    *(char**)(trampoline+2) = trampoline + 6;
    *(void**)(trampoline+6) = tgtAddr;
    return trampoline;
}

int main(int argc, char **argv)
{
    void * (*funcptr)(char*, int) = trampGen(oneWay);
    *funcptr("Test %d String", 12345);
    *(void **)(((char *)funcptr) + 6) = otherWay;
    *funcptr("Test %d String", 12345);
    munmap(funcptr, 10);
    return 0;
}

我输出:

$ ./tt
string is "Test %d String", int is 12345
Test 12345 String

请注意它的效率会低一点,预留一整页MMU只使用10个字节它。实现自己的内存管理器蹦床,如果你需要一个以上的人...

Note it's slightly inefficient to set aside an entire MMU page to use only ten bytes of it. Implement your own memory manager for trampolines if you need more than one of them ...

这篇关于直接调用在ASM /跳不使用相关性(86)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆