home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / virus / sentry.lha / Sentry.c < prev    next >
C/C++ Source or Header  |  1988-03-29  |  11KB  |  503 lines

  1. echo; /* Mar 28, 1988;  Assumes you've assigned your work area as a:
  2. lc -v -b -y -oa: Sentry.c
  3. blink lib:cback.o,Sentry.o +
  4.       to Sentry +
  5.       library lib:amiga.lib,lib:lc.lib +
  6.       sc sd nd +
  7.       map a:map plain
  8. quit
  9.  
  10. Just `execute Sentry.c'. Based on some weird Manx VirusX program
  11. source by Steve Tibbett. Reprogrammed and made to compile and link on
  12. Lattice 4.01 by Bruce Takahashi. This program doesn't need to be
  13. `run'ed or `runback'ed. It sets up it's own process. It can be loaded
  14. by a program icon and for those that use WorkBench only and cannot
  15. `install dfx:' from CLI, just Click into the Window and type the
  16. number of the drive unit to install. Be warned that writing to the
  17. boot sectors of a disk with CUSTOM BOOT SECTORS may prevent the
  18. program disk from ever working again.
  19.  
  20. "Wouldn't you like to play a nice game of chess?" -WOPAR
  21. Yup. -Bruce K. Takahashi
  22.  
  23. */
  24.  
  25. #include "exec/types.h"
  26. #include "exec/exec.h"
  27. #include "exec/execbase.h"
  28. #include "intuition/intuition.h"
  29. #include "intuition/intuitionbase.h"
  30. #include "devices/trackdisk.h"
  31.  
  32. #define BUFSIZE 2*TD_SECTOR   /* io data buffer size */
  33.  
  34. LONG _stack = 2500; /* That ol' black magic.. */
  35. char *_procname= "Sentry0.1";
  36. LONG _priority = 0;
  37. LONG _BackGroundIO = 0;
  38.  
  39. void MemCleanup(){}
  40.  
  41. struct MsgPort *diskport;
  42. struct IOExtTD *diskreq;
  43. struct IntuitionBase *IntuitionBase;
  44. struct GfxBase *GfxBase;
  45. struct IntuiMessage *Message;
  46. struct RastPort *RP;
  47. void cleanup(int);
  48. void CheckBlocks();
  49. long DiskInserted();
  50. void DoInstall(long);
  51.  
  52. long DisksChecked=0, DisksInstalled=0, SCAFound=0; /* for title bar info */
  53. long ChangeCount[4];     /* TD_CHANGENUM all 4 drives */
  54. long Virus, SCA;   /* Virus flags */
  55. long Unit, Class, Code, error, ok;
  56. UBYTE *diskbuffer;
  57. ULONG *sumbuffer;
  58. UBYTE *titlebuffer;
  59. static char TEXT1[] = "Danger: Disk in DFX:";
  60. static char TEXT2[] = "DFX:'s disk boot sectors?";
  61.  
  62. unsigned char bootblock[] = {
  63.    'D', 'O', 'S', 0, 0xc0, 0x20, 0x0f, 0x19,
  64.    0, 0, 3, 0x70, 0x43, 0xfa, 0, 0x18,
  65.    0x4e, 0xae, 0xff, 0xa0, 0x4a, 0x80, 0x67, 0x0a, 0x20, 0x40, 0x20, 0x68,
  66.    0x00, 0x16, 0x70, 0x00, 0x4e, 0x75, 0x70, 0xff, 0x60, 0xfa, 0x64,
  67.    0x6f, 0x73, 0x2e, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79,0,0,0,0,0
  68. };
  69.  
  70. struct TextAttr TxtAt_Plain = {
  71.    "topaz.font",
  72.    8,
  73.    FS_NORMAL,
  74.    FPF_ROMFONT
  75. };
  76.  
  77. /***  Non SCA warning requester IntuiText's ***/
  78. struct IntuiText Body2 = {
  79.    0, 1,
  80.    JAM2,
  81.    20,18,
  82.    &TxtAt_Plain,
  83.    "Nonstandard Boot Code!",
  84.    NULL
  85. };
  86.  
  87. struct IntuiText Body1 = {
  88.    0, 1,
  89.    JAM2,
  90.    20, 8,
  91.    &TxtAt_Plain,
  92.    TEXT1,
  93.    &Body2
  94. };
  95.  
  96. struct IntuiText Pos = {
  97.    0, 1,
  98.    JAM2,
  99.    7,3,
  100.    &TxtAt_Plain,
  101.    "Remove it",
  102.    NULL
  103. };
  104.  
  105. struct IntuiText Neg = {
  106.    0, 1,
  107.    JAM2,
  108.    7,3,
  109.    &TxtAt_Plain,
  110.    "Ignore it",
  111.    NULL
  112. };
  113.  
  114. /*
  115. * SCA Danger Requester IntuiText's
  116. */
  117. struct IntuiText SCABody2 = {
  118.    0, 1,
  119.    JAM2,
  120.    20,18,
  121.    &TxtAt_Plain,
  122.    "Infected with SCA Virus!!",
  123.    NULL
  124. };
  125.  
  126. struct IntuiText SCABody = {
  127.    0, 1,
  128.    JAM2,
  129.    20, 8,
  130.    &TxtAt_Plain,
  131.    TEXT1,
  132.    &SCABody2
  133. };
  134.  
  135. struct IntuiText SCAPos = {
  136.    0, 1,
  137.    JAM2,
  138.    7,3,
  139.    &TxtAt_Plain,
  140.    "Remove it",
  141.    NULL
  142. };
  143.  
  144. struct IntuiText SCANeg = {
  145.    0, 1,
  146.    JAM2,
  147.    7,3,
  148.    &TxtAt_Plain,
  149.    "Ignore it",
  150.    NULL
  151. };
  152.  
  153. /*
  154. * Write Protect Error Requester IntuiText's
  155. */
  156. struct IntuiText ERRBody2 = {
  157.    0, 1,
  158.    JAM2,
  159.    20,18,
  160.    &TxtAt_Plain,
  161.    "Disk is Write Protected",
  162.    NULL
  163. };
  164.  
  165. struct IntuiText ERRBody = {
  166.    0, 1,
  167.    JAM2,
  168.    20, 8,
  169.    &TxtAt_Plain,
  170.    "DISK ERROR:",
  171.    &ERRBody2
  172. };
  173.  
  174. struct IntuiText ERRPos = {
  175.    0, 1,
  176.    JAM2,
  177.    7,3,
  178.    &TxtAt_Plain,
  179.    "Retry",
  180.    NULL
  181. };
  182.  
  183. struct IntuiText ERRNeg = {
  184.    0, 1,
  185.    JAM2,
  186.    7,3,
  187.    &TxtAt_Plain,
  188.    "Cancel",
  189.    NULL
  190. };
  191.  
  192. /*
  193. * Rewrite block?  Really?
  194. */
  195. struct IntuiText REWBody4 = {
  196.    0, 1,
  197.    JAM2,
  198.    20,33,
  199.    &TxtAt_Plain,
  200.    TEXT2,
  201.    NULL
  202. };
  203.  
  204. struct IntuiText REWBody3 = {
  205.    0, 1,
  206.    JAM2,
  207.    20, 23,
  208.    &TxtAt_Plain,
  209.    "Are you sure you want to rewrite",
  210.    &REWBody4
  211. };
  212.  
  213. struct IntuiText REWBody2 = {
  214.    0, 1,
  215.    JAM2,
  216.    20, 13,
  217.    &TxtAt_Plain,
  218.    "be necessary for a program disk.",
  219.    &REWBody3
  220. };
  221.  
  222. struct IntuiText REWBody = {
  223.    0, 1,
  224.    JAM2,
  225.    20, 3,
  226.    &TxtAt_Plain,
  227.    "WARNING:  CUSTOM BOOT blocks may",
  228.    &REWBody2
  229. };
  230.  
  231. struct IntuiText REWPos = {
  232.    0, 1,
  233.    JAM2,
  234.    7,3,
  235.    &TxtAt_Plain,
  236.    "Yes",
  237.    NULL
  238. };
  239. struct IntuiText REWNeg = {
  240.    0, 1,
  241.    JAM2,
  242.    7,3,
  243.    &TxtAt_Plain,
  244.    "No!",
  245.    NULL
  246. };
  247.  
  248.  
  249. struct Window *LittleWindow;
  250. struct NewWindow NewLittleWindow = {
  251.    0, 10, 400, 10,  /* window position, size */
  252.    3, 2,             /* Frontpen, Backpen */
  253.    DISKINSERTED
  254.    | CLOSEWINDOW
  255.    | VANILLAKEY,   /* IDCMP Flags */
  256.    WINDOWDRAG
  257.    | WINDOWDEPTH
  258.    | WINDOWCLOSE
  259.    | NOCAREREFRESH
  260.    | SIMPLE_REFRESH
  261.    | RMBTRAP, /* Flags */
  262.    NULL, NULL,
  263.    NULL,        /* title */
  264.    NULL, NULL,
  265.    0, 0, 0, 0,
  266.    WBENCHSCREEN
  267. };
  268.  
  269.  
  270. void _main()
  271. {
  272.    int xx;
  273.    BOOL flag;
  274.  
  275.    /* my weird type of open  -BKT */
  276.    ok=0;
  277.    if(IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",33L)) {
  278.       ok=1;
  279.       if(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0)) {
  280.          ok=2;
  281.          if(diskport=(struct MsgPort *)CreatePort(0,0)) {
  282.             ok=3;
  283.             if(diskreq=(struct IOExtTD *)CreateExtIO(diskport,sizeof(struct IOExtTD))) {
  284.                ok=4;
  285.                if(titlebuffer=(UBYTE *)AllocMem(64,MEMF_PUBLIC)) {
  286.                   ok=5;
  287.                   if(diskbuffer=(UBYTE *)AllocMem(BUFSIZE,MEMF_CHIP|MEMF_CLEAR)) {
  288.                      ok=6;
  289.                      if(LittleWindow = (struct Window *)OpenWindow(&NewLittleWindow)) {
  290.                         RP = LittleWindow->RPort;
  291.                         ok=7;
  292.                      }
  293.                   }
  294.                }
  295.             }
  296.          }
  297.       }
  298.    }
  299.    if(ok!=7) { cleanup(ok); return; } /* It ain't Amiga, outta here! */
  300.  
  301.    for(xx=0;xx<4;xx++) ChangeCount[xx]=~0; /* forces check of all drives */
  302.    CheckBlocks();
  303.  
  304.    SetAPen(RP, 1);
  305.    SetBPen(RP, 0);
  306.    SetDrMd(RP, JAM2);
  307.  
  308.    flag=TRUE;
  309.    while(flag) {
  310.       sprintf(titlebuffer, " %ld disks: %ld infected; %ld cured",
  311.           DisksChecked, SCAFound, DisksInstalled);
  312.       SetWindowTitles(LittleWindow, titlebuffer, -1);
  313.  
  314.       (void)WaitPort(LittleWindow->UserPort);
  315.       while(Message = (struct IntuiMessage *)GetMsg(LittleWindow->UserPort)) {
  316.          Class = Message->Class;
  317.          Code = Message->Code;
  318.          ReplyMsg(Message);
  319.          if (Class == CLOSEWINDOW) flag=FALSE;
  320.          if (Class == DISKINSERTED) CheckBlocks();
  321.          if (Class == VANILLAKEY) {
  322.             switch(Code) {
  323.                case '3':
  324.                case '2':
  325.                case '1':
  326.                case '0':   DoInstall(Code-'0');
  327.                            break;
  328.             }
  329.          } /* if */
  330.       }/* while */
  331.    } /* for */
  332.    cleanup(ok);
  333. }
  334.  
  335.  
  336. void CheckBlocks()
  337. {
  338.    register long aa, Sum, LastSum;
  339.  
  340.    for(;;) {
  341.       SCA = FALSE;
  342.       Virus = FALSE;
  343.       Unit=DiskInserted(); /* new disks mounted? */
  344.       if(Unit==-1) break;  /* no.. just return */
  345.  
  346.       error = OpenDevice(TD_NAME,Unit,diskreq,0);
  347.       if (error) continue;
  348.  
  349.       diskreq->iotd_Req.io_Command = CMD_READ;
  350.       diskreq->iotd_Req.io_Data = (APTR)diskbuffer;
  351.       diskreq->iotd_Req.io_Length = BUFSIZE;
  352.       diskreq->iotd_Req.io_Offset = 0;
  353.       DoIO(diskreq); /* READ BOOT */
  354.       if(BUFSIZE!=diskreq->iotd_Req.io_Actual) {
  355.          CloseDevice(diskreq);
  356.          continue;
  357.       }
  358.       (APTR)sumbuffer=(APTR)diskbuffer;
  359.       Sum = 0;
  360.       for (aa=0; aa<256; aa++) {
  361.          LastSum = Sum;
  362.          Sum += sumbuffer[aa];
  363.          if (LastSum > Sum) Sum++;
  364.       }
  365.  
  366.       diskreq->iotd_Req.io_Length = 0;
  367.       diskreq->iotd_Req.io_Command = TD_MOTOR;
  368.       DoIO(diskreq);   /* turn off motor */
  369.       CloseDevice(diskreq);
  370.  
  371.       DisksChecked++;
  372.       if (Sum!=0) continue; /* not bootable */
  373.  
  374.       /* check specifically for SCA virus */
  375.       if (diskbuffer[8] == 'C') {
  376.          if (diskbuffer[9] == 'H') {
  377.             if (diskbuffer[10] == 'W') {
  378.                SCA = TRUE;     /* CHW is part of SCA virus */
  379.                SCAFound++;
  380.             }
  381.          }
  382.       }
  383.  
  384.       /* compare `standard' boot code with what was read */
  385.       for (aa=8; aa<39+8; aa++) { /* num of elements in bootblock */
  386.          if (diskbuffer[aa] != bootblock[aa])  Virus = TRUE;
  387.       }
  388.  
  389.       /* a Virus! */
  390.       if (Virus == TRUE) {
  391.          TEXT1[18] = '0'+Unit; /* change text `DFX' to real drive */
  392.          if (SCA != TRUE) {
  393.             error = AutoRequest(LittleWindow, &Body1, &Pos, &Neg, 0, 0, 320, 75);
  394.             if (error == TRUE) DoInstall(Unit);
  395.          }
  396.          else {
  397.             /* a nonstandard boot block */
  398.             error = AutoRequest(LittleWindow, &SCABody, &SCAPos, &SCANeg, 0, 0, 320, 75);
  399.             if (error == TRUE) DoInstall(Unit);
  400.          }
  401.       }
  402.    }/* End of loop */
  403. }
  404.  
  405.  
  406. long DiskInserted()
  407. {
  408.    long xx, RetVal=-1;    /* return -1 as no change */
  409.  
  410.    for (xx=0; xx<4; xx++) {
  411.       error = OpenDevice(TD_NAME,xx,diskreq,0);
  412.       if(error) continue; /* no drive */
  413.  
  414.       /* disk changed */
  415.       diskreq->iotd_Req.io_Command = TD_CHANGENUM;
  416.       DoIO(diskreq);
  417.       if (diskreq->iotd_Req.io_Actual != ChangeCount[xx]) {
  418.          ChangeCount[xx] = diskreq->iotd_Req.io_Actual;
  419.          RetVal=xx;
  420.          CloseDevice(diskreq);
  421.          break;
  422.       }
  423.    }
  424.    return(RetVal);
  425. }
  426.  
  427.  
  428. void DoInstall(unit)
  429. long unit; /* unit to write to */
  430. {
  431.    register long xx;
  432.  
  433.    TEXT2[2] = '0'+unit; /* change text `DFX' to real drive */
  434.    error = AutoRequest(LittleWindow,&REWBody,&REWPos,&REWNeg,0,0,320,75);
  435.    if (error != TRUE) return;
  436.  
  437.    error = OpenDevice(TD_NAME, unit,diskreq,0);
  438.    if (error > 0) return;
  439.  
  440.    for(;;) { /* check if disk is write protected */
  441.       diskreq->iotd_Req.io_Command = TD_PROTSTATUS;
  442.       DoIO(diskreq);
  443.  
  444.       if (diskreq->iotd_Req.io_Actual == 0) break;
  445.       else { /* write protect tab is enabled */
  446.          error = AutoRequest(LittleWindow,&ERRBody,&ERRPos,&ERRNeg,0,0,320,75);
  447.          if (error == TRUE) continue; /* user chose retry */
  448.          CloseDevice(diskreq);
  449.          return; /* user chose no */
  450.       }
  451.    }
  452.  
  453.      /* clear diskbuffer to zero.  clean. */
  454.    for(xx=0; xx<1024; xx++) diskbuffer[xx] = 0;
  455.      /* copy boot code into buffer */
  456.    for(xx=0; xx<50; xx++) diskbuffer[xx] = bootblock[xx];
  457.  
  458.    diskreq->iotd_Req.io_Data = (APTR)diskbuffer;
  459.    diskreq->iotd_Req.io_Length = 1024;
  460.    diskreq->iotd_Req.io_Offset = 0;
  461.    diskreq->iotd_Req.io_Command = CMD_WRITE;
  462.    DoIO(diskreq);
  463.  
  464.    /* flush buffer to disk */
  465.    diskreq->iotd_Req.io_Command = CMD_UPDATE;
  466.    DoIO(diskreq);
  467.  
  468.    error = diskreq->iotd_Req.io_Error;
  469.  
  470.    /* turn off motor */
  471.    diskreq->iotd_Req.io_Length = 0;
  472.    diskreq->iotd_Req.io_Command = TD_MOTOR;
  473.    DoIO(diskreq);
  474.  
  475.    CloseDevice(diskreq);
  476.  
  477.    if (error > 19) {
  478.       SetWindowTitles(LittleWindow, "Error, Nothing Done.", -1);
  479.    }
  480.    else {
  481.       SetWindowTitles(LittleWindow, "Boot Cleaned", -1);
  482.       DisksInstalled++;
  483.    }
  484.    Delay(150);
  485.    for(xx=0;xx<4;xx++) ChangeCount[xx]=~0; /* forces check of all drives */
  486. } /* endof DoInstall(unit) */
  487.  
  488.  
  489. void cleanup(ok)
  490. {
  491.    switch(ok) {
  492.       case 7: CloseWindow(LittleWindow);
  493.       case 6: FreeMem(diskbuffer,BUFSIZE);
  494.       case 5: FreeMem(titlebuffer,64);
  495.       case 4: DeleteExtIO(diskreq,sizeof(struct IOExtTD));
  496.       case 3: DeletePort((struct MsgPort *)diskport);
  497.       case 2: CloseLibrary((struct Library *)GfxBase);
  498.       case 1: CloseLibrary((struct Library *)IntuitionBase);
  499.       break;
  500.    }
  501. }
  502.  
  503.