// 该子程序用来打印出错中断的名称、出错号、调用程序的EIP、EFLAGS、ESP、fs寄存器值、 // 段的基址、段的长度、进程号pid、任务号、10字节指令码。如果堆栈在用户数据段,则还 // 打印16字节的堆栈内容。 static void die(char * str,long esp_ptr,long nr) { long * esp = (long *) esp_ptr; int i; printk("%s: %04x\n\r",str,nr&0xffff); // 下行打印语句显示当前调用进程的CS:EIP、EFLAGS和SS:ESP的值。参照图8-4,这里esp[0]即为 // 图中的esp0位置。因此我们把这句拆分开来看为: // 1)EIP:\t%04x:%p\n -- esp[1]是段选择符(cs),esp[0]是eip // 2)EFLAGS:\t%p -- esp[2]是EFLAGS // 3)ESP:\t%04x:%p\n -- esp[4]是原ss,esp[3]是原esp printk("EIP:\t%04x:%p\nEFLAGS:\t%p\nESP:\t%04x:%p\n", esp[1],esp[0],esp[2],esp[4],esp[3]); printk("fs: %04x\n",_fs()); printk("base: %p, limit: %p\n",get_base(current->ldt[1]),get_limit(0x17)); if (esp[4] == 0x17) { printk("Stack: "); for (i=0;i<4;i++) printk("%p ",get_seg_long(0x17,i+(long *)esp[3])); printk("\n"); } str(i); // 取当前运行任务的任务号(include/linux/sched.h 159) printk("Pid: %d, process nr: %d\n\r",current->pid,0xffff & i); for(i=0;i<10;i++) printk("%02x ",0xff & get_seg_byte(esp[1],(i+(char *)esp[0]))); printk("\n\r"); do_exit(11); /* play segment exception */ }
static void die(char * str,long esp_ptr,long nr) { long * esp = (long *) esp_ptr; int i; printk("%s: %04x\n\r",str,nr&0xffff); printk("EIP:\t%04x:%p\nEFLAGS:\t%p\nESP:\t%04x:%p\n", esp[1],esp[0],esp[2],esp[4],esp[3]); printk("fs: %04x\n",_fs()); printk("code base: %p, limit: %p\n",get_base(current->ldt[1]),get_limit(0x17)); printk("data base: %p, limit: %p\n",get_base(current->ldt[2]),get_limit(0x17)); long line = get_base(current->ldt[1])+esp[0]; long ph0 = (*(long *)(current->tss.cr3 + ((line>>20) & 0xffc ))); long ph1 = *(long*)(((line>>10) & 0xffc)+(*(long *)(current->tss.cr3 + ((line>>20) & 0xffc )))); printk("line: %p, ph: %p %p\n",line,ph0,ph1); if (esp[4] == 0x17) { printk("Stack: "); for (i=0;i<4;i++) printk("%p ",get_seg_long(0x17,i+(long *)esp[3])); printk("\n"); } str(i); printk("Pid: %d, process nr: %d\n\r",current->pid,0xffff & i); for(i=0;i<10;i++) printk("%02x ",0xff & get_seg_byte(esp[1],(i+(char *)esp[0]))); printk("\n\r"); do_exit(11); /* play segment exception */ }
// 该子程序用来打印出错中断的名称、出错号、调用程序的EIP、EFLAGS、ESP、fs段寄存器值、 // 段的基址、段的长度、进程号PID、任务号、10字节指令码。如果堆栈在用户数据段,则还 // 打印16字节的堆栈内容。 static void die(char * str,long esp_ptr,long nr) { long * esp = (long *) esp_ptr; int i; printk("%s: %04x\n\r",str,nr&0xffff); // 下行打印语句显示当前调用进程的CS:EIP、EFLAGS和SS:ESP的值。 // EIP:\t%04x:%p\n - esp[1]是段选择符(cs),esp[0]是eip. // EFLAGS:\t%p\n - esp[2]是eflags // ESP:\t%04x:%p\n - esp[4]是源ss,esp[3]是源esp printk("EIP:\t%04x:%p\nEFLAGS:\t%p\nESP:\t%04x:%p\n", esp[1],esp[0],esp[2],esp[4],esp[3]); printk("fs: %04x\n",_fs()); printk("base: %p, limit: %p\n",get_base(current->ldt[1]),get_limit(0x17)); if (esp[4] == 0x17) { printk("Stack: "); for (i=0;i<4;i++) printk("%p ",get_seg_long(0x17,i+(long *)esp[3])); printk("\n"); } str(i); // 取当前运行任务的任务号 printk("Pid: %d, process nr: %d\n\r",current->pid,0xffff & i); for(i=0;i<10;i++) printk("%02x ",0xff & get_seg_byte(esp[1],(i+(char *)esp[0]))); printk("\n\r"); do_exit(11); /* play segment exception */ }
int main(void) { unsigned int a = 0x400440; printf("%x\n", &a); //unsigned int *res = get_seg_byte(0x400440, &a); //printf("%x\n", *res); unsigned int res3 = get_seg_byte(2, &a); printf("%x\n", res3); printf("%x\n", a); //printf("%x\n", *(unsigned int *)(res3)); unsigned int res2 = get_seg_mov(2, &a); printf("res2 %x\n", res2); return 0; }
static void die(char * str,long esp_ptr,long nr) { long * esp = (long *) esp_ptr; int i; printk("%s: %04x\n\r",str,nr&0xffff); printk("EIP:\t%04x:%p\nEFLAGS:\t%p\nESP:\t%04x:%p\n", esp[1],esp[0],esp[2],esp[4],esp[3]); printk("fs: %04x\n",_fs()); printk("base: %p, limit: %p\n",get_base(current->ldt[1]),get_limit(0x17)); if (esp[4] == 0x17) { printk("Stack: "); for (i=0;i<4;i++) printk("%p ",get_seg_long(0x17,i+(long *)esp[3])); printk("\n"); } str(i); printk("Pid: %d, process nr: %d\n\r",current->pid,0xffff & i); for(i=0;i<10;i++) printk("%02x ",0xff & get_seg_byte(esp[1],(i+(char *)esp[0]))); printk("\n\r"); do_exit(11); /* play segment exception */ }