求教:关于恢复fsd hook的问题
我想得到fsd(ntfs。sys和fastfat。sys)中IRP_MJ_SET_INFORMATION派遣函数地址,我先得到ntfs。sys的内存基址base,如下结构中的base
typedef struct tagSYSTEM_MODULE_INFORMATION {
ULONG Reserved[2];
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
这步应该没有问题,然后利用这个base,通过pe得到驱动入口driverentry地址,如下
PCHAR GetDriverEntryAddress(PCHAR BaseAddr)
{
PIMAGE_DOS_HEADER pDosHdr=NULL;
PIMAGE_NT_HEADERS pNtHdr=NULL;
PIMAGE_OPTIONAL_HEADER pOptHdr=NULL;
pDosHdr = ( PIMAGE_DOS_HEADER )BaseAddr;
if ( IMAGE_DOS_SIGNATURE == pDosHdr->e_magic )
{
pNtHdr = ( PIMAGE_NT_HEADERS )( BaseAddr + pDosHdr->e_lfanew );
if( IMAGE_NT_SIGNATURE == pNtHdr->Signature || IMAGE_NT_SIGNATURE1 == pNtHdr->Signature )
{
pOptHdr = ( PIMAGE_OPTIONAL_HEADER )( BaseAddr + pDosHdr->e_lfanew + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) );
if(pOptHdr != NULL)
{
//DebugPrint("MajorOperatingSystemVersion=0x%08x\n",pOptHdr->MajorOperatingSystemVersion);
//DebugPrint("MinorOperatingSystemVersion=0x%08x\n",pOptHdr->MinorOperatingSystemVersion);
DebugPrint("BaseAddr=0x%08x\n",BaseAddr);
DebugPrint("AddressOfEntryPoint=0x%08x\n",pOptHdr->AddressOfEntryPoint);
return BaseAddr + pOptHdr->AddressOfEntryPoint;
}
}
}
return NULL;
}
这个步骤不知道是否正确,但我调试发现版本信息输出好像没有问题,然后我利用下面函数得到需要的IRP_MJ_SET_INFORMATION派遣函数地址结果总不成功,望高手赐教,多谢!
#define SearchDepth 0x100
DWORD GetFunctionAddrByID(PCHAR pDriverEntry, BYTE MajorFunction)
{
int i=0;
DWORD function=0;
BYTE ZZ = MajorFunction*4+0x38;
//DebugPrint("ZZ=0x%08x\n",ZZ);
//DebugPrint("pDriverEntry=0x%08x\n",pDriverEntry);
if(ZZ < 0x80)
{
for (i=0;i {
//DebugPrint("0x%08x ",*(pDriverEntry+i));
//DebugPrint("0x%08x ",*(pDriverEntry+i+1));
//DebugPrint("0x%08x \n",*(pDriverEntry+i+2));
if( (*(pDriverEntry+i)==0xc7)&&
( *(pDriverEntry+i+1)==0x46 || *(pDriverEntry+i+1)==0x43 ) &&
( *(pDriverEntry+i+2)==ZZ)
)
{
DebugPrint(("GetFunctionAddrByID:0x%08x\n",pDriverEntry+i+3));
function=*(DWORD*)(pDriverEntry+i+3);
break;
}
}
}
else
{
DebugPrint(">=0x80\n");
for (i=0;i {
if( (*(pDriverEntry+i)==0xc7)&&
( *(pDriverEntry+i+1)==0x86 || *(pDriverEntry+i+1)==0x83 ) &&
( *(pDriverEntry+i+2)==ZZ)
)
{
DebugPrint(("GetFunctionAddrByID:0x%08x\n",pDriverEntry+i+3));
function=*(DWORD*)(pDriverEntry+i+3);
break;
}
}
}
return function;
}
=============================
ULONG get_funaddr(ULONG* pdriver_entry,ULONG major_function)
{
int i=0;
ULONG function=0;
ULONG index = major_function*4+0x38;
//找到所对应的函数地址
if(index < 0x80)
index = (index else
index = (index for (i=0;i {
((char*)pdriver_entry)++;
if((*pdriver_entry&0xffffff00) == index)
{
if(index < 0x8083c700)
{
DbgPrint("GetFunctionAddrByID:0x%08x\n",(ULONG)((char*)pdriver_entry+4));
function=*(ULONG*)((char*)pdriver_entry+4);
break;
}
else
{
DbgPrint("GetFunctionAddrByID:0x%08x\n",(ULONG)((char*)pdriver_entry+4));
function=*(ULONG*)((char*)pdriver_entry+7);
break;
}
}
}
return function;
}
/*
0008BE6D: 8B 3D 58 2A 02 00 MOV EDI,[00022A58]
0008BE73: C7 43 38 7A E4 02 00 MOV DWORD PTR [EBX+38],0002E47A
0008BE7A: C7 43 40 F0 B8 02 00 MOV DWORD PTR [EBX+40],0002B8F0
0008BE81: C7 43 44 A3 2F 01 00 MOV DWORD PTR [EBX+44],00012FA3
0008BE88: C7 43 48 20 03 01 00 MOV DWORD PTR [EBX+48],00010320
0008BE8F: C7 43 4C 4C EB 02 00 MOV DWORD PTR [EBX+4C],0002EB4C
0008BE96: C7 43 50 27 88 02 00 MOV DWORD PTR [EBX+50],00028827
0008BE9D: C7 43 54 95 1B 06 00 MOV DWORD PTR [EBX+54],00061B95
0008BEA4: C7 43 58 DF 1C 06 00 MOV DWORD PTR [EBX+58],00061CDF
0008BEAB: C7 43 5C DF A6 03 00 MOV DWORD PTR [EBX+5C],0003A6DF
0008BEB2: C7 43 60 B8 4F 03 00 MOV DWORD PTR [EBX+60],00034FB8
0008BEB9: C7 43 64 E6 7C 08 00 MOV DWORD PTR [EBX+64],00087CE6
0008BEC0: C7 43 68 9D 06 03 00 MOV DWORD PTR [EBX+68],0003069D
0008BEC7: C7 43 6C 28 22 03 00 MOV DWORD PTR [EBX+6C],00032228
0008BECE: C7 43 70 BB FD 04 00 MOV DWORD PTR [EBX+70],0004FDBB
0008BED5: C7 43 7C F5 BA 03 00 MOV DWORD PTR [EBX+7C],0003BAF5
0008BEDC: C7 83 80 00 00 00 91 CC 02 00 MOV DWORD PTR [EBX+00000080],0002CC91
0008BEE6: C7 83 88 00 00 00 50 AC 02 00 MOV DWORD PTR [EBX+00000088],0002AC50
0008BEF0: C7 83 8C 00 00 00 F6 FF 07 00 MOV DWORD PTR [EBX+0000008C],0007FFF6
0008BEFA: C7 43 78 12 12 02 00 MOV DWORD PTR [EBX+78],00021212
0008BF01: C7 83 9C 00 00 00 52 62 07 00 MOV DWORD PTR [EBX+0000009C],00076252
0008BF0B: C7 83 A0 00 00 00 9C 63 07 00 MOV DWORD PTR [EBX+000000A0],0007639C
0008BF15: C7 83 A4 00 00 00 C2 5E 07 00 MOV DWORD PTR [EBX+000000A4],00075EC2
0008BF1F: C7 43 28 C0 5E 02 00 MOV DWORD PTR [EBX+28],00025EC0
0008BF26: A3 04 5F 02 00 MOV [00025F04],EAX
ntfs.sys反汇编出来的东西
通过查询c7 43 xx
c7 83 xx
来找到入口 */
PVOID get_object(WCHAR* name)
{
NTSTATUS status;
UNICODE_STRING file_ntfs;
PDRIVER_OBJECT pfile_driver_object;
RtlInitUnicodeString( &file_ntfs, name);
status = ObReferenceObjectByName (
&file_ntfs,
OBJ_CASE_INSENSITIVE,
NULL,
0,
*IoDriverObjectType,
KernelMode,
NULL,
(void*)&pfile_driver_object);
if( !NT_SUCCESS(status)) {
DbgPrint("myfsd: create failed.\n");
return NULL;
}
return pfile_driver_object;
}
PVOID get_moudle(char* name)
{
NTSTATUS status;
PVOID pbuffer, pmodule;
ULONG nret_size, i, n;
PSYSTEM_MODULE_INFORMATION pmoudle_info;
pbuffer = ExAllocatePool(PagedPool, 0x1000);
if (NULL == pbuffer)
{
DbgPrint("myfsd:allocate failed: %d\n");
return NULL;
}
status = ZwQuerySystemInformation(SystemModuleInformation, pbuffer, 0x1000, &nret_size);
if (STATUS_INFO_LENGTH_MISMATCH == status)
{
// 缓冲区不够时,重新分配
ExFreePool(pbuffer);
pbuffer = ExAllocatePool(PagedPool, nret_size);
if (NULL == pbuffer)
{
DbgPrint("myfsd:localalloc failed: %d\n");
return NULL;
}
status = ZwQuerySystemInformation(SystemModuleInformation, pbuffer, nret_size, &nret_size);
}
if (!NT_SUCCESS(status))
{
DbgPrint("myfsd:systeminformation failed: %d\n");
ExFreePool(pbuffer);
return NULL;
}
pmoudle_info = (PSYSTEM_MODULE_INFORMATION)((ULONG)pbuffer + 4);
n = *(ULONG*)pbuffer;
pmodule = NULL;
// 搜索指定的模块名
for (i=0; i {
if (!_stricmp(pmoudle_info->ImageName+pmoudle_info->ModuleNameOffset, name))
{
pmodule = pmoudle_info->Base;
break;
}
pmoudle_info++;
}
ExFreePool(pbuffer);
return pmodule;
}
void init_ntfs_fun(char* name,WCHAR* link_name,ULONG* map_fun,ULONG* map_base,ULONG index)
{
PVOID base_addr,fact_addr;
ULONG cause_addr;
PDRIVER_OBJECT pdriver_obj =NULL;
base_addr = get_moudle(name);
cause_addr = (ULONG)base_addr+(ULONG)map_fun-(ULONG)map_base;
pdriver_obj = (PDRIVER_OBJECT)get_object(link_name);
fact_addr = pdriver_obj->MajorFunction[index];
if( (ULONG)fact_addr != cause_addr)//查看入口是否被改
{
DbgPrint("DriverDispatcher:0x%08x\n" ,fact_addr);
fact_addr = (PVOID)cause_addr;
pdriver_obj->MajorFunction[index] = fact_addr;
}
DbgPrint("basemoudleaddress:0x%08x\n",base_addr);
DbgPrint("causeaddr:0x%08x\n",cause_addr);
DbgPrint("factaddr:0x%08x\n" ,fact_addr);
_asm{//查看前20字节是否有变动 如果有就恢复
mov eax, cr0
and eax, NOT 10000H
mov cr0, eax
pushad
mov ecx,5
xor edx,edx
mov edi,map_fun
mov esi,fact_addr
mov eax,dword ptr[edi]
mov ebx,dword ptr[esi]
cli
again: cmp eax,ebx
jz next
mov dword ptr[esi+edx*4],eax
next: inc edx
mov eax,dword ptr[edi+4*edx]
mov ebx,dword ptr[esi+edx*4]
loopz again
sti
popad
mov eax, cr0
or eax, 10000H
mov cr0, eax
}
}
NTSTATUS init_ntfs(ULONG index)
{
UNICODE_STRING file_sys_name;
OBJECT_ATTRIBUTES ob;
NTSTATUS status;
HANDLE h_file,h_section,h_mod;
IO_STATUS_BLOCK stat;
PVOID base_address,point_address;
IMAGE_DOS_HEADER* dos_header;
IMAGE_OPTIONAL_HEADER* op_header;
ULONG img_fun_address;
ULONG* img_fun_point;
SIZE_T size=0;
file_sys_name.Length = 0;
RtlInitUnicodeString( &file_sys_name,L"\\??\\C:\\WINNT\\system32\\drivers\\ntfs.sys");
if(file_sys_name.Length == 0)
{
DbgPrint("myfsd:Unicode fails\n");
return 0;
}
InitializeObjectAttributes( &ob,&file_sys_name,
OBJ_CASE_INSENSITIVE,0, NULL );
status = ZwOpenFile ( &h_file,FILE_EXECUTE|FILE_READ_DATA, &ob, &stat, 0,0);
if( !NT_SUCCESS( status )) {
DbgPrint("fails\n");
return status;
}
ob.ObjectName = 0;
status = ZwCreateSection(&h_section, SECTION_ALL_ACCESS, &ob, 0,PAGE_EXECUTE, SEC_IMAGE, h_file);
if( !NT_SUCCESS(status)) {
DbgPrint("myfsd: Create Section failed.\n");
return status;
}
//把目标文件映射到内存
//大小根据SizeOfImage而定
status = ZwMapViewOfSection(h_section,
NtCurrentProcess(),
&base_address,
0,
0x7ffff,
0,
&size,
(SECTION_INHERIT)1,
MEM_TOP_DOWN,
PAGE_READWRITE);
if( !NT_SUCCESS(status)) {
DbgPrint("myfsd: mapviewofsection fails.\n");
ZwClose(h_file);
ZwClose(h_section);
return status;
}
h_mod = base_address;
dos_header = (IMAGE_DOS_HEADER *)h_mod;
op_header =(IMAGE_OPTIONAL_HEADER *) ((char*)h_mod+dos_header->e_lfanew+24);
DbgPrint("BaseAddress:0x%08x\n",(ULONG)base_address);
DbgPrint("EntryPoint:0x%08x\n",(LONG)op_header->AddressOfEntryPoint);
DbgPrint("ImageBase:0x%08x\n",(LONG)op_header->ImageBase);
DbgPrint("SizeOfImage:0x%08x\n",op_header->SizeOfImage);
point_address = (PVOID*)((ULONG)base_address+op_header->AddressOfEntryPoint);
DbgPrint("FunAddr:0x%08x\n",*(ULONG*)point_address);
img_fun_address = get_funaddr(point_address,index);
DbgPrint("FunAddr:0x%08x\n",img_fun_address);
img_fun_point = (ULONG*)((ULONG)base_address+img_fun_address-(LONG)op_header->ImageBase);
DbgPrint("funaddress:0x%08x\n",img_fun_point);
init_ntfs_fun("ntfs.sys",L"\\FileSystem\\Ntfs",img_fun_point,base_address,index);
ZwClose(h_file);
ZwUnmapViewOfSection(h_section, base_address);
ZwClose(h_section);
return status;
}
2000上写的 我这里没问题 可能有错 有错请告诉我。。。。。