From: ams AT ludd DOT luth DOT se (Martin Str|mberg) Newsgroups: comp.os.msdos.djgpp Subject: LONG: My INT31 handler isn't feeling too swell Date: 3 Apr 1999 12:31:37 GMT Organization: University of Lulea, Sweden Lines: 330 Message-ID: <7e51n9$e96$1@news.luth.se> NNTP-Posting-Host: queeg.ludd.luth.se X-Newsreader: TIN [UNIX 1.3 950824BETA PL0] To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com I wonder what you people out there knowledgable in crash dumps have to say about this one. I'm trying to hook INT31 and intercept call to functions 0x0000 and 0x0001 (allocate and free ldt descriptor) to work around a bug in WINDOZE. After hooking INT31, the program simply spawnl()s bash. At the new bash prompt I'm able to do one ls, but next ls results in the crash. I just don't understand what the dump is telling me. WINDOZE 4.1 (98) English version. DJGPP 2.02. ----- Program crash starts. ----- bash$ cd hackery/ds/ bash$ ./apams cs = 319: base = 833a1000, limit = 5ffff, access = 40fb. ds = 327: base = 833a1000, limit = 5ffff, access = 40f3. ss = 327: base = 833a1000, limit = 5ffff, access = 40f3. descriptors = 000108cc, &descriptors = 000108cc. About to insert me... Spawning... bash$ ls #apams.S# apams.1.c apams~ get_sel.log simple.exe simple3.c~ 1 apams.c bash.exe rm_me simple2.c simple3.exe 1.c apams.c~ crash.txt simple simple2.c~ tst.c 1.exe apams.dis dpmi_sel.c simple.c simple3 tst.c~ apams apams.exe get_sel.EXE simple.c~ simple3.c tst.exe bash$ ls Exiting due to signal SIGSEGV General Protection Fault at eip=000003c0, error=fffc eax=00000300 ebx=00020021 ecx=00003c00 edx=000001df esi=00000000 edi=00001000 ebp=00160912 esp=0000075a program=F:\hackery\ds\apams cs: sel=01c7 base=0001f3c0 limit=0000ffff ds: sel=01bf base=0001f3c0 limit=0000ffff es: sel=01bf base=0001f3c0 limit=0000ffff fs: sel=0000 gs: sel=0000 ss: sel=01bf base=0001f3c0 limit=0000ffff App stack: [00057154..00017154] Exceptn stack: [00017040..00015100] ----- Program crash ends. ----- ----- Details from WINDOZE dialogue starts. ----- The program encountered a general protection exception. Fault location: 013F:1562 Interrupts in service: None ----- Details from WINDOZE dialogue ends. ----- Any ideas? Arnold, Symphony No. 3, MartinS For completeness, although it makes my post very long, I also post the code for my INT31 hooking program. I know it's not the world's best assembly program, but I'm new at assembly programming. Try it if you're feeling adventureous. ----- Prorgam starts. ----- #include #include #include #include #include #include #include #define MAX_BUF (16) extern void handler(void); extern void handler_end(void); unsigned short descriptors[ MAX_BUF] = { 0 }; __dpmi_paddr old_isr, new_isr; __dpmi_meminfo info; unsigned short the_ds; asm(" .text .align 2,0x90 .globl _handler _handler: pushw %ds /*pushw %ss popw %ds*/ movw %cs:_the_ds, %ds cmpw $0, %ax je allocate cmpw $1, %ax je free /* Fail */ fail: /* Jump to previous handler. */ chain: popw %ds ljmp %cs:_old_isr /* Allocate LDT descriptors. */ allocate: /* Check if we are supposed to allocate several ones and go to WINDOZE if so. */ cmpw $1, %cx jg chain jne fail /* Search for reusable one. */ pushl %edx movl $0, %eax movl $_descriptors, %edx allocate_try_again: cmpw $0, (%edx, %eax, 2) jne allocate_found_one incl %eax cmpl $0xf, %eax /* MAX_BUF - 1 */ jg allocate_not_found_one jmp allocate_try_again allocate_found_one: pushl %ecx movw (%edx, %eax, 2), %cx movw $0, (%edx, %eax, 2) movw %cx, %ax /* Set base and limit. */ pushl %ebx pushl %eax movl %eax, %ebx movl $0x7, %eax movl $0, %ecx movl $0, %edx sti int $0x31 cli popl %eax pushl %eax movl %eax, %ebx movl $0x8, %eax movl $0, %ecx movl $0, %edx sti int $0x31 cli popl %eax popl %ebx popl %ecx popl %edx clc done: popw %ds sti iret allocate_not_found_one: popl %edx movw $0, %ax jmp chain /* Free LDT descriptor. */ free: /* Search for empty slot. */ pushl %edx movl $0, %eax movl $_descriptors, %edx free_try_again: cmpw $0, (%edx, %eax, 2) je free_found_one incl %eax cmpl $0xf, %eax /* MAX_BUF - 1 */ jg free_not_found_one jmp free_try_again free_found_one: movw %bx, (%edx, %eax, 2) popl %edx clc jmp done free_not_found_one: popl %edx movw $1, %ax jmp chain /* End of fun. */ _handler_end: nop "); int main(int argc, char *argv[]) { unsigned long base; __dpmi_get_segment_base_address(_my_cs(), &base); printf("cs = %hd: base = %lx, limit = %lx, access = %x.\n", _my_cs(), base, __ dpmi_get_segment_limit(_my_cs()), __dpmi_get_descriptor_access_rights(_my_cs())) ; __dpmi_get_segment_base_address(_my_ds(), &base); printf("ds = %hd: base = %lx, limit = %lx, access = %x.\n", _my_ds(), base, __ dpmi_get_segment_limit(_my_ds()), __dpmi_get_descriptor_access_rights(_my_ds())) ; __dpmi_get_segment_base_address(_my_ss(), &base); printf("ss = %hd: base = %lx, limit = %lx, access = %x.\n", _my_ss(), base, __ dpmi_get_segment_limit(_my_ss()), __dpmi_get_descriptor_access_rights(_my_ss())) ; printf("descriptors = %08x, &descriptors = %08x.\n", (unsigned int)descriptors , (unsigned int)&descriptors); info.handle = 1; info.size = handler_end - handler; info.address = (unsigned long)&handler; if( __dpmi_lock_linear_region(&info) ) { perror("lock_linear_region 1 failed.\n"); } info.size = sizeof(descriptors) * MAX_BUF; info.address = (unsigned long)descriptors; if( __dpmi_lock_linear_region(&info) ) { perror("lock_linear_region 2 failed.\n"); } info.size = sizeof(old_isr); info.address = (unsigned long)&old_isr; if( __dpmi_lock_linear_region(&info) ) { perror("lock_linear_region 3 failed.\n"); } info.size = sizeof(the_ds); info.address = (unsigned long)&the_ds; if( __dpmi_lock_linear_region(&info) ) { perror("lock_linear_region 4 failed.\n"); } printf("About to insert me...\n"); getkey(); the_ds = _my_ds(); __dpmi_get_protected_mode_interrupt_vector(0x31, &old_isr); new_isr.offset32 = (int)&handler; asm("movw %%cs, %0": "=g" (new_isr.selector) ); if( __dpmi_set_protected_mode_interrupt_vector(0x31, &new_isr) ) { perror("set_protected_mode_int failed."); } printf("Spawning...\n"); spawnl(P_WAIT, "bash", "bash", NULL); /* system("bash");*/ printf("Spawning done.\n"); printf("About to remove...\n"); if( __dpmi_set_protected_mode_interrupt_vector(0x31, &old_isr) ) { perror("__dpmi_set_protected_mode_int (retore) failed."); } info.size = handler_end - handler; info.address = (unsigned long)&handler; if( __dpmi_unlock_linear_region(&info) ) { perror("unlock_linear_region 1 failed.\n"); } info.size = sizeof(descriptors) * MAX_BUF; info.address = (unsigned long)descriptors; if( __dpmi_unlock_linear_region(&info) ) { perror("unlock_linear_region 2 failed.\n"); } info.size = sizeof(old_isr); info.address = (unsigned long)&old_isr; if( __dpmi_unlock_linear_region(&info) ) { perror("unlock_linear_region 3 failed.\n"); } info.size = sizeof(the_ds); info.address = (unsigned long)&the_ds; if( __dpmi_unlock_linear_region(&info) ) { perror("unlock_linear_region 4 failed.\n"); } return 0; } ----- Prorgam ends. -----