v14i038: nlist: nlist interface/kmem dumper

Warren Tucker wht at n4hgf.UUCP
Fri Jul 27 09:54:11 AEST 1990


Posting-number: Volume 14, Issue 38
Submitted-by: wht at 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 at 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 at 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



More information about the Comp.sources.misc mailing list