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

  1. /*
  2.     CODEDAT2.C -- Demonstration of self-modifying code
  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 CODEDAT2 (for Borland C++ v3.00)
  8.                  WINIOMS CODEDAT2 (for Microsoft C/SDK)
  9. */
  10.  
  11. #define WINDOWS
  12.  
  13. #include <stdlib.h>
  14. #ifdef WINDOWS
  15. #include <dos.h>
  16. #include <windows.h>
  17. #include "winio.h"
  18.  
  19. #ifndef __BORLANDC__ 
  20. #define MK_FP(a,b)  ((void far *)(((unsigned long)(a) << 16) | (b))) 
  21. #endif 
  22.  
  23. /* undocumented function */
  24. WORD FAR PASCAL AllocCStoDSAlias(WORD code_sel);
  25. #else
  26. #include <stdio.h>
  27. #endif
  28.  
  29. /* opcodes -- oper ax, addr */
  30. #define ADD        0x03
  31. #define OR        0x0b
  32. #define AND        0x23
  33. #define SUB        0x2b
  34. #define XOR        0x33
  35. #define CMP        0x3b
  36.  
  37. static unsigned char far *oper_byte = 0;
  38.  
  39. short math2(short oper, short op1, short op2)
  40. {
  41.     *oper_byte = (unsigned char) oper;
  42.  
  43.     _asm jmp short go;        /* clear instruction prefetch */
  44. go:;
  45.     
  46.     _asm mov ax, op1        /* if need to set debug breakpoint, do here */
  47.     _asm xor ax, op2        /* will be modified!! */
  48.     /* return result in AX */
  49. }
  50.  
  51. main()
  52. {
  53. #ifdef WINDOWS
  54.     WORD code_sel, data_sel;
  55.     code_sel = FP_SEG(math2);
  56.  
  57.     winio_about("CODEDAT2"
  58.         "\nDemonstrates self-modifying code"
  59.         "\n\nFrom Chapter 5 of"
  60.         "\n\"Undocumented Windows\" (Addison-Wesley, 1992)"
  61.         "\nby Andrew Schulman, David Maxey and Matt Pietrek"
  62.         );
  63.     
  64.     GlobalPageLock(code_sel);    // still shareable? discardable?
  65.     data_sel = AllocCStoDSAlias(code_sel);
  66.     oper_byte = MK_FP(data_sel, FP_OFF(math2));
  67.     
  68.     GlobalCompact(-1);
  69. #else
  70.     oper_byte = (unsigned char far *) math2;
  71. #endif
  72.     while (*oper_byte != XOR)
  73.         oper_byte++;
  74.  
  75. #ifdef WINDOWS    
  76.     if (math2(AND, 1, 3) != 1)
  77.     {
  78.         if (__hPrevInst)
  79.             fail("Doesn't work with multiple instances!");
  80.         else
  81.             fail("Inexplicable math failure!");
  82.     }
  83. #endif
  84.     
  85.     printf("1 && 3 ==> %d\n", math2(AND, 1, 3));
  86.     printf("1 || 3 ==> %d\n", math2(OR, 1, 3));
  87.     printf("1 ^ 3  ==> %d\n", math2(XOR, 1, 3));
  88.     printf("1 + 3  ==> %d\n", math2(ADD, 1, 3));
  89.     printf("1 - 3  ==> %d\n", math2(SUB, 1, 3));
  90.     
  91. #ifdef WINDOWS
  92.     GlobalPageUnlock(code_sel);
  93.     FreeSelector(data_sel);        // important to undo AllocCStoDSAlias()!
  94. #endif
  95.  
  96.     return 0;
  97. }
  98.  
  99.