Tải bản đầy đủ (.doc) (46 trang)

Tìm hiểu kỹ thuật dịch ngược mã nguồn

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.18 MB, 46 trang )

HỌC VIỆN KỸ THUẬT MẬT MÃ
KHOA AN TOÀN THÔNG TIN

BÁO CÁO BÀI TẬP LỚN
Môn: Cơ sở an toàn thông tin
Đề tài: tìm hiểu kỹ thuật dịch ngược mã nguồn
Giảng viên: Vũ Thị Vân
Nhóm thực hiện:
1. Trần Văn Dũng Lớp: AT8B
2. Bùi Đức Thuận Lớp: AT8B
Hà Nội, 10/2014
Tìm hiểu kỹ thuật dịch ngược mã nguồn
PHÂN CÔNG CÔNG VIỆC
1. Trần Văn Dũng :
- Chương 3: Demo + dịch tài liệu.
- Các kỹ thuật dịch ngược mã nguồn phần
mềm
- Làm báo cáo bản .doc
- Các công cụ dịch ngược mã nguồn
- Các kỹ thuật dịch ngược mã nguồn phần
mềm.
2. Bùi Đức Thuận :
- Chương 1: Tổng quan dịch ngược mã
nguồn, ứng dụng dịch ngược mã nguồn.
- Cấu trúc PEfile trong windows.
- Các công cụ dịch ngược phần mềm.
- Làm báo cáo bản slide.
Nhóm 3 – AT8B 3
Tìm hiểu kỹ thuật dịch ngược mã nguồn
MỤC LỤC
PHÂN CÔNG CÔNG VIỆC 3


MỤC LỤC 4
DANH MỤC CÁC HÌNH VẼ 6
TÓM TẮT NỘI DUNG ĐỀ TÀI 7
LỜI MỞ ĐẦU 8
CHƯƠNG I: DỊCH NGƯỢC MÃ NGUỒN 9
I.1. Tổng quan về dịch ngược mã nguồn 9
I.2. Ứng dụng của dịch ngược mã nguồn 11
I.2.1. Dịch ngược – Bảo mật 11
I.2.2. Malicious Software 11
I.2.3. Dịch ngược giải thuật mã hóa 12
I.2.4. Cracking 13
CHƯƠNG II: DỊCH NGƯỢC MÃ NGUỒN PHẦN MỀM 15
II.1. Cấu trúc PE file trong windows 15
II.1.1. DOS MZ header 16
II.1.2. PE Header 18
II.1.3. Section Table 20
II.2. Các kỹ thuật dịch ngược mã nguồn 21
II.2.1. Kỹ thuật pack, unpack file 21
II.2.2. Kỹ thuật disassembly 26
II.2.3. Kỹ thuật Debugging 30
II.2.4. Kỹ thuật anti anti-disassembly 33
II.2.5. Kỹ thuật anti anti-debugging 36
II.3. Các phần mềm dịch ngược mã nguồn 36
II.3.1. Disassembler và Debugger 36
II.3.1.1. IDA Pro 36
II.3.1.2. OllyDbg 38
II.3.2. Định dạng PE file 43
II.3.2.1. PEBrowse 43
II.3.2.2. Peid 43
II.3.2.3. LordPE 44

KẾT LUẬN 45
CHƯƠNG III: DEMO 46
TÀI LIỆU THAM KHẢO 47
Nhóm 3 – AT8B 4
Tìm hiểu kỹ thuật dịch ngược mã nguồn
Nhóm 3 – AT8B 5
Tìm hiểu kỹ thuật dịch ngược mã nguồn
DANH MỤC CÁC HÌNH VẼ
Nhóm 3 – AT8B 6
Tìm hiểu kỹ thuật dịch ngược mã nguồn
TÓM TẮT NỘI DUNG ĐỀ TÀI
Đề tài tìm hiểu kỹ thuật dịch ngược mã nguồn được thực hiện bao
gồm các nội dung chính sau:
1. Tìm hiểu tổng quan về dịch ngược mã nguồn (khái niệm dịch
ngược mã nguồn, mục đích dịch ngược mã nguồn…), ứng dụng của dịch
ngược mã nguồn: dịch ngược bảo mật, dịch ngược giải thuật mã hóa, dịch
ngược dung trong cracking.
2. Tìm hiểu cụ thể về dịch ngược mã nguồn trong phần mềm.
Các kỹ thuật dịch ngược mã nguồn phần mềm trong môi trường windows,
file và cấu trúc file thực thi trong môi trường windows; các công cụ phổ
biến cho dịch ngược mã nguồn phần mềm.
3. Demo dịch ngược mã nguồn một phần mềm đơn giản. Mục
đích là biết cách sử dụng một số phần mềm dịch ngược, hiểu cơ bản về
dịch ngược mã nguồn nói chung và dịch ngược mã nguồn phần mềm nói
riêng.
Nhóm 3 – AT8B 7
Tìm hiểu kỹ thuật dịch ngược mã nguồn
LỜI MỞ ĐẦU
Kể từ khi máy tính ra đời, nó đã làm thay đổi từng ngày, từng giờ
cuộc sống con người chúng ta. Ngày nay, các hệ thống máy tính có mặt

