我想编译小型double(...)
作为x64 shellcode。我已经有一个工作程序来生成用于简单数学运算的编码程序集,如a + b/a
,其中a
和b
是double
函数的参数。shellcode内调用函数
生成的代码被加载到可执行文件mmap
缓冲区中,并且可以稍后调用。
我有以下问题:我想在我生成的shellcode中调用math.h
函数,如sin
,exp
等。由于所有call
操作码都以某种方式使用32位地址或相对跳转,因此我无法轻松使用这些指令。因此,我想实现我自己call
-instruction这样:
lea rax, [rip+0x0] ;load instruction pointer into rax
add rax, <offset-to-return-to>
push rax
moveabs rax, <adress-of-function> ;load the function pointer to rax
jmp rax
这是我的代码来生成这些指令:
//lea rax, [rip+0x0]
insertAll(code,std::list<uint8_t>{ 0x48, 0x8D, 0x05, 0x00, 0x00, 0x00, 0x00 });
//add rax, <offset-to-return-to>
insertAll(code,std::list<uint8_t>{ 0x48, 0x83, 0xC0, <offset-to-return-to>});
//push rax
code.push_back(0x50);
//moveabs rax, address-of-function
uint8_t reg = 0; //rax
uint8_t rexWPrefix = 0x48 + (reg > 8);
uint8_t opCode = 0xB8 + (reg % 8);
insertAll(code,std::list<uint8_t>{ rexWPrefix, opCode });
code.insert(code.end(),reinterpret_cast<uint8_t*>(&fabs),reinterpret_cast<uint8_t*>(&fabs) + 8);
//jmp rax
insertAll(code,std::list<uint8_t>{ 0xFF, 0xE0 });
不幸的是,调用函数这样是不行的,程序崩溃与一个SIGSEGV
错误。我的汇编代码或指令编码有问题吗? <offset-to-return-to>
有什么价值,让功能回到正确的位置?
声明:我知道,这不是处理代码动态生成的最佳方法......我可以编译一个动态库并使用dlsym
加载它。这只是一个有趣的方式来了解程序集/ shellcode,不应该太认真:)
乍一看有道理,使用调试器看在哪里以及为什么会发生故PS:你当然可以将'add rax'合并到'lea'中。确保你使用正确的偏移量。 – Jester
什么是“x64 shellcode”?而C和C++是不同的语言。不要垃圾标签。 – Olaf
@Olaf:我想说,我使用x86-64指令代码。这对于jmp指令可能很重要,因为地址大小是64位。 – tly