home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l430 / 1.ddi / CHAP5.ZIP / CODEDATA.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-12  |  3.3 KB  |  119 lines

  1. /*
  2.     CODEDATA.C -- Demonstration of executable data
  3.  
  4.     From Chapter 5 of "Undocumented Windows" (Addison-Wesley 1992)
  5.     by Andrew Schulman, Dave Maxey and Matt Pietrek
  6.  
  7.     Build using: WINIOBC CODEDATA (for Borland C++ v3.00)
  8.                  WINIOMS CODEDATA (for Microsoft C/SDK)
  9. */
  10.  
  11. #define WINDOWS
  12.  
  13. // Ignore MS warning about redefinition of NULL under Windows
  14. #include <stdlib.h>
  15. #ifdef WINDOWS
  16. #include <dos.h>
  17. #include "windows.h"
  18. #include "winio.h"
  19.  
  20. /* undocumented functions */
  21. void (FAR PASCAL *PrestoChangoSelector)(WORD sel1, WORD sel2);
  22. DWORD FAR PASCAL GetSelectorBase(WORD sel);
  23. #else
  24. #include <stdio.h>
  25. #endif
  26.  
  27. unsigned char data[] = {    
  28.     0xb8, 0x00, 0x00,   /* mov ax, 0000 */
  29.     0x00, 0x00, 0x00,   /* oper ax, immed */
  30.     0xcb,               /* retf */
  31.     } ;
  32.  
  33. #define OPER        3       /* offset in data of operation byte */
  34. #define AX_LO       1       /* ax operand lo byte */
  35. #define IMMED_LO    4       /* immediate operand lo byte */
  36.  
  37. /* opcodes */
  38. #define ADD     0x05
  39. #define OR      0x0d
  40. #define AND     0x25
  41. #define SUB     0x2d
  42. #define XOR     0x35
  43. #define CMP     0x3d
  44.  
  45. void (far *code)(void);
  46.  
  47. short math(short oper, short op1, short op2)
  48. {
  49.     /*
  50.         Compile code on the fly.  For example, math(AND, 1, 3)
  51.         becomes:
  52.             
  53.             B8 01 00        mov ax, 0001
  54.             25 03 00        and ax, 0003
  55.             CB              retf
  56.                 
  57.         Code is compiled by putting values in data[] array; it is
  58.         then immediately executed by calling (*code)() function ptr.
  59.     */
  60.     
  61.     *((short *) &data[AX_LO]) = op1;
  62.     *((short *) &data[IMMED_LO]) = op2;
  63.     data[OPER] = oper;
  64.     (*code)();
  65.     /* return result in AX */
  66. }
  67.  
  68. main()
  69. {
  70. #ifdef WINDOWS  
  71.     WORD data_sel, code_sel;
  72.     void far *fpdata = (void far *) data;   // Microsoft C FP_SEG wants lvalue
  73.     HANDLE hKernel;
  74.         
  75.     winio_about("CODEDATA"
  76.         "\nDemonstration of executable data"
  77.         "\n\nFrom Chapter 5 of"
  78.         "\n\"Undocumented Windows\" (Addison-Wesley, 1992)"
  79.         "\nby Andrew Schulman, David Maxey and Matt Pietrek"
  80.         );
  81.     
  82.     hKernel = GetModuleHandle("KERNEL");
  83.     PrestoChangoSelector = GetProcAddress(hKernel, "PRESTOCHANGOSELECTOR");
  84.     if (! PrestoChangoSelector)
  85.         PrestoChangoSelector = GetProcAddress(hKernel, "CHANGESELECTOR");
  86.     if (! PrestoChangoSelector)
  87.         fail("This program requires PrestoChangoSelector()");
  88.  
  89.     data_sel = FP_SEG(fpdata);
  90.     GlobalPageLock(data_sel); // Windows will not track changes for aliases!!
  91.     code_sel = AllocSelector(data_sel);
  92.     PrestoChangoSelector(data_sel, code_sel);
  93.     code = MK_FP(code_sel, FP_OFF(fpdata));
  94.         
  95.     /* Now try to shake code & data loose by moving memory */
  96.     GlobalCompact(-1L);
  97.  
  98.     if (GetSelectorBase(FP_SEG(code)) !=
  99.         GetSelectorBase(FP_SEG(fpdata)))
  100.             fail("Selectors out of sync!");
  101. #else
  102.     code = (void far *) data;
  103. #endif
  104.     
  105.     printf("1 && 3 ==> %d\n", math(AND, 1, 3));
  106.     printf("1 || 3 ==> %d\n", math(OR, 1, 3));
  107.     printf("1 ^ 3  ==> %d\n", math(XOR, 1, 3));
  108.     printf("1 + 3  ==> %d\n", math(ADD, 1, 3));
  109.     printf("1 - 3  ==> %d\n", math(SUB, 1, 3));
  110.     
  111. #ifdef WINDOWS
  112.     GlobalPageUnlock(data_sel);
  113.     FreeSelector(code_sel);
  114. #endif
  115.  
  116.     return 0;
  117. }
  118.  
  119.