home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************/
- /* */
- /* File : MODULE1.C */
- /* */
- /* Version : 1.0 */
- /* Date : 08/30/91 */
- /* */
- /* Author : Ernest Vogelsinger */
- /* */
- /* Description : Module 1 for DMalloc demo program */
- /* Main code for heap allocation and extinction (hehehe) */
- /* */
- /* */
- /* (c) E.Vogelsinger 1991, 1992 */
- /***************************************************************************/
-
- #include <stdio.h>
- #include <string.h>
- #include <conio.h>
- #include <stddef.h>
- #include <stdlib.h>
- #include <malloc.h>
- #include <dos.h>
-
-
- /*
- * To avoid multiple occurrences of the __FILE__ macro,
- * these lines must be present before including DMALLOC.H!
- */
- #define __DMFILE__
- static char * DM_file$ = __FILE__;
-
- #define _DMALLOC
- #include <dmalloc.h>
-
-
- #include "demo.h"
-
- #define LIMIT 1200
- #define FALSE 0
- #define TRUE (!FALSE)
- #define MK_FP(seg,ofs) ((void far *) (((unsigned long)(seg)<<16)|(unsigned)(ofs)))
- #define OFFSETOF(p) (((unsigned*)&(p))[0])
-
-
- char *apPtr[LIMIT]; /* storage for allocated pointers */
-
-
- /*
- * NAME:
- * printframe
- *
- * DESCRIPTION:
- * Prints a text and frames it
- *
- * PARAMETER(S):
- * char *apText[] Ptr to a NULL terminated string array
- *
- * RETURNS:
- * void
- */
- void printframe(char *apText[])
- {
- static char *frametop = "\n╔═════════════════"
- "════════════════════"
- "════════════════════"
- "═══════════════════╗\n";
- static char *framebottom = "╚═══════════════════"
- "════════════════════"
- "════════════════════"
- "═════════════════╝\n";
- static char *framecontent= "║%-76s║\n";
-
- int i = 0;
-
- printf(frametop);
- while(apText[i]) {
- printf(framecontent, apText[i]);
- i++;
- }
- printf(framebottom);
- }
-
-
- /*
- * NAME:
- * print
- *
- * DESCRIPTION:
- * Prints a text
- *
- * PARAMETER(S):
- * char *apText[] Ptr to a NULL terminated string array
- *
- * RETURNS:
- * void
- */
- void print(char *apText[])
- {
- int i = 0;
-
- while(apText[i]) {
- printf("%s\n", apText[i]);
- i++;
- }
- }
-
-
- /*
- * NAME:
- * anykey
- *
- * DESCRIPTION:
- * Waits for any key, and optionally asks to press one
- *
- * PARAMETER(S):
- * int fAsk If it should ask for a key or wait silent
- *
- * RETURNS:
- * void
- *
- */
- void anykey(int fAsk)
- {
- if (fAsk)
- printf(any_key);
- getch();
- printf("\n");
- }
-
-
- /*
- * NAME:
- * clrscr
- *
- * DESCRIPTION:
- * Clears the screen
- *
- * PARAMETER(S):
- * void
- *
- * RETURNS:
- * void
- */
- void clrscr(void)
- {
- union REGS regs;
-
- regs.x.ax = 0x600; /* clear screen */
- regs.x.bx = 0x700; /* paint it black */
- regs.x.cx = 0; /* from the left upper */
- regs.x.dx = 0x184F; /* to the right lower corner */
-
- int86(0x10, ®s, ®s); /* do the interrupt */
-
- regs.x.ax = 0x200; /* position the cursor */
- regs.x.bx = 0; /* default page */
- regs.x.dx = 0; /* left top */
-
- int86(0x10, ®s, ®s);
- }
-
- /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-
- #define ALLOC1 86
- #define ALLOC2 77
- #define ALLOC3 43
-
- void main(void)
- {
- DML_SAVEAREA(dmSave); /* variable to store DMalloc setup */
- int i;
- void *p;
-
- clrscr();
- printframe(welcome);
- anykey(FALSE);
-
- /* Say that we're allocating memory now. */
- print(explain1);
-
- for (i = 0; i < LIMIT; i += 3) {
-
- apPtr[i] = malloc(ALLOC1); /* This module (with DMalloc info) */
- apPtr[i+1] = alloc2(ALLOC2); /* Module 2 (with DMalloc info) */
- apPtr[i+2] = alloc3(ALLOC3); /* Module 3 (winthout DMalloc info) */
-
- printf("Allocating: %u\r", i);
- }
- anykey(TRUE);
-
- /* finished allocating - explain what happened */
- printframe(explain1a);
- anykey(FALSE);
-
- /* New screen, and ask to press PrintScreen */
- clrscr();
- printframe(explain2);
- printf(any_prtsc);
- anykey(FALSE);
-
- /* Announce that we're going to destroy some allocation units */
- clrscr();
- printframe(explain3);
- anykey(FALSE);
-
- /* note: blocks n+0 are allocated size 86
- n+1 have size 77
- n+2 have size 43 */
-
- memset(apPtr[3], 3, ALLOC1+1); /* overwrite element 3 */
- memset(apPtr[4], 4, ALLOC2+1); /* overwrite element 4 (odd/even) */
- memset(apPtr[8]-1, 5, 10); /* tamper element 11 with negative indexed */
- /* address (would normally destroy MCB) */
-
-
- /* DMalloc API:
- * Save the current setup
- */
- DML_SaveState(dmSave);
-
- /* DMalloc API:
- * modify setup parameters
- */
- DML_Setup(SET_UNCHANGED, /* fAlert: popup on problem */
- SET_UNCHANGED, /* fSaved: popup when known are allocated */
- SET_UNCHANGED, /* usPopCycles: popup on every n'th access */
- 1, /* usCycles: check on every cycle */
- PSZ_UNCHANGED, /* owner file */
- SET_UNCHANGED); /* line */
-
- /*
- * Free allocated unit 0
- * Since the setup defines to check the heap on each access,
- * this otherwise valid call will lead to problem detection.
- */
- free(apPtr[0]);
-
-
- /* Tell something on how to navigate within the heap window,
- * and ask the user to try it.
- */
- clrscr();
- printframe(explain4);
- printf(any_prtsc);
- anykey(FALSE);
-
- /*
- * DMalloc API:
- * Restore setup that has been saved
- */
- DML_RestoreState(dmSave);
-
- /*
- * Tell something about invalid pointer warning
- * Mention discarding and breakpoints
- */
- clrscr();
- printframe(explain5);
- anykey(TRUE);
-
- /* This could be fatal since it points into DOS! */
- free(MK_FP(0x65,0x5678));
-
- /* Demonstrate Null pointer assignment */
- clrscr();
- printframe(explain6);
- anykey(TRUE);
-
- /*
- * DMalloc API:
- * Restore saved setup
- * (we asked the user to change the selection)
- */
- DML_RestoreState(dmSave);
-
- /*
- * DMalloc API:
- * Set a Watchpoint on _DATA segment
- * This would not be needed, since this is the default.
- * Note: It will only work if the _nullcheck() function is not replaced.
- */
- DML_Watchpoint(DATA_NULLCHECK, SET_ON);
-
- /*
- * DMalloc API:
- * modify setup parameters
- */
- DML_Setup(SET_UNCHANGED, /* fAlert: popup on problem */
- SET_UNCHANGED, /* fSaved: popup when known are allocated */
- SET_UNCHANGED, /* usPopCycles: popup on every n'th access */
- 1, /* usCycles: check on every cycle */
- PSZ_UNCHANGED, /* owner file */
- SET_UNCHANGED); /* line */
-
-
- p = (char *)&i; /* since i is on the stack, apPtr points */
- OFFSETOF(p) = 0; /* to the data segment. To simulate a NULL */
- /* pointer access, we make the pointer */
- /* offset NULL. */
-
- strcpy(p, "This is an overwrite to the Data Segment Null Region!");
-
- /*
- * Free allocated unit 1
- * Since the setup defines to check the heap on each access,
- * this otherwise valid call will lead to problem detection.
- */
- free(apPtr[1]);
-
- /*
- * Make it clear that the final runtime error is intended and not a bug.
- */
- printframe(explain6a);
- anykey(TRUE);
-
- /*
- * DMalloc API:
- * Restore setup that has been saved
- */
- DML_RestoreState(dmSave);
-
- /*
- * ...More explanation
- */
- clrscr();
- printframe(explain7);
- anykey(FALSE);
-
- /*
- * Final page
- */
- clrscr();
- printframe(explain8);
- anykey(FALSE);
-
-
- /*
- * Uuuh - now the heap will be destroyed!!
- * Just tamper with the allocation info structure.
- * Just for this demo, a small introduction on allocation units
- * with DMalloc:
- * ┌───────────── Usable contents (variable)
- * ╦════╤═══╤═╧══════╤════╦═
- * ║info│dml│contents│ dml║ ...
- * ╩═╤══╧═╤═╧════════╧══╤═╩═
- * │ └─────────────┴─── DMalloc integrity info (2x4)
- * └────────────────────── malloc unit info (2)
- */
-
- apPtr[2] -= 6; /* point to <info> (4 bytes dml, 2 bytes info) */
- *(apPtr[2]) += 2; /* that's enough... */
-
-
- /*
- * Simply free the list of allocated pointers.
- * The heap should be corrupted immediately.
- */
- for (i = 2; i < LIMIT; i++) {
- free(apPtr[i]);
- printf("Freeing: %u\r", i);
- }
- }
-