trên mọi ngành, mọi gia đình, mọi quốc gia và giữ một vai trò vô cùng
quan trọng.
Để đáp ứng nhu cầu ngày càng cao về khoa học máy tính và công
nghệ thông tin, ngày càng có nhiều phần mềm, chương trình… cả có hại và
có lợi cho người sử dụng vi tính. Để hiểu rõ và kiểm soát chúng, chúng ta
cần phải tìm hiểu bản chất phần mềm, chương trình cho máy tính của
chúng ta để kịp nâng cấp, chỉnh sửa chúng hay kiểm soát ảnh hưởng của
chúng, hạn chế tác động có hại với hệ thống của ta. Với đa số các chương
trình phần mềm hiện nay chúng ta đều không có mã nguồn nên công việc
trên thực sự rất khó, từ đó kỹ thuật dịch ngược mã nguồn ra đời, trợ giúp
rất mạnh mẽ trong việc giải quyết các vấn đề trên.
Trong bài báo cáo này chúng em xin trình bày những tìm hiểu về kỹ
thuật dịch ngược mã nguồn. Nội dung báo cáo bao gồm 3 chương lớn:
Chương 1: Tổng quan về dịch ngược mã nguồn
Chương 2: Tìm hiểu dịch ngược mã nguồn phần mềm
Chương 3: Demo dịch ngược mã nguồn
Nhóm 3 – AT8B 8
Tìm hiểu kỹ thuật dịch ngược mã nguồn
CHƯƠNG I: DỊCH NGƯỢC MÃ NGUỒN
I.1. Tổng quan về dịch ngược mã nguồn
Kĩ thuật dịch ngược là quá trình tìm kiếm thông tin từ kiến thức
hoặc thiết kế blue-print từ tất cả những gì do con người làm ra. Định nghĩa
này ra đời rất lâu trước khi máy tính, hoặc những công nghệ hiện đại khác
ra đời, nó có từ cuộc cách mạng công nhiệp - reverse engineering với ý
nghĩa đi ngược lại quá trình chế tạo để tìm hiểu cơ chế hoạt động. Tương
tự như nghiên cứu khoa học, người nghiên cứu phải làm việc ngoài
“blueprint” của nguyên tử hoặc là trí óc con người. Điểm khác biệt giữa
dịch ngược và các môn khoa học tự nhiên khác khác là dịch ngược nghiên
cứu về những gì do con người tạo ra, chứ không phải những hiện tượng tự
nhiên.

