IP = .EXE_IP
+ Trao quyền điều khiển lại cho file.
Thực tế, .EXE header chỉ đ−ợc DOS sử dụng đến trong khi tải và thi hành một file, trong suốt quá trình thi hành file, không bao giờ DOS phải tham chiếu đến cấu trúc này. Tuy nhiên vẫn có nhiều điều lí thú về cấu trúc này.
c. ứng dụng của .EXE header: Ta có thể tính kích th−ớc thật của file (trong hầu hết các tr−ờng hợp) bằng cách lấy ra và tính thông tin từ .EXE header. (Chú ý: Một số file .EXE có kích th−ớc quá lớn đã dùng kĩ thuật giả overlay: Module tải có kích th−ớc nhỏ hơn nhiều so với kích th−ớc thật của file, nó có nhiệm vụ tải các phần overlay ngay trong ch−ơng trình khi có yêu cầu). Có thể có nhiều cách khác để tính kích th−ớc file. Tuy nhiên, để thực hiện một số tác vụ khác, ph−ơng pháp nay vẫn đ−ợc nhiều Hacker sử dụng. Kích th−ớc thật sự của file đ−ợc tính bằng cách tính số byte từ các trang mà file chiếm với mỗi trang 512 byte. Tuy nhiên vì có thể trang cuối cùng file không dùng hết, nên phải dự trù tr−ờng hợp này.
Đoạn ch−ơng trình sau tính kích th−ớc file dựa vào .EXE header đã đ−ợc đọc vào buffer có tên My_Buffer rồi gắn nó vào biến. Vì kích th−ớc file có thể lớn hơn 64 Kb nên giá trị kích th−ớc file đ−ợc biểu diễn bằng 2 word.
mov AX, My_buffer[4] ;Số trang
cmp My_buffer[2], 0 ;Trang cuối cùng có dùng hết không
je cont_1 ;Nếu dùng hết tính luôn dec AX, 1 ;Ng−ợc lại phải bớt đi 1 cont _1: ;Cộng cho phần byte d−
mul BytePerPage ;Đổi sang byte bằng cách nhân 512
add AX, My_buffer[2] ;Cộng thêm phần d− trang cuối
adc DX, 0 ;Kích th−ớc có thể là 32 bit DX:AX = kích th−ớc file
mov filesize_lo, AX mov filesize_hi, DX ...
BytePerPage dw 200h My_Buffer db 1c dup (?)
Chuyển file dạng .EXE sang .COM: Một file .EXE có thể đ−ợc biến đổi sang dạng .COM nếu kích th−ớc của nó không v−ợt quá một phân đoạn 64 Kb. Cách chuyển đổi này cần phải đ−ợc phân biệt rõ ràng với cách đổi từ .EXE sang .COM bằng lệnh ngoại trú .EXE2BIN của DOS.
Thực chất, việc chuyển đổi theo DOS chỉ đ−ợc thực hiện khi đầu vào của ch−ơng trình là 0100h và ch−ơng trình phải đ−ợc tổ chức trong một phân đoạn. Ng−ợc lại cách đổi này chỉ mang tính “trá hình “và đ−ợc áp dụng với toàn bộ những file .EXE d−ới 64 Kb. Nội dung của ph−ơng pháp này là “gắn “thêm vào sau file một đoạn mã cho phép thay mặt cho DOS để tiến hành các b−ớc định vị. Ký hiệu “MZ “truyền thống để cho DOS nhận diện file .EXE nay bị xóa đi thay vào đó là một lệnh nhảy để chuyển quyền điều khiển cho đoạn mã này (về sau một số virus cũng “noi “theo cách này để lây trên file .EXE có kích th−ớc d−ới 64 Kb).
Sự chuyển đổi không làm tăng tốc độ tổ chức hay thi hành file vì thực chất nó cũng phải tiến hành định vị lại nh− DOS sẽ phải làm tr−ớc đây. Tuy nhiên, điều này không quan trọng, vì chủ đích của nó là làm cho độc giả làm quen với cách định vị của DOS.
Đoạn ch−ơng trình sau minh họa đoạn mã thi hành chức năng tái định vị thay DOS.
;lệnh nhảy đầu ch−ơng trình sẽ chuyển quyền điều khiển lại cho nhãn begin sau
jmp begin
... ;Bảng tham số của .EXE header cũ
; Bảng tham số cần thiết trong quá trình tái định vị IP_value dw 0
CS_value dw 0 SP_value dw 0
SS_value dw 0 Begin:
call next ;Lấy ofofffset để liên hệ với bảng tham số ở trên, đoạn
Next: ;mã này có kích th−ớc pop BX ;4 byte nên BX liên hệ với push AX ;tham số cuối bảng là 5 mov AX, ES
add AX, 010 ;AX = PSP = 010 = start_SEG
; định vị các thanh ghi cho Stack và Code
mov CX, ptr word [010Eh] ;CX=ReloSS add CX, AX ;Tái định vị SS
mov ptr word [bx-5], AX ;Cất giá trị SS mov CX, ptr word [116h] ;CX = ReloCS add CX, AX ;Tái định vị CS mov ptr word [bx-9], CX ;Cất giá trị CS mov CX, ptr word [110h] ;CX = SP mov ptr word [bx-7], CX ;Cất giá trị SP mov CX, ptr word [114h] ;CX = IP mov ptr word [bx-0Bh], CX ;Cất giá trị IP ;Định vị các item và tái định vị
mov DI, ptr word [118h] ;DI = offset của item table
mov DX, ptr word [108h] ;Kích th−ớc Header (đoạn)
mov CL, 4 ;Nhân 16 để đổi sang byte shl DX, CL
mov CX, ptr word [106] ;Số item cần định vị lại
;Bắt đầu định vị Next_Item:
jcxz ok
lds SI, [DI+100h] ;Lấy i_Reg và i_Off add DL, 4 ;DI trỏ đén item kế tiếp mov BP, DS
add BP, ptr word [1C8h] ;BP = i_Seg
add BP, AX ;BP = i_Seg + Start_Seg mov DS, BP ;Giá trị tại Relo_seg: i_Off
add ptr word [si], AX ;sẽ đ−ợc cộng thêm Start_Seg
loop Next_item pop CS
pop DS
; Dời toàn bộ ch−ơng trình từ vi trí sau header lên offfset 100h
mov DI, 0100
mov SI, DX ;SI = kích th−ớc header add SI, 01C0 ;Điều chỉnh t−ơng ứng với file .COM
mov CX, BX ;CX = BX - SI = kích th−ớc ch−ơng trình
sub CX, SI ;Đoạn mã điều chỉnh = kích th−ớc ch−ơng trình
rep movsb pop AX cli
mov SS, ptr word [BX-5] ;Tạo stack mov SP, ptr word [BX-5]
sti
jmp far [BX-0B] (Trích Vacsina virus)
+ Điều chỉnh .EXE header để trỏ đến một đoạn mã khác sau ch−ơng trình: thủ thuật này t−ơng đối đơn giản, đ−ợc áp dụng để giành quyền điều khiển tr−ớc khi trao cho ch−ơng trình. Các b−ớc để tiến hành nh− sau :
Tính kích th−ớc file để “gắn “phần mã vào (bằng nhiều cách). Điều chỉnh tham số trong .EXE header (chủ yếu sẽ là CS:IP, SS:SP) trỏ đến đoạn mã này
Ví dụ minh họa cho cách này sẽ đ−ợc trình bày ở ch−ơng sau, phần kĩ thuật của F-virus lây lan trên file .EXE.
4/Chức năng .EXEC (tổ chức thi hành file): Sau khi 2 file hệ thống đ−ợc nạp lên, nó sẽ dùng chức năng 4B để thi hành file COMMAND.COM (nếu không có lệnh SHELL chỉ đến một file khác trong CONFIG.SYS). Đến l−ợt mình COMMAND sẽ phân tích dòng lệnh đ−a vào, nếu đó là tên một file thi hành đ−ợc có trên đĩa, nó sẽ dùng chính chức năng 4B để thi hành một lần nữa !
Chức năng 4B cho phép một ch−ơng trình (ch−ơng trình mẹ) tải một ch−ơng trình khác (ch−ơng trình con) vào vùng nhớ và thi hành nó. Sau khi ch−ơng trình con hoàn tất, quyền điều khiển sẽ đ−ợc trả về cho ch−ơng trình mẹ.
Ch−ơng trình mẹ có thể chuyển tham số cho ch−ơng trình con bằng cách truyền tham số nh− trên dòng lệnh, trong FCB, hay bằng chuỗi ASCIIZ trong khối tham số môi tr−ờng EPB. Ch−ơng trình con, khi đã đ−ợc trao quyền điều khiển sẽ thừa h−ởng tất cả các file đ−ợc mở trong ch−ơng trình mẹ, mọi thay đổi sau đó của ch−ơng trình con đều ảnh h−ởng đến ch−ơng trình mẹ.
Không nh− một số ng−ời mong đợi, DOS sẽ dừng việc thi hành ch−ơng trình mẹ cho đến khi nào ch−ơng trình con chấm dứt và quyền điều khiển trả về cho ch−ơng trình mẹ. Để có thể tăng c−ờng khả năng giao tiếp, DOS cho phép ch−ơng trình con trả lại mã ra (exit code) cho ch−ơng trình mẹ, nhằm thông
báo cho ch−ơng trình mẹ biết tình trạng hoạt động của ch−ơng trình con.
a. Tham số chức năng 4B: Gồm 2 chức năng con: tải và thi hành hoặc tải mà không thi hành.
Vào :
AH = 4Bh
AL = 0: tải và thi hành ch−ơng trình
3 : tải nh−ng không thi hành ch−ơng trình. DS:DX: Tên file cần thi hành, dạng ASCIIZ ES:BX: Địa chỉ của EBP.
Ra :
AX = mã lỗi nếu CF = 1.
Các thanh ghi DS, Stack có thể bị thay đổi (do đó nên cất giữ các thanh ghi cần thiết tr−ớc khi gọi chức năng này).
Vì ch−ơng trình mẹ có thể quản lý toàn bộ vùng nhớ (nhất là tr−ờng hợp file .COM) nên để thi hành một ch−ơng trình con, ch−ơng trình mẹ nên tuân thủ một số các b−ớc sau :
+ Vì ch−ơng trình mẹ tạm thời không dùng đến vùng nhớ nữa, có thể giảm số vùng nhớ mà nó cần bằng cách dùng chức năng 4Ah với ES = PSP hiện hành, BX = số vùng nhớ cần thiết của ch−ơng trình mẹ.
+ Chuẩn bị chuỗi ASCIIZ chứa tên file cần thi hành, và DS:DX chứa địa chỉ của xâu này. Điều cần l−u ý tên file phải bao gồm luôn cả phần mở rộng chứ không đơn giản nh− tên file đánh ở dấu nhắc của DOS (lúc này DOS sẽ tự động đi tìm những file có cùng tên, nh−ng phần mở rộng sẽ là .COM, .EXE, .BAT để thi hành).
+ Chuẩn bị EBP chứa các tham số cần thiết, trỏ ES:BX đến khối tham số này.
+ Cất giữ các giá trị của Stack, DTA, DS và ES trong các biến có thể đ−ợc tham chiếu đến bằng CS (để dễ khôi phục lại khi lấy lại quyền điều khiển).
+ Sau khi lấy lại quyền điều khiển (nếu AL = 0), khôi phục lại Stack, các thanh ghi cần thiết khác.
+ Kiểm tra mã lỗi để xác định chức năng này đã đ−ợc thi hành hay ch−a.
+ Khôi phục DTA nếu cần thiết .
+ Lấy mã ra (exit code) để xem mã kết quả thi hành của ch−ơng trình con.
b. Phân tích tham số của chức năng 4B: Thông th−ờng, chức năng tải và thi hành file đ−ợc dùng nhiều nhất, với phạm vi của cuốn sách này chúng ta chỉ bàn đến chức năng tải và thi hành .
+ Tên file: Phải đ−ợc chỉ định một cách t−ờng minh, nghĩa là không đ−ợc dùng kí tự * và ? để thay thế, và phải bao gồm cả phần mở rộng của tên file. Điều này làm cho một ng−ời gặp lỗi khi dùng đến chức năng này vì đơn giản họ t−ởng chức năng 4B sẽ tự động đi tìm tên file chỉ định và thi hành, tiếc thay, điều này chỉ có phần mã lệnh nội trú của COMMAND.COM làm thay cho bạn.
+ EBP (.EXEc parameter block): Khối tham số EBP là một cấu trúc cung cấp cho DOS những thông tin cần thiết về môi tr−ờng, về dòng tham số truyền ECB ...., tạo điều kiện thuận lợi cho DOS tổ chức môi tr−ờng làm việc cho file chỉ định.
Cấu trúc của khối này nh− sau: offset size nội dung
+0 2 Segment của môi tr−ờng con (0000 = thừa h−ởng
Env parm của ch−ơng trình con
+2 4 offfset segment Địa chỉ của dòng lệnh đặt ở PSP :80h
+6 4 offfset segment Địa chỉ của FCB đặt ở PSP: 5Ch
+0Ah 4 offfset segment Địa chỉ của FCB đặt ở PSP: 6Ch
Cấu trúc này, thực tế đ−ợc DOS dùng để tổ chức PSP cho ch−ơng trình bằng cách copy các thành phần t−ơng ứng vào PSP của ch−ơng trình con. Ta sẽ khảo sát từng vùng một trong cấu trúc này.
+ Tham số về môi tr−ờng: Mỗi ch−ơng trình đ−ợc tải bởi chức năng 4B đều đ−ợc thừa h−ởng một cấu trúc dữ liệu gọi là môi tr−ờng của ch−ơng trình mẹ. Con trỏ trỏ đến segment của môi tr−ờng ở offset 2C trong PSP . Cấu trúc này ít đ−ợc ai dùng đến, chỉ có COMMAND.COM là dùng.
Nếu muốn, ng−ời sử dụng có thể bổ sung, tạo một môi tr−ờng mới. Nếu giá trị của con trỏ tới khối môi tr−ờng bằng 0, ch−ơng trình con sẽ thừa h−ởng môi tr−ờng của ch−ơng trình mẹ, ng−ợc lại, giá trị của con trỏ này là segment của một khối môi tr−ờng mới. Tuy nhiên, cần phải chú ý kích th−ớc của môi tr−ờng không đ−ợc v−ợt quá 32 Kb.
Môi tr−ờng cho một ch−ơng trình là tĩnh, nghĩa là nếu có nhiều ch−ơng trình th−ờng trú trong RAM, thì mỗi ch−ơng trình có thể có riêng một khối môi tr−ờng và độc lập với nhau, nội dung của các khối này không đ−ợc cập nhật nếu sau đó lệnh PATH hay SET đ−ợc thực hiện.
+ Dòng lệnh: DOS copy dòng tham số này vào PSP của ch−ơng trình con ở offfseet 081 (đã đ−ợc mô tả trong phần PSP), dạng của dòng tham số này cũng cần phải chú ý: bắt đầu bằng một byte chỉ số byte của dòng lệnh, theo sau là dãy mã ASCII và chấm dứt bằng mã xuống dòng 0Dh, dấu xuống dòng không đ−ợc kể vào số l−ợng byte.
+ FCB ngầm định: DOS copy 2 FCB ngầm định đ−ợc chỉ ra bởi 2 tham số cuối bảng EBP vào PSP của ch−ơng trình con ở offfset 05C và 06C. Để cạnh tranh với chức năng của COMMAND.COM, ch−ơng trình mẹ nên dùng chức năng 29h của DOS để phân tích 2 tham số đầu của dòng lệnh vào FCB tr−ớc khi gọi chức năng 4Bh.
FCB rõ ràng không đ−ợc dùng rộng rãi d−ới DOS version 2 và 3 vì chúng không tiện cho cấu trúc phân cấp, tuy nhiên, trong một số ch−ơng trình ứng dụng có thể dùng chúng để lấy tham số trên dòng lệnh.
c. Lỗi thi hành: Thông th−ờng, ng−ời sử dụng áp dụng chức năng 4B hay gặp lỗi mà không biết rõ nguyên nhân. Sau đây là một số nguyên nhân mà ng−ời sử dụng hay mắc phải :
+ Không đủ vùng nhớ để thi hành. Lỗi này xảy ra khi ng−ời sử dụng quên không đặt lại vùng nhớ tr−ớc khi thi hành .
+ Không tìm thấy file. Lỗi này cũng th−ờng hay xảy ra khi ng−ời dùng không chỉ định rõ ổ đĩa chứa file, phần mở rộng của file vì lầm t−ởng DOS sẽ “tự “làm việc đó.
+ Khi thi hành xong ch−ơng trình con, máy th−ờng bị halt. Lỗi này xảy ra khi ch−ơng trình con đã thay đổi Stack, hay thay đổi một số thanh ghi phân đoạn.... để tránh những điều này có thể tiến hành tuần tự các b−ớc đã đ−ợc nêu trên.
d. Một số nhận xét lý thú:
+ Chức năng này dùng phần tải (loader portion) của COMMAND.COM, phần này luôn nằm ở vùng nhớ cao, không th−ờng trú và do đó rất dễ ch−ơng trình khác đè lên. Do đó, nhiều khi COMMAND.COM cần phải đ−ợc tải lại, việc thay đổi đĩa mềm (nếu đặt COMMAND.COM ở đó) cũng đôi khi gây nhiều phiền toái.
+ Nh− đã biết, có thể chỉ ra tên file cần thi hành ở DS:DX tuy nhiên cách này có nh−ợc điểm :
Ta phải tự phân tích FCB (mặc dù bây giờ không còn cần thiết nữa).
Không tự dùng PATH để tìm file nên đôi lúc không thể xác định xem file nằm ở đâu.
Do đó, có thể cho DOS tự làm điều này bằng cách: dùng COMMAND.COM để thi hành file với tham số vào là tên file của chúng ta! Lúc này, DOS sẽ tự mình tìm kiếm file và sẽ thi
hành nếu nó tìm thấy file (chú ý: để thi hành COMMAND.COM phải dùng với tham số /c)
Đoạn ch−ơng trình sau sẽ minh họa cách dùng COMMAND.COM để thi hành file Format.com của DOS .
; Tạo EBP mov AX, CS mov seg_cmd, AX mov seg_FCB1, AX mov seg_FCB2, AX mov AX, 04B00 mov BX, offset EBP mov DX, offset filename int 21h
...
filename db ‘\COMMAND.COM’, 0
EBP dw 0 ;thừa h−ởng môi tr−ờng off_cmd dw offfset Cmd_line
seg_cmd dw 0
off_FCB1 dw 05C seg_FCB1 dw 0 off_FCB2 dw 06C seg_FCB2 dw 0
cmd_line db 0Eh, ’/c format a: /s/4’, 0Dh
+ Một kĩ thuật khác cũng không kém phần thú vị: Ch−ơng trình mẹ thi hành ch−ơng trình con là chính nó. Điều này có thể khó thực hiện đ−ợc vì tên ch−ơng trình mẹ không cố định (ng−ời dùng có thể đổi tên bất kì lúc nào) và nhất là sẽ gặp tr−ờng hợp gọi lồng nhau khi ch−ơng trình con một lần nữa có thể lại gọi chính nó.
Dò trong môi tr−ờng dể tìm tên file (kĩ thuật này đ−ợc trình bày trong phần PSP)
Tạo EBP t−ơng ứng
Tạo dấu hiệu nhận dạng để lần thi hành sau rẽ nhánh sang tác vụ khác hơn là lại thi hành tiếp một mức nữa.
Bạn có thể tự mình thiết kế một ch−ơng trình nh− thế này và thực tế một só loại virus cũng đã làm.
II - Tổ chức và quản lý vùng nhớ.
Tất cả những điều mà DOS tổ chức và thi hành file đều có một nét chung: file đ−ợc tải vào vùng nhớ. Nh− vậy, câu hỏi đ−ợc đặt ra: rõ ràng DOS phải tổ chức vùng nhớ nh− thế nào đó để có thể thi hành file ?
Mặc dù DOS đã đ−a ra các chức năng cho phép thao tác trên vùng nhớ mà thực tế cũng đã quá đủ cho các nhà thảo ch−ơng. Tuy nhiên, biết cách tổ chức vùng nhớ của DOS cũng là điều cần biết trong mỗi chúng ta.
Các version hiện nay của DOS có thể quản lý đến 1Mb vùng nhớ. Trên các máy PC và t−ơng thích, vùng nhớ do DOS quản lý bắt đầu ở địa chỉ 00000h và đạt tới địa chỉ cao nhất (nếu có