替换二进制文件中的字符串

时间:2016-12-18 19:40:48

标签: c unix

我正在尝试编写一个复制自身并替换二进制文件中的字符串的* nix程序。复制过程似乎不起作用。

以下是代码:

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>

#define BUFSIZE 10
#define FILENAME "token"

void findstring(const char *exe, const char* str)
{
    char buf[BUFSIZE];
    int line_num = 1;
    int i = 0, find_result = 0;
    FILE *fp = fopen(exe, "rb");
    if(fp == NULL)
        exit(-1);

    FILE *out = fopen("out", "wb");
    if(out == NULL)
        exit(-1);

    while(fgets(buf, BUFSIZE, fp) != NULL) {
        if((strstr(buf, str)))
        {
            printf("A match found on line: %d\n", line_num);
            printf("\n%s\n", buf);
            find_result++;

            // reverse "token" string in the output
            for(i = 0; i< BUFSIZE; i++)
            {
                if(strstr(&buf[i], "t") != NULL)
                    buf[i] = 'n';
                else if(strstr(&buf[i], "o") != NULL)
                    buf[i] = 'e';
                else if(strstr(&buf[i], "k") != NULL)
                    buf[i] = 'k';
                else if(strstr(&buf[i], "e") != NULL)
                    buf[i] = 'o';
                else if(strstr(&buf[i], "n") != NULL)
                    buf[i] = 't';
            }
        }
        line_num++;

        fputs(buf, out);
    }

    if(find_result == 0) {
        printf("\nSorry, couldn't find a match.\n");
    }

    fclose(fp);
    fclose(out);
}

int main(int argc, char **argv, char **envp)
{
//    argv[1] = FILENAME;

    char buf[1024];
    int fd, rc;

    findstring(argv[0], "token");

    if(argc == 1) {
        printf("\n\n%s [file to read]\n\n", argv[0]);
        exit(1);
    }

    printf("FILENAME macro = %s", FILENAME);

    if(strstr(argv[1], "token") != NULL) {
        printf("\n\nYou may not access '%s'\n\n", argv[1]);
        exit(2);
    }

    fd = open(argv[1], O_RDONLY);
    if(fd == -1) {
        printf("\n\nUnable to open %s\n\n", argv[1]);
        exit(3);
    }

    rc = read(fd, buf, sizeof(buf));

    if(rc == -1) {
        printf("\n\nUnable to read fd %d\n\n", fd);
        exit(4);
    }

    write(1, buf, rc);

    return 0;
}

“Token”字符串应在输出二进制文件(“nekot”)中反转, findstring 函数负责执行此任务。 值得注意的是,发现的匹配数严格取决于BUFSIZE常量。

这段代码缺失了什么? 感谢

2 个答案:

答案 0 :(得分:1)

考虑这是做什么的:

  if(strstr(&buf[i], "t") != NULL)
      buf[i] = 'n';

这将从索引i开始搜索缓冲区,如果字符串"t"出现在缓冲区中的任何位置,它将用n替换第一个字符。所以如果你的缓冲区有

a string with token inside.

for循环的第一次迭代会将其更改为

n string with token inside.

随着循环的进行,你将获得

nnnnnnnnnnith token inside.

经过10次迭代后最终

nnnnnnnnnnnnnnnekooooooooo.

其他问题:

  • fgets读取一个字符串,直到换行符或最多BUFSIZE-1个字符。可能有一些字节等同于换行符。
  • 无论您读取多少字节,都要扫描BUFSIZE个字节。
  • fput将写入第一个NUL字节。如果输入二进制文件中的任何位置都有NUL字节,则缓冲区中NUL之后的内容将丢失。

以上意味着您可能希望使用fread / fwrite而不是fgets / fputs,并且您要仔细检查镜头读取或写入的返回值。

答案 1 :(得分:1)

1。 所有C风格的字符串函数首先打破'\ 0'。因此,如果buf在您的目标之前包含空字符,则永远不会找到。

if((strstr(buf, str))) { ... } 

我建议手工编码的第一步字符(字节)循环,或家庭memXXXXcmp等函数

  1. 如果您的令牌超过了两个缓冲区的边界(来自两个厕所[迭代],则无法进行比较