× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.


  • Subject: Retrieving the SEPT Part one
  • From: Leif Svalgaard <l.svalgaard@xxxxxxxxxxxxx>
  • Date: Wed, 8 Dec 1999 10:26:46 -0600

Don asked me to submit my previous posting in pieces.
So here is part one:



Here is first a C/400 program to print the System Entry Point Table (SEPT).

/* Test program to display System Entry Point Table */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
/* qsysinc:  */
#include <pointer.h>
#include <mimchobs.h>
#include <mispcobj.h>
#include <miptrnam.h>
#include <qliept.h>

static _MPTR_Template_T *mptr_area;

void main(void){
  int i;
  _OPENPTR *inv_sys;

  i = sizeof(_MPTR_Template_T);
  mptr_area = malloc(i);
  mptr_area->Obj_Ptr.Template_Size = i;

  for(i=0; i<WLISRHNMTBL_DIM; i++)
  {
     inv_sys = (((_SYSPTR **)_SYSEPT()) + i);
     if (*inv_sys != NULL)
     {
        matptr(mptr_area, *inv_sys);
        printf("Entry %d is %10.10s %10.10s\n", i,
                      mptr_area->Obj_Ptr.Library_ID.Name,
                      mptr_area->Obj_Ptr.Object_ID.Name);
     }
     else
     {
        printf("Entry %d is **null**\n", i);
     }
  }
  free(mptr_area);
}

When run under Security Level 30, the program prints out 6245 entries. When
run under level 40, the program bombs right away with a 'security
violation'. The program uses the MATPTR  API, which is documented in the
usual AS/400 manuals. 

Under any Security Level you can always dump the SEPT using the DUMPSYSOBJ
command:

DMPSYSOBJ OBJ(QINSEPT) CONTEXT(QSYS)

When you do that and select the QPSRVDMP spool file with WRKSPLF you see
something like the following; find the POINTERS section:
                            Display Spooled File                       
 File  . . . . . :   QPSRVDMP                         Page/Line   54/47  
 Control . . . . .                                    Columns     1 - 78 
 Find  . . . . . .   POINTERS                                            
 *...+....1....+....2....+....3....+....4....+....5....+....6....+....7..
 .POINTERS-                                                              
   000000   SYP 02 01 QT3REQIO                        04 01 QSYS         
   000010   SYP 02 01 QWSCLOSE                        04 01 QSYS         
   000020   SYP 02 01 QSFGET                          04 01 QSYS         
   000030   SYP 02 01 QWSOPEN                         04 01 QSYS         
   000040   SYP 02 01 QWSPBDVR                        04 01 QSYS         
   000050   SYP 02 01 QWSRST                          04 01 QSYS         
   000060   SYP 02 01 QWSRTSFL                        04 01 QSYS         
   000070   SYP 02 01 QSFCRT                          04 01 QSYS         
   000080   SYP 02 01 QWSSPEND                        04 01 QSYS         
   000090   SYP 02 01 QDCVRX                          04 01 QSYS         
   0000A0   SYP 02 01 QDMCLOSE                        04 01 QSYS         
   0000B0   SYP 02 01 QDMCOPEN                        04 01 QSYS         
   0000C0   SYP 02 01 QDBCLOSE                        04 01 QSYS
   0000D0   SYP 02 01 QDBGETDR                        04 01 QSYS   
   0000E0   SYP 02 01 QDBGETKY                        04 01 QSYS   
   0000F0   SYP 02 01 QDBGETSQ                        04 01 QSYS   
   000100   SYP 02 01 QDBOPEN                         04 01 QSYS   
   000110   SYP 02 01 QDBPUT                          04 01 QSYS   
   000120   SYP 02 01 QDBUDR                          04 01 QSYS   
   000130   SYP 02 01 QSPBPPRT                        04 01 QSYS   
   000140   SYP 02 01 QOESETEX                        04 01 QSYS   
   000150   SYP 02 01 QWSPUT                          04 01 QSYS   
   000160   SYP 02 01 QWSMEEH                         04 01 QSYS   
   000170   SYP 02 01 QWSMSG                          04 01 QSYS   
   000180   SYP 02 01 QWSPTMSG                        04 01 QSYS   
   000190   SYP 02 01 QLPCTLIN                        04 01 QSYS   
   0001A0   SYP 02 01 QLPTRANS                        04 01 QSYS   
   0001B0   SYP 02 01 QWCITUNR                        04 01 QSYS   
   0001C0   SYP 02 01 QTIMAIN1                        04 01 QSYS   
   . . . etc

