上节课说了对DbgkpProcessDebugPortMutex的修改会导致调试器卡死的问题。由于时间原因导致了我没有写代码实现如何处理它,那么本帖就详细介绍下这个东西该如何处理才好。
首先我的思路是替换掉这个内核变量,也就是说只要引用这个变量的位置的地方我都要替换掉。
内核中引用DbgkpProcessDebugPortMutex这个内核变量的地方很多,win7下面大概有十几处,这就给替换带来了麻烦。如果自己搜索所有特征码进行定位的话工作量是比较繁琐的。
为了节省代码量,我想到一个有趣的办法。
大家应该还记得当初重载内核时候写的重定位基址的功能吧。对了,说到这里可能有人就明白怎么回事儿了。因为DbgkpProcessDebugPortMutex 也是要重定位的一个东西,所以我们就可以在重定位基址那个函数里面获取到内核中有多少个地方的代码要重定位DbgkpProcessDebugPortMutex ,那么就能确定内核中所有访问DbgkpProcessDebugPortMutex 的代码了。
好了,下面我们看看代码把。
首先是初始化函数:- BOOLEAN InitCreateNewFastMutex(PDRIVER_OBJECT pDriver)
- {
- ULONG u_address;
- PLDR_DATA_TABLE_ENTRY pkernel_module;
-
- //这是我随便找的一点定位DbgkpProcessDebugPortMutex的特征码
- /*
- 83e67ac1 83bf9000000000 cmp dword ptr [edi+90h],0
- 83e67ac8 0f848c010000 je nt!DbgkCopyProcessDebugPort+0x1ba (83e67c5a)
- 83e67ace b101 mov cl,1
- 83e67ad0 ff155c61c183 call dword ptr [nt!_imp_KfRaiseIrql (83c1615c)]
- 83e67ad6 bea0c9d783 mov esi,offset nt!DbgkpProcessDebugPortMutex (83d7c9a0)
- */
- SignatureInfo Signature[5] = {{0xBF,20},{0x0F,14},{0xB1, 8},{0xFF, 6},{0xBE, 0}};
-
- pkernel_module = SearchDriver(pDriver,L"ntoskrnl.exe");
- if (!MmIsAddressValid(pkernel_module)){
- return FALSE;
- }
-
- //SearchAddress函数是自己写的一个定位特征码的函数
- u_address = SearchAddress(\
- (ULONG)pkernel_module->DllBase,\
- pkernel_module->SizeOfImage,\
- Signature);
-
- if (!MmIsAddressValid((PVOID)u_address))
- {
- //得到了原始的DbgkpProcessDebugPortMutex
- g_DbgkpProcessDebugPortMutex = *(ULONG*)(u_address+1);
- }
-
- //我们这里复制原始DbgkpProcessDebugPortMutex的内容到新定义的DbgkpProcessDebugPortMutex
- RtlCopyMemory(g_new_fast_mutex,(PVOID)g_DbgkpProcessDebugPortMutex,0x20);
- return TRUE;
- }
复制代码 那么怎么搜索所有的DbgkpProcessDebugPortMutex呢,我们看下面的代码:- void RelocModule(PVOID pNewImage,PVOID pOrigImage)
- {
- ULONG uIndex,uCount;
- ULONG uRelocTableSize;
- USHORT TypeValue;
- USHORT *pwOffsetArrayAddress;
- ULONG uTypeOffsetArraySize;
-
- ULONG uRelocOffset;
-
- ULONG uRelocAddress;
-
- PIMAGE_DOS_HEADER pImageDosHeader;
- PIMAGE_NT_HEADERS pImageNtHeader;
- IMAGE_DATA_DIRECTORY ImageDataDirectory;
- IMAGE_BASE_RELOCATION *pImageBaseRelocation;
-
- pImageDosHeader = (PIMAGE_DOS_HEADER)pNewImage;
- pImageNtHeader = (PIMAGE_NT_HEADERS)((ULONG)pNewImage + pImageDosHeader->e_lfanew);
-
- uRelocOffset = (ULONG)pOrigImage - pImageNtHeader->OptionalHeader.ImageBase;
-
- ImageDataDirectory = pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
-
- pImageBaseRelocation = (PIMAGE_BASE_RELOCATION)(ImageDataDirectory.VirtualAddress + (ULONG)pNewImage);
- uRelocTableSize = ImageDataDirectory.Size;
-
- uCount = 0;
-
- while(uRelocTableSize)
- {
- uTypeOffsetArraySize = (pImageBaseRelocation->SizeOfBlock - sizeof(ULONG)*2) / sizeof(USHORT);
-
- pwOffsetArrayAddress = pImageBaseRelocation->TypeOffset;
- for (uIndex = 0;uIndex<uTypeOffsetArraySize;uIndex++)
- {
- TypeValue = pwOffsetArrayAddress[uIndex];
- if (TypeValue>>12==IMAGE_REL_BASED_HIGHLOW)
- {
- uRelocAddress = (TypeValue&0xfff)+pImageBaseRelocation->VirtualAddress + (ULONG)pNewImage;
- if (!MmIsAddressValid((PVOID)uRelocAddress))
- {
- continue;
- }
-
- *(ULONG*)uRelocAddress += uRelocOffset;
- //g_fast_mutex_pointer是个数组,每个元素代表要修改的位置,我系统中所有用到DbgkpProcessDebugPortMutex不超过12个
- if (*(ULONG*)uRelocAddress==g_DbgkpProcessDebugPortMutex&&uCount<12)
- {
- g_fast_mutex_pointer[uCount] = uRelocAddress;
- uCount++;
- }
- }
- }
-
- uRelocTableSize -= pImageBaseRelocation->SizeOfBlock;
- pImageBaseRelocation = (IMAGE_BASE_RELOCATION *)(\
- (ULONG)pImageBaseRelocation + pImageBaseRelocation->SizeOfBlock);
- }
- }
复制代码 接下来就是修改和恢复了。我上所有代码吧。- #include "ntddk.h"
- #include "ntimage.h"
-
- #define __Max(a,b) a>b?a:b
-
- typedef struct _LDR_DATA_TABLE_ENTRY {
- LIST_ENTRY InLoadOrderLinks;
- LIST_ENTRY InMemoryOrderLinks;
- LIST_ENTRY InInitializationOrderLinks;
- PVOID DllBase;
- PVOID EntryPoint;
- ULONG SizeOfImage;
- UNICODE_STRING FullDllName;
- UNICODE_STRING BaseDllName;
- ULONG Flags;
- USHORT LoadCount;
- USHORT TlsIndex;
- union {
- LIST_ENTRY HashLinks;
- struct {
- PVOID SectionPointer;
- ULONG CheckSum;
- };
- };
- union {
- struct {
- ULONG TimeDateStamp;
- };
- struct {
- PVOID LoadedImports;
- };
- };
- } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
-
- typedef struct _SignatureInfo{
- UCHAR cSingature;
- int Offset;
- }SignatureInfo,*pSignatureInfo;
-
- //global
- ULONG g_DbgkpProcessDebugPortMutex;
- UCHAR g_new_fast_mutex[0x20];
- ULONG g_fast_mutex_pointer[12];
-
- PVOID g_new_kernel_pointer;
-
- ULONG g_kernel_increment;
-
- void PageProtectOn()
- {
- __asm{//恢复内存保护
- mov eax,cr0
- or eax,10000h
- mov cr0,eax
- sti
- }
- }
-
- void PageProtectOff()
- {
- __asm{//去掉内存保护
- cli
- mov eax,cr0
- and eax,not 10000h
- mov cr0,eax
- }
- }
-
- PLDR_DATA_TABLE_ENTRY SearchDriver(PDRIVER_OBJECT pDriverObject,wchar_t *strDriverName)
- {
- LDR_DATA_TABLE_ENTRY *pDataTableEntry,*pTempDataTableEntry;
- PLIST_ENTRY pList;
- UNICODE_STRING usModuleName;
-
- RtlInitUnicodeString(&usModuleName,strDriverName);
-
- pDataTableEntry = (LDR_DATA_TABLE_ENTRY*)pDriverObject->DriverSection;
- if (!pDataTableEntry)
- {
- return 0;
- }
-
- pList = pDataTableEntry->InLoadOrderLinks.Flink;
-
- while(pList!= &pDataTableEntry->InLoadOrderLinks)
- {
- pTempDataTableEntry = (LDR_DATA_TABLE_ENTRY *)pList;
-
- KdPrint(("%wZ",&pTempDataTableEntry->BaseDllName));
- if (0==RtlCompareUnicodeString(&pTempDataTableEntry->BaseDllName,&usModuleName,FALSE))
- {
- return pTempDataTableEntry;
- }
-
- pList = pList->Flink;
- }
-
- return 0;
- }
-
- ULONG SearchAddress(ULONG uStartBase,ULONG uSearchLength,SignatureInfo DebugProtInfo[5])
- {
- UCHAR *p;
- ULONG uIndex1,uIndex2;
-
- //ULONG uIndex;
- PIMAGE_DOS_HEADER pDosHeader;
- PIMAGE_NT_HEADERS pNtHeader;
- PIMAGE_SECTION_HEADER pSecHeader;
-
- if(!MmIsAddressValid((PVOID)uStartBase))
- { return 0; }
-
- pDosHeader = (PIMAGE_DOS_HEADER)uStartBase;
- pNtHeader = (PIMAGE_NT_HEADERS)((ULONG)uStartBase+pDosHeader->e_lfanew);
- pSecHeader = (PIMAGE_SECTION_HEADER)((ULONG)pNtHeader+sizeof(IMAGE_NT_HEADERS));
-
- for (uIndex1 = 0;uIndex1<pNtHeader->FileHeader.NumberOfSections;uIndex1++)
- {
- if (pSecHeader[uIndex1].Characteristics&0x60000000)
- {
- //可读可写的段
- //DbgPrint("SectionName:%s----0x%X----0x%X",pSecHeader[uIndex1].Name,\
- // pSecHeader[uIndex1].Misc.VirtualSize,uStartBase+pSecHeader[uIndex1].VirtualAddress);
- p = (UCHAR*)uStartBase + pSecHeader[uIndex1].VirtualAddress;
- for (uIndex2 = 0;uIndex2<pSecHeader[uIndex1].Misc.VirtualSize;uIndex2++)
- {
- if (!MmIsAddressValid((p-DebugProtInfo[0].Offset))||
- !MmIsAddressValid((p-DebugProtInfo[4].Offset)))
- {
- p++;
- continue;
- }
- __try{
- if (*(p-DebugProtInfo[0].Offset)==DebugProtInfo[0].cSingature&&
- *(p-DebugProtInfo[1].Offset)==DebugProtInfo[1].cSingature&&
- *(p-DebugProtInfo[2].Offset)==DebugProtInfo[2].cSingature&&
- *(p-DebugProtInfo[3].Offset)==DebugProtInfo[3].cSingature&&
- *(p-DebugProtInfo[4].Offset)==DebugProtInfo[4].cSingature)
- {
- return (ULONG)p;
- }
-
- }__except(EXCEPTION_EXECUTE_HANDLER){
- DbgPrint("11111111111111111111111111111111");
- }
- p++;
- }
- }
- }
-
- return 0;
- }
-
- BOOLEAN InitCreateNewFastMutex(PDRIVER_OBJECT pDriver)
- {
- ULONG u_address;
- PLDR_DATA_TABLE_ENTRY pkernel_module;
-
- /*
- 83e67ac1 83bf9000000000 cmp dword ptr [edi+90h],0
- 83e67ac8 0f848c010000 je nt!DbgkCopyProcessDebugPort+0x1ba (83e67c5a)
- 83e67ace b101 mov cl,1
- 83e67ad0 ff155c61c183 call dword ptr [nt!_imp_KfRaiseIrql (83c1615c)]
- 83e67ad6 bea0c9d783 mov esi,offset nt!DbgkpProcessDebugPortMutex (83d7c9a0)
- */
- SignatureInfo Signature[5] = {{0xBF,20},{0x0F,14},{0xB1, 8},{0xFF, 6},{0xBE, 0}};
-
- pkernel_module = SearchDriver(pDriver,L"ntoskrnl.exe");
- if (!MmIsAddressValid(pkernel_module)){
- return FALSE;
- }
-
- u_address = SearchAddress(\
- (ULONG)pkernel_module->DllBase,\
- pkernel_module->SizeOfImage,\
- Signature);
-
- if (!MmIsAddressValid((PVOID)u_address))
- {
- g_DbgkpProcessDebugPortMutex = *(ULONG*)(u_address+1);
- }
-
- RtlCopyMemory(g_new_fast_mutex,(PVOID)g_DbgkpProcessDebugPortMutex,0x20);
- return TRUE;
- }
-
- VOID SetNewFastMutex(PDRIVER_OBJECT pDriver)
- {
- ULONG Index;
- if (InitCreateNewFastMutex(pDriver))
- {
- PageProtectOff();
-
- for (Index = 0;Index<11;Index++)
- {
- *(ULONG*)(g_fast_mutex_pointer[Index]) = (ULONG)g_new_fast_mutex;
- *(ULONG*)(g_fast_mutex_pointer[Index] - g_kernel_increment) = (ULONG)g_new_fast_mutex;
- }
-
- PageProtectOn();
- }
- }
-
- VOID ResOldFastMutex()
- {
- ULONG Index;
- if (g_DbgkpProcessDebugPortMutex)
- {
- PageProtectOff();
-
- for (Index = 0;Index<11;Index++)
- {
- *(ULONG*)(g_fast_mutex_pointer[Index]) = g_DbgkpProcessDebugPortMutex;
- *(ULONG*)(g_fast_mutex_pointer[Index] - g_kernel_increment) = g_DbgkpProcessDebugPortMutex;
- }
-
- PageProtectOn();
- }
- }
-
- //////////////////////////////////////////////////////////////////////////
- void RelocModule(PVOID pNewImage,PVOID pOrigImage)
- {
- ULONG uIndex,uCount;
- ULONG uRelocTableSize;
- USHORT TypeValue;
- USHORT *pwOffsetArrayAddress;
- ULONG uTypeOffsetArraySize;
-
- ULONG uRelocOffset;
-
- ULONG uRelocAddress;
-
- PIMAGE_DOS_HEADER pImageDosHeader;
- PIMAGE_NT_HEADERS pImageNtHeader;
- IMAGE_DATA_DIRECTORY ImageDataDirectory;
- IMAGE_BASE_RELOCATION *pImageBaseRelocation;
-
- pImageDosHeader = (PIMAGE_DOS_HEADER)pNewImage;
- pImageNtHeader = (PIMAGE_NT_HEADERS)((ULONG)pNewImage + pImageDosHeader->e_lfanew);
-
- uRelocOffset = (ULONG)pOrigImage - pImageNtHeader->OptionalHeader.ImageBase;
-
- ImageDataDirectory = pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
-
- pImageBaseRelocation = (PIMAGE_BASE_RELOCATION)(ImageDataDirectory.VirtualAddress + (ULONG)pNewImage);
- uRelocTableSize = ImageDataDirectory.Size;
-
- uCount = 0;
-
- while(uRelocTableSize)
- {
- uTypeOffsetArraySize = (pImageBaseRelocation->SizeOfBlock - sizeof(ULONG)*2) / sizeof(USHORT);
-
- pwOffsetArrayAddress = pImageBaseRelocation->TypeOffset;
- for (uIndex = 0;uIndex<uTypeOffsetArraySize;uIndex++)
- {
- TypeValue = pwOffsetArrayAddress[uIndex];
- if (TypeValue>>12==IMAGE_REL_BASED_HIGHLOW)
- {
- uRelocAddress = (TypeValue&0xfff)+pImageBaseRelocation->VirtualAddress + (ULONG)pNewImage;
- if (!MmIsAddressValid((PVOID)uRelocAddress))
- {
- continue;
- }
-
- *(ULONG*)uRelocAddress += uRelocOffset;
- if (*(ULONG*)uRelocAddress==g_DbgkpProcessDebugPortMutex&&uCount<12)
- {
- g_fast_mutex_pointer[uCount] = uRelocAddress;
- uCount++;
- }
- }
- }
-
- uRelocTableSize -= pImageBaseRelocation->SizeOfBlock;
- pImageBaseRelocation = (IMAGE_BASE_RELOCATION *)(\
- (ULONG)pImageBaseRelocation + pImageBaseRelocation->SizeOfBlock);
- }
- }
-
- NTSTATUS ReadFileToMemory(wchar_t *strFileName,PVOID *lpVirtualAddress,PVOID pOrigImage)
- {
- NTSTATUS Status;
- HANDLE hFile;
- LARGE_INTEGER FileOffset;
- UNICODE_STRING usFileName;
- OBJECT_ATTRIBUTES ObjAttr;
- IO_STATUS_BLOCK IoStatusBlock;
-
- IMAGE_DOS_HEADER ImageDosHeader;
- IMAGE_NT_HEADERS ImageNtHeader;
- IMAGE_SECTION_HEADER *pImageSectionHeader;
-
- ULONG uIndex;
- PVOID lpVirtualPointer;
- ULONG SecVirtualAddress,SizeOfSection;
- ULONG PointerToRawData;
-
- if (!MmIsAddressValid(strFileName))
- {
- return STATUS_UNSUCCESSFUL;
- }
-
- RtlInitUnicodeString(&usFileName,strFileName);
-
- InitializeObjectAttributes(\
- &ObjAttr,\
- &usFileName,\
- OBJ_CASE_INSENSITIVE,\
- NULL,\
- NULL);
-
- Status = ZwCreateFile(\
- &hFile,\
- FILE_ALL_ACCESS,\
- &ObjAttr,\
- &IoStatusBlock,\
- NULL,\
- FILE_ATTRIBUTE_NORMAL,\
- FILE_SHARE_READ,\
- FILE_OPEN,\
- FILE_NON_DIRECTORY_FILE,\
- NULL,\
- 0);
- if (!NT_SUCCESS(Status))
- {
- KdPrint(("ZwCreateFile failed:%X",Status));
- return Status;
- }
-
- FileOffset.QuadPart = 0;
- Status = ZwReadFile(\
- hFile,\
- NULL,\
- NULL,\
- NULL,\
- &IoStatusBlock,\
- &ImageDosHeader,\
- sizeof(IMAGE_DOS_HEADER),\
- &FileOffset,\
- NULL);
- if (!NT_SUCCESS(Status))
- {
- KdPrint(("read iamge_dos_header failed:%X",Status));
- ZwClose(hFile);
- return Status;
- }
-
- FileOffset.QuadPart = ImageDosHeader.e_lfanew;
- Status = ZwReadFile(\
- hFile,\
- NULL,\
- NULL,\
- NULL,\
- &IoStatusBlock,\
- &ImageNtHeader,\
- sizeof(IMAGE_NT_HEADERS),\
- &FileOffset,\
- NULL);
- if (!NT_SUCCESS(Status))
- {
- KdPrint(("read IMAGE_NT_HEADERS failed:%X",Status));
- ZwClose(hFile);
- return Status;
- }
-
- pImageSectionHeader = ExAllocatePool(\
- NonPagedPool,\
- sizeof(IMAGE_SECTION_HEADER)*ImageNtHeader.FileHeader.NumberOfSections);
- if (pImageSectionHeader==0)
- {
- KdPrint(("pImageSectionHeader is null."));
- ZwClose(hFile);
- return STATUS_UNSUCCESSFUL;
- }
-
- FileOffset.QuadPart += sizeof(IMAGE_NT_HEADERS);
- Status = ZwReadFile(\
- hFile,\
- NULL,\
- NULL,\
- NULL,\
- &IoStatusBlock,\
- pImageSectionHeader,\
- sizeof(IMAGE_SECTION_HEADER)*ImageNtHeader.FileHeader.NumberOfSections,\
- &FileOffset,\
- NULL);
- if (!NT_SUCCESS(Status))
- {
- KdPrint(("read IMAGE_SECTION_HEADER failed:%X",Status));
- ExFreePool(pImageSectionHeader);
- ZwClose(hFile);
- return Status;
- }
-
- lpVirtualPointer = ExAllocatePool(NonPagedPool,ImageNtHeader.OptionalHeader.SizeOfImage);
- if (lpVirtualPointer==0)
- {
- KdPrint(("lpVirtualPointer is null"));
- ExFreePool(pImageSectionHeader);
- ZwClose(hFile);
- return STATUS_UNSUCCESSFUL;
- }
-
- memset(lpVirtualPointer,0,ImageNtHeader.OptionalHeader.SizeOfImage);
- RtlCopyMemory(\
- lpVirtualPointer,\
- &ImageDosHeader,\
- sizeof(IMAGE_DOS_HEADER));
- RtlCopyMemory(\
- (PVOID)((ULONG)lpVirtualPointer+ImageDosHeader.e_lfanew),\
- &ImageNtHeader,\
- sizeof(IMAGE_NT_HEADERS));
- RtlCopyMemory(\
- (PVOID)((ULONG)lpVirtualPointer+ImageDosHeader.e_lfanew+sizeof(IMAGE_NT_HEADERS)),\
- pImageSectionHeader,
- sizeof(IMAGE_SECTION_HEADER)*ImageNtHeader.FileHeader.NumberOfSections);
-
- for (uIndex = 0;uIndex<ImageNtHeader.FileHeader.NumberOfSections;uIndex++)
- {
- SecVirtualAddress = pImageSectionHeader[uIndex].VirtualAddress;
- SizeOfSection = __Max(pImageSectionHeader[uIndex].SizeOfRawData,\
- pImageSectionHeader[uIndex].Misc.VirtualSize);
-
- PointerToRawData = pImageSectionHeader[uIndex].PointerToRawData;
-
- FileOffset.QuadPart = PointerToRawData;
- Status = ZwReadFile(\
- hFile,\
- NULL,\
- NULL,\
- NULL,\
- &IoStatusBlock,\
- (PVOID)((ULONG)lpVirtualPointer+SecVirtualAddress),\
- SizeOfSection,\
- &FileOffset,\
- NULL);
- if (!NT_SUCCESS(Status))
- {
- KdPrint(("read failed is pImageSectionHeader[%d]",uIndex));
- ExFreePool(pImageSectionHeader);
- ExFreePool(lpVirtualPointer);
- ZwClose(hFile);
- return Status;
- }
- }
-
- RelocModule(lpVirtualPointer,pOrigImage);
-
- KdPrint(("ok!"));
-
- ExFreePool(pImageSectionHeader);
- *lpVirtualAddress = lpVirtualPointer;
- ZwClose(hFile);
- return STATUS_SUCCESS;
- }
-
- //////////////////////////////////////////////////////////////////////////
-
- VOID MyUnload(PDRIVER_OBJECT pDriver)
- {
- ResOldFastMutex();
- if (g_new_kernel_pointer)
- {
- ExFreePool(g_new_kernel_pointer);
- }
- }
-
- NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver,PUNICODE_STRING Reg_Path)
- {
- LDR_DATA_TABLE_ENTRY *pLdrDataTableEntry;
-
- pLdrDataTableEntry = SearchDriver(pDriver,L"ntoskrnl.exe");
- if (pLdrDataTableEntry)
- {
- ReadFileToMemory(L"\\??\\C:\\Windows\\System32\\ntkrnlpa.exe",&g_new_kernel_pointer,pLdrDataTableEntry->DllBase);
- g_kernel_increment = (ULONG)g_new_kernel_pointer - (ULONG)pLdrDataTableEntry->DllBase;
- }
-
- SetNewFastMutex(pDriver);
-
- pDriver->DriverUnload = MyUnload;
- return STATUS_SUCCESS;
- }
复制代码 代码逻辑基本如此,我倒是没试验,因为之前写的一份儿和这个有些不同,大家自己测试吧,方法绝对可行!
实际这种方法麻烦了些,处理这个目前我想到了三种方法,这是其中一种。还有一种是对SwapContext函数做手脚,SwapContext函数好好的利用可以做很多有趣的事情哟。
还有一种是通过异常机制,这种方法比较难处理但是威力很不错,比如debugport通过它可以轻而易举搞定。 |