Mail Archives: djgpp/1999/04/03/08:35:42
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 <stdio.h>
#include <stdlib.h>
#include <dpmi.h>
#include <go32.h>
#include <pc.h>
#include <process.h>
#include <keys.h>
#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. -----
- Raw text -