DF-3248 / hscan.c
#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> static int fd; static int rdok(unsigned long long a, unsigned char *b, int len){ ssize_t n = pread(fd, b, len, (off_t)a); return n == len; } int main(void){ fd=open("/dev/kmem",O_RDONLY); unsigned long long start=0xfffff80040000000ULL, end=0xfffff80080000000ULL; unsigned long long win=2ULL<<20; unsigned char *p=malloc(win); unsigned char magic[4]={0xAE,0x0A,0xE4,0xF7}; int hits=0; unsigned long long a=start; while(a<end){ ssize_t n=pread(fd,p,win,(off_t)a); if(n>4096){ unsigned char *q=p; while((q=memmem(q,(p+n)-(q),magic,4))){ if(q+0xA8<p+n && q[0x10]==5 && !memcmp(q+0x11,"ZFILE",5)){ unsigned long long addr=a+(q-p); unsigned char ext[8]; /* live hpfsnode (not the 512B fnode buffer copy): h_flag at * h_fn+560-... struct hpfsnode: h_fn@off, then h_vp..h_flag; * h_flag sits 40 bytes past the 520-byte h_fn */ if(rdok(addr+560, ext, 4)){ unsigned int fl; memcpy(&fl,ext,4); if((fl & 0xA)==0xA){ printf("HPFN %llx flag=%x\n",addr,fl); hits++; } else printf("SKIP %llx (flag=%x, fnode-buffer copy?)\n",addr,fl); } } q+=4; } a+=win; } else { for(unsigned long long b=a;b<a+win && b<end;b+=4096){ ssize_t m=pread(fd,p,4096,(off_t)b); if(m<4096) continue; unsigned char *q=p; while((q=memmem(q,(p+m)-(q),magic,4))){ if(q+0xA8<p+m && q[0x10]==5 && !memcmp(q+0x11,"ZFILE",5)){ unsigned long long addr=b+(q-p); unsigned char ext[8]; if(rdok(addr+560, ext, 4)){ unsigned int fl; memcpy(&fl,ext,4); if((fl & 0xA)==0xA){ printf("HPFN %llx flag=%x\n",addr,fl); hits++; } else printf("SKIP %llx (flag=%x)\n",addr,fl); } } q+=4; } } a+=win; } } printf("HSCAN_DONE hits=%d\n",hits); return 0;} |