【发布时间】:2020-04-29 01:31:38
【问题描述】:
好的,我正在尝试创建一个创建 shellcode 的函数。
我在处理 rex / mod 的东西时遇到了很多问题。
我当前的代码工作。
到目前为止,如果 regs 比 R8 小,它可以正常工作。
如果我使用一个小于 R8 的 reg 就可以了。
问题是一旦我必须 regs 小于 r8 并且相同,或者如果 src 更小我就会遇到问题
enum Reg64 : uint8_t {
RAX = 0, RCX = 1, RDX = 2, RBX = 3,
RSP = 4, RBP = 5, RSI = 6, RDI = 7,
R8 = 8, R9 = 9, R10 = 10, R11 = 11,
R12 = 12, R13 = 13, R14 = 14, R15 = 15
};
inline uint8_t encode_rex(uint8_t is_64_bit, uint8_t extend_sib_index, uint8_t extend_modrm_reg, uint8_t extend_modrm_rm) {
struct Result {
uint8_t b : 1;
uint8_t x : 1;
uint8_t r : 1;
uint8_t w : 1;
uint8_t fixed : 4;
} result{ extend_modrm_rm, extend_modrm_reg, extend_sib_index, is_64_bit, 0b100 };
return *(uint8_t*)&result;
}
inline uint8_t encode_modrm(uint8_t mod, uint8_t rm, uint8_t reg) {
struct Result {
uint8_t rm : 3;
uint8_t reg : 3;
uint8_t mod : 2;
} result{ rm, reg, mod };
return *(uint8_t*)&result;
}
inline void mov(Reg64 dest, Reg64 src) {
if (dest >= 8)
put<uint8_t>(encode_rex(1, 2, 0, 1));
else if (src >= 8)
put<uint8_t>(encode_rex(1, 1, 0, 2));
else
put<uint8_t>(encode_rex(1, 0, 0, 0));
put<uint8_t>(0x89);
put<uint8_t>(encode_modrm(3, dest, src));
}
//c.mov(Reg64::RAX, Reg64::RAX); // works
//c.mov(Reg64::RAX, Reg64::R9); // works
//c.mov(Reg64::R9, Reg64::RAX); // works
//c.mov(Reg64::R9, Reg64::R9); // Does not work returns (mov r9,rcx)
另外,如果没有所有 if 的情况下有更短的方法来做到这一点,那就太好了。
【问题讨论】:
-
仅供参考,大多数人通过使用像 NASM 这样的普通汇编程序进行汇编来创建 shellcode,然后将该二进制文件十六进制转储为 C 字符串。编写自己的汇编程序可能是一个有趣的项目,但不是您通常需要做的事情。
标签: c++ assembly x86-64 machine-code