You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UNIX C解析特定二进制文件格式:验证限制并输出指定信息

Alright, let's build this custom binary file parser for UNIX environments. I'll walk you through a complete implementation that handles all the requirements, including validation checks and the specified output format.

Custom Binary File Parser (UNIX C Implementation)

Quick Spec Recap

First, let's restate the file format to keep things clear:

File Header (variable total size)

  • Magic: 1 byte (unique identifier for your file type)
  • Header_size: 2 bytes (total size of the entire header, including section headers)
  • Version: 1 byte (file format version)
  • No_of_sections: 1 byte (number of sections in the file)
  • Section_headers: No_of_sections × sizeof(section_header) bytes (array of section metadata)

Section Header (29 bytes each)

  • Sect_name: 17 bytes (null-terminated section name)
  • Sect_type: 4 bytes (section type identifier)
  • Sect_offset: 4 bytes (offset from start of file to section data)
  • Sect_size: 4 bytes (size of the section data)

Complete Code Implementation

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <arpa/inet.h>

// Adjust this to match your file's actual magic number
#define EXPECTED_MAGIC 0x42

typedef struct {
    char sect_name[17];
    uint32_t sect_type;
    uint32_t sect_offset;
    uint32_t sect_size;
} section_header_t;

typedef struct {
    uint8_t magic;
    uint16_t header_size;
    uint8_t version;
    uint8_t no_of_sections;
} file_header_t;

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <binary_file>\n", argv[0]);
        return EXIT_FAILURE;
    }

    int fd = open(argv[1], O_RDONLY);
    if (fd == -1) {
        perror("Failed to open file");
        return EXIT_FAILURE;
    }

    // Get total file size to validate section bounds
    off_t file_size = lseek(fd, 0, SEEK_END);
    if (file_size == -1) {
        perror("Failed to get file size");
        close(fd);
        return EXIT_FAILURE;
    }
    lseek(fd, 0, SEEK_SET);

    // Read main file header
    file_header_t header;
    ssize_t bytes_read = read(fd, &header, sizeof(file_header_t));
    if (bytes_read != sizeof(file_header_t)) {
        perror("Failed to read file header");
        close(fd);
        return EXIT_FAILURE;
    }

    // Convert network byte order to host byte order (critical for cross-UNIX compatibility)
    uint16_t declared_header_size = ntohs(header.header_size);

    // Validation 1: Check magic number
    if (header.magic != EXPECTED_MAGIC) {
        fprintf(stderr, "Error: Invalid magic number (got 0x%02x, expected 0x%02x)\n",
                header.magic, EXPECTED_MAGIC);
        close(fd);
        return EXIT_FAILURE;
    }

    // Validation 2: Calculate expected header size vs declared size
    uint16_t expected_header_size = sizeof(file_header_t) + header.no_of_sections * sizeof(section_header_t);
    if (declared_header_size != expected_header_size) {
        fprintf(stderr, "Error: Header size mismatch (declared %u, expected %u)\n",
                declared_header_size, expected_header_size);
        close(fd);
        return EXIT_FAILURE;
    }

    // Validation 3: Ensure header doesn't exceed file size
    if (declared_header_size > file_size) {
        fprintf(stderr, "Error: Header size (%u) exceeds total file size (%ld)\n",
                declared_header_size, file_size);
        close(fd);
        return EXIT_FAILURE;
    }

    // Allocate memory for section headers
    section_header_t *sections = malloc(header.no_of_sections * sizeof(section_header_t));
    if (!sections) {
        perror("Failed to allocate memory for sections");
        close(fd);
        return EXIT_FAILURE;
    }

    // Read section headers
    bytes_read = read(fd, sections, header.no_of_sections * sizeof(section_header_t));
    if (bytes_read != header.no_of_sections * sizeof(section_header_t)) {
        perror("Failed to read section headers");
        free(sections);
        close(fd);
        return EXIT_FAILURE;
    }

    // Prepare output string
    printf("version=%u nr_sections=%u", header.version, header.no_of_sections);
    for (int i = 0; i < header.no_of_sections; i++) {
        // Convert section fields from network byte order
        uint32_t type = ntohl(sections[i].sect_type);
        uint32_t size = ntohl(sections[i].sect_size);

        // Validation 4: Ensure section data fits within file bounds
        uint32_t offset = ntohl(sections[i].sect_offset);
        if (offset + size > file_size) {
            fprintf(stderr, "\nWarning: Section %d (%s) exceeds file bounds - skipping\n",
                    i+1, sections[i].sect_name);
            continue;
        }

        printf(" section%d: %s %u %u", i+1, sections[i].sect_name, type, size);
    }
    printf("\n");

    // Cleanup
    free(sections);
    close(fd);
    return EXIT_SUCCESS;
}

Key Details & Validation Checks

Let's break down the critical parts of this implementation:

  • Magic Number Validation: Ensures we're parsing the correct file type (update EXPECTED_MAGIC to match your actual file specification)
  • Header Size Mismatch Check: Confirms the declared header size matches the calculated size (based on section count), catching malformed files
  • File Bound Checks: Prevents out-of-bounds reads by verifying section offsets + sizes don't exceed the total file size
  • Byte Order Handling: Uses ntohs() and ntohl() to convert network byte order (standard for most binary formats) to the host system's byte order, ensuring compatibility across different UNIX-based systems
  • Error Handling: Properly checks for failures in file operations, memory allocation, and reads, with clear error messages

Compilation & Usage

  1. Save the code to a file (e.g., bin_parser.c)
  2. Compile with GCC:
    gcc -o bin_parser bin_parser.c
    
  3. Run the parser on your binary file:
    ./bin_parser your_binary_file.bin
    

内容的提问来源于stack exchange,提问作者Siespi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:32:24