home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1990 / 10 / schulman.asc < prev    next >
Text File  |  1990-08-16  |  17KB  |  520 lines

  1. _OPENING OS/2'S BACKDOOR_
  2. by Andrew Schulman
  3.  
  4. [LISTING ONE]
  5.  
  6. ; DEVHLP.ASM
  7. ; to produce DEVHLP.SYS ("OS/2 Device Driver in a Can")
  8. ; Andrew Schulman, 32 Andrew St., Cambridge MA 02139
  9. ; with revisions by Art Rothstein, Morgan Labs, San Francisco, CA
  10.  
  11. ; DEF file:
  12. ; LIBRARY DEVHLP
  13. ; DESCRIPTION 'DEVHLP.SYS (c) Andrew Schulman 1990'
  14. ; PROTMODE
  15.  
  16. ; masm devhlp; && link devhlp,devhlp.sys,,,devhlp.def
  17.  
  18. ; put in OS/2 config.sys:
  19. ; device=devhlp.sys
  20.  
  21. ; access with DosOpen ("DEVHLPXX"), DosDevIOCTL (category 128, func 60h)
  22.  
  23. .286p
  24.  
  25. ; the only specific DevHlp that DEVHLP.SYS knows about
  26. VerifyAccess        equ 27h
  27.  
  28. ioctlpkt struc
  29.                     db 13 dup (?)   ; header
  30.         cat         db ?            ; category
  31.         fun         db ?            ; function
  32.         param       dd ?            ; param area
  33.         dataptr     dd ?            ; data area
  34. ioctlpkt ends
  35.  
  36. regs    struc
  37.         regs_ax     dw ?
  38.         regs_bx     dw ?
  39.         regs_cx     dw ?
  40.         regs_dx     dw ?
  41.         regs_si     dw ?
  42.         regs_di     dw ?
  43.         regs_ds     dw ?
  44.         regs_es     dw ?
  45.         regs_flags  dw ?
  46. regs    ends
  47.  
  48. regs_size   equ     size regs
  49.  
  50. dgroup  group   _DATA
  51.  
  52. _DATA   segment word public 'DATA'
  53.  
  54. header  dd -1
  55.         dw 8880h
  56.         dw Strat
  57.         dw 0
  58.         db 'DEVHLPXX'
  59.         db 8 dup (0)
  60.  
  61. DevHlp  dd 0
  62.  
  63. dispch  dw Init             ; 0 -- Init
  64.         dw 12 dup (Error)   ; 1..12 -- not supported
  65.         dw DevOp            ; 13 -- DevOpen
  66.         dw DevOp            ; 14 -- DevClose
  67.         dw Error            ; 15 -- not supported
  68.         dw GenIOCtl         ; 16 -- DevIOCtl
  69.         dw 10 dup (Error)   ; 17..26 -- not supported
  70.  
  71. enddata dw 0
  72. _DATA   ends
  73.  
  74. _TEXT   segment word public 'CODE'
  75.  
  76.         assume cs:_TEXT, ds:DGROUP, es:NOTHING
  77.  
  78. Strat   proc far
  79.         mov di, es:[bx+2]
  80.         and di, 0ffh
  81.         cmp di, 26                       ; max # of commands
  82.         jle Strat1
  83.         call Error
  84.         jmp short Strat2
  85. Strat1: add di, di
  86.         call word ptr [di+dispch]
  87. Strat2: mov word ptr es:[bx+3], ax       ; set request header status
  88.         ret
  89. Strat   endp
  90.  
  91. ; used by DevOpen and DevClose
  92. DevOp   proc near
  93.         mov ax, 0100h
  94.         ret
  95. DevOp   endp
  96.  
  97. GenIOCtl    proc near
  98.         push es
  99.         push bx
  100.         cmp es:[bx].cat, 128
  101.         jne bad
  102.         cmp es:[bx].fun, 60h
  103.         jne bad
  104.         call Do_DevHlp
  105.         jc bad
  106.         mov ax, 0100h            ; no error
  107.         jmp short done
  108. bad:    mov ax, 8101h            ; error
  109. done:   pop bx
  110.         pop es
  111.         ret
  112. GenIOCtl endp
  113.  
  114. Do_DevHlp proc near
  115.         ; verify user's access:
  116.         ; VerifyAccess will shut down user's app in the event of error
  117.         mov ax, word ptr es:[bx+17]      ; selector of parameter block
  118.         mov di, word ptr es:[bx+15]      ; offset
  119.         mov cx, regs_size                ; length to be read
  120.         mov dx, VerifyAccess             ; read
  121.         call DevHlp
  122.         jnc ok1
  123.         ret
  124.  
  125. ok1:    mov ax, word ptr es:[bx+21]      ; selector of data buffer
  126.         mov di, word ptr es:[bx+19]      ; offset
  127.         mov cx, regs_size                ; length to be written
  128.         mov dx, (1 SHL 8) + VerifyAccess ; read/write
  129.         call DevHlp
  130.         jnc ok2
  131.         ret
  132.  
  133. ok2:    push ds                  ; see if we should verify ds
  134.         lds di, es:[bx].param
  135.         mov ax, [di].regs_ds
  136.         pop ds
  137.         test ax, ax              ; need to verify?
  138.         je nods                  ; skip if no
  139.         xor di, di               ; verify seg:0 for read, 1 byte
  140.         mov cx, 1                ; length
  141.         mov dx, VerifyAccess     ; read=0
  142.         call DevHlp
  143.         jc fini                  ; if carry flag set
  144.  
  145. nods:   push ds                  ; see if we should verify es
  146.         lds di, es:[bx].param
  147.         mov ax, [di].regs_es
  148.         pop ds
  149.         test ax, ax              ; need to verify?
  150.         je noes                  ; skip if no
  151.         xor di, di               ; verify seg:0 for read, 1 byte
  152.         mov cx, 1                ; length
  153.         mov dx, VerifyAccess     ; read=0
  154.         call DevHlp
  155.         jc fini                  ; if carry flag set
  156.  
  157. noes:   push ds                  ; going to be bashed!
  158.         push es
  159.         push bx
  160.  
  161.         ; save DevHlp address on stack so we can change ds
  162.         push word ptr DevHlp+2
  163.         push word ptr DevHlp
  164.  
  165.         ; get the parameters for DevHlp from regs
  166.         lds di, es:[bx].param
  167.         mov ax, [di].regs_ax
  168.         mov bx, [di].regs_bx
  169.         mov cx, [di].regs_cx
  170.         mov dx, [di].regs_dx
  171.         mov si, [di].regs_si
  172.         mov es, [di].regs_es
  173.         push    [di].regs_ds
  174.         mov di, [di].regs_di
  175.         pop ds
  176.  
  177.         ; here it is, the whole point of this exercise!
  178.         mov bp, sp
  179.         call dword ptr [bp]
  180.         pop bp          ; pull DevHlp address off stack
  181.         pop bp          ; without changing carry flag
  182.         jc fini
  183.  
  184.         ; save ES:BX to put in out-regs: destroys DX
  185.         mov bp, es
  186.         mov dx, bx
  187.  
  188.         ; get back old DS, ES:BX
  189.         pop bx
  190.         pop es
  191.         pop ds
  192.  
  193.         ; save FLAGS, SI, DS on stack
  194.         pushf
  195.         push si
  196.         push ds
  197.  
  198.         ; set up regs to return to the app
  199.         lds si, es:[bx].dataptr
  200.         mov [si].regs_ax, ax
  201.         pop [si].regs_ds
  202.         pop [si].regs_si
  203.         pop [si].regs_flags
  204.         mov [si].regs_cx, cx
  205.         mov [si].regs_bx, dx
  206.         mov [si].regs_es, bp
  207.         mov [si].regs_di, di
  208.         clc
  209. fini:   ret
  210. Do_DevHlp   endp
  211.  
  212. Error   proc near
  213.         mov ax, 8103h
  214.         ret
  215. Error   endp
  216.  
  217. Init    proc near
  218.         mov ax, es:[bx+14]
  219.         mov word ptr DevHlp, ax
  220.         mov ax, es:[bx+16]
  221.         mov word ptr DevHlp+2, ax
  222.  
  223.         mov word ptr es:[bx+14], offset _TEXT:Init       ; end of code
  224.         mov word ptr es:[bx+16], offset DGROUP:enddata
  225.         mov ax, 0100h
  226.         ret
  227. Init    endp
  228.  
  229. _TEXT   ends
  230.  
  231.         end
  232.  
  233.  
  234. [LISTING TWO]
  235.  
  236. /* DRVRLIST.C
  237.    list the device drivers in OS/2
  238.    Art Rothstein, 1990
  239.  
  240.    we assume the first driver in the chain is NUL and is in the global data
  241.    segment, and that the second driver (CON) is the same segment.
  242.  
  243.    cl -AL drvrlist.c (four-byte data pointers required for memchr)
  244. */
  245. #define INCL_DOSDEVICES
  246. #include <os2.h>
  247. #include <process.h>
  248. #include <stdio.h>
  249. #include <string.h>
  250. #include "devhlp.h"
  251.  
  252. USHORT devhlp ;
  253.  
  254. SEL MakeSel( SEL selValue)
  255. {
  256.   extern USHORT devhlp ;
  257.   REGS regs ;
  258.   USHORT ret ;
  259.  
  260.   regs.dx = DevHlp_VirtToPhys ;         // function requested
  261.   regs.ds = selValue ;                  // selector
  262.   regs.es = 0 ;                         // avoid trap
  263.   regs.si = 0 ;                         // offset
  264.   ret = DosDevIOCtl( ®s, ®s, 0x60, 128, devhlp) ;
  265.   if ( ret != 0  ||  regs.flags.carry != 0)
  266.     return 0 ;
  267.   // physical address in ax:bx
  268.   regs.cx = 0 ;                                  // limit 65,535
  269.   regs.dx = MAKEUSHORT( DevHlp_PhysToUVirt, UVirt_ReadWrite);
  270.   regs.es = 0 ;                                  // avoid trap
  271.   ret = DosDevIOCtl( ®s, ®s, 0x60, 128, devhlp) ;
  272.   if ( ret != 0  ||  regs.flags.carry != 0)      // if error
  273.     return 0 ;
  274.   return regs.es ;                               // return the selector
  275. }
  276.  
  277. BOOL ReleaseSel( SEL selValue)
  278. {
  279.   extern USHORT devhlp ;
  280.   REGS regs ;
  281.   USHORT ret ;
  282.  
  283.   regs.ax = selValue ;                           // selector to free
  284.   regs.dx = MAKEUSHORT( DevHlp_PhysToUVirt, UVirt_Release);
  285.   regs.ds = 0 ;                                  // safety
  286.   regs.es = 0 ;
  287.   ret = DosDevIOCtl( ®s, ®s, 0x60, 128, devhlp) ;
  288.   if ( ret != 0  ||  regs.flags.carry != 0)     // if error
  289.     return FALSE ;
  290.   return TRUE ;                                 // successful return
  291. }
  292.  
  293. void main( void)
  294. {
  295.   USHORT usOffsetDriver
  296.        , usBytesLeft;                       // in search for NUL device
  297.   PCH pchGlobal ;                           // pointer to system global data
  298.   static CHAR szDriverName[] = "DEVHLPXX"   // device helper driver
  299.         , szNullDriver[] = "NUL     ";      // first driver in system
  300.  
  301.   typedef struct _DDHEADER  {               // device driver header
  302.     struct _DDHEADER * pddNext ;            // chain to next driver
  303.     USHORT fsAttribute ;                    // driver attributes
  304.     USHORT usStrategyEntryOffset ;
  305.     USHORT usIDCEntryOffset ;               // inter device communication
  306.     CHAR chName[ 8] ;                       // name for character devices
  307.     USHORT usIDCEntrySegmentProt ;
  308.     USHORT usIDCDataSegmentProt ;
  309.     USHORT usIDCEntrySegmentReal ;
  310.     USHORT usIDCDataSegmentReal ;
  311.   }  DDHEADER ;
  312.   typedef DDHEADER * PDDHEADER ;
  313.   PDDHEADER pddCurrent                      // current DCB
  314.       , pddNext;                            // next DCB
  315.   SEL selDriver ;                           // selector of DCB
  316.  
  317.   // open the DEVHLP device
  318.   if ((devhlp = open(szDriverName, 0)) == -1) {
  319.     puts( "Can't find DEVHLP.SYS") ;
  320.     exit( 1) ;
  321.   }
  322.  
  323.   // locate the first driver
  324.   selDriver = 0x50 ;                        // global data segment
  325.   usOffsetDriver = 0 ;
  326.   usBytesLeft = 32000 ;                     // should be large enough
  327.   pchGlobal = MAKEP( MakeSel( selDriver), usOffsetDriver) ;
  328.   do  {
  329.     PCH pchMatch ;
  330.  
  331.     pchMatch = memchr( pchGlobal + 1, 'N', usBytesLeft); //look for first char
  332.     if ( pchMatch == NULL)  {               // if no match
  333.       ReleaseSel( SELECTOROF( pchGlobal)) ; // release the selector
  334.       puts( "NUL driver not found") ;       // and give up
  335.       exit( 1) ;
  336.     }  // if no match
  337.                         // partial match
  338.     usBytesLeft -= pchMatch - pchGlobal ;   // reduce residual count
  339.     pchGlobal = pchMatch ;                  // point to start of match
  340.   }  while ( memcmp( pchGlobal              // break out if name matches
  341.            , szNullDriver                   //  exactly
  342.            , sizeof szNullDriver - 1) != 0);
  343.  
  344.   // run the chain
  345.   printf( "  Address Name\n") ;                      // column headings
  346.   for ( usOffsetDriver = OFFSETOF( pchGlobal) - 0x0a // back up to DCB start
  347.     , pddCurrent = ( PDDHEADER) ( pchGlobal - 0x0a)
  348.     , selDriver = SELECTOROF( pddCurrent->pddNext)   // selector of next DCB
  349.       ; ; ) {
  350.     printf( "%4X:%04X ", selDriver, usOffsetDriver);
  351.     if ( ( pddCurrent->fsAttribute & 0x8000) == 0)  // if block driver
  352.       printf( "Block device, %d logical units\n"
  353.           , pddCurrent->chName[ 0]);                // number of units
  354.     else                                            // if character driver
  355.       printf( "%-8.8s\n", pddCurrent->chName);
  356.     selDriver = SELECTOROF( pddCurrent->pddNext) ;  // point to next DCB
  357.     usOffsetDriver = OFFSETOF( pddCurrent->pddNext) ;
  358.     if ( usOffsetDriver == 0xffff)                  // if end of chain
  359.       break ;                                       // we are done
  360.     pddNext = MAKEP( MakeSel( selDriver), usOffsetDriver) ;
  361.     ReleaseSel( SELECTOROF( pddCurrent)) ;          // free previous DCB
  362.     pddCurrent = pddNext ;                          // age the pointer
  363.   }  // loop once for each device driver
  364.  
  365.   // release the last selector
  366.   ReleaseSel( SELECTOROF( pddCurrent)) ;
  367.  
  368.   exit( 0) ;
  369. }
  370.  
  371.  
  372. [LISTING THREE]
  373.  
  374. /* DEVHLP.H -- for use with DosDevIOCtl and DEVHLP.SYS */
  375.  
  376. #define DevHlp_SchedClockAddr       0x00
  377. #define DevHlp_DevDone              0x01
  378. #define DevHlp_Yield                0x02
  379. #define DevHlp_TCYield              0x03
  380. #define DevHlp_Block                0x04
  381. #define DevHlp_Run                  0x05
  382. #define DevHlp_SemRequest           0x06
  383. #define DevHlp_SemClear             0x07
  384. #define DevHlp_SemHandle            0x08
  385. #define DevHlp_PushReqPacket        0x09
  386. #define DevHlp_PullReqPacket        0x0A
  387. #define DevHlp_PullParticular       0x0B
  388. #define DevHlp_SortReqPacket        0x0C
  389. #define DevHlp_AllocReqPacket       0x0D
  390. #define DevHlp_FreeReqPacket        0x0E
  391. #define DevHlp_QueueInit            0x0F
  392. #define DevHlp_QueueFlush           0x10
  393. #define DevHlp_QueueWrite           0x11
  394. #define DevHlp_QueueRead            0x12
  395. #define DevHlp_Lock                 0x13
  396. #define DevHlp_Unlock               0x14
  397. #define DevHlp_PhysToVirt           0x15
  398. #define DevHlp_VirtToPhys           0x16
  399. #define DevHlp_PhysToUVirt          0x17
  400. #define DevHlp_AllocPhys            0x18
  401. #define DevHlp_FreePhys             0x19
  402. #define DevHlp_SetROMVector         0x1A
  403. #define DevHlp_SetIRQ               0x1B
  404. #define DevHlp_UnSetIRQ             0x1C
  405. #define DevHlp_SetTimer             0x1D
  406. #define DevHlp_ResetTimer           0x1E
  407. #define DevHlp_MonitorCreate        0x1F
  408. #define DevHlp_Register             0x20
  409. #define DevHlp_DeRegister           0x21
  410. #define DevHlp_MonWrite             0x22
  411. #define DevHlp_MonFlush             0x23
  412. #define DevHlp_GetDosVar            0x24
  413. #define DevHlp_SendEvent            0x25
  414. #define DevHlp_ROMCritSection       0x26
  415. #define DevHlp_VerifyAccess         0x27
  416. #define DevHlp_SysTrace             0x28
  417. #define DevHlp_AttachDD             0x2A
  418. #define DevHlp_AllocGDTSelector     0x2D
  419. #define DevHlp_PhysToGDTSelector    0x2E
  420. #define DevHlp_RealToProt           0x2F
  421. #define DevHlp_ProtToReal           0x30
  422. #define DevHlp_EOI                  0x31
  423. #define DevHlp_UnPhysToVirt         0x32
  424. #define DevHlp_TickCount            0x33
  425. #define DevHlp_GetLIDEntry          0x34
  426. #define DevHlp_FreeLIDEntry         0x35
  427. #define DevHlp_ABIOSCall            0x36
  428. #define DevHlp_ABIOSCommonEntry     0x37
  429. #define DevHlp_RegisterStackUsage   0x38
  430.  
  431. #define UVirt_Exec                  0
  432. #define UVirt_ReadWrite             1
  433. #define UVirt_Release               2
  434.  
  435. #pragma pack(1)
  436.  
  437. typedef struct {
  438.     unsigned int carry              : 1;
  439.     unsigned int                    : 1;
  440.     unsigned int parity             : 1;
  441.     unsigned int                    : 1;
  442.     unsigned int aux                : 1;
  443.     unsigned int                    : 1;
  444.     unsigned int zero               : 1;
  445.     unsigned int sign               : 1;
  446.     unsigned int trap               : 1;
  447.     unsigned int int_en             : 1;
  448.     unsigned int direction          : 1;
  449.     unsigned int overflow           : 1;
  450.     unsigned int iopl               : 2;
  451.     unsigned int nest_task          : 1;
  452.     unsigned int                    : 1;
  453.     } FLAGS;
  454.  
  455. typedef struct {
  456.     USHORT ax,bx,cx,dx,si,di,ds,es;
  457.     FLAGS  flags;
  458.     } REGS;
  459.  
  460.  
  461. [Figure 1║ Invoking the PhysToUVirt DevHlp]
  462.  
  463.     MOV AX, address_high        ; top of 32-bit physical absolute address
  464.     MOV BX, address_low         ; bottom of 32-bit physical absolute address
  465.     MOV CX, length              ; count of bytes to map (0=64k)
  466.     MOV DH, request_type        ; 0=code, 1=data, 2=cancel
  467.     MOV DL, DevHlp_PhysToUVirt  ; 17h
  468.     CALL DWORD PTR [DevHlp]     
  469.     JNC ok                      ; carry set=error, clear=ok
  470.     ; AX contains error code
  471. ok: ; ES:BX contains virtual address
  472.  
  473.  
  474. [Figure 2║ Parameters for calling DosDevIOCtl()]
  475.  
  476. USHORT DosDevIOCtl(pvData, pvParms, usFunction, usCategory, hDevice)
  477. PVOID pvData;       /* far pointer to data packet <- driver */
  478. PVOID pvParms;      /* far pointer to parameter packet -> driver */
  479. USHORT usFunction;  /* two-byte device function */
  480. USHORT usCategory;  /* two-byte device category */
  481. HFILE hDevice;      /* two-byte device handle */
  482.  
  483.  
  484. [Figure 3║ The DEVHLP parameter/data packet]
  485.  
  486. typedef struct {
  487.     USHORT ax, bx, cx, dx, si, di, ds, es, flags;
  488.     } REGS;
  489.  
  490. [Figure 4║ PhysToUVirt() in C]
  491.  
  492. #define DevHlp_PhysToUVirt      0x17
  493.  
  494. typedef enum { 
  495.     UVirt_Exec=0, UVirt_ReadWrite, UVirt_Release
  496.     } UVIRT_TYPE;
  497.  
  498. // turn physical address into virtual address
  499. void far *PhysToUVirt(ULONG addr, USHORT size, UVIRT_TYPE type)
  500. {
  501.     REGS r;
  502.     USHORT sel, ret=1;
  503.     HFILE devhlp;
  504.     r.ax = HIUSHORT(addr);
  505.     r.bx = LOUSHORT(addr);
  506.     r.cx = size;
  507.     r.si = r.di = r.ds = r.es = 0;  // not used
  508.     r.dx = MAKEUSHORT(DevHlp_PhysToUVirt, type);
  509.     if ((devhlp = open("DEVHLPXX", 0)) != -1)
  510.     {
  511.         ret = DosDevIOCtl(&r, &r, 0x60, 128, devhlp);
  512.         close(devhlp);
  513.     }
  514.     // if DosDevIOCtl failed OR if DevHlp set carry flag...
  515.     if (ret || (r.flags & 1))
  516.         return NULL;
  517.     else
  518.         return MAKEP(r.es, r.bx);
  519. }
  520.