It takes 144 seconds to produce the dump. The dump shows programs in their
context (QSYS). One could capture this output in a file and work on each
entry.

MI Program DSPSEPT to Materialize the SEPT.
For simplicity in experimentation the program sends its resulting output for
each entry to the job's message queue. Stop it with the System Request key,
then answer '2'. Don't worry about the details, go straight to the
discussion after the listing.


DCL SPC * BASPCO;
    DCL SPCPTR .SEPT_PCO DIR;  /* 1ST ENTRY */

DCL SYSPTR .SEPT(6440) BAS(.SEPT_PCO); 
DCL CON MAX_SEPT  BIN(2) INIT(6440); /* VERSION DEPENDENT */
DCL DD  ENTRY_NBR BIN(2);

DCL DD INFO CHAR(77) BDRY(16);
    DCL DD  INFO_PRV           BIN ( 4) DEF(INFO) POS( 1) INIT(77);
    DCL DD  INFO_AVL           BIN ( 4) DEF(INFO) POS( 5);
    DCL DD  INFO_PTR_TYPE      CHAR( 1) DEF(INFO) POS( 9);
    DCL DD  INFO_LIB_ID        CHAR(32) DEF(INFO) POS(10);
        DCL DD  INFO_LIB_TYPES CHAR( 2) DEF(INFO_LIB_ID) POS(1);
        DCL DD  INFO_LIB_NAME  CHAR(30) DEF(INFO_LIB_ID) POS(3);
    DCL DD  INFO_OBJ_ID        CHAR(32) DEF(INFO) POS(42);
        DCL DD  INFO_OBJ_TYPES CHAR( 2) DEF(INFO_OBJ_ID) POS(1);
        DCL DD  INFO_OBJ_NAME  CHAR(30) DEF(INFO_OBJ_ID) POS(3);
    DCL DD  INFO_BITS          CHAR( 4) DEF(INFO) POS(74);
DCL SPCPTR .INFO INIT(INFO);

DCL SYSPTR .FORGED;  /* SYSTEM POINTER TO FORGE */
DCL INSPTR  RETURN;  /* RETURN PTR FOR CALLI    */

ENTRY * EXT;
        CPYNV      ENTRY_NBR, 0;
NEXT_ENTRY:
        ADDN(S)    ENTRY_NBR, 1;
        SETSPFP   .FORGED, .SEPT(ENTRY_NBR); /* FORGE POINTER */
        MATPTR    .INFO, .FORGED;  BRK "1";
        CALLI      SHOW_OBJECT, *, RETURN; /* SHOW RESULT TO MSGQ */
TEST_ENTRY:
        CMPNV(B)   ENTRY_NBR, MAX_SEPT /LO(NEXT_ENTRY);
        RTX        *;

/******* SEND MESSAGE HANDLING ********/

DCL DD MSG_ID   CHAR (7) INIT("       ");
DCL SPCPTR .MSG_ID   INIT(MSG_ID);

DCL DD MSG_FILE CHAR(20) INIT("                    ");
DCL SPCPTR .MSG_FILE INIT(MSG_FILE);

DCL DD MSG_TEXT CHAR(74);
    DCL DD MSG_ENTRY_NBR ZND(4,0) DEF(MSG_TEXT) POS( 1);
    DCL DD *             CHAR( 1) DEF(MSG_TEXT) POS( 5) INIT(":");
    DCL DD MSG_OBJ_OBJ   CHAR(30) DEF(MSG_TEXT) POS( 6);
    DCL DD MSG_OBJ_LIB   CHAR(30) DEF(MSG_TEXT) POS(36);
    DCL DD *             CHAR( 1) DEF(MSG_TEXT) POS(66) INIT(" ");
    DCL DD MSG_OBJ_BITS  CHAR( 8) DEF(MSG_TEXT) POS(67);
DCL SPCPTR .MSG_TEXT INIT(MSG_TEXT);

DCL DD MSG_SIZE      BIN( 4)  INIT(74);
DCL SPCPTR .MSG_SIZE INIT(MSG_SIZE);