Kĩ thuật dịch ngược chỉ ra cách để tìm ra những tri thức chưa đầy
đủ, những ý tưởng, và cách thiết kế khi những thông tin trên ta không có.
Trong một vài trường hợp, người chủ thông tin không muốn chia sẻ. Trong
trường hợp khác thông tin đã bị mất hay phá hủy.
Không lâu về trước, dịch ngược đã thực sự là một sở thích, được
thực hiện bởi rất nhiều người (mặc dù nó không được cho là kỹ thuật dịch
ngược). Hãy nhớ cách mà nhiều người trong những ngày đầu của những
thiết bị điện tử, đã rất thích thú tháo những appliances như radio hay tivi ra
để xem nó gồm những gì và cái gì đang xảy ra bên trong? Đó chính là dịch
ngược. Tất nhiên, sự phát triển của các thiết bị điện tử đã làm cho việc này
trở nên không còn thiết thực. Những thiết bị số hiện đại quá bé nhỏ nên
ngày nay bạn gần như không thể thấy những thứ thú vị chỉ bằng cách open
the box.
Nhóm 3 – AT8B 9
Tìm hiểu kỹ thuật dịch ngược mã nguồn
Trong khái hơn ta xét tới, đó là dịch ngược trong ngành công nghệ
thông tin hiện nay. Như chúng ta đã biết, máy tính không thể hiểu được các
ngôn ngữ tự nhiên, ngôn ngữ bậc cao (pascal, C, C++, Java…) mà đều phải
được biên dịch hoặc thông dịch ra một ngôn ngữ bậc thấp mà máy có thể
hiểu được. Quá trình đó được gọi như là “dịch xuôi”.
Kỹ thuật dịch ngược là quá trình lấy một biên dịch nhị phân và cố
gắng để tái tạo lại (hay hiểu) cách chương trình ban đầu hoạt động. Một lập
trình viên ban đầu viết một chương trình, thường là trong một ngôn ngữ
cấp cao như C ++ hoặc Visual Basic (hoặc God Forbid, Delphi). Bởi vì
máy tính không vốn hiểu những ngôn ngữ đó, mà các đoạn mã do các lập
trình viên viết được lắp ráp thành một định dạng cụ thể, một trong những
ngôn ngữ một máy tính có thể hiểu. Mã này ban đầu được gọi là ngôn ngữ
máy. Loại mã này rất không phải là rất thân thiện với con người, và thường
lần đòi hỏi rất nhiều kiến thức và tư duy để tìm ra chính xác những gì các
lập trình viên đã nghi và viết.

Ngày nay, các phần mềm, các file, tài liệu và đặc biệt là các phần
mềm, để đảm bảo tính bí mật, tính toàn vẹn, gọn nhẹ hay vấn đề bản
quyền… chúng đều được che giấu (đóng gói hay mã hóa) thành một định
dạng khác để người sử dụng không thể biết mã nguồn. Nên việc dịch
ngược tìm lại mã nguồn trở thành công nghệ rất quan trọng đối với mục
đích riêng của mỗi reverser. Đôi khi ta có thể tìm kiếm lỗ hổng bảo mật,
mã độc, đôi khi bạn tò mò cách làm việc của bảo vệ chống sao chép, hay
để tìm cách phá hoại chen malware, virus… hoặc đơn giản là tìm cách để
sử dụng một phần mềm miễn phí v.v
Nhóm 3 – AT8B 10
Tìm hiểu kỹ thuật dịch ngược mã nguồn
I.2. Ứng dụng của dịch ngược mã nguồn
Kỹ thuật đảo ngược có thể được áp dụng cho rất nhiều lĩnh vực khoa
học máy tính, nhưng đây là một vài loại chung:
I.2.1. Dịch ngược – Bảo mật
Với một số người gắn liền bảo mật và dịch ngược có thể hơi khó
hình dung. Dịch ngược liên quan đến một vài khía cạnh khác của bảo mật.
Như là, dịch ngược được dùng trong nghiên cứu mã hóa - một người
nghiên cứu dịch ngược một sản phẩm và đánh giá mức độ bảo mật của nó.
Dịch ngược còn được sử dụng nhiều trong việc hình dung hoạt động của
các malware, ở cả hai đầu chiến tuyến : bởi cả người phát triển malware và
người chống lại nó. Cuối cùng, dịch ngược rất phổ biến với cracker, những
người dùng nó để phân tích và cả phá bỏ những phương thức bảo vệ phần
mềm.
I.2.2. Malicious Software
Internet đã thay đổi hoàn toàn nền công nghiệp máy tính về tổng thể
lẫn riêng về khía cạnh bảo mật máy tính. Malicious software, như virus,
worm, bùng nổ quá nhanh trong thế giới nơi mà hàng tỷ người đang kết nối
Internet và sử dụng e-mail. Khoảng 10 năm trước, một virus thường copy
nó vào đĩa mềm và đĩa mềm sẽ load nó vào một máy tính khác để lây

