Ignore:
Timestamp:
Feb 21, 2000, 5:45:47 AM (26 years ago)
Author:
bird
Message:

ProbKrnl and code for importing krnl symbols has been enhanched.
Now we'll lock 32-bit segments into memory too.
And some other fixes...

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/win32k/dev32/d32init.c

    r2832 r2836  
    1 /* $Id: d32init.c,v 1.12 2000-02-20 04:27:23 bird Exp $
     1/* $Id: d32init.c,v 1.13 2000-02-21 04:45:46 bird Exp $
    22 *
    33 * d32init.c - 32-bits init routines.
     
    1212*   Defined Constants                                                          *
    1313*******************************************************************************/
    14 #define MAXSIZE_PROLOG 0x10             /* Note that this must be synced with */
     14#define MAXSIZE_PROLOG 0x18             /* Note that this must be synced with */
    1515                                        /* the one used in calltab.asm.       */
    1616#define static                          /* just to make all symbols visible in the kernel debugger.  */
     
    3232#include "dev1632.h"
    3333#include "dev32.h"
     34#include "dev32hlp.h"
    3435#include "probkrnl.h"
    3536#include "log.h"
     
    3839#include "ldr.h"
    3940#include "ldrCalls.h"
    40 
     41#include "macros.h"
     42
     43/*******************************************************************************
     44*   Global Variables                                                           *
     45*******************************************************************************/
     46#ifdef DEBUG
     47static char * apszPE[] = {"FLAGS_PE_NOT", "FLAGS_PE_PE2LX", "FLAGS_PE_PE", "FLAGS_PE_MIXED", "!invalid!"};
     48static char * apszInfoLevel[] = {"INFOLEVEL_QUIET", "INFOLEVEL_ERROR", "INFOLEVEL_WARNING", "INFOLEVEL_INFO", "INFOLEVEL_INFOALL", "!invalid!"};
     49#endif
    4150
    4251/*******************************************************************************
    4352*   Internal Functions                                                         *
    4453*******************************************************************************/
    45 static ULONG    readnum(const char *pszNum);
    46 static signed char interpretFunctionProlog32(char *pach, BOOL fOverload);
    47 static signed char interpretFunctionProlog16(char *pach, BOOL fOverload);
    48 static int      ImportTabInit(void);
     54static ULONG        readnum(const char *pszNum);
     55_Inline int         ModR_M_32bit(char bModRM);
     56static int          interpretFunctionProlog32(char *pach, BOOL fOverload);
     57static int          interpretFunctionProlog16(char *pach, BOOL fOverload);
     58static int          ImportTabInit(void);
    4959
    5060
     
    5969/* extern(s) located in mytkExecPgm.asm  */
    6070extern char     mytkExecPgm;
    61 
     71extern char     CODE32START;
     72extern char     CODE32END;
     73extern char     CONST32_ROEND;
     74extern char     DATA16START;
     75extern char     DATA16_CONSTEND;
    6276
    6377
     
    8195    char   *pszTmp;
    8296    ULONG   ul;
     97    APIRET  rc;
     98    LOCKHANDLE lhData16={0,0,0,0, 0,0,0,0, 0,0,0,0};
     99    LOCKHANDLE lhData = {0,0,0,0, 0,0,0,0, 0,0,0,0};
     100    LOCKHANDLE lhCode = {0,0,0,0, 0,0,0,0, 0,0,0,0};
    83101
    84102    pulTKSSBase32 = (PULONG)_TKSSBase16;
     
    258276
    259277    /* log option summary - FIXME */
    260     kprintf(("Options - Summary\n"));
     278    kprintf(("Options - Summary - Start\n"));
     279    if (options.fQuiet)
     280        kprintf(("\tQuiet init\n"));
     281    else
     282        kprintf(("\tVerbose init\n"));
     283
     284    if (options.fLogging)
     285        kprintf(("\tlogging enabled\n"));
     286    else
     287        kprintf(("\tlogging disabled\n"));
     288    kprintf(("\tCom port no.%d\n", options.usCom));
     289
    261290    kprintf(("\tKernel: ver%d.%d  build %d  type %s\n",
    262291                options.usVerMajor,
     
    265294                (options.fKernel & KF_SMP) ? "SMP" : "UNI"
    266295              ));
    267     kprintf(("\tCom port no.%d\n", options.usCom));
    268     if (options.fQuiet)
    269         kprintf(("\tQuiet init\n"));
    270     else
    271         kprintf(("\tVerbose init\n"));
    272     if (options.fLogging)
    273         kprintf(("\tlogging enabled\n"));
    274     else
    275         kprintf(("\tlogging disabled\n"));
     296    kprintf(("\tfPE=%d (%s)\n", options.fPE, apszPE[MIN(options.fPE, 5)]));
     297    kprintf(("\tulInfoLevel=%d (%s)\n", options.ulInfoLevel, apszInfoLevel[MIN(options.ulInfoLevel, 5)]));
     298    kprintf(("\tfElf=%d\n", options.fElf));
     299    kprintf(("\tfScript=%d\n", options.fScript));
     300    kprintf(("\tfNoLoader=%d\n", options.fNoLoader));
     301    kprintf(("\tcbSwpHeapInit=0x%08x  cbSwpHeapMax=0x%08x\n",
     302             options.cbSwpHeapInit, options.cbSwpHeapMax));
     303    kprintf(("\tcbResHeapInit=0x%08x  cbResHeapMax=0x%08x\n",
     304             options.cbSwpHeapInit, options.cbSwpHeapMax));
     305    kprintf(("Options - Summary - End\n"));
    276306    /* end option summary */
    277307
     
    294324        if (ImportTabInit() != NO_ERROR)
    295325            return STATUS_DONE | STERR | ERROR_I24_QUIET_INIT_FAIL;
     326
     327    /*
     328     * Lock the 32-bit objects/segments and 16-bit datasegment in memory
     329     */
     330    /* 32-bit code segment */
     331    rc = D32Hlp_VMLock2(&CODE32START,
     332                        ((unsigned)&CODE32END & ~0xFFF) - (unsigned)&CODE32START, /* Round down so we don't overlap with the next request. */
     333                        VMDHL_LONG,
     334                        SSToDS(&lhCode));
     335    if (rc != NO_ERROR)
     336        kprintf(("code segment lock failed with with rc=%d\n", rc));
     337
     338    /* 32-bit data segment */
     339    rc = D32Hlp_VMLock2(callTab,
     340                        &CONST32_ROEND - (char*)callTab,
     341                        VMDHL_LONG | VMDHL_WRITE,
     342                        SSToDS(&lhData));
     343    if (rc != NO_ERROR)
     344        kprintf(("data segment lock failed with with rc=%d\n", rc));
     345
     346    /* 16-bit data segment */
     347    rc = D32Hlp_VMLock2(&DATA16START,
     348                        &DATA16_CONSTEND - &DATA16START,
     349                        VMDHL_LONG | VMDHL_WRITE,
     350                        SSToDS(&lhData16));
     351    if (rc != NO_ERROR)
     352        kprintf(("data segment lock failed with with rc=%d\n", rc));
    296353
    297354    return STATUS_DONE;
     
    395452
    396453
     454
     455/**
     456 * Functions which cacluates the instructionsize given a ModR/M byte.
     457 * @returns   Number of bytes to add to cb and pach.
     458 * @param     bModRM  ModR/M byte.
     459 * @status    completely implemented.
     460 * @author    knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
     461 */
     462_Inline int ModR_M_32bit(char bModRM)
     463{
     464    if ((bModRM & 0xc0) == 0x80  /* ex. mov ax,[ebp+11145543h] */
     465        || ((bModRM & 0xc0) == 0 && (bModRM & 0x07) == 5)) /* ex. mov ebp,[0ff231234h] */
     466    {   /* 32-bit displacement */
     467        return 5;
     468    }
     469    else if ((bModRM & 0xc0) == 0x40) /* ex. mov ecx,[esi]+4fh */
     470    {   /* 8-bit displacement */
     471        return 2;
     472    }
     473    /* no displacement (only /r byte) */
     474    return 1;
     475}
     476
     477
     478
     479
     480
    397481/**
    398482 * 32-bit! Interpret function prolog to find where to jmp back.
     
    404488 *                       FALSE: Function is to be imported.
    405489 */
    406 static signed char interpretFunctionProlog32(char *pach, BOOL fOverload)
     490static int interpretFunctionProlog32(char *pach, BOOL fOverload)
    407491{
    408     int cb;
     492    int cb = -3;
     493
     494    kprintf(("interpretFunctionProlog32(0x%08x, %d):\n"
     495             "\t%02x %02x %02x %02x - %02x %02x %02x %02x\n"
     496             "\t%02x %02x %02x %02x - %02x %02x %02x %02x\n",
     497             pach, fOverload,
     498             pach[0], pach[1], pach[2], pach[3], pach[4], pach[5], pach[6], pach[7],
     499             pach[8], pach[9], pach[10],pach[11],pach[12],pach[13],pach[14],pach[15]));
    409500
    410501    /*
     
    416507     *     push ebp
    417508     *     mov ecx, dword ptr [xxxxxxxx]
     509     *
     510     * These are allowed when not overloading:
     511     *     mov eax, imm32
     512     *     jmp short
     513     *  or
     514     *     mov eax, imm32
     515     *     push ebp
    418516     */
    419 
    420     if (pach[0] == 0x55 && pach[1] == 0x8b)
     517    if ((pach[0] == 0x55 && (pach[1] == 0x8b || pach[1] == 0xa1)) /* two first prologs */
     518        ||
     519        (pach[0] == 0xB8 && (pach[5] == 0xEB || pach[5] == 0x55) && !fOverload) /* two last prologs */
     520        )
    421521    {
    422         if (pach[2] == 0xec)
    423             cb = 3;
    424         else
    425             cb = 1;
    426         while (cb < 5)
    427         {
    428             /*
    429              * This is not at all very stable or correct - but it works
    430              * for the current functions.
    431              * There will never be any doubt when something goes wrong!
    432              */
    433             switch(pach[cb])
     522        BOOL fForce;
     523        cb = 0;
     524        while (cb < 5 || fForce)                  /* 5 is the size of a jump instruction. */
     525        {
     526            int cb2;
     527            fForce = FALSE;
     528            switch (*pach)
    434529            {
    435                 case 0x33: /* xor (ldrClose, ldrOpen) */
    436                     cb +=2;
    437                     break;
    438                 case 0x8b:
    439                     if (pach[cb+1] == 0x0d)
    440                         cb += 6;
     530                /* simple one byte prefixes */
     531                case 0x2e:              /* cs segment override */
     532                case 0x36:              /* ss segment override */
     533                case 0x3e:              /* ds segment override */
     534                case 0x26:              /* es segment override */
     535                case 0x64:              /* fs segment override */
     536                case 0x65:              /* gs segment override */
     537                    fForce = TRUE;
     538                    break;
     539
     540                /* simple one byte instructions */
     541                case 0x50:              /* push ax */
     542                case 0x51:              /* push cx */
     543                case 0x52:              /* push dx */
     544                case 0x53:              /* push bx */
     545                case 0x54:              /* push sp */
     546                case 0x55:              /* push bp */
     547                case 0x56:              /* push si */
     548                case 0x57:              /* push di */
     549                    break;
     550
     551                /* simple two byte instructions */
     552                case 0xb0:              /* mov al, imm8 */
     553                case 0xb1:              /* mov cl, imm8 */
     554                case 0xb2:              /* mov dl, imm8 */
     555                case 0xb3:              /* mov bl, imm8 */
     556                case 0xb4:              /* mov ah, imm8 */
     557                case 0xb5:              /* mov ch, imm8 */
     558                case 0xb6:              /* mov dh, imm8 */
     559                case 0xb7:              /* mov bh, imm8 */
     560                case 0x2c:              /* sub al, imm8 */
     561                case 0x34:              /* xor al, imm8 */
     562                case 0x3c:              /* cmp al, imm8 */
     563                case 0x6a:              /* push <byte> */
     564                    pach++;
     565                    cb++;
     566                    break;
     567
     568                /* simple five byte instructions */
     569                case 0xb8:              /* mov eax, imm32 */
     570                case 0xb9:              /* mov ecx, imm32 */
     571                case 0xba:              /* mov edx, imm32 */
     572                case 0xbb:              /* mov ebx, imm32 */
     573                case 0xbc:              /* mov esx, imm32 */
     574                case 0xbd:              /* mov ebx, imm32 */
     575                case 0xbe:              /* mov esi, imm32 */
     576                case 0xbf:              /* mov edi, imm32 */
     577                case 0x2d:              /* sub eax, imm32 */
     578                case 0x35:              /* xor eax, imm32 */
     579                case 0x3d:              /* cmp eax, imm32 */
     580                case 0x68:              /* push <dword> */
     581                    pach += 4;
     582                    cb += 4;
     583                    break;
     584
     585                /* complex sized instructions -  "/r" */
     586                case 0x30:              /* xor r/m8,  r8 */
     587                case 0x31:              /* xor r/m32, r32 */
     588                case 0x32:              /* xor r8,  r/m8 */
     589                case 0x33:              /* xor r32, r/m32 */
     590                case 0x38:              /* cmp r/m8, r8 */
     591                case 0x39:              /* cmp r/m32, r32 */
     592                case 0x3a:              /* cmp r8, r/m8 */
     593                case 0x3b:              /* cmp r32, r/m32 */
     594                case 0x28:              /* sub r/m8, r8 */
     595                case 0x29:              /* sub r/m32, r32 */
     596                case 0x2a:              /* sub r8, r/m8 */
     597                case 0x2b:              /* sub r32, r/m32 */
     598                case 0x8b:              /* mov /r */
     599                case 0x8d:              /* lea /r */
     600                    if ((pach[1] & 0x7) == 4 && (pach[1] & 0xc0) != 0xc0) /* invalid instruction!?! */
     601                        return -1;
     602                    cb += cb2 = ModR_M_32bit(pach[1]);
     603                    pach += cb2;
     604                    break;
     605
     606                /* complex sized instruction - "/5 ib" */
     607                case 0x80:              /* 5: sub r/m8, imm8  7: cmp r/m8, imm8 */
     608                case 0x83:              /* 5: sub r/m32, imm8 7: cmp r/m32, imm8 */
     609                    if ((pach[1] & 0x38) == (5<<3)
     610                        || (pach[1] & 0x38) == (7<<3)
     611                        )
     612                    {
     613                        cb += cb2 = 1 + ModR_M_32bit(pach[1]); /* 1 is the size of the imm8 */
     614                        pach += cb2;
     615                    }
    441616                    else
    442                         cb += 2; /*????!*/
    443                     break;
    444                 case 0x8d: /* lea (ldrRead) */
    445                     cb += 3;
    446                     break;
    447                 case 0x83: /* sub (LDRQAppType) */
    448                     cb += 3;
    449                     break;
     617                    {
     618                        kprintf(("interpretFunctionProlog32: unknown instruction (-3) 0x%x 0x%x 0x%x\n", pach[0], pach[1], pach[2]));
     619                        return -3;
     620                    }
     621                    break;
     622
     623                /* complex sized instruction - "/digit id" */
     624                case 0x81:              /* sub r/m32, imm32 + more instructions! */
     625                    if ((pach[1] & 0x38) == (5<<3)       /* sub r/m32, imm32  */
     626                        || (pach[1] & 0x38) == (7<<3)    /* cmp r/m32, imm32  */
     627                        )
     628                    {
     629                        cb += cb2 = 4 + ModR_M_32bit(pach[1]); /* 4 is the size of the imm32 */
     630                        pach += cb2;
     631                    }
     632                    else
     633                    {
     634                        kprintf(("interpretFunctionProlog32: unknown instruction (-2) 0x%x 0x%x 0x%x\n", pach[0], pach[1], pach[2]));
     635                        return -2;
     636                    }
     637                    break;
     638
    450639                default:
    451                     kprintf(("interpretFunctionProlog: unknown instruction 0x%x\n", pach[cb]));
     640                    kprintf(("interpretFunctionProlog32: unknown instruction 0x%x 0x%x 0x%x\n", pach[0], pach[1], pach[2]));
    452641                    return 0;
    453642            }
    454         }
    455     }
    456     else if (pach[0] == 0x55 && pach[1] == 0xa1) /* ldrEnum32bitRelRecs on WS4eB */
    457     {
    458         cb = 1 + 5;
     643            pach++;
     644            cb++;
     645        }
    459646    }
    460647    else
    461648    {
    462         /* special case for IOSftReadAt and IOSftWriteAt */
    463         if (fOverload == FALSE && pach[0] == 0xB8 && (pach[5] == 0xEB || pach[5] == 0x55))
    464             cb = 5;
    465         else
    466             cb = 0;
     649        kprintf(("interpretFunctionProlog32: unknown prolog start. 0x%x 0x%x 0x%x\n", pach[0], pach[1], pach[2]));
     650        cb = 0;
    467651    }
    468 
    469     return (signed char)cb;
     652    return cb;
    470653}
    471654
     
    480663 *                       FALSE: Function is to be imported.
    481664 */
    482 static signed char interpretFunctionProlog16(char *pach, BOOL fOverload)
     665static int interpretFunctionProlog16(char *pach, BOOL fOverload)
    483666{
    484     int cb;
    485 
     667    int cb = -7;
     668
     669    kprintf(("interpretFunctionProlog16(0x%08x, %d):\n"
     670             "\t%02x %02x %02x %02x - %02x %02x %02x %02x\n"
     671             "\t%02x %02x %02x %02x - %02x %02x %02x %02x\n",
     672             pach, fOverload,
     673             pach[0], pach[1], pach[2], pach[3], pach[4], pach[5], pach[6], pach[7],
     674             pach[8], pach[9], pach[10],pach[11],pach[12],pach[13],pach[14],pach[15]));
    486675    /*
    487676     * Check for the well known prolog (the only that is supported now)
     
    493682        BOOL fForce;
    494683        cb = 0;
    495         while (cb < 8 || fForce)
     684        while (cb < 8 || fForce)        /* 8 is the size of a 66h prefixed far jump instruction. */
    496685        {
    497686            fForce = FALSE;
     
    528717
    529718                case 0x8b:              /* mov /r */
    530                     if ((pach[1] & 0xc0) == 10  /* ex. mov ax,bp+1114h */
    531                         || ((pach[1] & 0xc0) == 0 && (pach[1] & 0xc0) == 6)) /* ex. mov bp,0ff23h */
     719                    if ((pach[1] & 0xc0) == 0x80  /* ex. mov ax,bp+1114h */
     720                        || ((pach[1] & 0xc0) == 0 && (pach[1] & 0x7) == 6)) /* ex. mov bp,0ff23h */
    532721                    {   /* 16-bit displacement */
    533722                        pach += 3;
     
    548737
    549738                default:
    550                     kprintf(("interpretFunctionProlog: unknown instruction 0x%x 0x%x 0x%x\n", pach[0], pach[1], pach[2]));
     739                    kprintf(("interpretFunctionProlog16: unknown instruction 0x%x 0x%x 0x%x\n", pach[0], pach[1], pach[2]));
    551740                    return 0;
    552741            }
     
    557746
    558747    fOverload = fOverload;
    559     return (signed char)cb;
     748    return cb;
    560749}
     750
    561751
    562752
     
    601791                 * Verify known function prolog.
    602792                 */
    603                 if (_aImportTab[i].fType & EPT_32BIT)
     793                if (EPT32BitEntry(_aImportTab[i]))
    604794                {
    605795                    cb = interpretFunctionProlog32((char*)_aImportTab[i].ulAddress, _aImportTab[i].fType == EPT_PROC32);
    606                     cbmin = 5;
     796                    cbmin = 5; /* Size of the jump instruction */
    607797                }
    608798                else
    609799                {
    610800                    cb = interpretFunctionProlog16((char*)_aImportTab[i].ulAddress, _aImportTab[i].fType == EPT_PROC16);
    611                     cbmin = 8;
     801                    cbmin = 7; /* Size of the far jump instruction */
    612802                }
    613803
     
    628818            default:
    629819                kprintf(("VerifyImportTab32: only EPT_PROC is implemented\n",i));
     820                Int3(); /* temporary fix! */
    630821                return STATUS_DONE | STERR | 4;
    631822        }
     
    665856    int i;
    666857    int cb;
    667 
     858    int cbmin;
    668859
    669860    /*
     
    676867            continue;
    677868
    678         if (_aImportTab[i].fType & EPT_32BIT)
     869        if (EPT32BitEntry(_aImportTab[i]))
     870        {
    679871            cb = interpretFunctionProlog32((char*)_aImportTab[i].ulAddress, _aImportTab[i].fType == EPT_PROC32);
     872            cbmin = 5; /* Size of the jump instruction */
     873        }
    680874        else
     875        {
    681876            cb = interpretFunctionProlog16((char*)_aImportTab[i].ulAddress, _aImportTab[i].fType == EPT_PROC16);
    682         if (cb <= 0 || cb + 5 >= MAXSIZE_PROLOG)
    683         {
    684             kprintf(("ImportTabInit: verify failed for procedure no.%d, cb=%d\n", i, cb));
     877            cbmin = 7; /* Size of the far jump instruction */
     878        }
     879        if (cb <= 0 || cb + cbmin >= MAXSIZE_PROLOG)
     880        {
     881            kprintf(("ImportTabInit: Verify failed for procedure no.%d, cb=%d\n", i, cb));
    685882            return 1;
    686883        }
     
    702899            case EPT_PROC32:
    703900            {
    704                 cb = _aImportTab[i].cbProlog = interpretFunctionProlog32((char*)_aImportTab[i].ulAddress, TRUE);
    705                 if (cb > 0 && cb + 5 < MAXSIZE_PROLOG)
    706                 {
     901                cb = interpretFunctionProlog32((char*)_aImportTab[i].ulAddress, TRUE);
     902                _aImportTab[i].cbProlog = (char)cb;
     903                if (cb >= 5 && cb + 5 < MAXSIZE_PROLOG) /* 5(1st): size of jump instruction in the function prolog which jumps to my overloading function */
     904                {                                       /* 5(2nd): size of jump instruction which jumps back to the original function after executing the prolog copied to the callTab entry for this function. */
    707905                    /*
    708906                     * Copy function prolog which will be overwritten by the jmp to calltabl.
     
    743941                Int3();
    744942
    745                 cb = _aImportTab[i].cbProlog = interpretFunctionProlog16((char*)_aImportTab[i].ulAddress, TRUE);
    746                 if (cb > 0 && cb + 8 < MAXSIZE_PROLOG) /* a 16:32 jump must be prefixed with 66h in a 16-bit segment */
    747                 {
     943                cb = interpretFunctionProlog16((char*)_aImportTab[i].ulAddress, TRUE);
     944                _aImportTab[i].cbProlog = (char)cb;
     945                if (cb >= 8 && cb + 7 < MAXSIZE_PROLOG) /* 8: size of a 16:32 jump which jumps to my overloading function (prefixed with 66h in a 16-bit segment) */
     946                {                                       /* 7: size of a 16:32 jump which is added to the call tab */
    748947                    /*
    749948                     * Copy function prolog which is to be overwritten.
     
    784983            case EPT_PROCIMPORT32:
    785984            {
    786                 cb = _aImportTab[i].cbProlog = interpretFunctionProlog32((char*)_aImportTab[i].ulAddress, FALSE);
    787                 if (cb > 0 && cb + 5 < MAXSIZE_PROLOG)
     985                cb = interpretFunctionProlog32((char*)_aImportTab[i].ulAddress, FALSE);
     986                _aImportTab[i].cbProlog = (char)cb;
     987                if (cb > 0) /* Since no prolog part is copied to the function table, it's ok as long as the prolog has been recognzied. */
    788988                {
    789989                    /*
     
    8111011            case EPT_PROCIMPORT16:
    8121012            {
    813                 cb = _aImportTab[i].cbProlog = interpretFunctionProlog16((char*)_aImportTab[i].ulAddress, FALSE);
    814                 if (cb > 0 && cb + 8 < MAXSIZE_PROLOG)
     1013                cb = interpretFunctionProlog16((char*)_aImportTab[i].ulAddress, FALSE);
     1014                _aImportTab[i].cbProlog = (char)cb;
     1015                if (cb > 0) /* Since no prolog part is copied to the function table, it's ok as long as the prolog has been recognzied. */
    8151016                {
    8161017                    /*
     
    8421043            case EPT_VARIMPORT32:
    8431044            case EPT_VARIMPORT16:
     1045                _aImportTab[i].cbProlog = (char)0;
    8441046                *(unsigned long*)(void*)&callTab[i][0] = _aImportTab[i].ulAddress;
    8451047                *(unsigned long*)(void*)&callTab[i][4] = _aImportTab[i].offObject;
Note: See TracChangeset for help on using the changeset viewer.