wht@n4hgf.UUCP (Warren Tucker) (07/27/90)
Posting-number: Volume 14, Issue 38 Submitted-by: wht@n4hgf.UUCP (Warren Tucker) Archive-name: nlist_wht/part01 [A solid week of network bounces and non-reconnectable sessions can lead to major frustration... and not just for the person getting bounced. ++bsa] This is a command-level interface to nlist(3)/nlist(S) for exploratory hacking. It can also dump kernel memory, privilege permitting. Works on *IX systems which support nlist. comp.sources.misc v06i019 xlist is an equivalent for XENIX systems. Compile by: cc -O -o nlist nlist.c Usage is below in the source header. Root is usually the only user who can even read /unix to nlist but certainly /dev/kmem should be protected as SOP. #!/bin/sh # This is nlist, a shell archive (shar 3.32) # made 07/17/1990 18:32 UTC by wht@n4hgf.Mt-Park.GA.US # Source directory /u1/src/u386mon/nlist # # existing files WILL be overwritten # This format requires very little intelligence at unshar time. # "echo" and "sed" will be needed. # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 6328 -rw-r--r-- nlist.c # # ============= nlist.c ============== echo "x - extracting nlist.c (Text)" sed 's/^X//' << 'SHAR_EOF' > nlist.c && X/* CHK=0x8201 */ X/*+-------------------------------------------------------------------------- X nlist.c - peruse /unix symbol table, optionally dumping kmem X wht@n4hgf.Mt-Park.GA.US X X This is a command-level interface to nlist(3)/nlist(S) for X exploratory hacking. X X Compile by: cc -O -o nlist nlist.c X X Root is usually the only user who can even read /unix to nlist X but certainly /dev/kmem should be protected as SOP. X X Usage: nlist ksym[:length] ... X X where ksym is a kernel symbol and length is an optional parameter X indicating the length of a block of data to dump from /dev/kmem X for example: X X$ nlist proc:0x20 sio_tty:010 v:23 ttyhog doo_dad X name type class value X-------------------------------- ---- ----- -------- Xproc 0000 02 d007cda0 Xsio_tty 0000 02 d007ba0c Xv 0000 02 d0072214 Xttyhog 0000 02 d00741a8 Xdoo_dad: not found X Xproc addr=d007cda0 length=00000020 XD007CDA0 01 00 00 14 19 20 00 00 00 00 00 00 00 00 00 00 | ..... .......... | XD007CDB0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ | X Xsio_tty addr=d007ba0c length=00000008 XD007BA0C 00 00 00 00 00 00 00 00 | ........ | X Xv addr=d0072214 length=00000017 XD0072214 58 02 00 00 32 00 00 00 C8 00 00 00 40 DC 09 D0 | X...2...H...@\.P | XD0072224 C8 00 00 00 34 C4 08 | H...4D. | X X---------------------------------------------------------------------------*/ X/*+:EDITS:*/ X/*:07-17-1990-13:43-wht-adapt xlist */ X X#include <stdio.h> X#include <fcntl.h> X#include <sys/types.h> X#include <nlist.h> X X#define UNIX_KERNEL "/unix" X X#define UINT8 unsigned char X#define UINT16 unsigned short X#define UINT32 unsigned long X Xint fd_kmem; X X#define dump_putc(ch) fputc((ch),stdout) X#define dump_puts(str) fputs(str,stdout) X X/*+----------------------------------------------------------------------- X hex_dump#... subservient routines X------------------------------------------------------------------------*/ Xvoid hex_dump4(int4) XUINT8 int4; X{ X int4 &= 15; X dump_putc((int4 >= 10) ? (int4 + 'A' - 10) : (int4 + '0')); X} X Xvoid hex_dump8(int8) XUINT8 int8; X{ X hex_dump4(int8 >> 4); X hex_dump4(int8); X} X Xvoid hex_dump16(int16) XUINT16 int16; X{ X hex_dump8(int16 >> 8); X hex_dump8(int16); X} X Xvoid hex_dump32(int32) XUINT32 int32; X{ X hex_dump16((UINT16)(int32 >> 16)); X hex_dump16((UINT16)int32); X} X X/*+----------------------------------------------------------------- X hex_dump(str,len) X------------------------------------------------------------------*/ Xvoid Xhex_dump(str,len,offset) XUINT8 *str; Xint len; Xlong offset; X{ X register int itmp; X register int istr = 0; X X while(istr < len) X { X hex_dump32(offset + istr); X for(itmp = 0; itmp < 16; ++itmp) X { X dump_putc(' '); X if( istr + itmp >= len) X { X dump_putc(' '); X dump_putc(' '); X continue; X } X hex_dump8(str[istr + itmp]); X } X dump_puts(" | "); X for(itmp = 0; itmp < 16; ++itmp) X { X register char dchar; X if(istr + itmp >= len) X dump_putc(' '); X else X { X dchar = str[istr + itmp] & 0x7F; X dump_putc(((dchar >= ' ') && (dchar < 0x7f)) ? dchar : '.' ); X } X } X dump_puts(" |\n"); X istr += 16; X } /* end of while(istr < len) */ X X} /* end of hex_dump */ X X/*+------------------------------------------------------------------------- X dump_kmem(seekpos,length) X--------------------------------------------------------------------------*/ Xvoid Xdump_kmem(seekpos,length) Xlong seekpos; Xint length; X{ X char *kmemdata; X char *malloc(); X long lseek(); X X if((kmemdata = malloc(length)) == NULL) X { X printf("cannot allocate %d bytes\n",length); X return; X } X X if(lseek(fd_kmem,seekpos,0) == -1L) X { X fprintf(stderr,"cannot seek kmem (%d) to %08lx",fd_kmem,seekpos); X perror(""); X free(kmemdata); X return; X } X X if(read(fd_kmem,kmemdata,length) != length) X { X perror("kmem read"); X free(kmemdata); X return; X } X X hex_dump(kmemdata,length,seekpos); X free(kmemdata); X X} /* end of dump_kmem */ X X/*+------------------------------------------------------------------------- X open_kmem() X--------------------------------------------------------------------------*/ Xvoid Xopen_kmem() X{ X if((fd_kmem = open("/dev/kmem",O_RDONLY,0)) < 0) X { X perror("/dev/kmem"); X exit(1); X } X} /* end of open_kmem */ X X/*+------------------------------------------------------------------------- X main(argc,argv,envp) X--------------------------------------------------------------------------*/ Xmain(argc,argv,envp) Xint argc; Xchar **argv; Xchar **envp; X{ X register int iargv; X struct nlist *nlst; X register struct nlist *nn; X register int *count; X char *cptr; X char *strrchr(); X char *calloc(); X int need_kmem = 0; X X if(argc < 2) X exit(1); X X#ifdef REPEAT_ARGV X for(iargv = 0; iargv < argc; iargv++) X printf("%s ",argv[iargv]); X printf("\n"); X#endif X X if((nlst = (struct nlist *)calloc(argc,sizeof(struct nlist))) == X (struct nlist *)0) X { X fprintf(stderr,"memory not available\n"); X exit(1); X } X X if((count = (int *)calloc(argc,sizeof(int))) == (int *)0) X { X fprintf(stderr,"memory not available\n"); X exit(1); X } X X nn = nlst; X for(iargv = 1; iargv < argc; iargv++) X { X if(cptr = strrchr(argv[iargv],':')) X { X *cptr++ = 0; X sscanf(cptr,"%i",&count[iargv - 1]); X need_kmem = 1; X } X nn->n_name = argv[iargv]; X nn++; X } X X nlist(UNIX_KERNEL,nlst); X X if(need_kmem) X open_kmem(); X X nn = nlst; X fputs(" name type class value\n",stdout); X fputs("-------------------------------- ---- ----- ---------\n",stdout); X for(iargv = 1; iargv < argc; iargv++) X { X if(!nn->n_sclass && !nn->n_value) X { X printf("%s: not found\n",nn->n_name); X nn++; X continue; X } X X printf("%-32.32s %04x %02x %08lx\n", X nn->n_name, X nn->n_type, X (unsigned char)nn->n_sclass, X nn->n_value); X X nn++; X } X X nn = nlst; X for(iargv = 1; iargv < argc; iargv++) X { X if(!nn->n_sclass && !nn->n_value) X { X nn++; X continue; X } X X if(count[iargv - 1]) X { X printf("\n%s addr=%08lx length=%08x\n", X nn->n_name,nn->n_value,count[iargv - 1]); X dump_kmem(nn->n_value,count[iargv - 1]); X } X X nn++; X } X exit(0); X} /* end of main */ X X/* vi: set tabstop=4 shiftwidth=4: */ X/* end of nlist.c */ SHAR_EOF exit 0