我试图创建一个调度表,用于更改AllocateMemoryOnRemoteProcess
分配的另一个地址中某些指令的位置。
我遇到的一个问题几乎都是Calls
,所有类型Jumps
都是near
和relative
,只要我在新版本中加载程序集位置,然后这些说明不起作用。
据我所知,我应该将这些说明转换为far jump
或far call
我在谷歌搜索中看到的一个解决方案是使用push
和ret
之类的:
push 0xdeadbeef
ret
或有人建议使用寄存器进行绝对寻址,例如:
mov %eax,0xdeadbeef
jmp %eax
这些解决方案在我的案例中不起作用,因为只要我在函数例程中更改堆栈状态,或者在第二种情况下更改像%eax
这样的寄存器会导致失败。 / p>
this question中有人写道:
- 调用far(使用操作码9A)跳转到绝对段和偏移量。 也就是说,它就像是一次设置CS和?IP。
所以我似乎应该将9A
的操作码用于far calls
,但这只适用于调用,我不知道用这种方法转换各种类型的跳转!
我经常使用objdump
反汇编二进制文件,然后使用clang
作为汇编程序使用以下命令:
clang -c MyAsm.asm -m32
但是当我用上面的命令汇编时,结果是相对的。
例如MyAsm.asm
为:
call 0x402af2
objdump
的结果是:
MyAsm.o: file format Mach-O 32-bit i386
Disassembly of section __TEXT,__text:
__text:
0: e8 ed 2a 40 00 calll 4205293 <__text+0x402AF2>
这些结果是相对的。
所以我的问题是:
far calls
或任何其他工具(当然,适用于80x86和Amd64结构)汇编far jumps
或j*
(clang
指令)? 答案 0 :(得分:4)
如果您可以备用注册表,我建议您使用
class Client():
def __init__(self):
host = socket.gethostname()
port = 5000
client_socket = socket.socket()
client_socket.connect((host, port))
gui = Dialog(client_socket)
gui.show()
message = ""
while message.lower().strip() != 'bye':
data = client_socket.recv(1024).decode()
print('message: ', data)
client_socket.close()
if __name__ == '__main__':
client = Client()
或者,如果您可以确保地址在前2 GB的地址空间内,
movabs $addr,%rax
jmp *%rax
我强烈建议您不要使用
mov $addr,%eax
jmp *%eax
因为这会破坏返回预测,使得接下来的几个函数返回的速度比必要的慢。远程跳跃和通话( push $addr
ret
和ljmp
)都是红鲱鱼。虽然它们可以在技术上使用,但它们无法帮助您实现目标,实际上是出于不同的目的(更改lcall
)并在现代处理器上实现为缓慢的微编码指令。
如果你不能备用一个寄存器,你可以使用这种技巧:
cs
这应该只是工作,此外不要求你使用额外的寄存器。它虽然比使用寄存器慢。
请注意,条件跳转严格要求跳转目标立即生效。如果你想要一个条件跳转到绝对地址,请使用这样的成语:
jmp *0f(%rip)
0: .quad addr