【发布时间】:2021-05-20 08:54:09
【问题描述】:
我写了这个函数来找出基于this talk关于破坏x86指令集的汇编指令的长度。
/* shellcode is a pointer to a buffer contains assembly instructions
size is the size of that buffer */
DWORD GetInstructionLength(BYTE* shellcode,SIZE_T size) {
LPVOID RWXBuff = nullptr; //buffer with read,write,execute perm
LPVOID RWBuff = nullptr; //buffer with read,write perm
HANDLE CurProc = GetCurrentProcess();
DWORD Tmp;
DWORD CurrOffset = 1;
RWXBuff = VirtualAllocEx(CurProc, NULL, 32, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
RWBuff = RWXBuff;
for (int i = 0; i < 16; i++, RWBuff = static_cast<char*>(RWBuff) + 1);
VirtualProtectEx(CurProc, RWBuff, 17, PAGE_READWRITE, &Tmp);
void (*func)();
for (;;CurrOffset++) {
__try {
LPVOID ShellcodeAddr = static_cast<char*>(RWXBuff) + 16 - CurrOffset;
std::cout << "memcpy(" << ShellcodeAddr << ", " << (void*)shellcode << ", " << size << ")\n";
memcpy(ShellcodeAddr, shellcode, size);
std::cout << "memcpied" << std::endl;
MEMORY_BASIC_INFORMATION minfo;
VirtualQueryEx(GetCurrentProcess(), ShellcodeAddr, &minfo, sizeof(MEMORY_BASIC_INFORMATION));
if (PAGE_EXECUTE_READWRITE == minfo.Protect)
std::cout << "shellcode at " << ShellcodeAddr << "is executable" << std::endl;
else
std::cout << "shellcode at " << ShellcodeAddr << "is NOT executable" << std::endl;
func = (void(*)())ShellcodeAddr;
func();
break;
}
__except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
std::cout << "Bug!" << std::endl;
continue;
}
}
VirtualFreeEx(CurProc, RWBuff, 0, MEM_RELEASE);
return CurrOffset;
}
来电者:
int main()
{
unsigned char shellcode = 0x90; // nop opcode
unsigned char* buf = &shellcode;
size_t size = helper::GetInstructionLength(buf, 1);
std::cout << "Shellcode lenght = " << size << std::endl;
}
输出:
buffer with rwx at 0000023048E80000
buffer with rw- at 0000023048E80010
shellcode at 0000023048E8000F is NOT executable
Bug!
shellcode at 0000023048E8000E is NOT executable
Bug!
shellcode at 0000023048E8000D is NOT executable
Bug!
shellcode at 0000023048E8000C is NOT executable
Bug!
shellcode at 0000023048E8000B is NOT executable
Bug!
shellcode at 0000023048E8000A is NOT executable
Bug!
shellcode at 0000023048E80009 is NOT executable
Bug!
shellcode at 0000023048E80008 is NOT executable
Bug!
shellcode at 0000023048E80007 is NOT executable
Bug!
shellcode at 0000023048E80006 is NOT executable
Bug!
shellcode at 0000023048E80005 is NOT executable
Bug!
shellcode at 0000023048E80004 is NOT executable
Bug!
shellcode at 0000023048E80003 is NOT executable
Bug!
shellcode at 0000023048E80002 is NOT executable
Bug!
shellcode at 0000023048E80001 is NOT executable
Bug!
shellcode at 0000023048E80000 is NOT executable
Bug!
Bug!
...
但它不会起作用,并且每次都会引发访问违规,我不知道为什么。你能帮我解决这个问题吗? 因为我只有 3 个月的编码经验,如果这对你来说是糟糕的代码,请见谅
【问题讨论】:
-
这段代码中有很多奇怪的决定,比如使用
Ex-versions 和GetCurrentProcess。或缺少FlushInstructionCache。或者大量缺乏错误检查。此外,您让我们猜测您要执行什么代码。shellcode是什么。那件事失败了。让我们真正看到那东西难道不合理吗? -
@IInspectable: x86 有coherent instruction cache; GCC 需要您使用
__builtin____clear_cache()的唯一原因是它知道存储不是“死的”,并且必须在通过函数指针调用之前实际位于内存中。 (How does __builtin___clear_cache work?)。 IDK 如果 MSVC 与需要 `FlushInstructionCache` 相似(但零 asm 指令),或者如果没有它也可以工作或volatile。
标签: c++ winapi assembly shellcode