Với đa số các chươngtrì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ấtkhó, từ đó kỹ thuật dịch ngược mã nguồn ra đời, trợ giúp rất mạnh mẽ trong việc g
Trang 1HỌC VIỆN KỸ THUẬT MẬT MÃ
AN TOÀN THÔNG TIN
CƠ SỞ AN TOÀN THÔNG TIN
TÌM HIỂU VỀ DỊCH NGƯỢC VÀ CÔNG CỤ OLLYDBG
Sinh viên thực hiện:
Ngô Xuân Hà
Phan Xuân Tính
Hà Nội , tháng 9 năm 2021
Trang 2LỜ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 conngườ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ọiquố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 vití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ươngtrì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ấtkhó, 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ếtcá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ịchngượ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
Chương 2: Các kỹ thuật trong dịch ngược mã nguồn
Chương 3: Thực nghiệm
Trang 3MỤC LỤC
CHƯƠNG 1: TỔNG QUAN VỀ DỊCH NGƯỢC 5
1.1 Giới thiệu 5
1.2 Ứng dụng của dịch ngược 6
1.2.1 Phân tích mã độc 6
1.2.2 Dịch ngược giải thuật mã hóa 7
1.2.3 Cracking 8
CHƯƠNG 2: CÁC KỸ THUẬT TRONG DỊCH NGƯỢC MÃ NGUỒN 9
2.1 Cấu trúc PE file trong windows 9
2.1.1 DOS MZ header 11
2.1.2 PE Header 12
2.1.3 Section Table 15
2.2 Các kỹ thuật dịch ngược mã nguồn 16
2.2.1 Kỹ thuật pack, unpack file 16
2.2.3 Kỹ thuật disassembly và anti disassembly 21
2.2.4 Kỹ thuật debugging và anti debugging 26
2.3 Phần mềm OllyDbg 29
CHƯƠNG 3: THỰC NGHIỆM 33
Trang 4DANH MỤC HÌNH VẼ
Hình 1 cấu trúc cơ bản của PE 10
Hình 2.Cấu trúc DOS Header 12
Hình 3.Cấu trúc Dos MZ header 12
Hình 4.Cấu trúc IMAGE_NT_HEADERS 13
Hình 5.Trường NumberOfSections 14
Hình 6.Danh sách các trường trong OptionalHeader 15
Hình 7.Cấu trúc IMAGE_SECTION_HEADER 16
Hình 8.Packed file 17
Hình 9.File thực thi ban đầu chưa được đóng gói 20
Hình 10.File thực thi sau khi bị nén 20
Hình 11.File thực thi sau khi giải nén và nạp vào bộ nhớ 20
Hình 12.File thực thi đầy đủ khi được giải nén thành công 21
Hình 13.Linear sweep disassembler và recursive disassembler 24
Hình 14.Quá trình Debugging 28
Hình 15.Cửa sổ chính OllyDBG 31
Hình 16.Các nút chức năng trong ollydbg 32
Hình 17.Các chức năng chính phục vụ debug 34
Trang 5CHƯƠNG 1: TỔNG QUAN VỀ DỊCH NGƯỢC
1.1 Giới thiệu
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ế 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áytí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ủanguyê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
blue-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ôngphả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 hayphá 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ấtnhiề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ềungườ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ữngappliances 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ệcnà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ạngần như không thể thấy những thứ thú vị chỉ bằng cách open the box
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ệnnay 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ônngữ 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ộtchương trình, thường là trong một ngôn ngữ cấp cao như C ++ hoặc Visual Basic (hoặc
Trang 6God 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ônngữ 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ấtkhô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ảotí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 (đónggó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ênviệ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 đíchriê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
1.2 Ứng dụng của dịch ngược
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ịchngượ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ùngtrong 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ườichố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
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:
1.2.1 Phân tích mã độc
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á nhanhtrong 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 10nă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
Trang 7tí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 đơngiả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ủacon 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ầunhư 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ữngngười phát triển malware thường dùng reversing để xác định lỗi trong hệ điều hành hoặctrong 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 malwarethự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
1.2.2 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 tinnhắ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ạnchế 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 khireversers 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ảithuậ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ỏnggiả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ộtvà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
Trang 8trê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).
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 tinban đầu Tuy vậy, vẫn có những trường hợp cần reverse, như là nhữ phươngphá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ầuhế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ươngphá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ếtchắ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ó
1.2.3 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ờicung 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 chophù 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ảnquyề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ủacá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 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
Trang 9ngượ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ậttoán sinh key cho phần mềm để sinh ra các keygen.
2.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ộcdạ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ể nhanhchóng thay đổi file và thoả mãn yêu cầu đề ra
Trang 10Từ hình vẽ trên, chúng ta thấy cấu trúc PE có thể gồm nhiều section, trong đó tốithiể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
Hình 1: cấu trúc cơ bản của PE
Trang 11Cấu trúc các section trên bộ nhớ và trên ổ đĩa là như nhau, tuy nhiên khi được nạplê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ácphầ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
2.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ủafiles 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ànhDOS 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
Trang 12Trong đó 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 Headerhợ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
2.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ầnthiế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ĩatrong windows.inc
Hình 3.Cấu trúc Dos MZ header
Trang 13Signature: 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ườngNumberOfSections, đây là trường chứa số section của file Nếu muốn thêm/xoá sectiontrong PE file, ta cần thay đổi tương ứng trường này
Optional Header: 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 tincủa một số trường cần quan tâm khi muốn chỉnh sửa file
Hình 4.Cấu trúc IMAGE_NT_HEADERS
Hình 5.Trường NumberOfSections
Trang 14 AddressOfEntryPoint (RVA): địa chỉ ảo tương đối của câu lệnh đầu tiên sẽ đượcthự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ệnhvớ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ệnhmuố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ônluô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ếptheo 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ư SectionAlignmentnhư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ácheaders và sections được liên kết tới SectionAlignment
Hình 6.Danh sách các trường trong OptionalHeader
Trang 15 SizeOfHeaders: Kích thước của tất cả headers và section table, bằng kích thước filetrừ đ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ỗicấu trúc liên quan tới 1 cấu trúc dữ liệu trong PE file
2.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ấutrúc IMAGE_SECTION_HEADER, mỗi phần tử chứa thông tin về một section trong PEfile Cấu trúc này được định nghĩa trong file windows.inc như hình dưới đây:
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 …
Hình 7.Cấu trúc IMAGE_SECTION_HEADER
Trang 162.2 Các kỹ thuật dịch ngược mã nguồn
2.2.1 Kỹ thuật pack, unpack file
2.2.1.1 Kỹ thuật pack 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, filethực thi “ngoài” sẽ giải nén (unpack) mọi nội dung file 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êntrong” 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íchthướ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ẽ đượcthực hiện một cách bình thường
Hình 8.Packed file