⬢ DragonFlyBSD Kernel Audit
DF-5833 / parse2.c
← back to finding ↓ download raw
#include <sys/types.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma pack(1)
typedef struct { unsigned char e_ident[16]; uint16_t e_type,e_machine; uint32_t e_version; uint64_t e_entry,e_phoff,e_shoff; uint32_t e_flags; uint16_t e_ehsize,e_phentsize,e_phnum,e_shentsize,e_shnum,e_shstrndx; } Ehdr;
typedef struct { uint32_t p_type,p_flags; uint64_t p_offset,p_vaddr,p_paddr,p_filesz,p_memsz,p_align; } Phdr;
#pragma pack()
int main(int argc,char**argv){
    FILE*f=fopen(argv[1],"rb"); Ehdr eh; fread(&eh,sizeof eh,1,f);
    Phdr*ph=calloc(eh.e_phnum,56); fseek(f,eh.e_phoff,SEEK_SET); fread(ph,56,eh.e_phnum,f);
    uint64_t no=0,ns=0,p1off=0;
    for(int i=0;i<eh.e_phnum;i++) if(ph[i].p_type==4){no=ph[i].p_offset;ns=ph[i].p_filesz;}
    for(int i=0;i<eh.e_phnum;i++) if(ph[i].p_type==1){p1off=ph[i].p_offset;break;}
    printf("phnum=%u note_off=%llu note_sz=%llu seg1_off=%llu\n",eh.e_phnum,(unsigned long long)no,(unsigned long long)ns,(unsigned long long)p1off);
    /* expected WRITE end raw = 64 + phnum*56 + note_sz + 100 + C + 4320 + 40 + nfileinfo*80 */
    /* inspect the region after the notes: vminfo(96) vn_count(4) vn_hdrs... sigs(4320) filehdr(40)... */
    unsigned char *b=malloc(ns+6000); fseek(f,no,SEEK_SET); fread(b,1,ns+6000,f);
    uint64_t p=no+ns; /* absolute file offset of vminfo */
    printf("vminfo region at %llu:\n",(unsigned long long)p);
    /* ckpt_vminfo: cvm_dsize.. 6 segsz + 6 caddr — dump first 96 bytes */
    for(int r=0;r<6;r++){ for(int c=0;c<16;c++) printf("%02x ", b[(p-no)+r*16+c]); printf("\n"); }
    int vnc; memcpy(&vnc, b+(p-no)+96, 4);
    printf("vn_count=%d\n", vnc);
    /* after vn_hdrs: siginfo: csi_ckptpisz = sizeof(struct ckpt_siginfo)=4320 */
    uint64_t sigp = p + 100 + (uint64_t)vnc*120;
    int pisz; memcpy(&pisz, b+(sigp-no), 4);
    printf("siginfo at %llu csi_ckptpisz=%d (expect 4320)\n",(unsigned long long)sigp,pisz);
    uint64_t fh = sigp + 4320;
    int magic=0,nfiles=0; memcpy(&magic,b+(fh-no),4); memcpy(&nfiles,b+(fh-no)+4,4);
    printf("filehdr at %llu magic=%x nfiles=%d\n",(unsigned long long)fh,magic,nfiles);
    /* WRITE_end_raw = fh + 40 + nfiles*80 ; check rounding vs seg1_off */
    uint64_t wer = fh + 40 + (uint64_t)nfiles*80;
    printf("WRITE_end_raw=%llu  round_page=%llu  seg1_off=%llu  %s\n",
        (unsigned long long)wer,(unsigned long long)((wer+4095)&~4095ULL),
        (unsigned long long)p1off,
        (((wer+4095)&~4095ULL)==p1off)?"CONSISTENT":"INCONSISTENT");
    return 0;
}