Kỹ thuật biến đổi nhân của Windows – Phần 2 : Nghệ thuật gây đột biến mã(3).
Link gốc: http://hardsoftvn.wordpress.com/category/bai-phan-tich-h%C6%B0%E1%BB%9Bng-d%E1%BA%ABn/
-Trong bài này , tôi sẽ bàn về kỹ thuật gậy đột biến bảng IDT (Interrupt Descriptor Table) (tạm dịch là bảng mô tả các ngắt) . Ngắt là từ dùng để chỉ cơ chế mà hệ điều hành dùng để gây đột biến một tiến trình bất kỳ (đúng vậy , hệ điều hành cũng muốn chiếm quyền kiểm soát một tiến trình nào đó khi nó thấy cần ), Có ba loại ngắt là : ngắt phần mềm , ngắt phần cứng và ngắt ngoại lệ .
-Ngắt phần cứng do nhà sản xuất quy định . Ví dụ : bất cứ khi nào một tiến trình nhập xuất hòan thành thì một ngắt phần cứng sẽ xảy ra. Ở đây chúng ta sẽ không quan tâm tới lọai ngắt này .
- Ngắt phần mềm là kết quả của một yêu cầu giúp đỡ từ phần mềm đến hệ điều hành . Phần mềm khi muốn tiếp xúc với dịch vụ hệ thống (đã nói ở bài trước) sẽ thông qua ngắt này . Điều này có nghĩa là ngắt sẽ được gọi trước khi bất kỳ dịch vụ hệ thống nào được gọi.
- Ngắt ngọai lệ xảy ra khi một tiến trình thực thi một lệnh bất hợp pháp như lấy 1 số chia cho 0 .
- Lệnh SIDT dùng để xác định vị trí của bảng IDT , giá trị trả về là cấu trúc IDTINFO
////////////////////////////////////////////////////////////////////////////
typedef struct
{
WORD IDTLimit;
WORD LowIDTbase;
WORD HiIDTbase;
} IDTINFO;
#define MAKELONG(a, b)((LONG)(((WORD)(a))|((DWORD)((WORD)(b)))
////////////////////////////////////////////////////////////////////////////
-Sau đây là mã nguồn của hàm dùng để gây đột biến của fuzen_op . Nó sẽ thay địa chỉ của hàm 0×2e (hàm dùng để đảm nhận ngắt phần mềm) bằng địa chỉ của một hàm do ta định sẵn :
////////////////////////////////////////////////////////////////////////////
DWORD KiRealSystemServiceISR_Ptr; // biến lưu địa chỉ của hàm 0×2e thật
#define NT_SYSTEM_SERVICE_INT 0×2e
int HookInterrupts()
{
IDTINFO idt_info;
IDTENTRY* idt_entries;
IDTENTRY* int2e_entry;
__asm{
sidt idt_info;
}
idt_entries =
(IDTENTRY*)MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);
KiRealSystemServiceISR_Ptr = // Lưu địa chỉ của hàm 2
MAKELONG(idt_entries[NT_SYSTEM_SERVICE_INT].LowOffset,
idt_entries[NT_SYSTEM_SERVICE_INT].HiOffset);
int2e_entry = &(idt_entries[NT_SYSTEM_SERVICE_INT]);
__asm{
cli; // Ngưng ngắt
lea eax,MyKiSystemService; // Lưu địa chỉ của hàm đột biến vào thanh ghi EAX
mov ebx, int2e_entry; // Lưu địa chỉ của hàm 0×2e vào thanh ghi EBX
mov [ebx],ax; // Ghi đè địa chỉ của hàm 0×2e bằng địa chỉ của hàm đột biến
shr eax,16
mov [ebx+6],ax;
sti; // Kích họat ngắt
}
return 0;
}
////////////////////////////////////////////////////////////////////////////
-Bây giờ bạn đã có thể gây đột biến bảng IDT . Từ đây bạn có thể theo dõi và ngăn chặn bất cứ yêu cầu sử dụng dịch vụ hệ thống nào từ vòng số 3 . Nên nhớ : số thứ tự của dịch vụ hệ thống(nhờ số này có thể lần ra tên của dịch vụ và chức năng của nó ) đang được yêu cầu sẽ được lưu trong thanh ghi EAX . Bạn có thể biết được tiến trình nào đang gọi bằng hàm PsGetCurrentProcess. Sau đây là ví dụ về hàm đột biến :
////////////////////////////////////////////////////////////////////////////
__declspec(naked) MyKiSystemService()
{
__asm{
pushad
pushfd
push fs
mov bx,0×30
mov fs,bx
push ds
push es
// Đặt mã xử lý thông tin vào đây
Finish:
pop es
pop ds
pop fs
popfd
popad
jmp KiRealSystemServiceISR_Ptr; // Gọi hàm 0×2e
}
}
////////////////////////////////////////////////////////////////////////////
- Mã nguồn của ví dụ gây đột biến bảng IDT (Win 2000) có thể tải ở đây : www.rootkit.com/vault/fuzen_op/strace_Fuzen.zip , dành cho win xp ở đây : www.rootkit.com/vault/fuzen_op/SysEnterHook.zip
- Đăng bởi Trần Hữu Đăng Khoa