nhiễm. Quá trình lây nhiễm thường rất chậm, và sự chống đỡ cũng đơn
giản hơn nhiều bởi cách thức chúng lây nhiễm khá quen thuộc và cần có sự
tác động của con người. Đó là câu chuyện cũ trong lịch sử. Internet đã tạo
ra một liên kết ảo giữa hầu như tất cả các máy tính trên thế giới. Ngày nay,
rất nhiều loại worm có thể lây một cách tự động tới hàng tỉ máy tính mà
không cần có bất cứ sự tác động nào của con người.
Dịch ngược được dùng rộng rãi ở cả hai mặt trong đường dây của
malware. Những người phát triển malware thường dùng reversing để xác
Nhóm 3 – AT8B 11
Tìm hiểu kỹ thuật dịch ngược mã nguồn
định lỗi trong hệ điều hành hoặc trong các phần mềm khác. Những lỗi có
thể được sử dụng để thâm nhập vào phần bảo vệ của hệ thống và chấp
nhận sự nhiễm độc - thường là trên Internet. Bên cạnh sự lây nhiễm, tội
phạm thỉnh thoảng mượn kĩ thuật dịch ngược để xác định lỗi có thể chấp
nhận malware thực hiện một kết nối tối những thông tin nhạy cảm hoặc
hơn nữa có thể điều khiển toàn bộ hệ thống.
Ở chiến tuyến đối nghịch, những người phát triển antivirus software
khảo sát và phân tích tất cả malware mà họ có được. Họ dùng reversing để
theo dõi từng bước mà chương trình làm và quyết định tổn thất có thể xảy
ra, mức độ nguy hiểm, và làm cách nào để remove chũng khỏi những hệ
thống bị nhiễm độc, và những lây nhiễm nào có thể tránh.
I.2.3. Dịch ngược giải thuật mã hóa
Mã hóa luôn được cho là công cụ cơ bản của bảo mật: Alice gửi cho
Bob một tin nhắn, và mã hóa tin nhắn đó sử dụng một bí mật chỉ được biết
bởi Bob và cô ấy. Giải thuật mã hóa có thể chia ra 2 kiểu: giải thuật hạn
chế và giải thuật dựa trên key. Giải thuật hạn chế giống như là một vài đứa
trẻ chơi với nhau, viết thư cho bạn bằng cách dịch mỗi chữ cái lên hoặc
xuống. Bí mật của giải thuật hạn chế là chính bản thân nó. Một khi quy
luật được tìm ra, nó không còn là bí mật nữa. Giải thuật hạn chế cung cấp
rất ít sự bảo vệ bởi kỹ thuật dịch ngược làm cho nó trở nên khó bảo vệ

được bí mật giải thuật. Một khi reversers có trong tay cách mã hóa hoặc
giải mã, điều còn lại chỉ là thời gian trước khi giải thuật bị khám phá. Bởi
giải thuật là bí mật, reversing có thể xem là một cách để phá hỏng giải
thuật. Một cách mã hóa khác, giải thuật mã hóa dựa trên key, bí mật nằm ở
key, một vài giá trị được dùng bởi giải thuật để mã hóa và giải mã thông
tin. Trong giải thuật dựa trên key, người dùng mã hóa thông tin bằng key
và giữ nó (và một vài divulged để legitimate recipient, dựa trên giải thuật).
Nhóm 3 – AT8B 12
Tìm hiểu kỹ thuật dịch ngược mã nguồn
Nó hầu như làm reversing pointless bởi giải thuật coi như đã biết. Để
decipher một thông tin như vậy, chúng ta có thể :
- Tìm kiếm key.
- Thử tất cả các phép so sánh có thể cho đến khi có được key.
- Tìm một kẽ hở trong giải thuật có thể sử dụng để tìm ra key hoặc
thông tin ban đầu. Tuy vậy, vẫn có những trường hợp cần
reverse, như là nhữ phương pháp hiện thực giải thuật mã hóa dựa
trên key không công khai. Mặc dù hầu hết các giải thuật mã hóa
dựa trên key đều phổ biến, chi tiết của một phương pháp đặc biệt
thường có tác động không ngờ trong mức độ bảo mật tổng thể
của một chương trình.
Giải thuật mã hóa thường mỏng manh, và một lỗi nhỏ trong quá
trình mã hóa có thể làm mất đi tính bảo mật được bảo vệ bởi giải thuật đó.
Con đường duy nhất để thực sự biết chắc khi nào một sản phẩm được mã
hóa hoàn thiện là xem toàn bộ source code hoặc, reverse nó.
I.2.4. Cracking
Có hai xu hướng công nghệ hiện nay trong lĩnh vực phần mềm, đó là
các phần mềm mã nguồn mở, tức là những deverlopers cung cấp cho mọi
người phần mềm và đồng thời cung cấp luôn mã nguồn của phần mềm đó.
Mọi người đều có thể sử dụng, chỉnh sửa cho phù hợp với nhu cầu sử dụng
của mình, miễn là sao cho phải phù hợp với giấy phép của mã nguồn đó.

