从exe的.data和.rdata读取值。字节对齐

时间:2017-02-13 21:01:20

标签: c++ layout binary exe ifstream

我有一个非常小的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部分以任何可靠的方式进行分配吗?您将如何实施将考虑这种转变的检查?或者也许有人完全不同的想法如何轻松地以编程方式更改此值。

祝你好运 马尔钦

2 个答案:

答案 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;
}