如何解决调用复制函数时访问冲突
这是一个将函数复制到堆上,将其设置为可执行文件并调用它的程序。
#include <iostream>
#include <iomanip>
#include <csignal>
#include <Windows.h>
using std::cout;
#define RET 0xC3
void printBytes(void* start,uintptr_t numBytes) {
std::ios_base::fmtflags savedFlags(cout.flags());
cout << std::hex << std::uppercase << std::setfill('0');
bool lineComplete = false;
for (unsigned int byte = 0; byte < numBytes; byte++) {
lineComplete = byte % 4 == 3;
cout << std::setw(2)
<< (int)*((uint8_t*)start + byte)
<< (lineComplete ? '\n' : ' ');
}
cout << (lineComplete ? "\n" : "\n\n");
cout.flags(savedFlags);
}
uint8_t* findByte(void* start,uint8_t targetByte) {
uint8_t* pByte = (uint8_t*) start;
while (*pByte != targetByte) pByte++;
return pByte;
}
uintptr_t findByteOffset(void* base,uint8_t targetByte) {
uint8_t* byte = findByte(base,targetByte);
return (uintptr_t)byte - (uintptr_t)base;
}
int main() {
void(*function)() = [] { cout << "Hello world"; };
uintptr_t size = findByteOffset(function,RET) + 1;
cout << "function : " << function << "\n\n";
printBytes(function,size);
void(*functioncopy)() = static_cast<void(*)()>(malloc(size));
cout << "functioncopy : " << functioncopy << "\n\n";
if (functioncopy)
{
memcpy(functioncopy,function,size);
printBytes(functioncopy,size);
DWORD oldProtect;
VirtualProtect(functioncopy,size,PAGE_EXECUTE_READWRITE,&oldProtect);
cout << "functioncopy()\n";
functioncopy();
VirtualProtect(functioncopy,oldProtect,&oldProtect);
}
else cout << "malloc(" << size << ") failed.";
}
当我运行程序时(在Release或Debug配置中,有或没有进行优化),它在functioncopy()中给出了访问冲突。我不知道为什么。
解决方法
绝对没有理由期望它能起作用。不管是否有人想到它不起作用的原因,根本没有理由期望它起作用。没有任何标准或参考资料表明这应该起作用,并且期望它起作用是直率的,疯狂的。
它可能会失败,这是最明显的方式:如果0xc3
恰好出现在该函数的代码中作为其他内容的一部分,可能是它调用的辅助函数的地址?如果它不使用RET
指令返回怎么办?如果该函数的代码相对于转换单元中的另一个函数使用了相对跳转,该怎么办?如果函数跳转并且其某些代码位于内存中的RET
之后怎么办?如果有一百万个其他问题出了错而我又想不出该怎么办?
这段代码是荒谬的。它不是基于任何理性的工程推理。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。