//------------------------------------------------------------------- // showgdt.cpp // // This application uses an "unprivileged" Pentium instruction // to obtain the base-address and segment-limit for the Global // Descriptor Table, located within the Linux kernel's address // space, and also installs a device-driver module ('dram.o'), // allowing it to read from our machine's memory as if it were // a file (named '/dev/dram'), so that the GDT descriptors can // be read and displayed as quadwords in hexadecimal notation. // Note that 'root' privileges are normally needed, to install // kernel modules or to create device-nodes, like this: // // root# /bin/mknod /dev/dram c 253 0 // root# /sbin/insmod dram.o // // NOTE: Written and tested using Linux kernel version 2.4.21. // // programmer: ALLAN CRUSE // written on: 16 MAR 2003 // revised on: 01 MAR 2004 -- use /dev/dram in lieu of /dev/ram //------------------------------------------------------------------- #include // for printf(), perror() #include // for open() #include // for exit() #include // for read(), close() #define TASK_SIZE 0xC0000000 #define virt_to_phys(vaddr) ( vaddr - TASK_SIZE ) char devname[] = "/dev/dram"; // name of the 'device' file unsigned short gdtr[3]; // to hold 48-bit GDTR value unsigned long long *gdt; // pointer to 64-bit entries int main( int argc, char **argv ) { // install device-driver module in the kernel system( "/sbin/insmod dram.o" ); // open device file for reading physical memory int fd = open( devname, O_RDONLY ); if ( fd < 0 ) { perror( devname ); exit(1);} // get virtual address of the processor's GDT asm(" sgdt gdtr " ); long gdtbase = *(unsigned long*)(gdtr+1); long gdtsize = 1 + gdtr[0]; // allocate a memory-buffer for the GDT gdt = (unsigned long long *)malloc( gdtsize ); if ( !gdt ) { perror( "malloc" ); exit(1); } // read the table of interrupt descriptors lseek( fd, virt_to_phys(gdtbase), SEEK_SET ); int n_entries = gdtsize/8; for (int i = 0; i < n_entries; i++) { int nbytes = read( fd, gdt+i, 8 ); if ( nbytes < 8 ) { perror( "read" ); exit(1); } } // display the descriptors in hexadecimal format printf( "\n\nTABLE OF GLOBAL DESCRIPTORS %25s", " " ); printf( "(GDTR=%04X%04X-%04X)\n", gdtr[2], gdtr[1], gdtr[0] ); for (int i = 0; i < n_entries; i++) { if ( ( i % 4 ) == 0 ) printf( "\n%04X: ", i*8 ); printf( "%016llX ", gdt[ i ] ); } printf( "\n\n" ); // release the memory-buffer and close the device file free( gdt ); close( fd ); }