DCL DD MSG_TYPE      CHAR(10) INIT("*INFO     ");
DCL SPCPTR .MSG_TYPE INIT(MSG_TYPE);

DCL DD MSG_QS        CHAR(20) INIT("*REQUESTER          ");
DCL SPCPTR .MSG_QS   INIT(MSG_QS);

DCL DD MSG_QSN       BIN( 4)  INIT(1);
DCL SPCPTR .MSG_QSN  INIT(MSG_QSN);

DCL DD REPLY_Q       CHAR(20) INIT("                    ");
DCL SPCPTR .REPLY_Q  INIT(REPLY_Q);

DCL DD MSG_KEY       CHAR( 4);
DCL SPCPTR .MSG_KEY  INIT(MSG_KEY);

DCL DD ERR_CODE      BIN( 4)  INIT(0);
DCL SPCPTR .ERR_CODE INIT(ERR_CODE);

DCL OL QMHSNDMOL (.MSG_ID,   .MSG_FILE, .MSG_TEXT, .MSG_SIZE,
                  .MSG_TYPE, .MSG_QS,   .MSG_QSN,  .REPLY_Q,
                  .MSG_KEY,  .ERR_CODE)  ARG;

ENTRY SHOW_OBJECT INT; /* SHOW OBJECT INFO */
        CPYNV      MSG_ENTRY_NBR, ENTRY_NBR;
        CPYBLA     MSG_OBJ_OBJ, INFO_OBJ_NAME;
        CPYBLA     MSG_OBJ_LIB, INFO_LIB_NAME;
        CVTHC      MSG_OBJ_BITS, INFO_BITS;  /* HEX TO CHAR */
        CALLX     .SEPT(4268), QMHSNDMOL, *; /* SEND MSG TO MSGQ */
        B          RETURN;

/******* EXCEPTION HANDLING ********/

DCL EXCM EXCEPTION_MONITOR EXCID(H'0000') /* ALL */
    BP(ERROR_DETECTED) IMD;

ERROR_DETECTED:
        CPYBLAP    INFO_OBJ_NAME, "*PROTECTED", " ";
        CPYBLAP    INFO_LIB_NAME, "QSYS", " ";
        CPYBLA     INFO_BITS, X'00000000';
        CALLI      SHOW_OBJECT, *, RETURN;
        B          TEST_ENTRY;
PEND;

 

The crucial instructions are:

        SETSPFP   .FORGED, .SEPT(ENTRY_NBR); /* FORGE POINTER */
        MATPTR    .INFO, .FORGED;  

If you simply try to materialize the entry point, that is:

        MATPTR   .INFO, .SEPT(ENTRY_NBR);