Xu hướng thứ hai, phần mềm cung cấp độc quyền, được nhà sản
xuất nghiên cứu và phân phối, người sử dụng muốn sử dụng các phần mềm
như vậy buộc phải trả phí bản quyền. Mã nguồn của chương trình sẽ không
được công khai. Và đôi khi phí bản quyền của các nhà deverlopers thật
không dễ chịu với tất cả mọi người sử dụng. Vậy làm sao để có thể không
Nhóm 3 – AT8B 13
Tìm hiểu kỹ thuật dịch ngược mã nguồn
cần “trả phí” mà vẫn được sử dụng những phần mềm như vậy. Kỹ thuật
dịch ngược mã nguồn giúp các cracker có thể “bẻ khóa” các chương trình,
hay tìm ra được thuật toán sinh key cho phần mềm để sinh ra các keygen.
Nhóm 3 – AT8B 14
Tìm hiểu kỹ thuật dịch ngược mã nguồn
CHƯƠNG II: DỊCH NGƯỢC MÃ NGUỒN PHẦN MỀM
II.1. Cấu trúc PE file trong windows
PE là định dạng riêng của Win32. Hầu hết các file thực thi trên
Win32 đều thuộc dạng PE (Trừ các tập tin VxDs và các file DLL 16 bít).
Để có thể thực thi trên máy tính, nội dung file PE được chia thành
các thành phần và có mối liên hệ mật thiết với nhau. Nắm rõ cấu trúc PE sẽ
giúp chúng ta hiểu được cơ chế thực thi của một chương trình, từ việc tổ
chức tới việc load lên bộ nhớ, các tài nguyên sử dụng….
Hơn nữa khi chúng ta muốn sửa đổi một file, ví dụ như thêm vào
một số đoạn mã, chỉnh sửa một số thành phần nhưng vẫn muốn chương
trình thực thi bình thường. Do đó, cần phải nắm rõ cấu trúc PE file, mối
liên hệ giữa các thành phần trong file để có thể nhanh chóng thay đổi file
và thoả mãn yêu cầu đề ra.
Hình 1: Cấu trúc cơ bản của PE.
Nhóm 3 – AT8B 15
Tìm hiểu kỹ thuật dịch ngược mã nguồn
Từ hình vẽ trên, chúng ta thấy cấu trúc PE có thể gồm nhiều section,
trong đó tối thiểu cần 2 section: data và code.

Một số section thông dụng hay được gặp ở các chương trình:
Executable Code Section, có tên là .text (Micro$oft) hoc là CODE
(Borland).
Data Sections, có nhng tên nh .data, .rdata hoc .bss (Micro$oft) hay
DATA (Borland)
Resources Section, có tên là .rsrc
Export Data Section, có tên là .edata
Import Data Section. có tên là .idata
Debug Information Section, có tên là .debug
Cấu trúc các section trên bộ nhớ và trên ổ đĩa là như nhau, tuy nhiên
khi được nạp lên bộ nhớ, các Windows loader sẽ quyết định thứ tự và vị trí
nạp các phần, do đó vị trí các phần trên ổ đĩa và trên bộ nhớ sẽ có sự khác
biệt.
Tiếp theo chúng ta sẽ đi chi tiết hơn về các phần cụ thể trong PE:
DOS MZ header, DOS stub, PE header, Section table.
II.1.1. DOS MZ header
Tất cả các file PE bắt đầu bằng DOS Header, vùng này chiếm 64
bytes đầu tiên của files. Vùng này được dùng trong trường hợp chương
trình chạy trên nền DOS, hệ điều hành DOS nhận biết đây là một file thực
thi hợp lệ và sẽ thực thi nội dung trong phần DOS stub.
DOS Header là một cấu trúc được định nghĩa trong file windows.inc
hoặc winnt.h. Cấu trúc này gồm 19 thành phần.
Nhóm 3 – AT8B 16
Tìm hiểu kỹ thuật dịch ngược mã nguồn
Hình 2: Cấu trúc DOS Header.
Trong đó chúng ta cần quan tâm tới hai trường:
e_magic: Chữ ký của PE file, giá trị: 4Dh, 5Ah (Ký tự “MZ”, tên
của người sáng lập MS-DOS: Mark Zbikowsky). Giá trị này đánh dấu một
DOS Header hợp lệ và được phép thực thi tiếp.
e_lfanew: là một DWORD nằm ở cuối cùng của DOS Header, là

