所以,我正在构建一个应该修改二进制文件中特定字节数的程序。首先输入二进制文件,然后输入要从中替换十六进制指令的偏移量,然后输入字节本身。
示例:我加载example.exe我指定偏移量0
(文件的开头)我指定了十六进制指令:4D FF 33 FD FE
文件的前5条指令应该替换为我提供的指令。我使用fwrite
进行修改,使用scanf
来获取偏移量和十六进制指令,但是,我找不到将它们实际存储为十六进制的方法。 fwrite实际上将4D FF 33 FD FE
作为文本写入二进制文件而不是hex。我假设我首先在char
中将它们保存错误。我是C的新手,所以我在网上找到的并没有真正帮助。
这是我的代码:
scanf("%ld",&offset_ed);//get the offset from the user.
fseek(f, offset_ed, SEEK_SET);
printf("Specify HEX bytes to be written to the binary: ");
scanf("%s\n", &hexes);
fwrite (hexes , sizeof(char), sizeof(hexes), f);
fclose (f);
其中hexes是char hexes;
您已将hexes作为字符串,因此您需要将它们转换为无符号字符(一个字节),然后才能将它们写入文件。
#include <string.h>
#include <stdio.h>
#define ishexchar(c) (c>='A' && c<='F') || (c>='a' && c<='f')
#define toupper(c) c - 32
#define isupper(c) c>='A' && c<='F'
unsigned char hexconv(const char* str, int size){
unsigned char ret = 0;
for(int i=0; i<size; i++){
if(ishexchar(str[i])){
char c = (isupper(str[i])) ? str[i] : toupper(str[i]);
ret = (ret*16) + (c - 'A') + 10;
}else{
ret = (ret*16) + (str[i] - '0');
}
}
return ret;
}
int main(){
printf("%x\n",hexconv("4b", 2));
}
上面的代码可能需要对您的需求进行一些修改,但它可以编译并运行。
一般的想法如下。
不要使用scanf()
,使用fgets()
读取一行用户输入。
错误检查省略(以// **标注)
char buf[100]; // Use some reasonable upper bound of expected user input.
puts("prompt for input");
fgets(buf, sizeof buf, stdin); // **
offset_ed = strtol(buf, NULL, 10); // **
fseek(f, offset_ed, SEEK_SET); // **
puts("prompt for input");
fgets(buf, sizeof buf, stdin); // **
size_t byte_count = 0;
unsigned char hexes[(sizeof buf)/2] = 0; // place to save the "hex bytes"
int n = 0;
unsigned byte;
现在解析字符串寻找十六进制输入。
// Use "%n" to save the offset of the scan to later update `p`
// Robust code would use `strtol()` for its better error handling
char *p = buf;
while (sscanf(p, "%x %n", &byte, &n) == 1) {
if (byte > 0xFF) Handle_OutOfRange();
hexes[byte_count] = byte;
p += n;
}
if (byte_count == 0) Handle_EmptyUserInput();
if (*p) Handle_ExtraJunkInUserInput();
fwrite (hexes , byte_count, sizeof hexes[0], f); // **
OP有scanf("%s\n",...
。 "\n"
是个问题。 scanf()
将阻止,直到用户在预期输入后输入一些非空白区域。避免这样做。
问题可以用scanf()
处理,但它很难看。实际上,代码需要使用'\n'
等在多个“十六进制”字节之后的某处查找scanf("%*1[^\n]")
。 scanf()
不是这里整体编码目标的最佳工具。 scanf()
很少是棚屋里最锋利的工具。