在不使用相关性的情况下直接在ASM中调用/跳转(x86)
我正在向游戏中注入C++ DLL,并且想要将一个函数挂接到我自己的一些代码中。由于DLL每次都映射到不同的位置,所以直接跳转和调用会更容易。另外,因为这是一个钩子,我不想在返回该函数时更改堆栈或注册表。 (char * asm =“\ x00”;) 如果你可以提供十六进制,这将为我节省一些时间。在不使用相关性的情况下直接在ASM中调用/跳转(x86)
我曾尝试使用FF和EA进行调用和跳转,但我想我只是不明白这些如何工作。当我使用它们时,我注意到我在手术中有一个冒号。
JMP FAR FWORD PTR DS:[00000000]
这不起作用,它仍然之后,我试图用一个指针跳跃位置没有工作。
这里之前,我开始尝试不同的方法,我用的是装配:
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
我使用奥利取得该块,因此它知道在当时所需的相关跳跃/调用。
之后,Asm在内存中,然后我必须在函数中写入两个操作(已被替换)以跳转到此位置。
那么,我该如何修复我的Asm块以使用直接跳转和调用?
回答:
可以这样的代码它(GCC式/ AT & T汇编语法):
jmp *.Ltgtaddr .Ltgtaddr: .long absoluteAddrOfFunctionToCall
此组装成10个字节(在32位x86)的 - ff 25
与32位内存操作数的绝对JMP,然后四个字节与下一个字的地址,然后是您的代码的(绝对)目标地址的内容。
编辑:我已经更新了一个编译和测试的例子下面的部分。
您可以从C源代码中动态创建这样一个蹦床。示例源(需要32位的x86,作为练习留给读者如何蹦床转换为64位):
#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页面只能使用它的十个字节。如果您需要不止一个蹦床,请实施您自己的蹦床内存管理器...
回答:
我从未尝试过这样的事情,
但我认为你应该使用从游戏的一个已知的内存位置的偏移量(用OllyDbg中找到),因此每多加一个这个时间(固定)偏移到(可变)地址。例如,这个地址可以是在ss:ebp
处找到的返回地址(因为你的函数被游戏调用),并且该地址的偏移量是在ollyDBG的帮助下计算的。
以上是 在不使用相关性的情况下直接在ASM中调用/跳转(x86) 的全部内容, 来源链接: utcz.com/qa/258709.html