Người phân tích cũng có thể quan tâm đến việc tìm kiếm cơ hội bổ sung để tối ưu hóa đầu ra của trình biên dịch và, từ góc độ an ninh, xác định xem trình biên dịch có bị tấn công đến mức
Trang 1TRƯỜNG ĐẠI HỌC XÂY DỰNG HÀ NỘI
KHOA CÔNG NGHỆ THÔNG TIN
BÁO CÁO BÀI TẬP LỚN MÔN HỌC
AN TOÀN BẢO MẬT THÔNG TIN
ĐỀ TÀI: TÌM HIỂU VỀ TRÌNH DỊCH NGƯỢC VÀ IDA
Trang 2Mục lục
1 KHÁI NIỆM TRÌNH DỊCH NGƯỢC VÀ IDA PRO 3
2 NỀN TẢNG CỦA IDA PRO 12
2.1 Bắt đầu với IDA……… 14
2.2 Hiển thị Dữ liệu của IDA……….……… 17
2.3 Điều hướng Giải Mã……… 21
2.4 Kiểu và dữ liệu……….25
2.5 Liên kết và đồ thị hóa………
3 CÁCH SỬ DỤNG IDA PRO NÂNG CAO 19
4 ỨNG DỤNG IDA TRONG THỰC TẾ 19
5 PHÂN CHIA CÔNG VIỆC 33
6 TÀI LIỆU THAM KHẢO……… ………34
Trang 31 KHÁI NIỆM TRÌNH DỊCH NGƯỢC VÀ IDA PRO
Phần 1 Giới thiệu về IDA
I.Giới thiệu về dịch ngược
Bạn có thể đang tự hỏi điều gì sẽ xuất hiện trong một cuốn sách dành riêng cho IDA Pro Mặc
dù rõ ràng là tập trung vào IDA, nhưng cuốn sách này không nhằm mục đích làm sách hướng dẫn người dùng IDA Pro Thay vào đó, chúng tôi có ý sử dụng IDA như một công cụ hỗ trợ để thảo luận về các kỹ thuật đảo ngược mà bạn sẽ thấy hữu ích khi phân tích đa dạng phần mềm, từ các ứng dụng có lỗ hổng đến phần mềm độc hại Khi cần thiết, chúng tôi sẽ cung cấp các bước chi tiết để thực hiện các hành động cụ thể liên quan đến nhiệm vụ đang thực hiện trong IDA Do
đó, chúng ta sẽ đi một cách khá vòng vo quanh các khả năng của IDA, bắt đầu từ các nhiệm vụ
cơ bản mà bạn muốn thực hiện khi kiểm tra một tệp và tiến lên đến những sử dụng và tùy chỉnh nâng cao của IDA để giải quyết các vấn đề đảo ngược khó khăn hơn Chúng tôi không cố gắng bao quát tất cả các tính năng của IDA Tuy nhiên, chúng tôi sẽ bao gồm những tính năng mà bạn
sẽ thấy hữu ích nhất trong việc đối mặt với thách thức đảo ngược của bạn Cuốn sách này sẽ giúpIDA trở thành vũ khí mạnh mẽ nhất trong bộ công cụ của bạn
Trước khi đào sâu vào bất kỳ chi tiết cụ thể nào của IDA, việc tìm hiểu một số kiến thức cơ bản
về quá trình disassembly cũng như xem xét một số công cụ khác có sẵn để đảo ngược mã máy biên dịch sẽ hữu ích Mặc dù không có công cụ nào cung cấp toàn bộ phạm vi các khả năng của IDA, mỗi công cụ đều giải quyết các phần nhỏ cụ thể của chức năng IDA và mang lại cái nhìn cógiá trị vào các tính năng cụ thể của IDA Phần còn lại của chương này sẽ dành để hiểu rõ quá trình disassembly
Lý thuyết tháo rời
Những người đã dành thời gian để nghiên cứu ngôn ngữ lập trình có lẽ đã biết về các thế hệ khácnhau của ngôn ngữ, nhưng tôi sẽ tóm tắt chúng ở đây cho những người có thể đã bỏ quên Ngôn ngữ thế hệ đầu tiên
Đây là hình thức ngôn ngữ thấp nhất, thường bao gồm các số một và số không hoặc một dạng rút gọn như hệ thập lục phân, chỉ có thể đọc được bởi các binja nhị phân Mọi thứ ở mức độ này trở nên phức tạp vì thường khó phân biệt dữ liệu và hướng dẫn vì mọi thứ đều trông giống nhau Ngôn ngữ thế hệ đầu tiên cũng có thể được gọi là ngôn ngữ máy, và trong một số trường hợp là
mã byte, trong khi chương trình ngôn ngữ máy thường được gọi là các tập tin nhị phân Ngôn ngữ thế hệ thứ hai
Còn được gọi là ngôn ngữ hợp nguyên, ngôn ngữ thế hệ thứ hai chỉ cách một bảng tra cứu xa ngôn ngữ máy và thường ánh xạ các mẫu bit cụ thể, hoặc các mã hoạt động (opcode), thành các dãy ký tự ngắn nhưng dễ nhớ được gọi là mnemonics Đôi khi, những mnemonics này thực sự
Trang 4giúp nhớ những hướng dẫn mà chúng được liên kết Một bộ biên dịch là một công cụ được sử dụng bởi các lập trình viên để dịch chương trình ngôn ngữ hợp nguyên của họ thành ngôn ngữ máy thích hợp để thực thi Ngôn ngữ thế hệ thứ ba Những ngôn ngữ này tiến thêm một bước nữađến khả năng diễn đạt của ngôn ngữ tự nhiên bằng cách giới thiệu từ khóa và cấu trúc mà lập trình viên sử dụng như là các khối xây dựng cho chương trình của họ.
Ngôn ngữ thế hệ thứ ba
Thường độc lập với nền tảng, mặc dù các chương trình được viết bằng chúng có thể phụ thuộc vào nền tảng do sử dụng các tính năng đặc biệt của một hệ điều hành cụ thể Những ví dụ thườngđược trích dẫn bao gồm FORTRAN, COBOL, C và Java Lập trình viên thường sử dụng trình biên dịch để dịch chương trình của họ thành ngôn ngữ hợp nguyên hoặc cho đến ngôn ngữ máy (hoặc một đối tượng tương đương như mã byte)
Lời hứa về "khôi phục mã nguồn" luôn luôn hấp dẫn trong một thị trường phần mềm cạnh tranh, và do đó, việc phát triển decompilers có thể sử dụng tiếp tục là một lĩnh vực nghiên cứu tích cực trong ngành khoa học máy tính Dưới đây chỉ là một số lý do mà quá trình
decompilation là khó khăn:
Quá trình biên dịch là quá trình mất mát thông tin.
Ở cấp độ ngôn ngữ máy, không có tên biến hoặc hàm, và thông tin về loại biến chỉ có thể được xác định thông qua cách dữ liệu được sử dụng thay vì các khai báo loại rõ ràng Khi bạn quan sát
32 bit dữ liệu được truyền, bạn sẽ cần thực hiện một số công việc điều tra để xác định liệu 32 bit
đó có đại diện cho một số nguyên, một giá trị dấu chấm động 32 bit, hay một con trỏ 32 bit
Quá trình biên dịch là một quá trình nhiều đối nhiễu.
Điều này có nghĩa là một chương trình nguồn có thể được dịch thành ngôn ngữ hợp nguyên theo nhiều cách khác nhau, và ngôn ngữ máy có thể được dịch ngược trở lại nguồn theo nhiều
Trang 5cách khác nhau Kết quả là, rất phổ biến khi biên dịch một tệp và ngay lập tức giải mã nó có thể tạo ra một tệp nguồn hoàn toàn khác với tệp đã đầu vào.
Decompilers phụ thuộc rất nhiều vào ngôn ngữ và thư viện.
Xử lý một tệp nhị phân được tạo ra bởi trình biên dịch Delphi với một decompiler được thiết
kế để tạo mã C có thể đưa ra kết quả rất kỳ lạ Tương tự, đưa một tệp nhị phân Windows đã biên dịch qua một decompiler không biết về API lập trình Windows có thể không mang lại bất kỳ điều gì hữu ích
Để có khả năng giải mã chính xác một tệp nhị phân, cần có khả năng tháo rời gần như hoàn hảo.
Bất kỳ lỗi hoặc sót sót nào trong giai đoạn tháo rời đều hầu như chắc chắn sẽ lan rộng sang mã giải mã.Hex-Rays, decompiler phức tạp nhất hiện nay trên thị trường
Tại sao phải tháo rời
Công cụ tháo rời thường được sử dụng để hỗ trợ trong việc hiểu rõ các chương trình khi mã nguồn không khả dụng Các tình huống phổ biến mà tháo rời được sử dụng bao gồm:
- Phân tích phần mềm độc hại
- Phân tích phần mềm mã nguồn đóng để tìm lỗ hổng
- Phân tích phần mềm mã nguồn đóng để kiểm tra khả năng tương thích
- Phân tích mã máy được tạo ra bởi trình biên dịch để xác nhận hiệu suất/chính xác của trình biêndịch
- Hiển thị các lệnh chương trình trong quá trình gỡ lỗi
Các phần tiếp theo sẽ giải thích chi tiết hơn về mỗi tình huống
Phân tích Phần mềm độc hại
Trừ khi bạn đang xử lý một loại ký tự worm, tác giả malware hiếm khi hỗ trợ bạn bằng cách cung cấp mã nguồn cho tác phẩm của họ Thiếu mã nguồn, bạn đối mặt với một bộ lựa chọn rất hạn chế để khám phá chính xác cách malware hoạt động Hai kỹ thuật chính cho phân tích malware là phân tích động và phân tích tĩnh Phân tích động liên quan đến việc cho phép malware thực thi trong một môi trường kiểm soát cẩn thận (sandbox) trong khi ghi lại mọi khía cạnh quan sát được của nó bằng bất kỳ số lượng tiện ích hệ thống nào Ngược lại, phân tích tĩnh
Trang 6cố gắng hiểu về hành vi của một chương trình chỉ bằng cách đọc mã nguồn của chương trình, trong trường hợp của malware, thường bao gồm một danh sách tháo rời.
Phân tích Lỗ hổng
Vì sự đơn giản, hãy chia quá trình kiểm thử bảo mật thành ba bước: phát hiện lỗ hổng, phân tích
lỗ hổng và phát triển exploit Các bước này áp dụng như nhau có mã nguồn hay không; tuy nhiên, mức độ nỗ lực tăng đáng kể khi bạn chỉ có một file nhị phân Bước đầu tiên trong quá trình này là phát hiện điều kiện có thể bị tận dụng trong một chương trình Thông thường, điều này được thực hiện bằng các kỹ thuật động như fuzzing, nhưng nó cũng có thể được thực hiện (thường với nhiều nỗ lực hơn) thông qua phân tích tĩnh Khi một vấn đề đã được phát hiện, thường cần phải phân tích thêm để xác định liệu vấn đề có thể bị tận dụng hay không và nếu có, trong điều kiện nào
Danh sách tháo rời cung cấp mức độ chi tiết cần thiết để hiểu rõ cách trình biên dịch đã chọn cách phân bổ biến của chương trình Ví dụ, có thể hữu ích biết rằng một mảng ký tự 70 byte được khai báo bởi một lập trình viên đã được làm tròn lên thành 80 byte khi được phân bổ bởi trình biên dịch Danh sách tháo rời cũng cung cấp phương tiện duy nhất để xác định chính xác cách mà trình biên dịch đã chọn cách sắp xếp tất cả các biến được khai báo toàn cục hoặc trong các hàm Hiểu về mối quan hệ không gian giữa các biến thường là quan trọng khi cố gắng phát triển exploit Cuối cùng, bằng cách sử dụng một công cụ tháo rời và một bộ gỡ lỗi cùng nhau, một exploit có thể được phát triển
Xác thực trình biên dịch
Vì mục đích của một trình biên dịch (hoặc bộ hợp ngữ) là tạo ra ngôn ngữ máy, thường cần sử dụng các công cụ tháo rời chất lượng để xác minh rằng trình biên dịch đang thực hiện công việc của nó theo các đặc tả thiết kế Người phân tích cũng có thể quan tâm đến việc tìm kiếm cơ hội
bổ sung để tối ưu hóa đầu ra của trình biên dịch và, từ góc độ an ninh, xác định xem trình biên dịch có bị tấn công đến mức mà nó có thể chèn cửa sau vào mã máy được tạo ra hay không.Hiển thị Gỡ lỗi
Có lẽ việc sử dụng tháo rời để tạo danh sách trong các bộ gỡ lỗi là một trong những ứng dụng phổ biến nhất Thật không may, các công cụ tháo rời được tích hợp trong các bộ gỡ lỗi thường khá đơn giản Thông thường, chúng không thể thực hiện tháo rời hàng loạt và đôi khi gặp khó khăn khi tháo rời khi không thể xác định ranh giới của một hàm Điều này là một trong những lý
do tại sao việc sử dụng một bộ gỡ lỗi kết hợp với một công cụ tháo rời chất lượng cao là tốt nhất
để cung cấp cái nhìn toàn cảnh và ngữ cảnh tốt hơn trong quá trình gỡ lỗi
Làm thế nào để Tháo rời
Bây giờ bạn đã thông thạo về mục đích của tháo rời, là lúc chuyển sang cách quá trình này thực
sự hoạt động Hãy xem xét một công việc đầy thách thức thường gặp đối mặt bởi một công cụ tháo rời: Lấy 100KB này, phân biệt mã từ dữ liệu, chuyển đổi mã thành ngôn ngữ lập trình hợp ngữ để hiển thị cho người dùng, và xin đừng bỏ sót bất cứ điều gì trên đường đi
Trang 7Chúng ta có thể thêm bất kỳ yêu cầu đặc biệt nào vào cuối công việc này, như yêu cầu công cụ tháo rời để định vị các hàm, nhận diện bảng nhảy và xác định biến cục bộ, làm cho công việc củacông cụ tháo rời trở nên khó khăn hơn.
Để đáp ứng tất cả các yêu cầu của chúng ta, bất kỳ công cụ tháo rời nào sẽ cần lựa chọn từ nhiều thuật toán khi điều hướng qua các tệp mà chúng ta cung cấp Chất lượng của danh sách tháo rời được tạo ra sẽ trực tiếp liên quan đến chất lượng của các thuật toán được sử dụng và cách chúng
đã được triển khai Trong phần này, chúng ta sẽ thảo luận về hai thuật toán cơ bản đang được sử dụng ngày nay để tháo rời mã máy Khi chúng tôi trình bày những thuật toán này, chúng tôi cũng
sẽ chỉ ra nhược điểm của chúng để chuẩn bị bạn cho những tình huống khi công cụ tháo rời của bạn có vẻ không thành công Bằng cách hiểu rõ về những hạn chế của công cụ tháo rời, bạn có thể can thiệp thủ công để cải thiện chất lượng tổng thể của đầu ra tháo rời
Một Thuật toán Tháo rời Cơ bản
Đầu tiên, hãy phát triển một thuật toán đơn giản để nhận mã máy làm đầu vào và tạo ra ngôn ngữlập trình hợp ngữ làm đầu ra Trong quá trình này, chúng ta sẽ hiểu về những thách thức, giả định và sự hy sinh đằng sau quá trình tháo rời tự động
Bước 1
Bước đầu tiên trong quá trình tháo rời là xác định một khu vực mã để tháo rời Điều này không nhất thiết đơn giản như có vẻ Hướng dẫn thường được trộn lẫn với dữ liệu, và quan trọng là phảiphân biệt giữa chúng Trong trường hợp phổ biến nhất, tháo rời của một tệp thực thi, tệp sẽ tuân theo một định dạng chung cho tệp thực thi như định dạng Portable Executable (PE) sử dụng trên Windows hoặc định dạng Executable and Linking Format (ELF) phổ biến trên nhiều hệ thống dựa trên Unix Những định dạng này thường chứa các cơ chế (thường dưới dạng các tiêu đề tệp phân cấp) để xác định các phần của tệp chứa mã và điểm vào (entry points) vào mã đó.Bước 2
Được đưa vào địa chỉ ban đầu của một lệnh, bước tiếp theo là đọc giá trị chứa tại địa chỉ đó (hoặc vị trí tệp) và thực hiện tìm kiếm trong bảng để so khớp giá trị opcode nhị phân với hình ảnh mnemonics ngôn ngữ lập trình Tùy thuộc vào sự phức tạp của bộ chỉ thị được tháo rời, điều này có thể là một quá trình đơn giản hoặc có thể liên quan đến một số hoạt động bổ sung như hiểu các tiền tố có thể sửa đổi hành vi của lệnh và xác định bất kỳ toán tử nào cần thiết bởi lệnh Đối với các bộ chỉ thị với lệnh có chiều dài biến, như Intel x86, có thể cần phải lấy thêm byte lệnh để hoàn toàn tháo rời một lệnh duy nhất
Bước 3
Sau khi lệnh đã được lấy và bất kỳ toán tử cần thiết nào đã được giải mã, phiên bản ngôn ngữ lậptrình tương đương được định dạng và xuất ra như một phần của danh sách tháo rời Có thể có khả năng chọn từ nhiều cú pháp ngôn ngữ lập trình Ví dụ, hai định dạng chủ yếu cho ngôn ngữ lập trình hợp ngữ x86 là định dạng Intel và định dạng AT&T
Trang 8Cú pháp X86 ASSEMBLY: AT&T VS INTEL
Có hai cú pháp chính được sử dụng cho mã nguồn lập trình hợp ngữ: AT&T và Intel Mặc dù chúng là ngôn ngữ thế hệ thứ hai, nhưng hai loại này khác nhau rất nhiều về cú pháp từ truy cậpbiến, hằng số và thanh ghi đến ghi đè kích thước phân đoạn và lệnh, gián tiếp và offset Cú pháplập trình hợp ngữ AT&T được phân biệt bởi việc sử dụng ký hiệu % để tiền tố cho tất cả tên thanh ghi, việc sử dụng $ như một tiền tố cho hằng số chữ (còn được gọi là toán hạng ngay lập tức), và thứ tự toán hạng của nó, trong đó toán hạng nguồn xuất hiện như toán hạng bên trái và toán hạng đích xuất hiện bên phải Sử dụng cú pháp AT&T, lệnh cộng bốn vào thanh ghi EAX sẽđọc: add $0x4,%eax Bộ Assembler GNU (Gas) và nhiều công cụ GNU khác, bao gồm gcc và gdb, sử dụng cú pháp AT&T
Cú pháp Intel khác biệt so với AT&T ở chỗ nó không yêu cầu tiền tố cho thanh ghi hoặc hằng số
và thứ tự toán hạng được đảo ngược sao cho toán hạng nguồn xuất hiện bên phải và toán hạng đích xuất hiện bên trái Cùng một lệnh cộng bằng cách sử dụng cú pháp Intel sẽ đọc: add eax,0x4 Assembler sử dụng cú pháp Intel bao gồm Microsoft Assembler (MASM), Turbo Assembler của Borland (TASM) và Netwide Assembler (NASM)
Bước 4
Sau khi xuất lệnh, chúng ta cần tiến tới lệnh tiếp theo và lặp lại quy trình trước đó cho đến khi chúng ta đã tháo rời mọi lệnh trong tệp.Có nhiều thuật toán khác nhau để xác định nơi bắt đầu quá trình tháo rời, cách chọn lệnh tiếp theo cần tháo rời, cách phân biệt giữa mã và dữ liệu, và cách xác định khi nào lệnh cuối cùng đã được tháo rời Hai thuật toán tháo rời quan trọng nhất là linear sweep và recursive descent
Phần 2 CÔNG CỤ ĐẢO NGƯỢC VÀ THÁO RỜI
Với một số kiến thức về tháo rời, và trước khi chúng ta bắt đầu khám phá cụ thể về IDA Pro, việc hiểu biết về một số công cụ khác được sử dụng để đảo ngược mã nhị phân sẽ hữu ích Nhiềutrong số này đã xuất hiện trước IDA và vẫn hữu ích để nhanh chóng xem qua các tệp cũng như kiểm tra lại công việc của IDA Như chúng ta sẽ thấy, IDA tích hợp nhiều khả năng của những công cụ này vào giao diện người dùng của nó để cung cấp môi trường tích hợp duy nhất cho đảo ngược mã nhị phân Cuối cùng, IDA chứa một trình gỡ lỗi tích hợp
Công cụ Phân loại
Khi đối mặt với một tệp không xác định lúc đầu, thường hữu ích để trả lời những câu hỏi đơn giản như "Đây là cái gì?" Quy tắc đầu tiên khi cố gắng trả lời câu hỏi đó là không bao giờ dựa vào phần mở rộng tên tệp để xác định điều gì thực sự là một tệp Đó cũng là quy tắc thứ hai, thứ
ba và thứ tư Khi bạn đã trở thành người ủng hộ cho quan điểm rằng phần mở rộng tên tệp không
có ý nghĩa, bạn có thể muốn làm quen với một hoặc nhiều trong các tiện ích sau đây
file
Trang 9Lệnh file là một tiện ích tiêu chuẩn, được bao gồm trong hầu hết các hệ điều hành kiểu *NIX và trong các công cụ Cygwin1 hoặc MinGW2 cho Windows Lệnh file cố gắng xác định loại tệp bằng cách xem xét các trường cụ thể trong tệp Trong một số trường hợp, lệnh file nhận ra chuỗi phổ biến như #!/bin/sh (một script shell) hoặc <html> (một tài liệu HTML) Tệp chứa nội dung không phải ASCII đôi khi đặt ra thách thức lớn hơn Trong những trường hợp như vậy, lệnh file
cố gắng xác định xem nội dung có dạng theo một định dạng tệp biết đến hay không Trong nhiều trường hợp, nó tìm kiếm các giá trị thẻ cụ thể (thường được gọi là magic numbers3) được biết đến là duy nhất đối với các loại tệp cụ thể Các mã hex dưới đây thể hiện một số ví dụ về các magic numbers được sử dụng để xác định một số loại tệp phổ biến
Tệp có khả năng xác định một số lượng lớn định dạng tệp, bao gồm nhiều loại tệp văn bản ASCII và các định dạng tệp thực thi và dữ liệu khác nhau Việc kiểm tra số phép thuật (magic number) được thực hiện bởi tệp được điều khiển bởi các quy tắc chứa trong một tệp số phép thuật Tệp số phép thuật mặc định thay đổi tùy thuộc vào hệ điều hành, nhưng các địa điểm phổ biến bao gồm /usr/share/file/magic, /usr/share/misc/magic và /etc/magic
MÔI TRƯỜNG CYWIN
Cygwin là một bộ công cụ dành cho hệ điều hành Windows, cung cấp một dòng lệnh và các chương trình liên quan giống như trong hệ điều hành Linux Trong quá trình cài đặt, người dùng
có thể chọn từ một số lượng lớn các gói tiêu chuẩn, bao gồm các trình biên dịch (gcc, g++), trình thông dịch (Perl, Python, Ruby), các tiện ích mạng (nc, ssh), và nhiều gói khác Sau khi càiđặt Cygwin, nhiều chương trình được viết để sử dụng trên Linux có thể được biên dịch và thực thi trên hệ thống Windows
Trong một số trường hợp, file có thể phân biệt các biến thể trong một loại tệp nhất định Danh sách dưới đây thể hiện khả năng của file trong việc xác định không chỉ một số biến thể của các tệp nhị phân ELF mà còn thông tin liên quan đến cách liên kết của tệp nhị phân (tĩnh hoặc động)
và liệu tệp nhị phân đã được loại bỏ thông tin hay không
Trang 10LOẠI BỎ CÁC BIỂU TƯỢNG TRONG TỆP NHỊ PHÂN THỰC HIỆN
Quá trình loại bỏ biểu tượng (stripping) là quá trình loại bỏ các biểu tượng khỏi tệp nhị phân Các tệp nhị phân đối tượng chứa các biểu tượng như là kết quả của quá trình biên dịch Một số trong số các biểu tượng này được sử dụng trong quá trình liên kết để giải quyết các tham chiếu giữa các tệp khi tạo ratệp thực thi hoặc thư viện cuối cùng Trong các trường hợp khác, các biểu tượng có thể tồn tại để cung cấp thông tin bổ sung cho việc sử dụng với các công cụ gỡ lỗi Sau quá trình liên kết, nhiều biểu tượng không còn cần thiết nữa Các tùy chọn được truyền cho trình liên kết có thể khiến trình liên kết loại bỏ các biểu tượng không cần thiết trong quá trình xây dựng Một cách khác, một tiện ích mang tên strip có thể được sử dụng để loại bỏ các biểu tượng từ các tệp nhị phân hiện tại Mặc dù một tệp nhị phân đã được loại bỏ sẽ nhỏ hơn so với phiên bản chưa được loại bỏ, nhưng hành vi của tệp nhị phân đã được loại bỏ sẽ không thay đổi
Các tiện ích như file và tương tự không phải là hoàn toàn đáng tin cậy Rất có khả năng một tệp nhất định bị nhận dạng sai chỉ vì nó có nhãn hiệu nhận dạng của một định dạng tệp nào đó Bạn có thể tự kiểm tra điều này bằng cách sử dụng một trình chỉnh sửa hex để sửa đổi bốn byte đầu tiên của bất kỳ tệp nào thành chuỗi số phép thuật của Java: CA FE BA BE Tiện ích file sẽ nhận dạng sai tệp mới được sửa đổi này là dữ liệu lớp Java đã được biên dịch Tương tự, một tệp văn bản chỉ chứa hai ký tự MZ sẽ được nhậndạng là một tệp thực thi MS-DOS Một cách tiếp cận tốt trong bất kỳ nỗ lực nghịch đảo nào là không bao giờ tin tưởng hoàn toàn vào đầu ra của bất kỳ công cụ nào cho đến khi bạn đã đối chiếu đầu ra đó với nhiều công cụ và phân tích thủ công
Công cụ PE Tools4
Là một bộ sưu tập các công cụ hữu ích để phân tích cả quy trình đang chạy và các tệp thực thi trên hệ thống Windows Hình 2-1 cho thấy giao diện chính của PE Tools, hiển thị một danh sách các quy trình hoạt động và cung cấp quyền truy cập đến tất cả các tiện ích của PE Tools
Trang 11Hình 2-1: Tiện ích PE Tools
Từ danh sách quy trình, người dùng có thể ghi dữ liệu hình ảnh bộ nhớ của quy trình vào một tệp hoặc sử dụng tiện ích PE Sniffer để xác định bộ biên dịch nào đã được sử dụng để xây dựng tệp thực thi hoặc xemxét liệu tệp thực thi đã được xử lý bởi bất kỳ tiện ích làm rối nào đã biết Menu Công cụ cung cấp các tùy chọn tương tự cho phân tích các tệp trên đĩa Người dùng có thể xem các trường tiêu đề PE của một tệp bằng cách sử dụng tiện ích PE Editor tích hợp, cũng cho phép dễ dàng sửa đổi bất kỳ giá trị tiêu đề nào Việc sửa đổi tiêu đề PE thường cần thiết khi cố gắng tái tạo một PE hợp lệ từ một phiên bản bị làm rối của tệp đó
PEiD5 là một công cụ Windows khác, với mục đích chính là xác định trình biên dịch đã được sử dụng để
xây dựng một tệp nhị phân Windows PE cụ thể và xác định bất kỳ công cụ nào đã được sử dụng để làm rối một tệp nhị phân Windows PE Hình 2-2 cho thấy việc sử dụng PEiD để xác định công cụ (trong trường hợp này là ASPack) được sử dụng để làm rối một biến thể của worm Gaobot
Tóm tắt về Công Cụ
Vì mục tiêu của chúng ta là nghịch đảo các tệp chương trình nhị phân, chúng ta sẽ cần những công cụ tinh
vi hơn để trích xuất thông tin chi tiết sau khi phân loại ban đầu của một tệp Các công cụ được thảo luận trong phần này, theo cách tự nhiên, hiểu rõ hơn về định dạng của các tệp mà chúng xử lý Trong hầu hết các trường hợp, những công cụ này hiểu rõ về một định dạng tệp cụ thể, và chúng được sử dụng để phân tích các tệp đầu vào để trích xuất thông tin cụ thể rất cụ thể
Trang 12PHẦN 3 Nền tảng của IDA PRO
IDA Pro, được biết đến là một Disassembler Nghệ Thuật Chuyên Nghiệp, là sản phẩm của Hex-Rays, có trụ sở tại Liège, Bỉ Được sáng tạo bởi Ilfak Guilfanov, IDA Pro xuất phát từ một ứng dụng MS-DOS console-based cách đây hơn một thập kỷ IDA Pro không chỉ là một disassembler theo chiều sâu đệ quy
mà còn sử dụng nhiều kỹ thuật heuristics để xác định mã nguồn bổ sung và loại dữ liệu Mục tiêu chính của IDA là tạo ra một hình ảnh gần với mã nguồn, với chú thích chi tiết bao gồm thông tin về loại dữ liệu,tên biến và hàm IDA Pro đã trải qua quá trình phát triển để trở thành một công cụ mạnh mẽ trong lĩnh vực nghịch đảo và phân tích mã nguồn
The Interactive Disassembler Professional, được biết đến tốt hơn và cho đến nay được biết đến là IDA Pro hoặc đơn giản là IDA, là một sản phẩm của Hex-Rays,1 nằm ở Liège, Bỉ Thiên tài lập trình đằng sau IDA là Ilfak Guilfanov, được biết đến tốt hơn với cái tên Ilfak IDA bắt đầu cuộc sống của mình hơn một thập kỷ trước dưới dạng một ứng dụng dựa trên MS-DOS, dựa trên console, điều quan trọng là nó giúp chúng ta hiểu một số điều về bản chất của giao diện người dùng của IDA Ngoài ra, các phiên bản không
có giao diện người dùng (non-GUI) của IDA được phát hành cho tất cả các nền tảng được hỗ trợ bởi IDA2 và vẫn tiếp tục sử dụng giao diện kiểu console được dẫn xuất từ các phiên bản DOS ban đầu
Ở tâm điểm của nó, IDA là một trình giải lắp đặt đệ quy; tuy nhiên, đã có một lượng lớn công sức được
bỏ vào việc phát triển logic để bổ sung quá trình giải lắp đặt đệ quy Để vượt qua một trong những hạn chế lớn của giải lắp đặt đệ quy, IDA sử dụng một số lượng lớn các kỹ thuật lược đồ để xác định mã nguồn
bổ sung có thể không được tìm thấy trong quá trình giải lắp đặt đệ quy Vượt qua quá trình giải lắp đặt đệ quy, IDA không chỉ phân biệt giữa giải lắp đặt dữ liệu và giải lắp đặt mã, mà còn xác định chính xác loại
dữ liệu đang được biểu diễn bởi những giải lắp đặt dữ liệu đó Trong khi mã bạn xem trong IDA là ngôn ngữ lập trình hợp ngữ, một trong những mục tiêu cơ bản của IDA là tạo ra một hình ảnh gần nhất có thể với mã nguồn IDA nỗ lực để chú thích các giải lắp đặt tạo ra không chỉ với thông tin kiểu dữ liệu mà còn với tên biến và hàm tạo ra từ đó Những chú thích này giảm thiểu lượng hex thô và tối đa hóa lượng thôngtin biểu tượng được trình bày cho người dùng
Sự chặt chẽ của Hex-Rays
Đối với việc sao chép trái phép sản phẩm mũi nhọn của họ, IDA, là rất rõ ràng Công ty đã quan sát được mối liên quan trực tiếp giữa việc phát hành các phiên bản IDA bị sao chép trái phép và sự giảm giá bán Những người phát hành trước đó, như DataRescue, thậm chí đã công khai xấu hổ những kẻ sao chép trái phép bằng cách liệt kê tên họ Để chống lại việc sao chép trái phép, IDA sử dụng nhiều kỹ thuật chống sao chép
Đầu tiên, mỗi bản IDA đều được đánh dấu nước, liên kết duy nhất với người mua Nếu một bản IDA xuất hiện trên các trang web không được phép, Hex-Rays có khả năng theo dõi bản sao đó về người mua gốc, người sau đó có thể bị cấm mua trong tương lai Thường xuyên có các thảo luận về bản IDA "rò rỉ" trên diễn đàn hỗ trợ của Hex-Rays
Một kỹ thuật khác liên quan đến việc quét các bản sao bổ sung của IDA đang chạy trên mạng cục bộ Khi phiên bản Windows của IDA được khởi chạy, một gói UDP được phát sóng, kiểm tra phản hồi để xem liệu có các bản IDA khác dưới cùng một khóa cấp phép trên mạng cùng một mạng con hay không Nếu phát hiện quá nhiều bản sao trên mạng, IDA có thể từ chối khởi động Lưu ý rằng việc chạy nhiều bản IDA trên cùng một máy tính với một bản quyền là được phép
Phương thức cuối cùng của việc thực thi giấy phép liên quan đến việc sử dụng các tệp khóa liên kết với mỗi người mua Khi khởi động, IDA tìm kiếm một tệp ida.key hợp lệ Việc không tìm thấy tệp khóa hợp
Trang 13lệ sẽ khiến IDA tắt ngay lập tức Tệp khóa cũng được sử dụng để xác định quyền lợi đối với các bản IDA được nâng cấp Nói một cách đơn giản, ida.key đại diện cho biên nhận mua của bạn, và bạn nên bảo vệ nó
để đảm bảo được quyền lợi cho các nâng cấp IDA trong tương lai
Thu thập IDA ProO
Đầu tiên và quan trọng nhất, IDA không phải là phần mềm miễn phí Nhóm tại Hex-Rays kiếm sống một phần thông qua việc bán IDA Có một phiên bản miễn phí với chức năng giới hạn, dành cho những người muốn làm quen với các khả năng cơ bản của nó, nhưng nó không theo kịp với các phiên bản mới nhất Phiên bản miễn phí này, được thảo luận chi tiết hơn trong Phụ lục A, là một phiên bản giản lược củaIDA 5.0 (phiên bản hiện tại là 6.1) Bên cạnh phiên bản miễn phí, Hex-Rays cũng phân phối một bản sao giới hạn chức năng của phiên bản hiện tại Nếu những đánh giá tích cực xuất hiện mọi nơi khi nói về đảo ngược kỹ thuật, không đủ để thuyết phục bạn mua một bản sao, thì thời gian dành với phiên bản miễn phí hoặc phiên bản demo sẽ giúp bạn nhận ra rằng IDA, và hỗ trợ khách hàng đi kèm, đều đáng để sở hữu
Các phiên bản IDA
Tính đến phiên bản 6.0, IDA có sẵn ở cả phiên bản GUI và console cho Windows, Linux và OS X IDA
sử dụng thư viện GUI đa nền tảng Qt để cung cấp một giao diện người dùng nhất quán trên ba nền tảng này Về mặt chức năng, IDA Pro được cung cấp ở hai phiên bản: tiêu chuẩn và nâng cao Hai phiên bản này khác nhau chủ yếu ở số lượng kiến trúc bộ xử lý mà chúng hỗ trợ giải lắp đặt Một cái nhìn nhanh vàodanh sách các bộ xử lý được hỗ trợ cho thấy rằng phiên bản tiêu chuẩn (khoảng 540 USD tính đến thời điểm viết bài) hỗ trợ hơn 30 họ gia đình xử lý, trong khi phiên bản nâng cao (với giá gần gấp đôi) hỗ trợ hơn 50 họ gia đình Các kiến trúc bổ sung được hỗ trợ trong phiên bản nâng cao bao gồm x64, AMD64, MIPS, PPC và SPARC, cùng nhiều loại khác
Giấy phép IDA
Có hai tùy chọn giấy phép khi bạn mua IDA Theo trang web của Hex-Rays: "Giấy phép có tên được liên kết với một người dùng cụ thể và có thể được sử dụng trên bất kỳ máy tính nào mà người dùng đó sử dụng," trong khi "Giấy phép máy tính được liên kết với một máy tính cụ thể và có thể được sử dụng bởi các người dùng khác nhau trên máy tính đó miễn là chỉ có một người dùng hoạt động vào mọi thời điểm."Lưu ý rằng mặc dù một giấy phép có tên cho phép bạn cài đặt phần mềm trên bất kỳ máy tính nào bạn muốn, bạn là người duy nhất có thể chạy các bản IDA đó, và đối với một giấy phép duy nhất, IDA chỉ có thể chạy trên một trong những máy tính đó vào bất kỳ thời điểm nào
Trang 14được tải Nếu bạn quên chỉ định một địa chỉ cơ sở trong quá trình tải ban đầu, bạn có thể sửa đổi địa chỉ
cơ sở của hình IDA bất kỳ lúc nào bằng cách sử dụng lệnh "Edit Segments Rebase Program."Các nút "Kernel Options" cung cấp quyền truy cập để cấu hình các tùy chọn phân tích giải lắp đặt cụ thể
mà IDA sẽ sử dụng để tăng cường quá trình giảm đệ quy Trong đa số lớn các trường hợp, các tùy chọn mặc định cung cấp giảm lắp đặt tốt nhất có thể Các tệp trợ giúp của IDA cung cấp thông tin bổ sung về các tùy chọn nhân hạt có sẵn
Nút "Processor Options" cung cấp quyền truy cập để cấu hình các tùy chọn áp dụng cho mô-đun bộ xử lý
đã chọn Tuy nhiên, tùy chọn bộ xử lý không nhất thiết có sẵn cho mọi mô-đun bộ xử lý Hỗ trợ hạn chế
có sẵn cho các tùy chọn bộ xử lý vì những tùy chọn này phụ thuộc rất nhiều vào mô-đun bộ xử lý đã chọn
và khả năng chuyên môn lập trình của tác giả mô-đun
Các hộp kiểm "Options" còn lại được sử dụng để có kiểm soát tốt hơn quá trình tải tệp Mỗi tùy chọn được mô tả thêm trong tệp trợ giúp của IDA Các tùy chọn không áp dụng cho tất cả các loại tệp đầu vào
và trong hầu hết các trường hợp, bạn có thể tin tưởng vào các lựa chọn mặc định
Tệp Cơ sở dữ liệu IDA
Khi bạn hài lòng với các tùy chọn tải của mình và nhấp OK để đóng hộp thoại, công việc thực sự của việc tải tệp bắt đầu Tại điểm này, mục tiêu của IDA là tải tệp thực thi đã chọn vào bộ nhớ và phân tích các phần liên quan Điều này dẫn đến việc tạo ra một cơ sở dữ liệu IDA với bốn tệp, mỗi tệp có tên cơ sở phù hợp với tệp thực thi đã chọn và có các phần mở rộng là id0, id1, nam và til Tệp id0 chứa nội dungcủa một cơ sở dữ liệu theo kiểu cây B, trong khi tệp id1 chứa các cờ mô tả từng byte chương trình Tệp nam chứa thông tin chỉ mục liên quan đến các vị trí chương trình có tên như hiển thị trong cửa sổ Names của IDA (được thảo luận thêm trong Chương 5) Cuối cùng, tệp til được sử dụng để lưu trữ thông tin về các định nghĩa kiểu cục bộ cụ thể cho một cơ sở dữ liệu đã chọn Các định dạng của mỗi tệp này đều thuộc sở hữu của IDA và chúng không dễ dàng chỉnh sửa bên ngoài môi trường IDA Vì sự thuận tiện, bốn tệp này được lưu trữ lại, và có thể nén, thành một tệp IDB duy nhất mỗi khi bạn đóng dự án hiệntại của mình Khi người ta nói đến cơ sở dữ liệu IDA, họ thường đang nói về tệp IDB Một tệp cơ sở dữ liệu không nén thường có kích thước khoảng 10 lần kích thước của tệp nhị phân đầu vào ban đầu Khi cơ
sở dữ liệu được đóng đúng cách, bạn không bao giờ thấy các tệp có phần mở rộng id0, id1, nam hoặc til trong thư mục làm việc của bạn Sự xuất hiện của chúng thường chỉ ra rằng một cơ sở dữ liệu không được đóng đúng cách (ví dụ, khi IDA bị sự cố) và có thể bị hỏng
Tạo Cơ sở dữ liệu IDA
Sau khi bạn đã chọn một tệp để phân tích và chỉ định các tùy chọn, IDA bắt đầu quá trình tạo cơ sở dữ liệu Trong quá trình này, IDA chuyển quyền kiểm soát cho mô-đun loader được chọn, nhiệm vụ của nó
là tải tệp từ đĩa, phân tích thông tin tiêu đề tệp mà nó có thể nhận biết, tạo các phần chương trình chứa mãhoặc dữ liệu như được chỉ định trong tiêu đề của tệp, và cuối cùng, xác định các điểm nhập cụ thể vào mã trước khi trả quyền kiểm soát lại cho IDA Liên quan đến điều này, các mô-đun loader của IDA hoạt độnggiống như cách các loader hệ điều hành hoạt động Mô-đun loader của IDA sẽ xác định bố cục bộ nhớ ảo dựa trên thông tin chứa trong tiêu đề của tệp chương trình và cấu hình cơ sở dữ liệu tương ứng Khi loader hoàn thành, bộ máy dịch trong IDA tiếp tục và bắt đầu truyền từng địa chỉ một đến mô-đun
xử lý được chọn Nhiệm vụ của mô-đun xử lý là xác định loại lệnh tại địa chỉ đó, độ dài của lệnh tại địa chỉ đó, và vị trí(s) mà việc thực hiện có thể tiếp tục từ địa chỉ đó (ví dụ, lệnh hiện tại có phải là tuần tự hay nhảy nhánh không?) Khi IDA chắc chắn rằng nó đã tìm thấy tất cả các lệnh trong tệp, nó thực hiện
Trang 15lượt điều tra thứ hai qua danh sách các địa chỉ lệnh và yêu cầu mô-đun xử lý tạo ra phiên bản ngôn ngữ lập trình hợp ngữ của mỗi lệnh để hiển thị.
Sau quá trình dịch này, IDA tự động tiến hành phân tích thêm của tệp nhị phân để trích xuất thông tin bổsung có khả năng hữu ích cho nhà phân tích Người dùng có thể mong đợi tìm thấy một số hoặc tất cả các thông tin sau đây tích hợp vào cơ sở dữ liệu sau khi IDA hoàn thành phân tích ban đầu của nó
Đóng Cơ sở dữ liệu IDA
Mọi khi bạn đóng một cơ sở dữ liệu, cho dù bạn đang đóng toàn bộ IDA hay chỉ đơn giản là chuyển sang một cơ sở dữ liệu khác, bạn sẽ nhìn thấy hộp thoại Lưu Cơ sở dữ liệu
Mở lại một Cơ sở dữ liệu
Dĩ nhiên, việc mở lại một cơ sở dữ liệu hiện có không đòi hỏi sự phức tạp như việc phát triển tên lửa,5 vì vậy bạn có thể tự hỏi tại sao chủ đề này lại được đề cập Dưới điều kiện bình thường, việc quay lại làm việc trên một cơ sở dữ liệu hiện có đơn giản như việc chọn cơ sở dữ liệu bằng một trong những phương pháp mở tệp của IDA Các tệp cơ sở dữ liệu mở nhanh chóng hơn trong lần thứ hai (và những lần sau) vì không có phân tích nào cần thực hiện Như một phần thưởng thêm, IDA khôi phục lại bàn làm việc IDA của bạn với cùng trạng thái như nó đã đóng cửa
2.2 Hiển thị Dữ liệu của IDA
I.Các Hiển thị Chính của IDA
Mặc định, IDA tạo bảy (tính đến phiên bản 6.1) cửa sổ hiển thị trong giai đoạn tải và phân tích ban đầu cho một tệp nhị phân mới Mỗi cửa sổ hiển thị này có thể truy cập thông qua một bộ thẻ tiêu đề hiển thị ngay phía dưới dải điều hướng (đã được hiển thị trước đó trong Hình 4-9) Ba cửa sổ ngay lập tức hiển thị
là cửa sổ IDA-View, cửa sổ Functions và cửa sổ Output Cho dù chúng có được mở mặc định hay không, tất cả các cửa sổ được thảo luận trong chương này có thể được mở qua menu View → Open Subviews Hãy nhớ điều này, vì khá dễ vô tình đóng các cửa sổ hiển thị
Phím ESC là một trong những phím tắt hữu ích nhất trong IDA Khi cửa sổ dịch mã đang hoạt động, phímESC hoạt động giống như nút quay lại của trình duyệt web và do đó rất hữu ích trong việc điều hướng hiển thị mã dịch (điều hướng được đề cập chi tiết trong Chương 6) Thật không may, khi bất kỳ cửa sổ nào khác đang hoạt động, phím ESC phục vụ để đóng cửa sổ Đôi khi, điều này chính là điều bạn muốn Tuy nhiên, có những lúc bạn ngay lập tức ước rằng bạn có thể khôi phục lại cửa sổ đã đóng
Trang 16II Hiển thị Phụ của IDA
Cửa sổ Hex Window
Tên Hex View có vẻ như không phù hợp trong trường hợp này, vì cửa sổ IDA Hex View có thể được cấu hình để hiển thị nhiều định dạng và đóng vai trò như một trình soạn thảo hex Mặc định, cửa sổ Hex Viewcung cấp một bản in hex tiêu chuẩn của nội dung chương trình với 16 byte trên mỗi dòng và phiên bản ASCII được hiển thị cùng bên Tương tự như cửa sổ dịch mã, có thể mở nhiều cửa sổ hex cùng một lúc Cửa sổ Hex đầu tiên có tiêu đề là Hex View-A, Hex thứ hai là Hex View-B, Hex tiếp theo là Hex View-C
và cứ tiếp tục như vậy Theo mặc định, cửa sổ Hex đầu tiên được đồng bộ với cửa sổ dịch mã đầu tiên Khi một dạng xem dịch mã được đồng bộ với một dạng xem hex, cuộn trong một cửa sổ sẽ khiến cửa sổ khác cuộn đến cùng một vị trí (cùng địa chỉ ảo) Ngoài ra, khi một mục được chọn trong dạng xem dịch
mã, các byte tương ứng sẽ được đánh dấu nổi bật trong dạng xem hex Trong hình dưới, con trỏ dạng xemdịch mã đang được đặt tại địa chỉ 0040108C, một lệnh gọi, làm cho năm byte tạo thành lệnh được đánh dấu nổi bật trong cửa sổ Hex
Các Hiển thị Tertiary IDA
Các cửa sổ cuối cùng mà chúng ta sẽ thảo luận là những cửa sổ mà IDA không mở theo mặc định Mỗi cửa sổ này có thể mở qua View → Open Subviews, nhưng chúng thường cung cấp thông tin mà bạn có thể không cần truy cập ngay lập tức và do đó ban đầu được giữ ngoài đường
Trang 17Tổng quan về IDA Text View
Cửa sổ dịch mã tập trung vào văn bản là hiển thị truyền thống được sử dụng để xem và thao tác các bảng dịch mã do IDA tạo ra Bảng hiển thị văn bản trình bày toàn bộ danh sách dịch mã của một chương trình (so với chỉ một hàm tại một thời điểm ở chế độ đồ thị) và cung cấp phương tiện duy nhất để xem các khu vực dữ liệu của một tệp nhị phân Tất cả thông tin có sẵn trong bảng hiển thị đồ thị đều có sẵn trong bảng hiển thị văn bản dưới một dạng nào đó
Khi bạn làm việc với một cơ sở dữ liệu, cửa sổ Đầu ra được sử dụng để xuất trạng thái của các hoạt động khác nhau mà bạn thực hiện Nội dung của cửa sổ Đầu ra có thể được sao chép vào clipboard hệ thống
Trang 18hoặc xóa hoàn toàn bằng cách nhấp chuột phải bất kỳ nơi nào trong cửa sổ và chọn thao tác thích hợp Cửa sổ Đầu ra thường sẽ là phương tiện chính để hiển thị đầu ra từ các kịch bản và plug-in mà bạn phát triển cho IDA.
III Các Hiển thị IDA Cấp Ba
Cửa sổ Strings là phiên bản tích hợp của IDA tương đương với tiện ích strings và nhiều tính năng khác Trong các phiên bản IDA từ 5.1 trở về trước, cửa sổ Strings được mở sẵn như một phần của giao diện người dùng mặc định; tuy nhiên, từ phiên bản 5.2 trở đi, cửa sổ Strings không còn mở sẵn theo mặc định, mặc dù vẫn có thể mở qua View → Open Subviews → Strings
Mục đích của cửa sổ Strings là hiển thị danh sách các chuỗi được trích xuất từ mã nhị phân cùng với địa chỉ mà mỗi chuỗi đó đang nằm Tương tự như việc nhấp đúp vào tên trong cửa sổ Names, việc nhấp đúp vào bất kỳ chuỗi nào được liệt kê trong cửa sổ Strings sẽ khiến cửa sổ tháo rời nhảy đến địa chỉ của chuỗi được chọn Khi sử dụng cùng với các tham chiếu chéo (Chương 9), cửa sổ Strings cung cấp cách nhanh chóng để nhận diện một chuỗi quan trọng và theo dõi ngược lại đến bất kỳ vị trí nào trong chương trình tham chiếu đến chuỗi đó Ví dụ, bạn có thể thấy chuỗi SOFTWARE\Microsoft\Windows\CurrentVersion\Run được liệt kê và muốn biết tại sao một ứng dụng đang tham chiếu đến khóa cụ thể này trong registry của Windows Như bạn sẽ thấy trong chương tiếp theo, việc di chuyển đến vị trí chương trình tham chiếu đến chuỗi này chỉ mất bốn lần nhấp chuột Hiểu cách hoạt động của cửa sổ Strings là quan trọng để sử dụng nó một cách hiệu quả
IDA không lưu trữ vĩnh viễn các chuỗi mà nó trích xuất từ mã nhị phân Do đó, mỗi khi cửa sổ Strings được mở, toàn bộ cơ sở dữ liệu phải được quét hoặc quét lại để tìm nội dung chuỗi Việc quét chuỗi được thực hiện theo cài đặt của cửa sổ Strings, và bạn có thể truy cập các cài đặt này bằng cách nhấp chuột phảitrong cửa sổ Strings và chọn Setup Như được thể hiện trong Hình 5-7, cửa sổ Setup Strings được sử dụng
để chỉ định loại chuỗi mà IDA nên quét Loại chuỗi mặc định mà IDA quét là chuỗi ASCII kiểu C, kết thúc bằng null, 7-bit, có ít nhất năm ký tự
Trang 192.3:Điều hướng Giải Mã
Trong trải nghiệm đầu tiên của bạn với IDA, bạn có thể chỉ cần sử dụng các tính năng điều hướng mà IDA cung cấp Ngoài việc cung cấp các tính năng tìm kiếm khá chuẩn
mà bạn quen thuộc từ việc sử dụng trình soạn thảo văn bản hoặc xử lý từ, IDA phát triển
và hiển thị một danh sách toàn diện các tham chiếu chéo hoạt động tương tự như các liên kết siêu văn bản trên một trang web Kết quả cuối cùng là, trong hầu hết các trường hợp, việc điều hướng đến các vị trí quan tâm không yêu cầu gì ngoài một cú nhấp đúp.Double-Click Navigation
Khi một chương trình được giải mã, mọi vị trí trong chương trình đều được gán một địa chỉ ảo Do đó, chúng ta có thể điều hướng đến bất kỳ đâu trong chương trình bằng cách cung cấp địa chỉ ảo của vị trí mà chúng ta quan tâm để truy cập Thật không may cho chúng ta, việc duy trì một danh mục địa chỉ trong đầu không phải là một nhiệm vụ đơn giản Sự thực này đã thôi thúc những lập trình viên đầu tiên gán tên biểu tượng cho các
vị trí chương trình mà họ muốn tham chiếu, làm cho mọi thứ trở nên dễ dàng hơn nhiều cho họ Việc gán tên biểu tượng cho các địa chỉ chương trình không khác gì việc gán tênlệnh ghi nhớ cho các mã lệ
Jump to Address
Đôi khi, bạn sẽ biết chính xác địa chỉ mà bạn muốn điều hướng đến, nhưng không có tênnào hiện có trong cửa sổ disassembly để đơn giản hóa việc nhấp đúp để điều hướng Trong trường hợp như vậy, bạn có một vài lựa chọn Lựa chọn đầu tiên, và cũng là cách primitve nhất, là sử dụng thanh cuộn cửa sổ disassembly để cuộn lên hoặc xuống cho đến khi vị trí mong muốn xuất hiện Thường thì điều này chỉ khả thi khi bạn biết vị trí bạnđang điều hướng đến thông qua địa chỉ ảo, vì cửa sổ disassembly được tổ chức theo thứ tự tuyến tính theo địa chỉ ảo Nếu bạn chỉ biết về một vị trí có tên như một subroutine được đặt tên là "foobar", thì việc điều hướng bằng thanh cuộn trở thành việc tìm kiếm giống như tìm kim trong đống cỏ khô Tại thời điểm đó, bạn có thể chọn sắp xếp cửa sổ Functions theo thứ tự bảng chữ cái, cuộn đến tên mong muốn và nhấp đúp
Trang 20vào tên Lựa chọn thứ ba là sử dụng một trong các tính năng tìm kiếm của IDA có sẵn qua menu Tìm kiếm, thường thì điều này liên quan đến việc xác định một số tiêu chí tìm kiếm trước khi yêu cầu IDA thực hiện tìm kiếm Trong trường hợp tìm kiếm vị trí đã biết, điều này thường là một sự lãng phí thời gian.
Stack Frames
Để hiểu và sử dụng IDA Pro, người dùng cần có kiến thức cơ bản về các khái niệm thấp hơn trong ngôn ngữ lập trình biên dịch Cuốn sách này cung cấp một số khái niệm cơ bản, trong đó có khung ngăn xếp (stack frame), một khối bộ nhớ được sử dụng trong chương trình để quản lý các lời gọi hàm cụ thể
Khi một hàm được gọi, nó cần bộ nhớ cho tham số và biến cục bộ Trình biên dịch sử dụng khung ngăn xếp để quản lý việc này, làm cho quá trình trở nên trong suốt đối với người lập trình
Các bước khi gọi hàm bao gồm:
Đặt tham số vào vị trí quy định theo quy tắc gọi hàm
Chuyển quyền điều khiển cho hàm được gọi và lưu địa chỉ trả về
Hàm được gọi cấu hình khung ngăn xếp và lưu giữ các giá trị đăng ký
Hàm được gọi cấp phát không gian cho biến cục bộ
Hàm thực hiện các hoạt động của mình, có thể trả về kết quả
Sau khi hoàn thành, hàm giải phóng không gian trên ngăn xếp
Khôi phục giá trị đăng ký và khung của người gọi
Trả quyền điều khiển cho người gọi và xóa tham số khỏi ngăn xếp
Người gọi có thể cần xóa tham số khỏi ngăn xếp
Bước 3 và 4 là phần mở đầu của hàm, còn bước 6 đến 8 là phần kết thúc của hàm Ngoại trừ bước 5, tất cả các bước này đại diện cho công đoạn gọi hàm
CHAPTER 6:DISASSEMBLY MANIPULATION
Trang 21Sau khi điều hướng, các tính năng quan trọng tiếp theo của IDA được thiết kế để cho phép bạn chỉnh sửa disassembly theo nhu cầu của bạn Trong chương này, chúng tôi sẽ chỉ ra rằng do tính chất cơ sở dữ liệu cơ bản của IDA, các thay đổi bạn thực hiện trên disassembly dễ dàng được áp dụng cho tất cả các chế độ xem con của IDA để duy trì một hình ảnh nhất quán về disassembly của bạn Một trong những tính năng mạnh mẽ nhất mà IDA cung cấp là khả năng dễ dàng chỉnh sửa disassembly để thêm thông tin mới hoặc định dạng lại danh sách để phù hợp với nhu cầu cụ thể của bạn IDA tự động
xử lý các hoạt động như tìm kiếm và thay thế toàn cục khi có ý nghĩa và làm việc không đáng kể với việc định dạng lại hướng dẫn và dữ liệu và ngược lại, tính năng không có trong các công cụ disassembly khác
LƯU Ý: Hãy nhớ rằng không có chức năng "hoàn tác" trong IDA Hãy lưu ý điều này khi bạn bắt đầu chỉnh sửa cơ sở dữ liệu Điều gần giống nhất mà bạn có thể là lưu cơ sở dữ liệu thường xuyên và quay trở lại phiên bản cơ sở dữ liệu đã lưu gần đây
Names and Naming
Tại điểm này, chúng ta đã gặp hai loại tên trong disassembly của IDA: tên liên quan đến địa chỉ ảo (vị trí có tên) và tên liên quan đến biến trong khung ngăn xếp Trong hầu hết các trường hợp, IDA sẽ tự động tạo tất cả các tên này theo các hướng dẫn đã được thảoluận trước đó IDA gọi những tên được tạo tự động như "dummy names" (tên giả).Thật không may, những tên này hiếm khi gợi ý về mục đích dự định của một vị trí hoặc biến và do đó thường không đóng góp nhiều vào sự hiểu biết về hành vi của chương trình Khi bạn bắt đầu phân tích một chương trình, một trong những cách đầu tiên và phổ biến nhất mà bạn muốn thay đổi danh sách disassembly là thay đổi tên mặc định thành các tên có ý nghĩa hơn May mắn thay, IDA cho phép bạn dễ dàng thay đổi bất kỳ tên nào và xử lý tất cả chi tiết liên quan đến việc truyền tên đã thay đổi này ra toàn bộ disassembly Trong hầu hết các trường hợp, việc thay đổi tên chỉ đơn giản là bấm chuột vào tên bạn muốn thay đổi (điều này sẽ làm nổi bật tên) và sử dụng phím tắt N để mở hộp thoại thay đổi tên Hoặc, bạn có thể nhấp chuột phải vào tên cần thay đổi và thường
sẽ xuất hiện một menu phản ứng theo ngữ cảnh chứa tùy chọn
Parameters and Local Variables
Names associated with stack variables are the simplest form of name in a disassembly listing, primarily because they are not associated with a specific virtual address and thus can never appear in the Names window As in most programming languages, such names are considered to be restricted in scope based on the function to which a given stack frame belongs Thus, every function in a program might have its own stack variable named arg_0, but no function may have more than one variable named arg_0 The dialog shown in Figure 7-1 is used to rename a stack variable
Named Locations
Việc đổi tên một vị trí đã được đặt tên hoặc thêm tên cho một vị trí chưa được đặt tên
có chút khác biệt so với việc thay đổi tên biến trong ngăn xếp Quá trình truy cập hộp thoại đổi tên tương tự (phím tắt N), nhưng có sự khác biệt nhanh chóng Hình 7-2 hiển thị hộp thoại đổi tên liên quan đến các vị trí đã được đặt tên
Trang 22Hộp thoại này cung cấp thông tin về địa chỉ bạn đang đặt tên cùng với danh sách các thuộc tính có thể được gắn liền với tên Độ dài tên tối đa chỉ là một giá trị sao chép từ một trong các tệp cấu hình của IDA (<IDADIR>/ cfg/ida.cfg) Bạn có thể tự do sử dụng tên dài hơn giá trị này, điều này sẽ khiến IDA phàn nàn một cách yếu ớt bằng cách thôngbáo bạn đã vượt quá độ dài tên tối đa và đề nghị tăng độ dài tối đa tên cho bạn Nếu bạn chọn làm như vậy, giá trị độ dài tối đa tên mới sẽ được áp dụng (một cách yếu ớt) chỉ trong cơ sở dữ liệu hiện tại Bất kỳ cơ sở dữ liệu mới nào bạn tạo ra sẽ tiếp tục được quản lý bằng độ dài tên tối đa được chứa trong tệp cấu hình.
Local name
Một tên địa phương (local name) bị giới hạn trong phạm vi của hàm hiện tại, do đó tính duy nhất của các tên địa phương chỉ được áp dụng trong một hàm cụ thể Tương tự nhưbiến địa phương (local variables), hai hàm khác nhau có thể chứa các tên địa phương giống nhau, nhưng một hàm duy nhất không thể chứa hai tên địa phương giống nhau Những vị trí có tên mà tồn tại bên ngoài giới hạn của hàm không thể được xem xét là các tên địa phương Điều này bao gồm cả các tên đại diện cho tên hàm cũng như các biến toàn cục Sử dụng phổ biến nhất cho các tên địa phương là cung cấp các tên biểu tượng cho các mục tiêu của các lệnh nhảy bên trong một hàm, chẳng hạn như các mục tiêu liên quan đến cấu trúc kiểm soát nhánh
Include in names list
Chọn tùy chọn này sẽ khiến tên được thêm vào cửa sổ "Names" (Danh sách tên), điều này có thể làm cho việc tìm kiếm tên dễ dàng hơn khi bạn muốn quay lại nó Tên được tạo tự động (dummy) mặc định sẽ không bao giờ được bao gồm trong cửa sổ "Names" (Danh sách tên)
2.4 Kiểu và dữ liệu
Trang 23Các trường hợp dễ nhất để hiểu về hành vi của các chương trình nhị phân nằm ở việc liệt kê các hàm thư viện mà chương trình gọi Một chương trình C gọi hàm connect đang tạo một kết nối mạng Một chương trình Windows gọi hàm RegOpenKey đang truy cập vào Registry của Windows Tuy nhiên, cần phân tích thêm để hiểu cách và tại sao các hàm này được gọi Để hiểu cách một hàm được gọi, cần biết các tham số nào được truyền vào hàm Trong trường hợp gọi connect, ngoài việc xác định rằng hàm đang được gọi, quan trọng biết rõ địa chỉ mạng mà chương trình đang kết nối tới Hiểu về dữ liệu được truyền vào các hàm là chìa khóa
để phân tích ngược chữ ký của một hàm (bao gồm số lượng, kiểu và thứ tự các tham
số cần thiết cho hàm), và vì vậy, làm nổi bật tầm quan trọng của việc hiểu cách các kiểu dữ liệu và cấu trúc dữ liệu được thao tác tại cấp độ ngôn ngữ lập trình hợp ngữ (assembly)
Recognizing Data Structure Use
Mặc dù các kiểu dữ liệu nguyên thủy thường phù hợp tự nhiên với kích thước của thanh ghi CPU hoặc toán tử hướng dẫn, các kiểu dữ liệu phức hợp như mảng và cấu trúc thường yêu cầu chuỗi hướng dẫn phức tạp hơn để truy cập các mục dữ liệu riêng lẻ chứa trong chúng Trước khi chúng ta có thể thảo luận về tính năng của IDA để cải thiện tính đọc của mã sử dụng các kiểu dữ liệu phức hợp, chúng ta cần xem xét mã đó trông như thế nào
Truy cập Thành viên trong Mảng Mảng là cấu trúc dữ liệu phức tạp đơn giản nhất về bố cục bộ nhớ Theo truyền thống, mảng là các khối liên tiếp trong
bộ nhớ chứa các phần tử liên tiếp cùng kiểu dữ liệu Kích thước của một mảng dễ tính, vì nó là tích của số phần tử trong mảng và kích thước của mỗi phần tử Sử dụng biểu thức C, số byte tối thiểu được tiêu thụ bởi mảng
Creating a New Structure (or Union)
Khi một chương trình dường như đang sử dụng một cấu trúc mà IDA không có thông tin về bố cục, IDA cung cấp các tính năng để chỉ định cấu trúc và cho phép cấu trúc mới được định nghĩa được tích hợp vào phần giải mã Việc tạo cấu trúc trong IDA diễn ra trong cửa sổ Cấu trúc (xem Hình 8-2) Không cấu trúc nào có thể được tích hợp vào phần giải mã cho đến khi nó được liệt kê lần đầu trong cửa sổ Cấu trúc Bất
kỳ cấu trúc nào mà IDA biết và được nhận diện là được sử dụng bởi chương trình sẽ
tự động được liệt kê trong cửa sổ Cấu trúc