测试环境:Windows XP SP3
本质:通过InlineHOOK,NtReadFile,判断参数来判断是否是自己的暗号
Ring3(应用)代码:
#include "stdio.h"
#include "windows.h"
void main(){
char buf[20] = {0};
ReadFile(-1,buf,0,0,0);
getchar();
return;
}
Ring0(驱动)头文件
#pragma once
#include "ntifs.h"
typedef NTSTATUS(*p)(
HANDLE FileHandle ,
HANDLE Event ,
PIO_APC_ROUTINE ApcRoutine ,
PVOID ApcContext ,
PIO_STATUS_BLOCK IoStatusBlock ,
PVOID Buffer ,
ULONG Length ,
PLARGE_INTEGER ByteOffset ,
PULONG Key
);
//获取NtReadFile函数地址
unsigned int GetNtReadFileAddr();
//改回原来的数据
void cancel();
//修改成jmp到自己的函数
void Modify();
//原始数据保留
extern UCHAR buf[10];
Ring0(驱动)主函数
#include "Tools.h"
VOID DriverUnload(PDRIVER_OBJECT driver) {
cancel();
DbgPrint("firts:Our driver is unloading!!\r\n");
}
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath){
DriverObject->DriverUnload = DriverUnload;
DbgPrint("first : hello ,load server!!\n");
DbgPrint("NtReadFile:%x\n" , GetNtReadFileAddr());
//保留原始数据
for(size_t i = 0; i < 10; i++) {
buf[i] = *(unsigned char*) (GetNtReadFileAddr() + i);
}
Modify();
return STATUS_SUCCESS;
}
Ring0(驱动)实现
#include "Tools.h"
UCHAR buf[10] = { 0 };
unsigned int GetNtReadFileAddr() {
unsigned int* SericeTable;
_asm {
mov eax , fs:[0x124];
mov eax , [eax + 0xe0];
mov[SericeTable] , eax;
}
return *(unsigned int*) (*SericeTable + 0xb7 * 4);
}
NTSTATUS MyNtReadFile(
HANDLE FileHandle ,
HANDLE Event ,
PIO_APC_ROUTINE ApcRoutine ,
PVOID ApcContext ,
PIO_STATUS_BLOCK IoStatusBlock ,
PVOID Buffer ,
ULONG Length ,
PLARGE_INTEGER ByteOffset ,
PULONG Key
) {
if(-1 == (unsigned int) FileHandle) {
if(NULL != Buffer) {
LPSTR str = (LPSTR) Buffer;
strcpy(str , "Hello World!\n");
}
DbgPrint("成功捕捉!\n");
}
p NtReadFile = (p) GetNtReadFileAddr();
cancel();
NTSTATUS ret = NtReadFile(FileHandle , Event , ApcRoutine , ApcContext , IoStatusBlock , Buffer , Length , ByteOffset , Key);
Modify();
return ret;
}
void Modify() {
unsigned int NtReadFile = GetNtReadFileAddr();
*(UCHAR*) NtReadFile = 0xe9;
*(unsigned int*) (NtReadFile + 1) = (unsigned int) &MyNtReadFile - GetNtReadFileAddr() - 5;
}
void cancel() {
for(size_t i = 0; i < 10; i++) {
*(unsigned char*) (GetNtReadFileAddr() + i) = buf[i];
}
}