- 注册时间
- 2021-4-16
- 最后登录
- 2023-8-13
- 在线时间
- 4 小时
编程入门
- 龙马币
- 48
|
- typedef struct _PEB_LDR_DATA
- {
- ULONG Length;
- ULONG Initialized;
- PVOID64 SsHandle;
- LIST_ENTRY InLoadOrderModuleList;
- LIST_ENTRY InMemoryOrderModuleList;
- LIST_ENTRY InInitializationOrderModuleList;
- PVOID64 EntryInProgress;
- ULONG64 ShutdownInProgress;
- PVOID64 ShutdownThreadId;
- }PEB_LDR_DATA, *PPEB_LDR_DATA;
- typedef struct _LDR_DATA_TABLE_ENTRY {
- LIST_ENTRY64 InLoadOrderLinks;
- LIST_ENTRY64 InMemoryOrderLinks;
- LIST_ENTRY64 InInitializationOrderLinks;
- PVOID64 DllBase;
- PVOID64 EntryPoint;
- ULONG64 SizeOfImage;
- UNICODE_STRING64 FullDllName;
- UNICODE_STRING64 BaseDllName;
- ULONG Flags;
- USHORT LoadCount;
- USHORT TlsIndex;
- union {
- LIST_ENTRY64 HashLinks;
- struct {
- PVOID64 SectionPointer;
- ULONG64 CheckSum;
- };
- };
- union {
- struct {
- ULONG TimeDateStamp;
- };
- struct {
- PVOID64 LoadedImports;
- };
- };
- ULONG64 * EntryPointActivationContext;
- PVOID64 PatchInformation;
- LIST_ENTRY64 ForwarderLinks;
- LIST_ENTRY64 ServiceTagLinks;
- LIST_ENTRY64 StaticLinks;
- } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
复制代码
- //枚举进程并返回进程对象
- PEPROCESS EnumProcessALL(char *ProcessName)//通过进程对象的对向链表遍历进程,缺点是进程名只能取十五个非中文字符
- {
- CHAR TProcessName[32] = { 0 };
- CHAR CProcessName[16] = { 0 };
- RtlZeroMemory(TProcessName, 32);
- memcpy(TProcessName, ProcessName, strlen(ProcessName));//一般传进来的进程名不超过32个字符
- _strupr(TProcessName); //转换成大写
- PEPROCESS process;
- PLIST_ENTRY64 plist, plist1;
- process = PsGetCurrentProcess();
- plist1 = plist = *(PULONG64)((ULONG64)process + 0x188);
- do
- {
- process = (ULONG64)plist1 - 0x188;
- RtlZeroMemory(CProcessName, 16);
- memcpy(CProcessName, (char*)process + 0x2e0, 16);//一般传进来的进程名不超过32个字符
- _strupr(CProcessName);
- if (strstr(CProcessName, TProcessName) != 0 && *(ULONG64*)((ULONG64)process + 0x200)!=0)//句柄表中有值才是活的进程,句柄表中无值是同名的死进程
- {
- return process;
- }
- //进程对象从链表中摘除
- //((PLIST_ENTRY64)(plist1->Flink))->Blink = plist1->Blink;//让前一个节点的后指针指向我的后一个节点,抹hashlinks
- //((PLIST_ENTRY64)(plist1->Blink))->Flink = plist1->Flink;//让后一个节点的前指针指向我的前一个节点
- //64位KdPrint 输出十进制用%ld,输出十六进制%p
- //KdPrint(("count %ld -- process name is %15s --process id is %ld\n", count, (char*)process + 0x2e0, *(ULONG64*)((ULONG64)process + 0x180)));
- plist1 = plist1->Blink;
- } while (plist1 != plist);
- return 0;
- }
复制代码- WCHAR removeName[256] = { 0 };
- PEPROCESS pebprocess=0;
- VOID HideDLLByPEBandNThash()//遍历进程用户层模块by PEB
- {
- pebprocess = EnumProcessALL("dnf");
- if (pebprocess == NULL)
- {
- KdPrint(("dnf process is null \n"));
- return;
- }
- PPEB processPEB=0;
- PPEB_LDR_DATA pldr_data, pldr_dataT;
- LIST_ENTRY InLoadOrderModuleList;
- LIST_ENTRY InMemoryOrderModuleList;
- LIST_ENTRY InInitializationOrderModuleList;
- PLIST_ENTRY plistLDR, plistLDR1;
- PLDR_DATA_TABLE_ENTRY ldr_table_entry;
- UNICODE_STRING KeattachProce;
- UNICODE_STRING KeDetachProce;
- PIMAGE_DOS_HEADER pimage_dos_header;
- PIMAGE_NT_HEADERS pimage_nt_header;
- MyKeAttachProcess((PKPROCESS)pebprocess);//附加到我们要摘链的用户层进程
- processPEB = *(ULONG64*)((ULONG64)pebprocess + 0x338);//取得PEB
- if (processPEB==0)
- {
- KdPrint(("peb is null \n"));
- MyKeDetachProcess(pebprocess);
- return;
- }
- KdPrint(("X64peb is %x\n", processPEB));
- pldr_data = *(ULONG64*)((ULONG64)processPEB + 0x18);//取得_PEB_LDR_DATA
- InLoadOrderModuleList = pldr_data->InLoadOrderModuleList;//从_PEB_LDR_DATA取得按加载顺序组织的模块链表
- InMemoryOrderModuleList = pldr_data->InMemoryOrderModuleList;//从_PEB_LDR_DATA取得按内存顺序组织的模块链表
- InInitializationOrderModuleList = pldr_data->InInitializationOrderModuleList;
- /**********先处理x64NT模块中的那份HASH表,此表里面保存的是进程所有已加载模块******/
- PLIST_ENTRY pNThash, pnt;
- PLDR_DATA_TABLE_ENTRY pNTHashTalbeList;
- plistLDR = InLoadOrderModuleList.Blink;
- plistLDR1 = plistLDR;
- do
- {
- ldr_table_entry = plistLDR;
- memset(removeName, 0, 256 * 2);
- RtlCopyMemory(removeName, ldr_table_entry->FullDllName.Buffer, ldr_table_entry->FullDllName.Length);
- _wcsupr(removeName);
- if (wcsstr(removeName, L"NTDLL") != 0 )//通过PEB遍历模块,如果找到NT模块就处理里面的HASHTABLE
- {
- //64位WIN7环境下syswow64目录下的NT模块基址加偏移0x13A940就是那份HASH数组的地址
- pNThash = (PLIST_ENTRY)((ULONG64)ldr_table_entry->DllBase + 0x13A940);//在NTDLL里搜字符串LdrpHashTable可以定位此数组地址
- KdPrint(("X64NT base is %p--hashtable is %p\n", ldr_table_entry->DllBase, pNThash));
- //nt模块里的HASHtable是个数组,该数组有32个成员,每个成员是LIST_ENTRY,
- //每个(LIST_ENTRY)双向链表维护了一组哈希值相同的模块
- //每个进程中的NT基址是相同的,但是这个hashtalbe是和进程相关的,
- //也就是说每一个进程有一份独立的hashtalbe
- for (ULONG64 i = 0; i < 32; i++, pNThash++)
- {
- //如果数组中某个(LIST_ENTRY)双向链表成员是空,那么该元素的Blink和Flink的值就是LIST_ENTRY的地址
- if (pNThash->Blink != pNThash)
- {
- pnt = pNThash->Blink;
- do
- {
- pNTHashTalbeList = (ULONG64)pnt - 0x70;//X64 WIN7环境下hashlinks在_LDR_DATA_TABLE_ENTRY中的偏移是0x70
- //memset(removeName, 0, 256 * 2);
- if (MmIsAddressValid(pNTHashTalbeList->FullDllName.Buffer))
- {
- //RtlCopyMemory(removeName, pNTHashTalbeList->FullDllName.Buffer, pNTHashTalbeList->FullDllName.Length);
- //_wcsupr(removeName);
- //if (wcsstr(removeName, L"AACD") != 0 || wcsstr(removeName, L"ABCD") != 0 || wcsstr(removeName, L"ACCD") != 0)
- //{
- // KdPrint(("find AACD IN NTDLL HASHTABLE AND REMOVE\n"));
- // //pnt->Flink->Blink = pnt->Blink;//让前一个节点的后指针指向我的后一个节点,抹hashlinks
- // //pnt->Blink->Flink = pnt->Flink;//让后一个节点的前指针指向我的前一个节点
- //}
- KdPrint(("X64nt hash index %d--dll base is %x -size %x--name %wZ\n", i, pNTHashTalbeList->DllBase, pNTHashTalbeList->SizeOfImage, &pNTHashTalbeList->FullDllName));
- }
- pnt = pnt->Blink;
- } while (pnt != pNThash);//如果某个成员有值就循环遍历
- }
- }
- break;
- }
- plistLDR = plistLDR->Blink;
- } while (plistLDR != plistLDR1);
- /*****************遍历x64PEB LDR第一个链表并将指定模块摘链******************************/
- plistLDR = InLoadOrderModuleList.Blink;
- plistLDR1 = plistLDR;
- ULONG64 count = 0;
- do
- {
- count = count + 1;
- ldr_table_entry = plistLDR;
- //memset(removeName, 0, 256 * 2);
- //RtlCopyMemory(removeName, ldr_table_entry->BaseDllName.Buffer, ldr_table_entry->BaseDllName.Length);
- //_wcsupr(removeName);
- //if (wcsstr(removeName, L"AACD") != 0 || wcsstr(removeName, L"ABCD") != 0 || wcsstr(removeName, L"ACCD") != 0)//如果是我们要摘链的模块就进行摘链
- //{
- // KdPrint(("find and remove"));
- // pimage_dos_header = ldr_table_entry->DllBase;
- // KdPrint(("e_magic is %s\n", &pimage_dos_header->e_magic));
- // PageProtectOff();
- // //pimage_dos_header->e_magic= "0x1234";
- // pimage_nt_header = pimage_dos_header->e_lfanew + (ULONG64)ldr_table_entry->DllBase;
- // ULONG64 sizeheader = pimage_nt_header->OptionalHeader.SizeOfHeaders;
- // KdPrint(("size of header is %d\n", sizeheader));
- // memset(pimage_dos_header, 0, sizeheader);//整个PE头全部清零
- // //pimage_nt_header->Signature = "0x87654321";
- // PageProtectOn();
- // plistLDR->Flink->Blink = plistLDR->Blink;//让前一个节点的后指针指向我的后一个节点
- // plistLDR->Blink->Flink = plistLDR->Flink;//让后一个节点的前指针指向我的前一个节点
- // break;
- //}
- KdPrint(("X64 LDR one index %d--base is %x--size %x--file name is %wZ\n",count, ldr_table_entry->DllBase, ldr_table_entry->SizeOfImage, &ldr_table_entry->FullDllName));
- plistLDR = plistLDR->Blink;
- } while (plistLDR != plistLDR1);
- /*****************遍历x64PEB LDR第二个链表并将指定模块摘链***************************/
- plistLDR = InMemoryOrderModuleList.Blink;
- plistLDR1 = plistLDR;
- count = 0;
- do
- {
- count = count + 1;
- ldr_table_entry = (ULONG64)plistLDR - 0x10;
- //memset(removeName, 0, 128 * 2);
- //RtlCopyMemory(removeName, ldr_table_entry->BaseDllName.Buffer, ldr_table_entry->BaseDllName.Length);
- //_wcsupr(removeName);
- //if (wcsstr(removeName, L"AACD") != 0 || wcsstr(removeName, L"ABCD") != 0 || wcsstr(removeName, L"ACCD") != 0)//如果是我们要摘链的模块就进行摘链
- //{
- // KdPrint(("find and remove"));
- // plistLDR->Flink->Blink = plistLDR->Blink;//让前一个节点的后指针指向我的后一个节点
- // plistLDR->Blink->Flink = plistLDR->Flink;//让后一个节点的前指针指向我的前一个节点
- // break;
- //}
- KdPrint(("X64 LDR two index %d--base is %x--size %x--file name is %wZ\n", count, ldr_table_entry->DllBase, ldr_table_entry->SizeOfImage, &ldr_table_entry->FullDllName));
- plistLDR = plistLDR->Blink;
- } while (plistLDR1 != plistLDR);
- /*****************遍历x64PEB LDR第三个链表并将指定模块摘链***************************/
- plistLDR = InInitializationOrderModuleList.Blink;
- plistLDR1 = plistLDR;
- count = 0;
- do
- {
- count = count + 1;
- ldr_table_entry = (ULONG64)plistLDR - 0x20;
- //memset(removeName, 0, 128 * 2);
- //RtlCopyMemory(removeName, ldr_table_entry->BaseDllName.Buffer, ldr_table_entry->BaseDllName.Length);
- //_wcsupr(removeName);
- //if (wcsstr(removeName, L"AACD") != 0 || wcsstr(removeName, L"ABCD") != 0 || wcsstr(removeName, L"ACCD") != 0)//如果是我们要摘链的模块就进行摘链
- //{
- // KdPrint(("find and remove"));
- // plistLDR->Flink->Blink = plistLDR->Blink;//让前一个节点的后指针指向我的后一个节点
- // plistLDR->Blink->Flink = plistLDR->Flink;//让后一个节点的前指针指向我的前一个节点
- // break;
- //}
- KdPrint(("X64 LDR three index %d--base is %x--size %x--file name is %wZ\n", count, ldr_table_entry->DllBase, ldr_table_entry->SizeOfImage, &ldr_table_entry->FullDllName));
- plistLDR = plistLDR->Blink;
- } while (plistLDR1 != plistLDR);
- /*****************x64PEB三个链表指定模块摘链完毕***************************/
- //////开始遍历x64环境中的 PEB32三个链表中的模块,X64平台中的32位程序有两个PEB,一个里面保存了X64模块,一个里面保存了X86模块
- ULONG processPEB32=0;
- PPEB_LDR_DATA32 pldr_data32, pldr_dataT32;
- LIST_ENTRY32 InLoadOrderModuleList32;
- LIST_ENTRY32 InMemoryOrderModuleList32;
- LIST_ENTRY32 InInitializationOrderModuleList32;
- PLIST_ENTRY32 plistLDR32, plistLDR132;
- PLDR_DATA_TABLE_ENTRY32 ldr_table_entry32;
- processPEB32 = *(ULONG*)((ULONG64)pebprocess + 0x320);//取得PEB32 //process是ulong64类型
- if (processPEB32==0)
- {
- KdPrint(("processPEB32 if null \n"));
- MyKeDetachProcess(pebprocess);
- return;
- }
- KdPrint(("wow64peb is %x\n", processPEB32));
- pldr_data32 = *(ULONG*)((ULONG)processPEB32 + 0xc);//取得_PEB_LDR_DATA
- InLoadOrderModuleList32 = pldr_data32->InLoadOrderModuleList;//从_PEB_LDR_DATA取得按加载顺序组织的模块链表
- InMemoryOrderModuleList32 = pldr_data32->InMemoryOrderModuleList;//从_PEB_LDR_DATA取得按内存顺序组织的模块链表
- InInitializationOrderModuleList32 = pldr_data32->InInitializationOrderModuleList;
- /**********先处理x64NT32模块中的那份HASH表,此表里面保存的是进程所有已加载的32位模块******/
- PLIST_ENTRY32 pNThash32, pnt32;
- PLDR_DATA_TABLE_ENTRY32 pNTHashTalbeList32;
- plistLDR32 = InLoadOrderModuleList32.Blink;
- plistLDR132 = plistLDR32;
- do
- {
- ldr_table_entry32 = plistLDR32;
- memset(removeName, 0, 256 * 2);
- RtlCopyMemory(removeName, ldr_table_entry32->FullDllName.Buffer, ldr_table_entry32->FullDllName.Length);
- _wcsupr(removeName);
- if (wcsstr(removeName, L"NTDLL") != 0)//通过PEB遍历模块,如果找到NT模块就处理里面的HASHTABLE
- {
- //64位WIN7环境下syswow64目录下的NT模块基址加偏移0x104800就是那份HASH数组的地址
- pNThash32 = (PLIST_ENTRY32)((ULONG)ldr_table_entry32->DllBase + 0x104800);//在NTDLL里搜字符串LdrpHashTable可以定位此数组地址
- KdPrint(("NT base is %x--hashtable is %x\n", ldr_table_entry32->DllBase, pNThash32));
- //nt模块里的HASHtable是个数组,该数组有32个成员,每个成员是LIST_ENTRY,
- //每个(LIST_ENTRY)双向链表维护了一组哈希值相同的模块
- //每个进程中的NT基址是相同的,但是这个hashtalbe是和进程相关的,
- //也就是说每一个进程有一份独立的hashtalbe
- for (ULONG i = 0; i < 32; i++, pNThash32++)
- {
- //如果数组中某个(LIST_ENTRY)双向链表成员是空,那么该元素的Blink和Flink的值就是LIST_ENTRY的地址
- if (pNThash32->Blink != pNThash32)
- {
- pnt32 = pNThash32->Blink;
- do
- {
- pNTHashTalbeList32 = (ULONG)pnt32 - 0x3C;
- if (MmIsAddressValid(pNTHashTalbeList32->FullDllName.Buffer))
- {
- KdPrint(("wow64 nt hush index %d--dll base is %x -size %x --name %S\n", i, pNTHashTalbeList32->DllBase, pNTHashTalbeList32->SizeOfImage,pNTHashTalbeList32->FullDllName.Buffer));
- }
- pnt32 = pnt32->Blink;
- } while (pnt32 != pNThash32);//如果某个成员有值就循环遍历
- }
- }
- break;
- }
- plistLDR32 = plistLDR32->Blink;
- } while (plistLDR32 != plistLDR132);
- /*****************遍历x64 PEB32 LDR第一个链表并将指定模块摘链******************************/
- plistLDR32 = InLoadOrderModuleList32.Blink;
- plistLDR132 = plistLDR32;
- count = 0;
- do
- {
- count = count + 1;
- ldr_table_entry32 = plistLDR32;
- KdPrint(("wow64 LDR one index %d--base is %x--size %x--file name is %ws\n", count, ldr_table_entry32->DllBase, ldr_table_entry32->SizeOfImage, ldr_table_entry32->FullDllName.Buffer));
- plistLDR32 = plistLDR32->Blink;
- } while (plistLDR32 != plistLDR132);
- /*****************遍历x64 PEB32 LDR第二个链表并将指定模块摘链***************************/
- plistLDR32 = InMemoryOrderModuleList32.Blink;
- plistLDR132 = plistLDR32;
- count = 0;
- do
- {
- count = count + 1;
- ldr_table_entry32 = (ULONG)plistLDR32 - 8;
- KdPrint(("wow64 LDR two index %d--base is %x--size %x--file name is %S\n", count, ldr_table_entry32->DllBase, ldr_table_entry32->SizeOfImage, ldr_table_entry32->FullDllName.Buffer));
- plistLDR32 = plistLDR32->Blink;
- } while (plistLDR132 != plistLDR32);
- /*****************遍历x64 PEB32 LDR第三个链表并将指定模块摘链***************************/
- plistLDR32 = InInitializationOrderModuleList32.Blink;
- plistLDR132 = plistLDR32;
- count = 0;
- do
- {
- count = count + 1;
- ldr_table_entry32 = (ULONG)plistLDR32 - 0x10;
- KdPrint(("wow64 LDR three index %d--base is %x--size %x--file name is %ws\n", count, ldr_table_entry32->DllBase, ldr_table_entry32->SizeOfImage, ldr_table_entry32->FullDllName.Buffer));
- plistLDR32 = plistLDR32->Blink;
- } while (plistLDR132 != plistLDR32);
- MyKeDetachProcess(pebprocess);
- }
复制代码
|
|