trường chứa offset của PE Header so với vị trí đầu file.
Nhóm 3 – AT8B 17
Tìm hiểu kỹ thuật dịch ngược mã nguồn
Hình 3: Cấu trúc Dos MZ header
II.1.2. PE Header
PE Header thực chất là cấu trúc IMAGE_NT_HEADERS bao gồm
các thông tin cần thiết cho quá trình loader load file lên bộ nhớ. Cấu trúc
này gồm 3 phần được định nghĩa trong windows.inc
Hình 4: Cấu trúc IMAGE_NT_HEADERS.
Signature: là 1 DWORD bắt đầu PE Header chứa chữ ký PE: 50h,
45h, 00h, 00h
FileHeader: bao gồm 20 bytes tiếp theo của PE Header, phần này
chứa thông tin về sơ đồ bố trí vật lý và các đặc tính của file. Trong trường
này chúng ta cần chú ý tới trường NumberOfSections, đây là trường chứa
số section của file. Nếu muốn thêm/xoá section trong PE file, ta cần thay
đổi tương ứng trường này.
Nhóm 3 – AT8B 18
Tìm hiểu kỹ thuật dịch ngược mã nguồn
Hình 5: Trường NumberOfSections
OptionalHeader: bao gồm 224 bytes tiếp theo sau FileHeader. Cấu
trúc này được định nghĩa trong windows.inc, đây là phần chứa thông tin về
sơ đồ logic trong PE file. Dưới đây là danh sách các trường trong cấu trúc
này, đồng thời sẽ đưa ra một số chỉ dẫn về thông tin của một số trường cần
quan tâm khi muốn chỉnh sửa file.
Nhóm 3 – AT8B 19
Tìm hiểu kỹ thuật dịch ngược mã nguồn
Hình 6: Danh sách các trường trong OptionalHeader
AddressOfEntryPoint (RVA): địa chỉ ảo tương đối của câu lệnh đầu
tiên sẽ được thực thi. Nếu muốn chương trình bắt đầu từ một địa chỉ khác
(để thực thi câu lệnh với mục đích khác) thì cần thay đổi địa chỉ này về địa

chỉ tương đối của câu lệnh muốn thực thi.
ImageBase: Địa chỉ được ưu tiên nạp cho PE file.
SectionAlignment: Phần liên kết các section trong bộ nhớ, tức là một
section luôn luôn được bắt đầu bằng bội số của sectionAlignment. Ví dụ:
sectionAlignment là 1000h, section đầu tiên bắt đầu ở vị trí 401000h và
kích thước là 10h, section tiếp theo sẽ bắt đầu tại địa chỉ 402000h.
FileAlignment: Phần liên kết các section trong file. Tương tự như
SectionAlignment nhưng áp dụng với file.
SizeOfImage: Toàn bộ kích thước PE file trong bộ nhớ, là tổng của
tất cả các headers và sections được liên kết tới SectionAlignment.
SizeOfHeaders: Kích thước của tất cả headers và section table, bằng
kích thước file trừ đi tổng kích thước của các section trong file.
DataDirectory: là một mảng gồm 16 cấu trúc
IMAGE_DATA_DIRECTORY, mỗi cấu trúc liên quan tới 1 cấu trúc dữ
liệu trong PE file.
II.1.3. Section Table
Section Table là thành phần ngày sau PE Header, bao gồm một
mảng những cấu trúc IMAGE_SECTION_HEADER, mỗi phần tử chứa
thông tin về một section trong PE file. Cấu trúc này được định nghĩa trong
file windows.inc như hình dưới đây:
Nhóm 3 – AT8B 20
Tìm hiểu kỹ thuật dịch ngược mã nguồn
Hình 7: Cấu trúc IMAGE_SECTION_HEADER
Thông tin về một số trường quan trọng:
VirtualSize: Kích thước thật sự của dữ liệu trên section tính theo
byte, giá trị này có thể nhỏ hơn kích thước trên ổ đĩa (SizeOfRawData)
VirtualAddress: RVA của section, là giá trị để ánh xạ khi section
được load lên bộ nhớ
SizeOfRawData: Kích thước section data trên ổ đĩa.
PointerToRawData: là offset từ vị trí đầu file tới section data.

