Changeset 2832 for trunk/src/win32k/dev32/d32init.c
- Timestamp:
- Feb 20, 2000, 5:27:24 AM (26 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/win32k/dev32/d32init.c
r2831 r2832 1 /* $Id: d32init.c,v 1.1 1 2000-02-19 23:51:59bird Exp $1 /* $Id: d32init.c,v 1.12 2000-02-20 04:27:23 bird Exp $ 2 2 * 3 3 * d32init.c - 32-bits init routines. … … 14 14 #define MAXSIZE_PROLOG 0x10 /* Note that this must be synced with */ 15 15 /* the one used in calltab.asm. */ 16 #define static 16 #define static /* just to make all symbols visible in the kernel debugger. */ 17 17 18 18 19 #define INCL_DOSERRORS 19 20 #define INCL_NOPMAPI 20 21 #define LDR_INCL_INITONLY 21 22 22 23 23 /******************************************************************************* … … 44 44 *******************************************************************************/ 45 45 static ULONG readnum(const char *pszNum); 46 static int interpretFunctionProlog(char *p, BOOL fOverload); 47 static int procInit(void); 46 static signed char interpretFunctionProlog32(char *pach, BOOL fOverload); 47 static signed char interpretFunctionProlog16(char *pach, BOOL fOverload); 48 static int ImportTabInit(void); 48 49 49 50 … … 291 292 /* functionoverrides */ 292 293 if (!options.fNoLoader) 293 if ( procInit() != NO_ERROR)294 if (ImportTabInit() != NO_ERROR) 294 295 return STATUS_DONE | STERR | ERROR_I24_QUIET_INIT_FAIL; 295 296 … … 338 339 339 340 return i > 0 ? ulRet : ~0UL; 340 }341 342 343 /**344 * Verifies the aImportTab.345 * @returns 0 if ok. !0 if not ok.346 * @remark Called from IOCtl.347 */348 USHORT _loadds _Far32 _Pascal VerifyProcTab32(void)349 {350 int i;351 int cb;352 353 /* verify */354 for (i = 0; i < NBR_OF_KRNLIMPORTS; i++)355 {356 /* verify that it is found */357 if (!_aImportTab[i].fFound)358 {359 kprintf(("VerifyProcTab32: procedure no.%d was not found!\n", i));360 return STATUS_DONE | STERR | 1;361 }362 363 /* verify read/writeable. - FIXME */364 if (_aImportTab[i].ulAddress < 0xffe00000UL)365 {366 kprintf(("VerifyProcTab32: procedure no.%d has an invlalid address, %#08x!\n",367 i, _aImportTab[i].ulAddress));368 return STATUS_DONE | STERR | 2;369 }370 371 switch (_aImportTab[i].fType)372 {373 case EPT_PROC:374 case EPT_PROCIMPORT:375 /* verify known function prolog. */376 if ((cb = interpretFunctionProlog((char*)_aImportTab[i].ulAddress, _aImportTab[i].fType == EPT_PROC))377 <= 0 && cb + 5 >= MAXSIZE_PROLOG)378 {379 kprintf(("VerifyProcTab32: verify failed for procedure no.%d\n",i));380 return STATUS_DONE | STERR | 3;381 }382 break;383 384 default:385 kprintf(("VerifyProcTab32: only EPT_PROC is implemented\n",i));386 return STATUS_DONE | STERR | 4;387 }388 }389 390 return STATUS_DONE;391 341 } 392 342 … … 446 396 447 397 /** 448 * Interpret function prolog to find where to jmp back.398 * 32-bit! Interpret function prolog to find where to jmp back. 449 399 * @returns Length of prolog need to be copied - which is also the offset of 450 400 * where the jmp instr should be placed. … … 454 404 * FALSE: Function is to be imported. 455 405 */ 456 static int interpretFunctionProlog(char *pach, BOOL fOverload)406 static signed char interpretFunctionProlog32(char *pach, BOOL fOverload) 457 407 { 458 int rc;408 int cb; 459 409 460 410 /* … … 471 421 { 472 422 if (pach[2] == 0xec) 473 rc= 3;423 cb = 3; 474 424 else 475 rc= 1;476 while ( rc< 5)425 cb = 1; 426 while (cb < 5) 477 427 { 478 428 /* … … 481 431 * There will never be any doubt when something goes wrong! 482 432 */ 483 switch(pach[ rc])433 switch(pach[cb]) 484 434 { 485 435 case 0x33: /* xor (ldrClose, ldrOpen) */ 486 rc+=2;436 cb +=2; 487 437 break; 488 438 case 0x8b: 489 if (pach[ rc+1] == 0x0d)490 rc+= 6;439 if (pach[cb+1] == 0x0d) 440 cb += 6; 491 441 else 492 rc+= 2; /*????!*/442 cb += 2; /*????!*/ 493 443 break; 494 444 case 0x8d: /* lea (ldrRead) */ 495 rc+= 3;445 cb += 3; 496 446 break; 497 447 case 0x83: /* sub (LDRQAppType) */ 498 rc+= 3;448 cb += 3; 499 449 break; 500 450 default: 501 kprintf(("interpretFunctionProlog: unknown instruction 0x%x\n", pach[ rc]));451 kprintf(("interpretFunctionProlog: unknown instruction 0x%x\n", pach[cb])); 502 452 return 0; 503 453 } … … 506 456 else if (pach[0] == 0x55 && pach[1] == 0xa1) /* ldrEnum32bitRelRecs on WS4eB */ 507 457 { 508 rc= 1 + 5;458 cb = 1 + 5; 509 459 } 510 460 else … … 512 462 /* special case for IOSftReadAt and IOSftWriteAt */ 513 463 if (fOverload == FALSE && pach[0] == 0xB8 && (pach[5] == 0xEB || pach[5] == 0x55)) 514 rc= 5;464 cb = 5; 515 465 else 516 rc= 0;466 cb = 0; 517 467 } 518 468 519 return rc;469 return (signed char)cb; 520 470 } 521 471 472 473 /** 474 * 16-bit! Interpret function prolog to find where to jmp back. 475 * @returns Length of prolog need to be copied - which is also the offset of 476 * where the jmp instr should be placed. 477 * On error it returns 0. 478 * @param pach Pointer to prolog. 479 * @param fOverload TRUE: Function is to be overloaded. 480 * FALSE: Function is to be imported. 481 */ 482 static signed char interpretFunctionProlog16(char *pach, BOOL fOverload) 483 { 484 int cb; 485 486 /* 487 * Check for the well known prolog (the only that is supported now) 488 * which is: 489 * push 2 490 */ 491 if (*pach == 0x6A) /* push 2 (don't check for the 2) */ 492 { 493 BOOL fForce; 494 cb = 0; 495 while (cb < 8 || fForce) 496 { 497 fForce = FALSE; 498 switch (*pach) 499 { 500 case 0x50: /* push ax */ 501 case 0x51: /* push cx */ 502 case 0x52: /* push dx */ 503 case 0x53: /* push bx */ 504 case 0x54: /* push sp */ 505 case 0x55: /* push bp */ 506 case 0x56: /* push si */ 507 case 0x57: /* push di */ 508 break; 509 510 case 0x2e: /* cs segment override */ 511 case 0x36: /* ss segment override */ 512 case 0x3e: /* ds segment override */ 513 case 0x26: /* es segment override */ 514 case 0x64: /* fs segment override */ 515 case 0x65: /* gs segment override */ 516 fForce = TRUE; 517 break; 518 519 case 0x6a: /* push <byte> */ 520 pach++; 521 cb++; 522 break; 523 524 case 0x68: /* push <word> */ 525 pach += 2; 526 cb += 2; 527 break; 528 529 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 */ 532 { /* 16-bit displacement */ 533 pach += 3; 534 cb += 3; 535 } 536 else 537 if ((pach[1] & 0xc0) == 0x40) /* ex. mov ax,[si]+4fh */ 538 { /* 8-bit displacement */ 539 pach += 2; 540 cb += 2; 541 } 542 else 543 { /* no displacement (only /r byte) */ 544 pach++; 545 cb++; 546 } 547 break; 548 549 default: 550 kprintf(("interpretFunctionProlog: unknown instruction 0x%x 0x%x 0x%x\n", pach[0], pach[1], pach[2])); 551 return 0; 552 } 553 pach++; 554 cb++; 555 } 556 } 557 558 fOverload = fOverload; 559 return (signed char)cb; 560 } 561 562 563 /** 564 * Verifies the aImportTab. 565 * @returns 0 if ok. !0 if not ok. 566 * @remark Called from IOCtl. 567 * WARNING! VerifyImporTab32 is called before the initroutine! 568 */ 569 USHORT _loadds _Far32 _Pascal VerifyImportTab32(void) 570 { 571 int i; 572 int cb; 573 int cbmin; 574 575 /* VerifyImporTab32 is called before the initroutine! */ 576 pulTKSSBase32 = (PULONG)_TKSSBase16; 577 578 /* verify */ 579 for (i = 0; i < NBR_OF_KRNLIMPORTS; i++) 580 { 581 /* verify that it is found */ 582 if (!_aImportTab[i].fFound) 583 { 584 kprintf(("VerifyImportTab32: procedure no.%d was not found!\n", i)); 585 return STATUS_DONE | STERR | 1; 586 } 587 588 /* verify read/writeable. - FIXME */ 589 if (_aImportTab[i].ulAddress < 0xffe00000UL) 590 { 591 kprintf(("VerifyImportTab32: procedure no.%d has an invlalid address, %#08x!\n", 592 i, _aImportTab[i].ulAddress)); 593 return STATUS_DONE | STERR | 2; 594 } 595 596 switch (_aImportTab[i].fType & ~EPT_BIT_MASK) 597 { 598 case EPT_PROC: 599 case EPT_PROCIMPORT: 600 /* 601 * Verify known function prolog. 602 */ 603 if (_aImportTab[i].fType & EPT_32BIT) 604 { 605 cb = interpretFunctionProlog32((char*)_aImportTab[i].ulAddress, _aImportTab[i].fType == EPT_PROC32); 606 cbmin = 5; 607 } 608 else 609 { 610 cb = interpretFunctionProlog16((char*)_aImportTab[i].ulAddress, _aImportTab[i].fType == EPT_PROC16); 611 cbmin = 8; 612 } 613 614 /* 615 * Check result of the function prolog interpretations. 616 */ 617 if (cb <= 0 && cb + cbmin >= MAXSIZE_PROLOG) 618 { /* failed, too small or too large. */ 619 kprintf(("VerifyImportTab32: verify failed for procedure no.%d (cd=%d)\n", i, cb)); 620 return STATUS_DONE | STERR | 3; 621 } 622 break; 623 624 case EPT_VARIMPORT: 625 /* do nothing! */ 626 break; 627 628 default: 629 kprintf(("VerifyImportTab32: only EPT_PROC is implemented\n",i)); 630 return STATUS_DONE | STERR | 4; 631 } 632 } 633 634 return STATUS_DONE; 635 } 522 636 523 637 … … 526 640 * @returns NO_ERROR on success. !0 on error. 527 641 */ 528 static int procInit(void)642 static int importTabInit(void) 529 643 { 644 /* This table must be updated with the overloading functions. */ 645 static unsigned auFuncs[NBR_OF_KRNLIMPORTS] = 646 { 647 (unsigned)myldrRead, 648 (unsigned)myldrOpen, 649 (unsigned)myldrClose, 650 0,//(unsigned)myLDRQAppType, 651 (unsigned)myldrEnum32bitRelRecs, 652 0, 653 0, 654 0, 655 0, 656 0, 657 0, 658 0, 659 0, 660 (unsigned)&mytkExecPgm, 661 0, 662 0 663 }; 664 530 665 int i; 531 666 int cb; 667 532 668 533 669 /* … … 536 672 for (i = 0; i < NBR_OF_KRNLIMPORTS; i++) 537 673 { 538 if (_aImportTab[i].fType != EPT_PROC && _aImportTab[i].fType != EPT_PROCIMPORT) 539 { 540 kprintf(("procInit: EPT_VAR is not supported. (procedure no.%d, cb=%d)\n", i, cb)); 541 return 1; 542 } 543 cb = interpretFunctionProlog((char*)_aImportTab[i].ulAddress, _aImportTab[i].fType == EPT_PROC); 674 /* EPT_VARIMPORTs are skipped */ 675 if ((_aImportTab[i].fType & ~EPT_BIT_MASK) == EPT_VARIMPORT) 676 continue; 677 678 if (_aImportTab[i].fType & EPT_32BIT) 679 cb = interpretFunctionProlog32((char*)_aImportTab[i].ulAddress, _aImportTab[i].fType == EPT_PROC32); 680 else 681 cb = interpretFunctionProlog16((char*)_aImportTab[i].ulAddress, _aImportTab[i].fType == EPT_PROC16); 544 682 if (cb <= 0 || cb + 5 >= MAXSIZE_PROLOG) 545 683 { 546 kprintf((" procInit: verify failed for procedure no.%d, cb=%d\n", i, cb));684 kprintf(("ImportTabInit: verify failed for procedure no.%d, cb=%d\n", i, cb)); 547 685 return 1; 548 686 } … … 556 694 switch (_aImportTab[i].fType) 557 695 { 558 case EPT_PROC: 696 /* 697 * 32-bit procedure overload. 698 * The overloading procedure is found in the auFuncs table (at the same index 699 * as the overloaded procedure has in aImportTab). 700 * The overloaded procedure is called by issuing a call to the callTab entry. 701 */ 702 case EPT_PROC32: 559 703 { 560 cb = interpretFunctionProlog((char*)_aImportTab[i].ulAddress, TRUE);704 cb = _aImportTab[i].cbProlog = interpretFunctionProlog32((char*)_aImportTab[i].ulAddress, TRUE); 561 705 if (cb > 0 && cb + 5 < MAXSIZE_PROLOG) 562 706 { 563 static unsigned auFuncs[NBR_OF_KRNLIMPORTS] = /* This table must be updated with the overloading functions. */ 564 { 565 (unsigned)myldrRead, 566 (unsigned)myldrOpen, 567 (unsigned)myldrClose, 568 0,//(unsigned)myLDRQAppType, 569 (unsigned)myldrEnum32bitRelRecs, 570 0, 571 0, 572 0, 573 0, 574 0, 575 0, 576 0, 577 0, 578 (unsigned)&mytkExecPgm 579 }; 580 581 /* copy function prolog */ 707 /* 708 * Copy function prolog which will be overwritten by the jmp to calltabl. 709 */ 582 710 memcpy(callTab[i], (void*)_aImportTab[i].ulAddress, (size_t)cb); 583 711 584 /* jump from calltab to original function */ 712 /* 713 * Make jump instruction which jumps from calltab to original function. 714 * 0xE9 <four bytes displacement> 715 * Note: the displacement is relative to the next instruction 716 */ 585 717 callTab[i][cb] = 0xE9; /* jmp */ 586 *(unsigned*)(void*)&callTab[i][cb+1] = _aImportTab[i].ulAddress + cb - (unsigned)&callTab[i][cb+5]; 587 588 589 /* jump from original function to my function - an cli(?) could be needed here */ 718 *(unsigned long*)(void*)&callTab[i][cb+1] = _aImportTab[i].ulAddress + cb - (unsigned long)&callTab[i][cb+5]; 719 720 /* 721 * Jump from original function to my function - an cli(?) could be needed here 722 */ 590 723 *(char*)_aImportTab[i].ulAddress = 0xE9; /* jmp */ 591 *(unsigned *)(_aImportTab[i].ulAddress + 1) = auFuncs[i] - (_aImportTab[i].ulAddress + 5);724 *(unsigned long*)(_aImportTab[i].ulAddress + 1) = auFuncs[i] - (_aImportTab[i].ulAddress + 5); 592 725 } 593 726 else 594 727 { /* !fatal! - this could never happen really... */ 595 kprintf((" procInit: FATAL verify failed for procedure no.%d when rehooking it!\n",i));728 kprintf(("ImportTabInit: FATAL verify failed for procedure no.%d when rehooking it!\n",i)); 596 729 Int3(); /* ipe - later! */ 597 730 return 1; … … 600 733 } 601 734 602 case EPT_PROCIMPORT: 735 736 /* 737 * 16-bit procedure overload. 738 * Currently disabled due to expected problems when calltab is a 32-bit segment. 739 */ 740 case EPT_PROC16: 603 741 { 604 cb = interpretFunctionProlog((char*)_aImportTab[i].ulAddress, FALSE); 742 kprintf(("ImportTabInit: Overloading 16-bit procedures are not supported yet!!! Calltable in 32-bit segment!\n", i)); 743 Int3(); 744 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 { 748 /* 749 * Copy function prolog which is to be overwritten. 750 */ 751 memcpy(callTab[i], (void*)_aImportTab[i].ulAddress, (size_t)cb); 752 753 /* 754 * Create far jump from calltab to original function. 755 * 0xEA <four byte target address> <two byte target selector> 756 */ 757 callTab[i][cb] = 0xEA; /* jmp far ptr */ 758 *(unsigned long*)(void*)&callTab[i][cb+1] = _aImportTab[i].offObject; 759 *(unsigned short*)(void*)&callTab[i][cb+5] = _aImportTab[i].usSel; 760 761 /* 762 * jump from original function to my function - an cli(?) could be needed here 763 * 0x66 0xEA <four byte target address> <two byte target selector> 764 */ 765 *(char*)(_aImportTab[i].ulAddress ) = 0x66; /* operandsize prefix */ 766 *(char*)(_aImportTab[i].ulAddress + 1) = 0xEA; /* jmp far ptr */ 767 *(unsigned long*)(_aImportTab[i].ulAddress + 2) = auFuncs[i]; /* FIXME? */ 768 *(unsigned short*)(_aImportTab[i].ulAddress + 6) = _R0FlatCS16; /* FIXME */ 769 } 770 else 771 { /* !fatal! - this could never happen really... */ 772 kprintf(("ImportTabInit: FATAL verify failed for procedure no.%d when rehooking it!\n",i)); 773 Int3(); /* ipe - later! */ 774 return 1; 775 } 776 break; 777 } 778 779 780 /* 781 * 32-bit imported procedure 782 * This is called by issuing a near call to the callTab entry. 783 */ 784 case EPT_PROCIMPORT32: 785 { 786 cb = _aImportTab[i].cbProlog = interpretFunctionProlog32((char*)_aImportTab[i].ulAddress, FALSE); 605 787 if (cb > 0 && cb + 5 < MAXSIZE_PROLOG) 606 788 { 607 /* jump from calltab to original function */ 789 /* 790 * Make jump instruction which jumps from calltab to original function. 791 * 0xE9 <four bytes displacement> 792 * Note: the displacement is relative to the next instruction 793 */ 608 794 callTab[i][0] = 0xE9; /* jmp */ 609 795 *(unsigned*)(void*)&callTab[i][1] = _aImportTab[i].ulAddress - (unsigned)&callTab[i][cb+5]; 610 796 } 611 797 else 612 { /* !fatal! - this could never happen really... */613 kprintf((" procInit: FATAL verify failed for procedure no.%d when importing it!\n",i));798 { /* !fatal! - this should never really happen... */ 799 kprintf(("ImportTabInit: FATAL verify failed for procedure no.%d when importing it!\n",i)); 614 800 Int3(); /* ipe - later! */ 615 801 return 1; … … 618 804 } 619 805 806 807 /* 808 * 16-bit imported procedure. 809 * This is called by issuing a far call to the calltab entry. 810 */ 811 case EPT_PROCIMPORT16: 812 { 813 cb = _aImportTab[i].cbProlog = interpretFunctionProlog16((char*)_aImportTab[i].ulAddress, FALSE); 814 if (cb > 0 && cb + 8 < MAXSIZE_PROLOG) 815 { 816 /* 817 * Create far jump from calltab to original function. 818 * 0xEA <four byte target address> <two byte target selector> 819 */ 820 callTab[i][0] = 0xEA; /* jmp far ptr */ 821 *(unsigned long*)(void*)&callTab[i][1] = _aImportTab[i].offObject; 822 *(unsigned short*)(void*)&callTab[i][5] = _aImportTab[i].usSel; 823 } 824 else 825 { /* !fatal! - this should never really happen... */ 826 kprintf(("ImportTabInit: FATAL verify failed for procedure no.%d when importing it!\n",i)); 827 Int3(); /* ipe - later! */ 828 return 1; 829 } 830 break; 831 } 832 833 834 /* 835 * 16/32-bit importe variable. 836 * This is used by accessing the 32-bit flat address in the callTab. 837 * callTab-entry + 4 holds the offset of the variable into the object. 838 * callTab-entry + 8 holds the selector for the object. (These two fields is the 16:32-bit pointer to the variable.) 839 * callTab-entry + a holds the 16-bit offset for the variable. 840 * callTab-entry + c holds the selector for the object. (These two fiels is the 16:16-bit pointer to the variable.) 841 */ 842 case EPT_VARIMPORT32: 843 case EPT_VARIMPORT16: 844 *(unsigned long*)(void*)&callTab[i][0] = _aImportTab[i].ulAddress; 845 *(unsigned long*)(void*)&callTab[i][4] = _aImportTab[i].offObject; 846 *(unsigned short*)(void*)&callTab[i][8] = _aImportTab[i].usSel; 847 *(unsigned short*)(void*)&callTab[i][0xa] = (unsigned short)_aImportTab[i].offObject; 848 *(unsigned short*)(void*)&callTab[i][0xc] = _aImportTab[i].usSel; 849 break; 850 620 851 default: 621 kprintf((" procInit: EPT_VAR is not supported. (procedure no.%d, cb=%d)\n", i, cb));852 kprintf(("ImportTabInit: unsupported type. (procedure no.%d, cb=%d)\n", i, cb)); 622 853 Int3(); /* ipe - later! */ 623 854 return 1;
Note:
See TracChangeset
for help on using the changeset viewer.