【问题标题】:Cant edit a binary program using fwrite and writing an int?无法使用 fwrite 编辑二进制程序并编写 int?
【发布时间】:2020-10-15 01:45:42
【问题描述】:

我正在尝试编写一个程序,使用fwrite 和fseek 将数字写入两个不同的文件(二进制elf 文件)偏移量,但两者似乎都报告写入和查找正确,但objdump -s 0x2db0 -n 0x16 test似乎显示没有改变。 fwrite 和 fseek 称为:

error = fwrite((void*)&value, sizeof(value), 1, file);
seek_error = fseek(file, offset, SEEK_SET);

整个程序的执行如下所示,应该在偏移量0x2db0 和0x01 处写入0x119e:

./patch test 0x01 0x2db0 0x119e

因此,在运行 objdump 时,在两个偏移量处都没有看到 119e,似乎根本没有发生任何变化。

整个源代码是:(主要是检查函数返回值)

#include <stdio.h>
#include <stdlib.h>
#include <zconf.h>
#include <errno.h>

int main(int argc, char *argv[]){
    long error, seek_error;
    long value, offset;

    if (argc < 5){
        fprintf(stderr, "Incorrect arg number\n");
        exit(1);
    }

    FILE* file = fopen(argv[1], "ab");
    if (file == NULL){
        fprintf(stderr, "Error openning File\n");
        perror("fopen() :");
        exit(1);
    }
    printf("\t\t File opened successfully\n");

    value = strtol(argv[4], NULL, 16); /* convert target value to int */
    if (value == LONG_MIN || value == LONG_MAX){
        fprintf(stderr, "Error calling strtol\n");
        perror("strtol() :");
        exit(1);
    }

    offset = strtol(argv[2], NULL, 16);
    printf("offset is %ld\n", offset);
    if (offset == LONG_MIN || offset == LONG_MAX) {
        fprintf(stderr, "Error calling strtol during offset\n");
        perror("strtol() :");
        exit(1);
    }

    seek_error = fseek(file, offset, SEEK_SET); /* From start go to end*/
    if (seek_error != 0){
        fprintf(stderr, "Error calling fseek\n");
        perror("fseek(): ");
        exit(1);
    }
    printf("File position is: 0x%lx\n", ftell(file));

    error = fwrite((void*)&value, sizeof(value), 1, file);
    if (error != 1){
        fprintf(stderr, "Error calling write\n");
        perror("write() :");
        exit(1);
    }
    printf("Number of bytes written %ld\n", error);

    offset = strtol(argv[3], NULL, 16);
    printf("offset is %ld\n", offset);
    if (offset == LONG_MIN || offset == LONG_MAX) {
        fprintf(stderr, "Error calling strtol during scond offset\n");
        perror("strtol() :");
        exit(1);
    }

    seek_error = fseek(file, offset, SEEK_SET);  /* Seek to the new offset */
    if (seek_error != 0){
        fprintf(stderr, "Error calling second fseek\n");
        perror("fseek(): ");
        exit(1);
    }
    printf("File position is: 0x%lx\n", ftell(file));

    error = fwrite((void*)&value, sizeof(value), 1, file);
    if (error != 1){
        fprintf(stderr, "Error calling write\n");
        perror("write() :");
        exit(1);
    }
    printf("Number of bytes written %ld\n", error);

    fflush(file);   /* flush changes not nesessecarly */
    error = fclose(file);
    if (error != 0){
        fprintf(stderr, "error closing file\n");
        perror("close() :");
        exit(1);
    }
}

【问题讨论】:

    标签: c linux fopen elf fwrite


    【解决方案1】:

    您正在使用fopen(argv[1], "ab") 以追加模式打开文件。因此,所有写入都在文件末尾完成,而忽略了您寻找的位置。

    请改用fopen(argv[1], "rb+")。 r 表示以读取方式打开,所以文件不会先被清空,+ 表示也允许写入。

    【讨论】:

    • 非常感谢。它现在工作了,但为什么 fseek 没有报告错误,而 ftell 说该文件已正确查找
    • fseek 有效,只是没用。当你写东西时,它会自动先搜索到结尾。
    猜你喜欢
    • 1970-01-01
    • 2011-05-08
    • 2019-04-27
    • 2017-10-20
    • 1970-01-01
    • 2014-01-24
    • 1970-01-01
    • 2013-06-06
    • 2010-12-02
    相关资源
    最近更新 更多