修改已编译的 ELF 可执行文件中的全局变量

问题描述 投票:0回答:1

我有一个类似于 UPX 的程序。它通过全局变量执行包含在可执行文件中的嵌入式程序:

const char programData[] = { 0x12,0x13… }

有没有办法在不重新编译程序的情况下修改这个变量值?

我不希望我的用户必须安装整个构建工具链来更改嵌入式可执行文件,也不希望我因为环境限制而无法使用外部文件

c executable elf
1个回答
-1
投票

我会添加两个变量,首先是一个

blockSize
,然后是
programData
的大块。

我认为你需要存储数据的大小,因为probablypayload program size may change.

如果你构建这个简单的可执行文件:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#define MAX_BLOCK_SIZE 8192ul   // probably much bigger in practice

uint64_t blockSize = MAX_BLOCK_SIZE;
uint8_t  programData[ MAX_BLOCK_SIZE ] = {
                                            0xf0, 0x0d, 0xf0, 0x0d, 0xf0, 0x0d, 0xf0, 0x0d,
                                            0xf0, 0x0d, 0xf0, 0x0d, 0xf0, 0x0d, 0xf0, 0x0d,
// ... huge block of MAX_BLOCK_SIZE~sized initialisation data, 
                                            0xf0, 0x0d, 0xf0, 0x0d, 0xf0, 0x0d, 0xf0, 0x0d,
                                         };

int main( int argc, char **argv )
{
    fprintf( stderr, "Maximum block size is %lu bytes\n", MAX_BLOCK_SIZE );
    fprintf( stderr, "Used block size is %lu bytes\n", blockSize );

    return 0;
}

可以用十六进制编辑器之类的东西检查可执行字节。编译器会将初始化字节嵌入到可执行文件中。很容易看出大小和块在可执行文件中的位置(注意 gcc/Linux/x86-64 的

hexdump
输出):

0001000 0000 0000 0000 0000 1008 0020 0000 0000
0001010 0000 0000 0000 0000 0000 0000 0000 0000
0001020 2000 0000 0000 0000 0000 0000 0000 0000
0001030 0000 0000 0000 0000 0000 0000 0000 0000
0001040 0df0 0df0 0df0 0df0 0df0 0df0 0df0 0df0
*
0003040 4347 3a43 2820 6255 6e75 7574 3720 352e

很明显上面的大小和字节在哪里:0x1020 和 0x1040。但如果不使用一些易于识别的常见模式,例如0x88558855...

接下来,编写 another 程序打开可执行文件进行读/写 - 就像任何二进制数据文件一样,然后用有效负载可执行文件的详细信息覆盖

blockSize
programData
。也许stdio功能
fseek()
,而
fwrite()
将使这变得微不足道。

© www.soinside.com 2019 - 2024. All rights reserved.