Characteristics: đặc tính của section: thực thi, dữ liệu khởi tạo …
II.2. Các kỹ thuật dịch ngược mã nguồn
II.2.1. Kỹ thuật pack, unpack file
Pack file là để che giấu hay nén một tập tin thực thi, các trình nén
chương trình sẽ đóng gói chúng lại thành một tập tin thực thi khác. File
thực thi này cũng có thể lại được được đóng gói thành một file thực thi
khác nữa. Chúng ta có thể liên tưởng tới búp bê Matryoshka của nước Nga,
kỹ thuật pack file cũng là như vậy.
Một file thực thi bị “đóng gói” vào một file thực thi khác. Khi ta
thực thi file, file thực thi “ngoài” sẽ giải nén (unpack) mọi nội dung file
Nhóm 3 – AT8B 21
Tìm hiểu kỹ thuật dịch ngược mã nguồn
thực thi “trong” chứa bên trong nó ra bộ nhớ rồi sau đó tiến trình thực thi
mới thực sự bắt đầu. Như vậy, file thực thi “bên trong” mới là file thực thi
“thực sự’.
Các trình nén tập tin PE đầu tiên được thiết kế như là một phương
pháp giảm kích thước của một thực thi trên đĩa, thông qua việc nén file đó
lại. Các trình đóng gói (packes) sẽ thực hiện đóng gói nhỏ hơn vào ổ đĩa, nhưng khi chạy sẽ 'giải nén' chính nó vào
trong bộ nhớ. Một khi các file thực thi được giải nén vào bộ nhớ, tập tin
thực thi kèm theo sẽ được thực hiện một cách bình thường.
Hình 8: Packed file
Kỹ thuật unpack file
Kỹ thuật unpack file mục đích là tái tạo tập tin thực thi, ở dạng bản
gốc của nó, trước khi nó đóng gói. Điều này cho phép chúng ta thực hiện
phân tích tĩnh ngay trên dữ liệu được giải nén. Đồng thời chúng ta sẽ
không cần các PE file gốc (bị đóng gói) một lần nào nữa, do đó, chúng ta
Nhóm 3 – AT8B 22
Tìm hiểu kỹ thuật dịch ngược mã nguồn
có thể xoá nó đi. Và chúng ta sẽ có được file thực thi như là chúng chưa bị
đóng gói.

Ở bên trong một file thực thi đã bị nén thì các bảng import tables
thường thường là đã bị thay đổi, làm mất hiệu lực và phần dữ liệu thì luôn
bị mã hóa. Các chương trình đóng gói (hay nén) sẽ chèn thêm mã lệnh để
giải nén chương trình trong bộ nhớ vào lúc thực thi và sau đó nhảy tới OEP
(orginal entry point - Đây là nơi mà chương trình gốc thực sự bắt đầu thực
thi, thi hành). Chúng ta phải tìm được cách để (dump) kết xuất vùng nhớ
này sau khi mà chương trình đóng gói hoàn tất được quá trình giải nén tập
tin thực thi, đồng thời thêm vào đó chúng ta cũng phải chỉnh sửa lại các
section và bảng import table trước khi mà ứng dụng của chúng ta sẽ thực
thi.
Vậy kỹ thuật giải nén một chương trình ở đây cốt lõi là đi tìm lại
OEP thật của trình thực thi mà chúng ta cần giải nén. Và tìm IAT (Import
Address Table - đây là một bảng của những con trỏ tới các địa chỉ hàm mà
đã được điền vào bởi trình windows loader khi các file Dll được nạp) sau
đó chỉnh sửa bảng này sao cho chỏ tới địa chỉ các hàm của chương trình
“thật”. Nếu như tìm được hai mục tiêu trên coi như chúng ta đã giải nén
thành công một tập tin đã bị nén.
Các bước để giải nén một tập tin đã được nén:
1. Giải nén tập tin thực thi ban đầu vào bộ nhớ.
2. Giải quyết tất cả các hàm khai báo của các thực thi ban đầu.
3. Thực hiện để chuyển điểm vào gốc của mã thực thi chính
(OEP).
4. Chỉnh sửa IAT và giảm kích thước sau khi giải nén.
Mã thực thi được tải vào bộ nhớ
Khi mã thực thi được tải vào bộ nhớ, một bộ nạp đọc tiêu đề PE trên
đĩa, và cấp phát bộ nhớ cho mỗi phần của thực thi dựa trên tiêu đề đó. Bộ
Nhóm 3 – AT8B 23
Tìm hiểu kỹ thuật dịch ngược mã nguồn
nạp sau đó sao chép các phần section vào không gian được phân bổ trong
bộ nhớ. Đóng gói và giải nén 385 các mã thực thi cùng định dạng tiêu đề

