home *** CD-ROM | disk | FTP | other *** search
- /*
- CODEDAT2.C -- Demonstration of self-modifying code
-
- From Chapter 5 of "Undocumented Windows" (Addison-Wesley 1992)
- by Andrew Schulman, Dave Maxey and Matt Pietrek
-
- Build using: WINIOBC CODEDAT2 (for Borland C++ v3.00)
- WINIOMS CODEDAT2 (for Microsoft C/SDK)
- */
-
- #define WINDOWS
-
- #include <stdlib.h>
- #ifdef WINDOWS
- #include <dos.h>
- #include <windows.h>
- #include "winio.h"
-
- #ifndef __BORLANDC__
- #define MK_FP(a,b) ((void far *)(((unsigned long)(a) << 16) | (b)))
- #endif
-
- /* undocumented function */
- WORD FAR PASCAL AllocCStoDSAlias(WORD code_sel);
- #else
- #include <stdio.h>
- #endif
-
- /* opcodes -- oper ax, addr */
- #define ADD 0x03
- #define OR 0x0b
- #define AND 0x23
- #define SUB 0x2b
- #define XOR 0x33
- #define CMP 0x3b
-
- static unsigned char far *oper_byte = 0;
-
- short math2(short oper, short op1, short op2)
- {
- *oper_byte = (unsigned char) oper;
-
- _asm jmp short go; /* clear instruction prefetch */
- go:;
-
- _asm mov ax, op1 /* if need to set debug breakpoint, do here */
- _asm xor ax, op2 /* will be modified!! */
- /* return result in AX */
- }
-
- main()
- {
- #ifdef WINDOWS
- WORD code_sel, data_sel;
- code_sel = FP_SEG(math2);
-
- winio_about("CODEDAT2"
- "\nDemonstrates self-modifying code"
- "\n\nFrom Chapter 5 of"
- "\n\"Undocumented Windows\" (Addison-Wesley, 1992)"
- "\nby Andrew Schulman, David Maxey and Matt Pietrek"
- );
-
- GlobalPageLock(code_sel); // still shareable? discardable?
- data_sel = AllocCStoDSAlias(code_sel);
- oper_byte = MK_FP(data_sel, FP_OFF(math2));
-
- GlobalCompact(-1);
- #else
- oper_byte = (unsigned char far *) math2;
- #endif
- while (*oper_byte != XOR)
- oper_byte++;
-
- #ifdef WINDOWS
- if (math2(AND, 1, 3) != 1)
- {
- if (__hPrevInst)
- fail("Doesn't work with multiple instances!");
- else
- fail("Inexplicable math failure!");
- }
- #endif
-
- printf("1 && 3 ==> %d\n", math2(AND, 1, 3));
- printf("1 || 3 ==> %d\n", math2(OR, 1, 3));
- printf("1 ^ 3 ==> %d\n", math2(XOR, 1, 3));
- printf("1 + 3 ==> %d\n", math2(ADD, 1, 3));
- printf("1 - 3 ==> %d\n", math2(SUB, 1, 3));
-
- #ifdef WINDOWS
- GlobalPageUnlock(code_sel);
- FreeSelector(data_sel); // important to undo AllocCStoDSAlias()!
- #endif
-
- return 0;
- }
-