- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我发布了一个question on a similar topic几天前(and one a couple years ago),但我决定继续并开始。我正在尝试将 C++ 代码注入(inject)到 C++ 代码中(以某种可移植的方式,不使用操作系统特定的功能,并试图成为编译器/工具链独立的方式)。我基本上想这样做是为了尝试执行运行时 C++ 脚本。我写了一个小测试程序(它真的有点乱七八糟):Main.cpp:
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <sstream>
#include <vector>
#include <tuple>
constexpr char hexmap[] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
std::string HexStr( unsigned char *data, int len )
{
std::string s( len * 2, ' ' );
for( int i = 0; i < len; ++i ) {
s[ 2 * i ] = hexmap[ ( data[ i ] & 0xF0 ) >> 4 ];
s[ 2 * i + 1 ] = hexmap[ data[ i ] & 0x0F ];
}
return s;
}
/*I am aware there is a standard GC and that this is
by no means production.*/
template< typename T, unsigned short ARRAY >
struct GarbageCollector
{
std::vector< T* > ts;
GarbageCollector() = default;
~GarbageCollector() {
for( T* i : ts )
delete i;
}
};
template< typename T >
struct GarbageCollector< T, 1 >
{
std::vector< T* > ts;
GarbageCollector() = default;
~GarbageCollector() {
for( T* i : ts )
delete[] i;
}
};
std::tuple< char*, std::streamoff > ReadBinaryBuffer(
std::string fileName, GarbageCollector< char, 1 >* gc )
{
std::ifstream binaryData;
binaryData.open( "Source.obj", std::ios::binary );
if( binaryData.fail() ) {
std::cerr << "Failed to open file!\n";
return { "Failed to open file!\n", 1 };
}
binaryData.seekg( 0, std::ios::end );
std::streamoff i = binaryData.tellg();
char* buffer = new char[ i ];
binaryData.seekg( 0, std::ios::beg );
binaryData.read( buffer, i );
binaryData.close();
gc->ts.push_back( buffer );
return { buffer, i };
}
std::string ReadBinary( std::string fileName )
{
GarbageCollector< char, 1 > gc;
auto result = ReadBinaryBuffer( fileName, &gc );
std::string stringBuffer;
stringBuffer.assign( std::get< 0 >( result ), std::get< 1 >( result ) );
return stringBuffer;
}
std::string ReadBinary( std::tuple< char*,
std::streamoff > bufferContainer )
{
std::string stringBuffer;
stringBuffer.assign( std::get< 0 >( bufferContainer ),
std::get< 1 >( bufferContainer ) );
return stringBuffer;
}
extern "C"
{
int test() {
return 3;
}
int( *cmpp )();
}
int main( int argc, char* args )
{
cmpp = &test;
auto binary = ReadBinary( "Source.obj" );
auto function = binary.substr( 347, 56 );
const char* code = function.c_str();
std::cout << HexStr( ( unsigned char* ) ( code ), function.size() );
//strcpy( ( char* )cmpp, ( ( char* ) code ) );
char* testp = ( char* ) cmpp;
char* testpp = ( char* ) code;
for( size_t i = 0; i < 54; ++i ) {
*testp++ = *testpp++;
}
cmpp();
char close;
std::cin >> close;
return 0;
}
源.cpp:
extern "C"
{
int calc()
{
int q = 30 * 123;
for( int i = 0; i < 10; ++i )
q *= i;
return q;
}
}
基本上我只是尝试用 malloc 和 new 分配一大块内存,但我想也许我可以覆盖已经专用于进程内存的内存(这就是为什么我有 test 指向的函数 < em>cmpp 并尝试覆盖它)。但是我收到写访问错误。我看了一下 this post来自 answers 之一似乎可以在没有访问冲突的情况下覆盖程序自己的内存(这是我想做的),错误不少。有人可以对此进行详细说明并告诉我如何以一种可能的可移植方式不使用任何非标准功能(或至少可以/被抽象掉的功能)来做到这一点吗?
最佳答案
默认情况下,您的程序将加载到只读和执行内存中,不允许写入(至少在任何现代操作系统上)。不同的保护措施是出于安全原因,如果有人破坏了您的软件,他们不应该对您这样做,例如泄露信息。
此请求存储在二进制文件中,由链接器完成。您可以更改链接器以请求将您的程序加载到可写内存中,但这远非最佳且不可移植。
更好的方法是从您的操作系统请求一个可执行和可写的页面(Linux 上的 mmap
等),但据我所知,也没有可移植的方法来执行此操作.
关于C++ 让程序重写自己,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50165795/
我是一名优秀的程序员,十分优秀!