1. Intro: Để biết được ý nghĩa của InlinePatching chúng ta cần trả lời những câu hỏi sau đây: Question: Trình đóng gói hay trình bảo vệ (packer/protector) thường làm những gì đối với chương trình gốc. Answer: Nó nén ( ASPACK/UPX) hay mã hóa (tElock/Themida) hoặc làm cả hai (ASPROTECT/ARMADILLO) đối với những đoạn mã gốc của ứng dụng. Cuối cùng nó dịch chuyển EP (EntryPoint) vào thay thế cho OEP của chương trình. Question: Vậy đoạn mã của trình đóng gói gồm những gi? Answer: 1) Định vị bộ nhớ cho riêng nó. (Có thể có) 2) Giải mã và ghi mã của anh ta lên bộ nhớ đã định vị. (tự giải mã) 3) Giải mã và ghi mã của chương trình gốc lên imagebase gốc (400000h). 4) Trong một vài trường hợp, trình bảo vệ sẽ giả cách/hoặc thay thế API. 5) Nó sửa Import Table. 6) Nhảy đến vị trí OEP. Lưu ý: giai đoạn 2 nếu xảy ra nhiều lần thì quá trình inlinepatching sẽ khó hơn. Giờ thì ta nói về lý thuyết InlinePatching cũng bằng question và answer: Question: InlinePatching là gì ? Answer: là một kỹ thuật chèn mã của ta vào một chương trình đóng gói (packer) mà không cần Unpack nó. Question: Làm thế nào để làm được điều đó? Answer: Để làm được điều này ta phải tạo một đoạn mã rồi “tiêm” vào trong đoạn mã của packer (tìm khoảng trống thích hợp mà “tiêm” heng) từ lúc mãcủa ứng dụng gốc được ghi cho đến trước khi ứng dụng gốc được thực thi. Một trong những vấn đề quan trọng trong InlinePatching là tìm giá trị CRC mà thường được tính toán bởi việc đọc file (CreateFile –ReadFile, CreateFileMaping – MapViewofFile). Question: Vậy làm thế nào để hook các hàm API? Answer: Tôi biết có 2 cách để hook hàm API: Cách đơn giản: 1* Đọc 5/6 bytes của hàm API và ghi chúng vào địa chỉ “X”. 2* Ghi một lệnh nhảy mà trỏ đến địa chỉ “X” thay vào 5/6 bytes đầu tiên của API 3* Ghi đoạn mã của chúng ta ở địa chỉ “X” + 5/6 Bytes. 4* Rồi sau cùng ghi một lệnh nhảy đến “Địa chỉ hàm API” + 5*6 Bytes Cách này không làm việc trên tất cả các API và tất cả nền Windows. Cách Khó: 1* Đọc 5/6 Bytes đầu của API, và lưu giữ nó. 2* Ghi một lệnh nhảy mà trỏ đến địa chỉ “X” thay vì thực thi 5/6 bytes đầu của của API. 3* Ghi đoạn mã của chúng ta ở “X” và sau đó thêm một vài mã để lưu giữ, và thay đổi địa chỉ trả về đến mã của ta “Y” và ghi lại 5/6 BYTES đầu của API và rồi nhảy đến API. 4* “Y” phải làm nhiệm vụ thứ 2 lần nữa sau đó nhảy đến địa chỉ gốc được trả về Rất khó nhưng làm việc trên tất cả các API và tất cả các nền Windows. Question: Vậy bạn dùng phương pháp gì? Answer: Phương pháp của tôi là sẽ chỉ cho bạn cách hook các API để chống lại CRC check và patch ứng dụng Question: Hãy chỉ tôi? Answer: BẠn nên làm các bước sau: Bước 1: làm vô hiệu CRC check, có các cách sau, các bạn có thể kết hợp: - Hook ReadFile/MapViewOfFile và ghi lại BYTEs gốc đến bộ đệm. (ASPROTECT) - Hook những lời gọi API gần nhất đến CRC check sau đó ghi lại giá trị CRC gốc thay vì CRC đã được tính toán. (chúng ta thường dùng cách này) - Đối với các trình packer mà có kiểm tra memory, chúng ta nên chỉnh sửa bộ nhớ một chút. (Themida). Bước 2: Hook những APIs khác như (GetModuleHandeA Delphi/C++, GetVersion -> C++, ThunRTMAin VB) mà sẽ được gọi ở gần OEP; patch BYTES của chúng ta. (Trong một vài trường hợp bạn phải tạo ra một biến đếm để xem xét những lời gọi này để tiến gần tới OEP.) Trong những packers mà không có Import Elimination, bạn cũng có thể so sánh giá trị địa chỉ trả về của GetModuleHandleA với “CodeSectionAddress+CodeSectionSize” Bây giờ chúng ta hãy thực hành một chút với một vài đích: Ừm, tôi chỉ dịch 2 cái đầu thôi, vì tôi thấy nó rất cơ bản. Mở đích của chúng ta với ToPo…. (người dịch không rõ lắm là tiện ích gì, nhưng có lẽ là tiện ích dùng dể kiểm tra các section. Ok, 815 Bytes là khá đủ ! Vì thế chúng ta sử dụng section trên đang tồn tại. Không gian còn trống ở vị trí 4898D1 … vì thế hãy thay đổi EP thành 89898D1: Hãy nghĩ bạn sẽ làm gì cho trường hợp này: 1, Không gian trống sẽ thay đổi bởi ASPR, vì thế phải cài đặt bộ nhớ cho riêng cái hook của chúng ta. 2, Sau đó ghi đoạn mã của ta vào bộ nhớ được cấp phát: 3, Hook “MapViewOfFile” để vô hiệu CRC: Thay đổi Access code thành 1 (File_Map_Copy) để làm cho nó có thể thay đổi được. … Thay đổi địa chỉ trả về từ MapViewOfFile đến mã của chúng ta (Sau khi MapVewOfFile thực thi ,chúng ta phải patch bộ đệm của nó (trong EAX)…. Sau đó, sau khi nó so sánh EP của Maped File với EP của chúng ta (898D1), chúng ta sẽ ghi lại OEP của trình packer (1000) để sửa CRC. 4, Hook GetModuleHandleA để patch nag screen: Lời gọi GetModuleHandleA đầu tiên có tham số hModule là NULL trên section mã của tôi, rồi căn cứ trên đoạn mã gốc của ứng dụng, có nghĩa là căn cứ mã ứng dụng đã được unpack trong bộ nhớ bởi mã của trình packers và đây là thời điểm rất tốt để patch. . Answer: 1) Định vị bộ nhớ cho riêng nó. (Có thể có) 2) Giải mã và ghi mã của anh ta lên bộ nhớ đã định vị. (tự giải mã) 3) Giải mã và ghi mã của chương trình gốc lên imagebase gốc ( 400 000 h) Sau đó, sau khi nó so sánh EP của Maped File với EP của chúng ta (898D1), chúng ta sẽ ghi lại OEP của trình packer ( 10 00) để sửa CRC. 4, Hook GetModuleHandleA để patch nag screen: Lời gọi. tra các section. Ok, 815 Bytes là khá đủ ! Vì thế chúng ta sử dụng section trên đang tồn tại. Không gian còn trống ở vị trí 4898D1 … vì thế hãy thay đổi EP thành 89898D1: Hãy nghĩ bạn sẽ làm