我有一个非常小的exe,我从这段代码编译(调试,没有优化):
struct some_data
{
unsigned long long a;
unsigned long long b;
}
int main ()
{
constexpr some_data {0x1234567890abcdef, 0xabcdabcdabcdabcd}
cout << some_data.a << endl;
return 0;
}
现在我想创建另一个程序,在第一个exe中找到值0x1234567890abcdef并将其替换为0x11111111111111然后保存exe,所以下次运行它时我会得到&#34;注入&#34; 0x111111111111111作为输出。
我做了一个简单的程序,可以按照这些方式做点什么:
uint64_t key = 0x1234567890abcdef;
uint64_t value;
fstream file ("file", ios::in| ios::out | ios::binary);
if (file.is_open())
{
while (not_end_of_file) {
file.read (&value, sizeof(value));
if (value == key) {
//code that overwrittes the old value with new
}
}
它确实工作了一两次让我开心,但在我为第一个项目添加了一些代码并重建之后,替换(第二个项目)突然停止工作。在停止输入if(value == key)部分代码时。我认为发生这种情况的原因是,在添加一些代码之后,.data部分中的结构在文件中向前移动了几个字节,现在当读取8字节的块时,它不再像这样(little_endianess)
XX XX XX ef cd ab 90 78 one read operation
56 34 12 XX XX XX XX XX the next read operation
您认为是这种情况吗?我可以期望.data和.rdata部分以任何可靠的方式进行分配吗?您将如何实施将考虑这种转变的检查?或者也许有人完全不同的想法如何轻松地以编程方式更改此值。
祝你好运 马尔钦
答案 0 :(得分:1)
这可能看起来有点贫民窟,但您可以将整个文件加载到字节数组中,并将字节解除引用到uint64_t,如下所示:
(是的,对不起,我没有包含完整的代码,但这应该给你一个想法/明确)
byte* bytes = new byte[filesizeinbytes];
//read to the byte array
then:
DWORD offset = 0;
while( *(uint64_t*)((DWORD)bytes+offset) != 0x1234567890abcdef )
{
offset++;
}
//We found the right address, so we can replace the bytes/address/offset
*(uint64_t*)((DWORD)bytes+offset) = 0x111111111111111;
//write the entire file, starting from bytes till the end of the file
delete[] bytes; // free the allocated memory
bytes = 0;
答案 1 :(得分:0)
您似乎无法依赖数据分配或至少不是我以前的方式。
注意如果您想要复制实现,最好使用来自解除引用程序的答案中的代码,因为它更加清晰。我留下我的答案,以获取有关数据分配的信息以及实现它的另一种方法。
这是我提出的代码,它将字节1加1并检查最后8个字节。这是一个小的结束,对于大的我认为你需要改变字节是“值”引用,并改变转移方向。
#include <iostream>
#include <fstream>
using namespace std;
using magic_bytes_t = uint64_t;
const magic_bytes_t search_key{ 0x1234567890abcdef };
const magic_bytes_t replacemenet_key{ 0x1212121212121212 };
struct data_struct
{
const magic_bytes_t value_to_replace;
};
union parsing_union
{
magic_bytes_t value;
uint8_t bytes[sizeof(magic_bytes_t)];
};
int main()
{
std::fstream myFile("C:\\Users\\crazy_path\\x64\\Debug\\SampleApplication.exe", ios::in | ios::out | ios::binary);
if (!myFile) {
cout << "Couldn't open file" << endl;
return EXIT_FAILURE;
} else {
parsing_union parsing_helper{ 0x0000000000000000 };
uint8_t &single_byte_value = parsing_helper.bytes[7];
while (myFile.read((char*)&single_byte_value, sizeof(single_byte_value)))
{
if (parsing_helper.value == search_key)
{
uint64_t control_key_start_position = myFile.tellg();
control_key_start_position -= sizeof(parsing_helper.value);
myFile.seekp(control_key_start_position);
myFile.write(reinterpret_cast<const char*>(&replacemenet_key), sizeof(replacemenet_key));
cout << "GOT EM !! GOT EM GOOD" << endl;;
break;
} else {
parsing_helper.value >>= (sizeof(single_byte_value) * 8);
}
}
}
system("pause");
return EXIT_SUCCESS;
}