www.delorie.com/archives/browse.cgi   search  
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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019