home *** CD-ROM | disk | FTP | other *** search
/ The Education Master 1994 (4th Edition) / EDUCATIONS_MASTER_4TH_EDITION.bin / files / progng_c / dmalloc / install.lib / SAMPLE / MODULE1.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-01  |  9.7 KB  |  364 lines

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*         File : MODULE1.C                                                */
  4. /*                                                                         */
  5. /*      Version : 1.0                                                      */
  6. /*         Date : 08/30/91                                                 */
  7. /*                                                                         */
  8. /*       Author : Ernest Vogelsinger                                       */
  9. /*                                                                         */
  10. /*  Description : Module 1 for DMalloc demo program                        */
  11. /*                Main code for heap allocation and extinction (hehehe)    */
  12. /*                                                                         */
  13. /*                                                                         */
  14. /*                  (c) E.Vogelsinger 1991, 1992                           */
  15. /***************************************************************************/
  16.  
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <conio.h>
  20. #include <stddef.h>
  21. #include <stdlib.h>
  22. #include <malloc.h>
  23. #include <dos.h>
  24.  
  25.  
  26. /*
  27.  * To avoid multiple occurrences of the __FILE__ macro,
  28.  * these lines must be present before including DMALLOC.H!
  29.  */
  30. #define __DMFILE__
  31. static char * DM_file$ = __FILE__;
  32.  
  33. #define _DMALLOC
  34. #include <dmalloc.h>
  35.  
  36.  
  37. #include "demo.h"
  38.  
  39. #define LIMIT           1200
  40. #define FALSE           0
  41. #define TRUE            (!FALSE)
  42. #define MK_FP(seg,ofs)  ((void far *) (((unsigned long)(seg)<<16)|(unsigned)(ofs)))
  43. #define OFFSETOF(p)     (((unsigned*)&(p))[0])
  44.  
  45.  
  46. char *apPtr[LIMIT];    /* storage for allocated pointers */
  47.  
  48.  
  49. /*
  50.  * NAME:
  51.  *  printframe
  52.  *
  53.  * DESCRIPTION:
  54.  *  Prints a text and frames it
  55.  *
  56.  * PARAMETER(S):
  57.  *  char *apText[]   Ptr to a NULL terminated string array
  58.  *
  59.  * RETURNS:
  60.  *  void    
  61.  */
  62. void printframe(char *apText[])
  63. {
  64.    static char *frametop    = "\n╔═════════════════"
  65.                               "════════════════════"
  66.                               "════════════════════"
  67.                               "═══════════════════╗\n";
  68.    static char *framebottom = "╚═══════════════════"
  69.                               "════════════════════"
  70.                               "════════════════════"
  71.                               "═════════════════╝\n";
  72.    static char *framecontent= "║%-76s║\n";
  73.  
  74.    int i = 0;
  75.  
  76.    printf(frametop);
  77.    while(apText[i]) {
  78.       printf(framecontent, apText[i]);
  79.       i++;
  80.    }
  81.    printf(framebottom);
  82. }
  83.  
  84.  
  85. /*
  86.  * NAME:
  87.  *  print
  88.  *
  89.  * DESCRIPTION:
  90.  *  Prints a text
  91.  *
  92.  * PARAMETER(S):
  93.  *  char *apText[]   Ptr to a NULL terminated string array
  94.  *
  95.  * RETURNS:
  96.  *  void    
  97.  */
  98. void print(char *apText[])
  99. {
  100.    int i = 0;
  101.  
  102.    while(apText[i]) {
  103.       printf("%s\n", apText[i]);
  104.       i++;
  105.    }
  106. }
  107.  
  108.  
  109. /*
  110.  * NAME:
  111.  *  anykey
  112.  *
  113.  * DESCRIPTION:
  114.  *  Waits for any key, and optionally asks to press one
  115.  *
  116.  * PARAMETER(S):
  117.  *  int  fAsk     If it should ask for a key or wait silent
  118.  *
  119.  * RETURNS:
  120.  *  void    
  121.  *
  122.  */
  123. void anykey(int fAsk)
  124. {
  125.    if (fAsk)
  126.       printf(any_key);
  127.    getch();
  128.    printf("\n");
  129. }
  130.  
  131.  
  132. /*
  133.  * NAME:
  134.  *  clrscr
  135.  *
  136.  * DESCRIPTION:
  137.  *  Clears the screen
  138.  *
  139.  * PARAMETER(S):
  140.  *  void
  141.  *
  142.  * RETURNS:
  143.  *  void    
  144.  */
  145. void clrscr(void)
  146. {
  147.    union REGS regs;
  148.  
  149.    regs.x.ax = 0x600;          /* clear screen           */
  150.    regs.x.bx = 0x700;          /* paint it black        */
  151.    regs.x.cx = 0;          /* from the left upper       */
  152.    regs.x.dx = 0x184F;          /* to the right lower corner */
  153.  
  154.    int86(0x10, ®s, ®s); /* do the interrupt       */
  155.  
  156.    regs.x.ax = 0x200;          /* position the cursor       */
  157.    regs.x.bx = 0;          /* default page           */
  158.    regs.x.dx = 0;          /* left top           */
  159.  
  160.    int86(0x10, ®s, ®s);
  161. }
  162.  
  163. /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
  164.  
  165. #define ALLOC1    86
  166. #define ALLOC2    77
  167. #define ALLOC3    43
  168.  
  169. void main(void)
  170. {
  171.    DML_SAVEAREA(dmSave);      /* variable to store DMalloc setup */
  172.    int   i;
  173.    void *p;
  174.  
  175.    clrscr();
  176.    printframe(welcome);
  177.    anykey(FALSE);
  178.  
  179.    /* Say that we're allocating memory now. */
  180.    print(explain1);
  181.  
  182.    for (i = 0; i < LIMIT; i += 3) {
  183.  
  184.       apPtr[i]   = malloc(ALLOC1);  /* This module (with DMalloc info)  */
  185.       apPtr[i+1] = alloc2(ALLOC2);  /* Module 2 (with DMalloc info)     */
  186.       apPtr[i+2] = alloc3(ALLOC3);  /* Module 3 (winthout DMalloc info) */
  187.  
  188.       printf("Allocating: %u\r", i);
  189.    }
  190.    anykey(TRUE);
  191.  
  192.    /* finished allocating - explain what happened */
  193.    printframe(explain1a);
  194.    anykey(FALSE);
  195.  
  196.    /* New screen, and ask to press PrintScreen */
  197.    clrscr();
  198.    printframe(explain2);
  199.    printf(any_prtsc);
  200.    anykey(FALSE);
  201.  
  202.    /* Announce that we're going to destroy some allocation units */
  203.    clrscr();
  204.    printframe(explain3);
  205.    anykey(FALSE);
  206.  
  207.    /* note: blocks n+0 are allocated size 86
  208.                    n+1 have size 77
  209.                    n+2 have size 43 */
  210.  
  211.    memset(apPtr[3], 3, ALLOC1+1);   /* overwrite element 3                     */
  212.    memset(apPtr[4], 4, ALLOC2+1);   /* overwrite element 4 (odd/even) */
  213.    memset(apPtr[8]-1, 5, 10);       /* tamper element 11 with negative indexed */
  214.                                     /* address (would normally destroy MCB)    */
  215.  
  216.  
  217.    /* DMalloc API:
  218.     * Save the current setup
  219.     */
  220.    DML_SaveState(dmSave);
  221.  
  222.    /* DMalloc API:
  223.     * modify setup parameters
  224.     */
  225.    DML_Setup(SET_UNCHANGED,         /* fAlert: popup on problem                */
  226.              SET_UNCHANGED,         /* fSaved: popup when known are allocated  */
  227.              SET_UNCHANGED,         /* usPopCycles: popup on every n'th access */
  228.              1,                     /* usCycles: check on every cycle          */
  229.              PSZ_UNCHANGED,         /* owner file                             */
  230.              SET_UNCHANGED);        /*      line                              */
  231.  
  232.    /*
  233.     * Free allocated unit 0
  234.     * Since the setup defines to check the heap on each access,
  235.     * this otherwise valid call will lead to problem detection.
  236.     */
  237.    free(apPtr[0]);
  238.  
  239.  
  240.    /* Tell something on how to navigate within the heap window,
  241.     * and ask the user to try it.
  242.     */
  243.    clrscr();
  244.    printframe(explain4);
  245.    printf(any_prtsc);
  246.    anykey(FALSE);
  247.  
  248.    /*
  249.     * DMalloc API:
  250.     * Restore setup that has been saved
  251.     */
  252.    DML_RestoreState(dmSave);
  253.  
  254.    /*
  255.     * Tell something about invalid pointer warning
  256.     * Mention discarding and breakpoints
  257.     */
  258.    clrscr();
  259.    printframe(explain5);
  260.    anykey(TRUE);
  261.  
  262.    /* This could be fatal since it points into DOS! */
  263.    free(MK_FP(0x65,0x5678));
  264.  
  265.    /* Demonstrate Null pointer assignment */
  266.    clrscr();
  267.    printframe(explain6);
  268.    anykey(TRUE);
  269.  
  270.    /*
  271.     * DMalloc API:
  272.     * Restore saved setup
  273.     * (we asked the user to change the selection)
  274.     */
  275.    DML_RestoreState(dmSave);
  276.  
  277.    /*
  278.     * DMalloc API:
  279.     * Set a Watchpoint on _DATA segment
  280.     * This would not be needed, since this is the default.
  281.     * Note: It will only work if the _nullcheck() function is not replaced.
  282.     */
  283.    DML_Watchpoint(DATA_NULLCHECK, SET_ON);
  284.  
  285.    /*
  286.     * DMalloc API:
  287.     * modify setup parameters
  288.     */
  289.    DML_Setup(SET_UNCHANGED,         /* fAlert: popup on problem                */
  290.              SET_UNCHANGED,         /* fSaved: popup when known are allocated  */
  291.              SET_UNCHANGED,         /* usPopCycles: popup on every n'th access */
  292.              1,                     /* usCycles: check on every cycle          */
  293.              PSZ_UNCHANGED,         /* owner file                              */
  294.              SET_UNCHANGED);        /*      line                               */
  295.  
  296.  
  297.    p = (char *)&i;               /* since i is on the stack, apPtr points      */
  298.    OFFSETOF(p) = 0;              /* to the data segment. To simulate a NULL    */
  299.                                  /* pointer access, we make the pointer       */
  300.                                  /* offset NULL.                               */
  301.  
  302.    strcpy(p, "This is an overwrite to the Data Segment Null Region!");
  303.  
  304.    /*
  305.     * Free allocated unit 1
  306.     * Since the setup defines to check the heap on each access,
  307.     * this otherwise valid call will lead to problem detection.
  308.     */
  309.    free(apPtr[1]);
  310.  
  311.    /*
  312.     * Make it clear that the final runtime error is intended and not a bug.
  313.     */
  314.    printframe(explain6a);
  315.    anykey(TRUE);
  316.  
  317.    /*
  318.     * DMalloc API:
  319.     * Restore setup that has been saved
  320.     */
  321.    DML_RestoreState(dmSave);
  322.  
  323.    /*
  324.     * ...More explanation
  325.     */
  326.    clrscr();
  327.    printframe(explain7);
  328.    anykey(FALSE);
  329.  
  330.    /*
  331.     * Final page
  332.     */
  333.    clrscr();
  334.    printframe(explain8);
  335.    anykey(FALSE);
  336.  
  337.  
  338.    /*
  339.     * Uuuh - now the heap will be destroyed!!
  340.     * Just tamper with the allocation info structure.
  341.     * Just for this demo, a small introduction on allocation units
  342.     * with DMalloc:
  343.     *            ┌───────────── Usable contents (variable)
  344.     * ╦════╤═══╤═╧══════╤════╦═
  345.     * ║info│dml│contents│ dml║ ...
  346.     * ╩═╤══╧═╤═╧════════╧══╤═╩═
  347.     *   │    └─────────────┴─── DMalloc integrity info (2x4)
  348.     *   └────────────────────── malloc unit info (2)
  349.     */
  350.  
  351.    apPtr[2]    -= 6;       /* point to <info> (4 bytes dml, 2 bytes info) */
  352.    *(apPtr[2]) += 2;       /* that's enough...                            */
  353.  
  354.  
  355.    /*
  356.     * Simply free the list of allocated pointers.
  357.     * The heap should be corrupted immediately.
  358.     */
  359.    for (i = 2; i < LIMIT; i++) {
  360.       free(apPtr[i]);
  361.       printf("Freeing: %u\r", i);
  362.    }
  363. }
  364.