you get an exception ('Object domain or hardware storage protection
violation'). By setting another system pointer, .FORGED, from the entry
point (the SETSPFP instruction) you essentially forge a new pointer from the
old. This new pointer can be materialized in some cases, bypassing the
security integrity check for the SEPT object itself. I've marked (with OK)
the entries that can be materialized in the following table: 

   000000   SYP 02 01 QT3REQIO                        04 01 QSYS   
   000010   SYP 02 01 QWSCLOSE                        04 01 QSYS   
   000020   SYP 02 01 QSFGET                          04 01 QSYS   
   000030   SYP 02 01 QWSOPEN                         04 01 QSYS   
   000040   SYP 02 01 QWSPBDVR                        04 01 QSYS   
   000050   SYP 02 01 QWSRST                          04 01 QSYS   
   000060   SYP 02 01 QWSRTSFL                        04 01 QSYS   
   000070   SYP 02 01 QSFCRT                          04 01 QSYS   
   000080   SYP 02 01 QWSSPEND                        04 01 QSYS   
   000090   SYP 02 01 QDCVRX                          04 01 QSYS   
   0000A0   SYP 02 01 QDMCLOSE       OK               04 01 QSYS   
   0000B0   SYP 02 01 QDMCOPEN       OK               04 01 QSYS   
   0000C0   SYP 02 01 QDBCLOSE                        04 01 QSYS   
   0000D0   SYP 02 01 QDBGETDR       OK               04 01 QSYS   
   0000E0   SYP 02 01 QDBGETKY       OK               04 01 QSYS   
   0000F0   SYP 02 01 QDBGETSQ       OK               04 01 QSYS   
   000100   SYP 02 01 QDBOPEN                         04 01 QSYS   
   000110   SYP 02 01 QDBPUT         OK               04 01 QSYS   
   000120   SYP 02 01 QDBUDR         OK               04 01 QSYS   
   000130   SYP 02 01 QSPBPPRT                        04 01 QSYS   
   000140   SYP 02 01 QOESETEX                        04 01 QSYS   
   000150   SYP 02 01 QWSPUT         OK               04 01 QSYS   
   000160   SYP 02 01 QWSMEEH                         04 01 QSYS   
   . . .

If you display the program information (DSPPGM PGM(QSYS/QDMCLOSE) for two
entries (one that can be materialized and one that cannot) you see something
like this:

  Program   . . . .  . .. . . . . .:   QDMCLOSE                  QDBCLOSE
  Program creation date/time .. .. :   03/18/98  15:36:56        05/18/98
23:04:18
  Type of program  . . . . . . . . :   OPM                       OPM
  Source file  . . . . . . . . . . :                           
    Library  . . . . . . . . . . . :                           
  Source member  . . . . . . . . . :                           
  Source file change date/time . . :                           
  Observable information . . . . . :   *NONE                     *NONE
  User profile . . . . . . . . . . :   *USER                     *USER
  Use adopted authority  . . . . . :   *YES                      *YES
  Fix decimal data . . . . . . . . :   *NO                       *NO
  Text description . . . . . . . . :                           
  Program size (bytes) . . . . . . :   49152                     32768
  Associated space size (bytes)  . :   0                         0
  Static storage size (bytes)  . . :   0                         0
  Automatic storage size (bytes) . :   2208                      1488
  Program state  . . . . . . . . . :   *SYSTEM                   *SYSTEM
  Program domain . . . . . . . . . :   *USER                     *SYSTEM
  Compiler . . . . . . . . . . . . :           V4R3M0
V4R3M0
  Earliest release for running. .. :   V4R3M0                    V4R3M0
  Conversion required  . . . . . . :   *NO                      *NO
  Sort sequence  . . . . . . . . . :   *HEX                     *HEX
  Language identifier  . . . . . . :   *JOBRUN                  *JOBRUN
  Optimization . . . . . . . . . . :   *OPTIMIZE                *OPTIMIZE
  Paging pool  . . . . . . . . . . :   *USER                    *USER
  Update PASA  . . . . . . . . . . :   *UPDPASA                 *NOUPDPASA 
  Clear PASA . . . . . . . . . . . :   *CLRPASA                 *NOCLRPASA 
  Paging amount  . . . . . . . . . :   *BLOCK                   *BLOCK 

The only real difference is that QDMCLOSE is in the *USER domain and
QDBCLOSE is in the *SYSTEM domain. To put it differently: QDMCLOSE is for
general use (this does not necessarily mean that it is a documented API;
e.g. QDBPUT is not) and QDBCLOSE is for system use only.

With the MATPTR MI-instruction you had to forge the pointer to access an
entry in the SEPT. There is another instruction, Materialize System Object -
MATSOBJ, that can materialize a system object; e.g.:

        MATSOBJ   .INFO, .SEPT(ENTRY_NBR);

This works directly without using a forged pointer. However, you still
cannot materialize objects in the system domain (in spite of the name of the
MI-instruction).

Why Are We Doing This
The System Entry Point Table (SEPT) is important, because the programs in it
are before any programs in the library list and are the basic operating
system calls (e.g. to open files, read records, etc). If you could place one
of your own programs here in lieu of a standard entry point, you could act
as a Trojan Horse and essentially bypass most security. A minimum defense
against this would be to print a listing of all the programs including their
properties.

If you are running under at least Security Level 40, you are supposedly
protected against tampering with the SEPT so you need only to worry about
the entries you can have access to. The problem here is that you want to be
*sure* that it has not been tampered with. 

+---
| This is the MI Programmers Mailing List!
| To submit a new message, send your mail to MI400@midrange.com.
| To subscribe to this list send email to MI400-SUB@midrange.com.
| To unsubscribe from this list send email to MI400-UNSUB@midrange.com.
| Questions should be directed to the list owner/operator: dr2@cssas400.com
+---


As an Amazon Associate we earn from qualifying purchases.

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.