PE để bộ nạp sẽ phân bổ không gian cho các phần, trong đó có thể đến
chương trình gốc, hoặc phần Unpacking Stub có thể tạo ra các phần. Phần
giải nén sẽ giải nén mã cho mỗi phần và bản sao nó vào không gian đã
được phân bổ. Phương pháp giải nén chính xác được sử dụng phụ thuộc
vào các mục tiêu của các trình giải nén, và nó thường được chứa trong
phần Unpacking Stub.
Xử lý các khai báo
Các tập tin PE không bị nén bao gồm một phần khai báo chức năng,
và một phần lưu trữ địa chỉ của các tên của tất cả các chức năng được khai
báo. Bộ nạp Windows đọc các thông tin khai báo, xác định chức năng nào
là cần thiết, và sau đó điền vào các địa chỉ.
Bộ nạp Windows không thể đọc thông tin khai báo được đóng gói.
Đối với một thực thi đóng gói, phần giải nén sẽ giải quyết vấn đề khai báo.
Cách tiếp cận cụ thể phụ thuộc vào cách đóng gói.
Phương pháp phổ biến nhất là phần khai báo của giải nén phải có
chức năng LoadLibrary và GetProcAddress. Sau khi phần giải nén mã thực
thi gốc, nó đọc thông tin khai báo ban đầu. Nó sẽ gọi LoadLibrary cho mỗi
thư viện, để nạp DLL vào bộ nhớ, và sau đó sẽ sử dụng GetProcAddress để
có được địa chỉ của từng chức năng.
The Tail Jump
Sau khi khi phần giải nén hoàn tất, nó phải thực hiện chuyển đến
OEP.
Các lệnh thực hiện mà chuyển đến OEP thường được gọi là lệnh
nhảy.
Một lệnh nhảy là cách đơn giản và phổ biến nhất để chuyển giao
thực hiện. Kể từ khi nó quá phổ biến, các mã độc hại sẽ cố gắng để che
khuất chức năng này bằng cách sử dụng một lệnh ret hoặc call.
Thông qua Hình 9 đến 12 minh họa cho quá trình đóng gói và giải
nén, như sau:
Nhóm 3 – AT8B 24

Tìm hiểu kỹ thuật dịch ngược mã nguồn
Hình 9. File thực thi ban đầu. chưa được đóng gói
Hình 10: File thực thi sau khi bị nén
Nhóm 3 – AT8B 25
Tìm hiểu kỹ thuật dịch ngược mã nguồn
Hình 11: File thực thi sau khi giải nén và nạp vào bộ nhớ
Hình 12: File thực thi đầy đủ khi được giải nén thành công
- Hình 9: File trước khi được nén. Các header và sections có thể
nhìn thấy, và điểm bắt đầu được thiết lập để tới OEP
- Hình 10 cho thấy thực thi đóng gói như nó tồn tại trên đĩa. Tất cả
những gì có thể nhìn thấy là tiêu đề mới, Phần Unpacking Stub
và Packed Original Code.
- Hình 11 cho thấy file thực thi đóng gói khi nó được nạp vào bộ
nhớ. Phần Unpacking Stub đã giải nén mã ban đầu, và .text hợp
lệ và phần .data có thể nhìn thấy. Điểm khởi đầu cho việc thực thi
vẫn còn chỉ tới Phần Unpacking Stub, và bảng khai báo thường là
không có giá trị ở giai đoạn này.
- Hình 12 cho thấy thực thi đầy đủ sau khi được giải nén. Bảng
nhập khẩu đã được xây dựng lại, và điểm khởi đầu đã được chỉnh
sửa để trỏ đến OEP.
Lưu ý rằng chương trình giải nén cuối cùng là khác so với chương
trình ban đầu. Chương trình giải nén vẫn còn phần Unpacking Stub.
Chương trình giải nén có một PE Header đã được tái tạo bằng các trình
giải nén và sẽ không được chính xác giống như các chương trình ban đầu.
II.2.2. Kỹ thuật disassembly
Nhóm 3 – AT8B 26

×