Hướng dẫn phân tích file viết bằng Visual Basic
[h=1]Trong bài viết lần trước mình đã hướng dẫn các bạn cách reverse một chương trình viết bằng dotNET. Để tiếp tục trong bài viết này mình sẽ hướng dẫn các bạn cách phân tích file viết bằng Visual Basic. Rất mong nhận được sự quan tâm và góp ý của các bạn.[/h][h=2]I. Tổng quan về Visual Basic[/h][h=2]- Visual Basic (VB) là ngôn ngữ lập trình hướng đối tượng trực quan trên môi trường windows. Bất kể bạn là một nhà chuyên nghiệp hay là một người mới lập trình Windows, Visual Basic cung cấp cho bạn một tập hợp các công cụ hoàn chỉnh để nhanh chóng phát triển các ứng dụng.[/h][h=2]- VB có nhiều phiên bản trong đó 2 phiên bản tốt nhất là Visual Basic 6.0 và Visual Basic .Net[/h][h=2] + Visual Basic 6.0 sử dụng công nghệ COM (Common Object Model)[/h][h=2] + Visual Basic .Net sử dụng công nghệ .Net Framework.[/h]Để tìm hiểu thêm thông tin về 2 phiên bản này các bạn có thể tra google nhé hoặc có thể tham khảo 2 bài viết tại địa chỉ :
+ http://123doc.vn/document/858976-tai-lieu-tong-quan-ve-visual-basic-6-0-docx.htm?page=6
+ http://www.slideshare.net/phongchitien/visual-basic-6-ly-thuyet
Trong bài viết này mình sẽ hướng dẫn các bạn cách phân tích file viết bằng Visual Basic 6.0
[h=2]II. Reverse và debug Visual Basic Programs[/h][h=3]1. Khó khăn gặp phải khi debug một chương trình[/h]Để có thể debug một chương trình viết bằng visual basic không hề đơn giản. Nếu như bạn đã từng debug một chương trình viết bằng visual basic chắc chắn sẽ từng gặp phải những vấn đề sau :
+ Function được thực hiện của file phụ thuộc vào ngữ cảnh giao diện => khó xác định khi nào function đó được thực hiện.
+ Sử dụng API tự xây dựng, trong khi tài liệu về các API này là rất hạn chế.
+ Hàm có tham số nhưng có thể không cần push vào stack mà sử dụng 2 thanh ghi ECX và EDX để lưu giá trị của các tham số không giống như các chương trình được build bằng VC++. VD: __vbaStrCat… => rất khó quan sát giá trị các tham số của hàm khi debug động.
+ Thường sử dụng cấu trúc Object nên tham số của hàm truyền trong stack không giống như các chương trình được build bằng VC++ => khó quan sát giá trị của các tham số của hàm nếu không biết cấu trúc Object.
+ Sử dụng cách gọi lồng hàm. VD: hàm rtcShell thực hiện thực gọi hàm CreateProcess trong quá trình thực thi.
[h=3]2. Reverse và debug Visual Basic Programs[/h]- Công cụ mình sử dụng ở đây bao gồm :
+ debug tĩnh : IDA + Script, P32DASM hoặc VB Decompiler Lite
+ debug động : OllyDbg.
- Khi cho file visual basic vào trong OllyDbg lệnh đầu tiên bắt đầu từ EntryPoint của file như sau :
push offset RT_MainStruct
call ThunRTMain
tương đương với lệnh trong C:
ThunRTMain(&RT_MainStruct);
trong đó RT_MainStruct là con trỏ đến 1 cấu trúc rất lớn chứa thông tin của chương trình
Hình 1. Cấu trúc của RT_MainStruct Trong đó cấu trúc ProjectStruct là quan trọng nhất chứa địa chỉ vùng code được load lên trên mem , địa chỉ bắt đầu được lưu tại trường StartOfCode và địa chỉ kết thúc được lưu tại trường EndOfCode.
Hình 2. Cấu trúc ProjectStruct- Vùng code luôn được xác định bởi 2 dẫu hiệu :
+ Vùng bắt đầu của code luôn bắt đầu là 4 byte 0xE9 0x E9 0x E9 0xE9
và 12 byte 0xC3 ngay sau đó.
+ Kết thúc code luôn bắt đầu bởi 12 byte 0xC3 và cuối cùng là 4byte
0xE9 0xE9 0xE9 0xE9
- Dấu hiệu bắt đầu một function trong VB :
+ bắt đầu hàm là byte 0x90 hoặc 0xC3
+ ngay sau đó là cặp lệnh :
push ebp
mov ebp, esp
Hình 3. StartOfCode của file tại địa chỉ 0x40A100
Hình 4. EndOfCode của file tại địa chỉ 0x40F790è Thực hiện quét từ đầu vùng StartOfCode đến vùng EndOfCode là sẽ nhận diện được các hàm của chương trình
- Mặc dù function thực hiện đầu tiên phụ thuộc vào ngữ cảnh giao diện, nhưng do đặc thù của file virus :
+ giao diện rất đơn giản và thường set visibile là false
+ thường bắt đầu từ function form_load
è Có thể sử dụng P32DASM hoặc VB Decompiler Lite để xác định địa chỉ của function form_load
Hình 5. Xác định địa chỉ function Form_Load bằng VB Decompiler Lite- Để debug tĩnh một file viết bằng IDA chúng ta sử dụng các script hỗ trợ như :
VB5060DLLcall, vb_GetProcedure ...
Các bạn có thể vào địa chỉ [url]http://www.openrce.org/downloads/browse/IDA_Scripts[/URL] để download các script về. Sau khi thực hiện load script lên code thu được trong IDA là rất rõ ràng và dễ đọc hơn rất nhiều so với ban đầu không sử dụng script .
Hình 6. IDA trong trường hợp không sử dụng script
Hình 7. IDA trong trường hợp có sử dụng script
- Tiếp theo chúng ta sẽ nói đến cách mà một chương trình Visual Basic gọi hàm. Để có thể hiểu rõ hơn khi phân tích động một file VB bằng OllyDbg
+ C1: địa chỉ nguồn tại edx, địa chỉ đích tại ecx, kết quả tại eax
VD: __vbaStrMove, __vbaStrCat …
+ C2: đỉnh stack và các phần tử tiếp theo là các tham số của hàm, eax
lưu kết quả.
VD: __vabStrCat, rtcMsgBox, rtcFileLen …
+ C3: các tham số là các object, đỉnh stack là object nhận kết quả trả về,
các tham của hàm ngay sau phần tử đỉnh stack, eax vẫn lưu kết quả trả
về.
VD : rtcRightVarChar …
- Trong VB 1 object có cấu trúc như sau :
+00 SizeOf(RT_Text_Object)
+04 Method1
+08 Data
+0C etc (other values or methods)
Trong đó trường quan trọng nhất với chúng ta là trường Data, trường chứa dữ liệu của object đó.
- Đa số hàm khi sử dụng sau khi được trình biên dịch build ra sẽ không còn đúng tên như vậy nữa è sử dụng P32DASM để xem tên hàm chuẩn để tra cứu trên MSDN
VD: hàm FileLen() sau khi build sẽ là : rtcFileLen().
- Như mình đã nói ở phần trên, một trong những khó khăn khi phân tích file VB đó chính là việc gọi lồng hàm của Windows. Ở đây mình sẽ phân tích Một số hàm tác động đến file sử dụng cách gọi lồng API của windows trong lúc thực hiện. Các bạn khi phân tích động gặp những hàm này đơn giản có thể đặt BreakPoint tại các hàm tương ứng được gọi của Windows để có thể quan sát dễ dàng hơn :
+ rtcShell gọi hàm CreateProcess.
+ __vbaFileOpen gọi hàm CreateFile với tham số là OPEN_ALWAY.
+ rtcSetFileAttr gọi hàm SetFileAttributes .
+ __vbaGetOwner3, __vbaGet3 gọi hàm ReadFile và SetFilePointer.
+ __vbaPut3, __vbaPutOwner3 gọi hàm SetFilePointer và WriteFile.
Trên đây là một số kinh nghiệm và kiến thức mình thu được trong quá trình tìm hiểu và phân tích dịch ngược các mẫu virus viết bằng VB, hy vọng nó sẽ giúp ích cho các bạn. Bài viết còn nhiều thiếu xót, mình rất mong nhận được sự góp ý của các bạn để bài viết được hoàn chỉnh hơn.
+ http://123doc.vn/document/858976-tai-lieu-tong-quan-ve-visual-basic-6-0-docx.htm?page=6
+ http://www.slideshare.net/phongchitien/visual-basic-6-ly-thuyet
Trong bài viết này mình sẽ hướng dẫn các bạn cách phân tích file viết bằng Visual Basic 6.0
[h=2]II. Reverse và debug Visual Basic Programs[/h][h=3]1. Khó khăn gặp phải khi debug một chương trình[/h]Để có thể debug một chương trình viết bằng visual basic không hề đơn giản. Nếu như bạn đã từng debug một chương trình viết bằng visual basic chắc chắn sẽ từng gặp phải những vấn đề sau :
+ Function được thực hiện của file phụ thuộc vào ngữ cảnh giao diện => khó xác định khi nào function đó được thực hiện.
+ Sử dụng API tự xây dựng, trong khi tài liệu về các API này là rất hạn chế.
+ Hàm có tham số nhưng có thể không cần push vào stack mà sử dụng 2 thanh ghi ECX và EDX để lưu giá trị của các tham số không giống như các chương trình được build bằng VC++. VD: __vbaStrCat… => rất khó quan sát giá trị các tham số của hàm khi debug động.
+ Thường sử dụng cấu trúc Object nên tham số của hàm truyền trong stack không giống như các chương trình được build bằng VC++ => khó quan sát giá trị của các tham số của hàm nếu không biết cấu trúc Object.
+ Sử dụng cách gọi lồng hàm. VD: hàm rtcShell thực hiện thực gọi hàm CreateProcess trong quá trình thực thi.
[h=3]2. Reverse và debug Visual Basic Programs[/h]- Công cụ mình sử dụng ở đây bao gồm :
+ debug tĩnh : IDA + Script, P32DASM hoặc VB Decompiler Lite
+ debug động : OllyDbg.
- Khi cho file visual basic vào trong OllyDbg lệnh đầu tiên bắt đầu từ EntryPoint của file như sau :
push offset RT_MainStruct
call ThunRTMain
tương đương với lệnh trong C:
ThunRTMain(&RT_MainStruct);
trong đó RT_MainStruct là con trỏ đến 1 cấu trúc rất lớn chứa thông tin của chương trình
Hình 1. Cấu trúc của RT_MainStruct
Hình 2. Cấu trúc ProjectStruct
+ Vùng bắt đầu của code luôn bắt đầu là 4 byte 0xE9 0x E9 0x E9 0xE9
và 12 byte 0xC3 ngay sau đó.
+ Kết thúc code luôn bắt đầu bởi 12 byte 0xC3 và cuối cùng là 4byte
0xE9 0xE9 0xE9 0xE9
- Dấu hiệu bắt đầu một function trong VB :
+ bắt đầu hàm là byte 0x90 hoặc 0xC3
+ ngay sau đó là cặp lệnh :
push ebp
mov ebp, esp
Hình 3. StartOfCode của file tại địa chỉ 0x40A100
Hình 4. EndOfCode của file tại địa chỉ 0x40F790
- Mặc dù function thực hiện đầu tiên phụ thuộc vào ngữ cảnh giao diện, nhưng do đặc thù của file virus :
+ giao diện rất đơn giản và thường set visibile là false
+ thường bắt đầu từ function form_load
è Có thể sử dụng P32DASM hoặc VB Decompiler Lite để xác định địa chỉ của function form_load
Hình 5. Xác định địa chỉ function Form_Load bằng VB Decompiler Lite
VB5060DLLcall, vb_GetProcedure ...
Các bạn có thể vào địa chỉ [url]http://www.openrce.org/downloads/browse/IDA_Scripts[/URL] để download các script về. Sau khi thực hiện load script lên code thu được trong IDA là rất rõ ràng và dễ đọc hơn rất nhiều so với ban đầu không sử dụng script .
Hình 6. IDA trong trường hợp không sử dụng script
Hình 7. IDA trong trường hợp có sử dụng script
- Tiếp theo chúng ta sẽ nói đến cách mà một chương trình Visual Basic gọi hàm. Để có thể hiểu rõ hơn khi phân tích động một file VB bằng OllyDbg
+ C1: địa chỉ nguồn tại edx, địa chỉ đích tại ecx, kết quả tại eax
VD: __vbaStrMove, __vbaStrCat …
+ C2: đỉnh stack và các phần tử tiếp theo là các tham số của hàm, eax
lưu kết quả.
VD: __vabStrCat, rtcMsgBox, rtcFileLen …
+ C3: các tham số là các object, đỉnh stack là object nhận kết quả trả về,
các tham của hàm ngay sau phần tử đỉnh stack, eax vẫn lưu kết quả trả
về.
VD : rtcRightVarChar …
- Trong VB 1 object có cấu trúc như sau :
+00 SizeOf(RT_Text_Object)
+04 Method1
+08 Data
+0C etc (other values or methods)
Trong đó trường quan trọng nhất với chúng ta là trường Data, trường chứa dữ liệu của object đó.
- Đa số hàm khi sử dụng sau khi được trình biên dịch build ra sẽ không còn đúng tên như vậy nữa è sử dụng P32DASM để xem tên hàm chuẩn để tra cứu trên MSDN
VD: hàm FileLen() sau khi build sẽ là : rtcFileLen().
- Như mình đã nói ở phần trên, một trong những khó khăn khi phân tích file VB đó chính là việc gọi lồng hàm của Windows. Ở đây mình sẽ phân tích Một số hàm tác động đến file sử dụng cách gọi lồng API của windows trong lúc thực hiện. Các bạn khi phân tích động gặp những hàm này đơn giản có thể đặt BreakPoint tại các hàm tương ứng được gọi của Windows để có thể quan sát dễ dàng hơn :
+ rtcShell gọi hàm CreateProcess.
+ __vbaFileOpen gọi hàm CreateFile với tham số là OPEN_ALWAY.
+ rtcSetFileAttr gọi hàm SetFileAttributes .
+ __vbaGetOwner3, __vbaGet3 gọi hàm ReadFile và SetFilePointer.
+ __vbaPut3, __vbaPutOwner3 gọi hàm SetFilePointer và WriteFile.
Trên đây là một số kinh nghiệm và kiến thức mình thu được trong quá trình tìm hiểu và phân tích dịch ngược các mẫu virus viết bằng VB, hy vọng nó sẽ giúp ích cho các bạn. Bài viết còn nhiều thiếu xót, mình rất mong nhận được sự góp ý của các bạn để bài viết được hoàn chỉnh hơn.