2023-2024-1 20211327 myxxd(课上测试)
myxxd(课上测试)
学***d的使用,提交至少3个应用截图
xxd的主要功能是什么?需要使用什么系统调用来实现?写出你的推导过程,命令
xxd
主要用于查看文件的十六进制表示,并提供了一些额外的功能,如生成C语言风格的数组表示。它的主要功能包括:
-
查看文件的十六进制表示: 显示文件内容的十六进制表示,每行显示16个字节,同时还显示ASCII字符。
-
生成C语言风格的数组: 生成一个包含文件内容的C语言数组,可用于在程序中嵌入二进制数据。
-
逆向操作: 将十六进制表示还原为二进制数据。
xxd
主要使用文件I/O和格式化输出相关的系统调用来实现其功能。推导过程
1.查看文件的十六进制表示:
- 使用系统调用
open
打开文件。 - 使用
read
从文件中读取数据。 - 格式化数据并输出,可能使用系统调用
write
。
xxd filename
2.生成C语言风格的数组:
- 使用系统调用
open
打开文件。 - 使用
read
从文件中读取数据。 - 格式化数据并输出,可能使用系统调用
write
。
xxd -i filename
3.逆向操作 - 将十六进制还原为二进制:
- 使用系统调用
open
创建一个新文件。 - 使用
write
将十六进制数据写入新文件。
xxd -r -p hexfile > binaryfile
写出实现xxd的伪代码
function xxd(filename):
file = open(filename, 'rb') # 使用二进制模式打开文件
address = 0 # 内存地址,用于显示在输出中
while True:
data = file.read(16) # 从文件读取16个字节
if not data:
break # 文件读取完毕
hex_string = to_hex_string(data) # 将字节数据转换为十六进制字符串
ascii_string = to_ascii_string(data) # 将字节数据转换为ASCII字符串
print(f'{address:08x}: {hex_string} {ascii_string}')
address += len(data)
file.close()
function xxd_i(filename):
file = open(filename, 'rb') # 使用二进制模式打开文件
data = file.read()
hex_string = to_hex_string(data) # 将字节数据转换为十六进制字符串
print(f'static unsigned char {filename}_data[] = {{ {hex_string} }};')
file.close()
function xxd_r(hexfile, binaryfile):
hex_data = read_hex_file(hexfile)
binary_data = hex_to_binary(hex_data)
write_binary_file(binaryfile, binary_data)
function to_hex_string(data):
return ' '.join(f'{byte:02x}' for byte in data)
function to_ascii_string(data):
return ''.join(chr(byte) if 32 <= byte <= 126 else '.' for byte in data)
function read_hex_file(hexfile):
with open(hexfile, 'r') as file:
return file.read().replace(' ', '').replace('\n', '')
function hex_to_binary(hex_data):
return bytes.fromhex(hex_data)
function write_binary_file(binaryfile, binary_data):
with open(binaryfile, 'wb') as file:
file.write(binary_data)
编写myxxd实现xxd的功能
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 16
void print_hex(const unsigned char *data, size_t size, size_t offset) {
size_t i;
printf("%08lx: ", offset);
for (i = 0; i < size; i++) {
printf("%02x ", data[i]);
if ((i + 1) % 8 == 0)
printf(" ");
}
for (; i < BUFFER_SIZE; i++) {
printf(" ");
if ((i + 1) % 8 == 0)
printf(" ");
}
printf(" ");
for (i = 0; i < size; i++) {
if (data[i] >= 32 && data[i] <= 126)
printf("%c", data[i]);
else
printf(".");
}
printf("\n");
}
void display_file(const char *filename, int display_type, size_t num_bytes) {
FILE *file = fopen(filename, "rb");
if (file == NULL) {
perror("Error opening file");
exit(EXIT_FAILURE);
}
fseek(file, 0, SEEK_END);
long len = ftell(file);
fseek(file, 0, SEEK_SET);
unsigned char buffer[BUFFER_SIZE];
size_t offset = 0;
if (display_type == 1) {
printf("File length: %ld\n", len);
printf("Displaying first %ld bytes:\n", num_bytes);
while (offset < num_bytes) {
size_t read_size = fread(buffer, 1, BUFFER_SIZE, file);
print_hex(buffer, read_size, offset);
offset += read_size;
}
} else if (display_type == 2) {
if (num_bytes > len) {
fprintf(stderr, "Error: Display size exceeds file length.\n");
exit(EXIT_FAILURE);
}
fseek(file, len - num_bytes, SEEK_SET);
printf("File length: %ld\n", len);
printf("Displaying last %ld bytes:\n", num_bytes);
while (offset < num_bytes) {
size_t read_size = fread(buffer, 1, BUFFER_SIZE, file);
offset += read_size;
if (offset > num_bytes) {
// Move back to the correct position if we have read too much
fseek(file, offset - num_bytes, SEEK_SET);
offset = num_bytes;
}
}
while (offset > 0) {
size_t read_size = fread(buffer, 1, BUFFER_SIZE, file);
print_hex(buffer, read_size, len - offset);
offset -= read_size;
}
} else {
fprintf(stderr, "Error: Invalid display type.\n");
exit(EXIT_FAILURE);
}
fclose(file);
}
int main(int argc, char *argv[]) {
if (argc != 4) {
fprintf(stderr, "Usage: %s <filename> -h <n>|-t <n>\n", argv[0]);
exit(EXIT_FAILURE);
}
const char *filename = argv[1];
const char *option = argv[2];
size_t num_bytes = atoi(argv[3]);
int display_type;
if (strcmp(option, "-h") == 0) {
display_type = 1;
} else if (strcmp(option, "-t") == 0) {
display_type = 2;
} else {
fprintf(stderr, "Error: Invalid option. Use -h or -t.\n");
exit(EXIT_FAILURE);
}
display_file(filename, display_type, num_bytes);
return 0;
}
myxxd 支持命令行传入参数-h n 显示前n个字节,-t n 显示最后面n 个字节,注意要先打印文件长度len, 保证n <= len
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具