龙马谷

 找回密码
 立即注册

QQ登录

只需一步,快速开始

龙马谷VIP会员办理客服QQ:82926983(如果临时会话没有收到回复,请先加QQ好友再发。)
1 [已完结] GG修改器新手入门与实战教程 31课 2 [已完结] GG修改器美化修改教程 6课 3 [已完结] GG修改器Lua脚本新手入门教程 12课
4 [已完结] 触动精灵脚本新手入门必学教程 22课 5 [已完结] 手游自动化脚本入门实战教程 9课 6 [已完结] C++射击游戏方框骨骼透视与自瞄教程 27课
7 [已完结] C++零基础UE4逆向开发FPS透视自瞄教程 29课 8 [已完结] C++零基础大漠模拟器手游自动化辅助教程 22课 9 [已完结] C++零基础开发DXF内存脚本辅助教程 32课
以下是天马阁VIP教程,本站与天马阁合作,赞助VIP可以获得天马阁对应VIP会员,名额有限! 点击进入天马阁论坛
1 [已完结] x64CE与x64dbg入门基础教程 7课 2 [已完结] x64汇编语言基础教程 16课 3 [已完结] x64辅助入门基础教程 9课
4 [已完结] C++x64内存辅助实战技术教程 149课 5 [已完结] C++x64内存检测与过检测技术教程 10课 6 [已完结] C+x64二叉树分析遍历与LUA自动登陆教程 19课
7 [已完结] C++BT功能原理与x64实战教程 29课 8 [已完结] C+FPS框透视与自瞄x64实现原理及防护思路
查看: 7311|回复: 0

X64环境遍历32位进程的模块驱动代码

[复制链接]

14

主题

3

回帖

22

积分

编程入门

Rank: 1

龙马币
48

  1. typedef struct _PEB_LDR_DATA
  2. {
  3.         ULONG Length;
  4.         ULONG Initialized;
  5.         PVOID64 SsHandle;
  6.         LIST_ENTRY InLoadOrderModuleList;
  7.         LIST_ENTRY InMemoryOrderModuleList;
  8.         LIST_ENTRY InInitializationOrderModuleList;
  9.         PVOID64 EntryInProgress;
  10.         ULONG64 ShutdownInProgress;
  11.         PVOID64 ShutdownThreadId;
  12. }PEB_LDR_DATA, *PPEB_LDR_DATA;

  13. typedef struct _LDR_DATA_TABLE_ENTRY {
  14.         LIST_ENTRY64 InLoadOrderLinks;
  15.         LIST_ENTRY64 InMemoryOrderLinks;
  16.         LIST_ENTRY64 InInitializationOrderLinks;
  17.         PVOID64 DllBase;
  18.         PVOID64 EntryPoint;
  19.         ULONG64 SizeOfImage;
  20.         UNICODE_STRING64 FullDllName;
  21.         UNICODE_STRING64 BaseDllName;
  22.         ULONG Flags;
  23.         USHORT LoadCount;
  24.         USHORT TlsIndex;
  25.         union {
  26.                 LIST_ENTRY64 HashLinks;
  27.                 struct {
  28.                         PVOID64 SectionPointer;
  29.                         ULONG64 CheckSum;
  30.                 };
  31.         };
  32.         union {
  33.                 struct {
  34.                         ULONG TimeDateStamp;
  35.                 };
  36.                 struct {
  37.                         PVOID64 LoadedImports;
  38.                 };
  39.         };
  40.         ULONG64 * EntryPointActivationContext;
  41.         PVOID64 PatchInformation;
  42.         LIST_ENTRY64 ForwarderLinks;
  43.         LIST_ENTRY64 ServiceTagLinks;
  44.         LIST_ENTRY64 StaticLinks;
  45. } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
复制代码

  1. //枚举进程并返回进程对象
  2. PEPROCESS EnumProcessALL(char *ProcessName)//通过进程对象的对向链表遍历进程,缺点是进程名只能取十五个非中文字符
  3. {
  4.         CHAR TProcessName[32] = { 0 };
  5.         CHAR CProcessName[16] = { 0 };
  6.         RtlZeroMemory(TProcessName, 32);
  7.         memcpy(TProcessName, ProcessName, strlen(ProcessName));//一般传进来的进程名不超过32个字符
  8.         _strupr(TProcessName); //转换成大写

  9.         PEPROCESS process;
  10.         PLIST_ENTRY64 plist, plist1;
  11.         process = PsGetCurrentProcess();
  12.         plist1 = plist = *(PULONG64)((ULONG64)process + 0x188);

  13.         do
  14.         {
  15.                 process = (ULONG64)plist1 - 0x188;
  16.                 RtlZeroMemory(CProcessName, 16);
  17.                 memcpy(CProcessName, (char*)process + 0x2e0, 16);//一般传进来的进程名不超过32个字符
  18.                 _strupr(CProcessName);
  19.                 if (strstr(CProcessName, TProcessName) != 0 && *(ULONG64*)((ULONG64)process + 0x200)!=0)//句柄表中有值才是活的进程,句柄表中无值是同名的死进程
  20.                 {
  21.                         return process;
  22.                 }
  23.             //进程对象从链表中摘除
  24.             //((PLIST_ENTRY64)(plist1->Flink))->Blink = plist1->Blink;//让前一个节点的后指针指向我的后一个节点,抹hashlinks
  25.                 //((PLIST_ENTRY64)(plist1->Blink))->Flink = plist1->Flink;//让后一个节点的前指针指向我的前一个节点
  26.                 //64位KdPrint 输出十进制用%ld,输出十六进制%p
  27.                 //KdPrint(("count %ld -- process name is %15s --process id is %ld\n", count, (char*)process + 0x2e0, *(ULONG64*)((ULONG64)process + 0x180)));
  28.                 plist1 = plist1->Blink;
  29.         } while (plist1 != plist);
  30.         return 0;
  31. }
复制代码
  1. WCHAR removeName[256] = { 0 };
  2. PEPROCESS pebprocess=0;
  3. VOID HideDLLByPEBandNThash()//遍历进程用户层模块by PEB
  4. {
  5.         pebprocess = EnumProcessALL("dnf");
  6.         if (pebprocess == NULL)
  7.         {
  8.                 KdPrint(("dnf process is null \n"));
  9.                 return;
  10.         }
  11.         PPEB processPEB=0;
  12.         PPEB_LDR_DATA  pldr_data, pldr_dataT;
  13.         LIST_ENTRY InLoadOrderModuleList;
  14.         LIST_ENTRY InMemoryOrderModuleList;
  15.         LIST_ENTRY InInitializationOrderModuleList;
  16.         PLIST_ENTRY plistLDR, plistLDR1;
  17.         PLDR_DATA_TABLE_ENTRY ldr_table_entry;
  18.         UNICODE_STRING KeattachProce;
  19.         UNICODE_STRING KeDetachProce;
  20.         PIMAGE_DOS_HEADER pimage_dos_header;
  21.         PIMAGE_NT_HEADERS pimage_nt_header;

  22.         MyKeAttachProcess((PKPROCESS)pebprocess);//附加到我们要摘链的用户层进程
  23.         processPEB = *(ULONG64*)((ULONG64)pebprocess + 0x338);//取得PEB
  24.         if (processPEB==0)
  25.         {
  26.                 KdPrint(("peb is null \n"));
  27.                 MyKeDetachProcess(pebprocess);
  28.                 return;
  29.         }
  30.         KdPrint(("X64peb is %x\n", processPEB));
  31.         pldr_data = *(ULONG64*)((ULONG64)processPEB + 0x18);//取得_PEB_LDR_DATA
  32.         InLoadOrderModuleList = pldr_data->InLoadOrderModuleList;//从_PEB_LDR_DATA取得按加载顺序组织的模块链表
  33.         InMemoryOrderModuleList = pldr_data->InMemoryOrderModuleList;//从_PEB_LDR_DATA取得按内存顺序组织的模块链表
  34.         InInitializationOrderModuleList = pldr_data->InInitializationOrderModuleList;
  35.         /**********先处理x64NT模块中的那份HASH表,此表里面保存的是进程所有已加载模块******/
  36.         PLIST_ENTRY pNThash, pnt;
  37.         PLDR_DATA_TABLE_ENTRY pNTHashTalbeList;
  38.         plistLDR = InLoadOrderModuleList.Blink;
  39.         plistLDR1 = plistLDR;
  40.         do
  41.         {
  42.                 ldr_table_entry = plistLDR;
  43.                 memset(removeName, 0, 256 * 2);
  44.                 RtlCopyMemory(removeName, ldr_table_entry->FullDllName.Buffer, ldr_table_entry->FullDllName.Length);
  45.                 _wcsupr(removeName);
  46.                 if (wcsstr(removeName, L"NTDLL") != 0 )//通过PEB遍历模块,如果找到NT模块就处理里面的HASHTABLE
  47.                 {
  48.                         //64位WIN7环境下syswow64目录下的NT模块基址加偏移0x13A940就是那份HASH数组的地址
  49.                         pNThash = (PLIST_ENTRY)((ULONG64)ldr_table_entry->DllBase + 0x13A940);//在NTDLL里搜字符串LdrpHashTable可以定位此数组地址
  50.                         KdPrint(("X64NT base is %p--hashtable is %p\n", ldr_table_entry->DllBase, pNThash));
  51.                         //nt模块里的HASHtable是个数组,该数组有32个成员,每个成员是LIST_ENTRY,
  52.                         //每个(LIST_ENTRY)双向链表维护了一组哈希值相同的模块
  53.                         //每个进程中的NT基址是相同的,但是这个hashtalbe是和进程相关的,
  54.                         //也就是说每一个进程有一份独立的hashtalbe
  55.                         for (ULONG64 i = 0; i < 32; i++, pNThash++)
  56.                         {
  57.                                 //如果数组中某个(LIST_ENTRY)双向链表成员是空,那么该元素的Blink和Flink的值就是LIST_ENTRY的地址
  58.                                 if (pNThash->Blink != pNThash)
  59.                                 {
  60.                                         pnt = pNThash->Blink;
  61.                                         do
  62.                                         {
  63.                                                 pNTHashTalbeList = (ULONG64)pnt - 0x70;//X64 WIN7环境下hashlinks在_LDR_DATA_TABLE_ENTRY中的偏移是0x70
  64.                                                 //memset(removeName, 0, 256 * 2);
  65.                                                 if (MmIsAddressValid(pNTHashTalbeList->FullDllName.Buffer))
  66.                                                 {
  67.                                                         //RtlCopyMemory(removeName, pNTHashTalbeList->FullDllName.Buffer, pNTHashTalbeList->FullDllName.Length);
  68.                                                         //_wcsupr(removeName);
  69.                                                         //if (wcsstr(removeName, L"AACD") != 0 || wcsstr(removeName, L"ABCD") != 0 || wcsstr(removeName, L"ACCD") != 0)
  70.                                                         //{
  71.                                                         //        KdPrint(("find AACD IN NTDLL HASHTABLE AND REMOVE\n"));
  72.                                                         //        //pnt->Flink->Blink = pnt->Blink;//让前一个节点的后指针指向我的后一个节点,抹hashlinks
  73.                                                         //        //pnt->Blink->Flink = pnt->Flink;//让后一个节点的前指针指向我的前一个节点
  74.                                                         //}
  75.                                                         KdPrint(("X64nt hash index %d--dll base is %x  -size %x--name %wZ\n", i, pNTHashTalbeList->DllBase, pNTHashTalbeList->SizeOfImage, &pNTHashTalbeList->FullDllName));
  76.                                                 }
  77.                                                 pnt = pnt->Blink;
  78.                                         } while (pnt != pNThash);//如果某个成员有值就循环遍历
  79.                                 }
  80.                         }
  81.                         break;
  82.                 }
  83.                 plistLDR = plistLDR->Blink;
  84.         } while (plistLDR != plistLDR1);

  85.         /*****************遍历x64PEB LDR第一个链表并将指定模块摘链******************************/
  86.         plistLDR = InLoadOrderModuleList.Blink;
  87.         plistLDR1 = plistLDR;
  88.         ULONG64 count = 0;
  89.         do
  90.         {
  91.                 count = count + 1;
  92.                 ldr_table_entry = plistLDR;
  93.                 //memset(removeName, 0, 256 * 2);
  94.                 //RtlCopyMemory(removeName, ldr_table_entry->BaseDllName.Buffer, ldr_table_entry->BaseDllName.Length);
  95.                 //_wcsupr(removeName);
  96.                 //if (wcsstr(removeName, L"AACD") != 0 || wcsstr(removeName, L"ABCD") != 0 || wcsstr(removeName, L"ACCD") != 0)//如果是我们要摘链的模块就进行摘链
  97.                 //{
  98.                 //        KdPrint(("find and remove"));
  99.                 //        pimage_dos_header = ldr_table_entry->DllBase;
  100.                 //        KdPrint(("e_magic is %s\n", &pimage_dos_header->e_magic));
  101.                 //        PageProtectOff();
  102.                 //        //pimage_dos_header->e_magic= "0x1234";
  103.                 //        pimage_nt_header = pimage_dos_header->e_lfanew + (ULONG64)ldr_table_entry->DllBase;
  104.                 //        ULONG64 sizeheader = pimage_nt_header->OptionalHeader.SizeOfHeaders;
  105.                 //        KdPrint(("size of header is %d\n", sizeheader));
  106.                 //        memset(pimage_dos_header, 0, sizeheader);//整个PE头全部清零
  107.                 //        //pimage_nt_header->Signature = "0x87654321";
  108.                 //        PageProtectOn();
  109.                 //        plistLDR->Flink->Blink = plistLDR->Blink;//让前一个节点的后指针指向我的后一个节点
  110.                 //        plistLDR->Blink->Flink = plistLDR->Flink;//让后一个节点的前指针指向我的前一个节点
  111.                 //        break;
  112.                 //}
  113.                 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));
  114.                 plistLDR = plistLDR->Blink;
  115.         } while (plistLDR != plistLDR1);
  116.         /*****************遍历x64PEB LDR第二个链表并将指定模块摘链***************************/
  117.         plistLDR = InMemoryOrderModuleList.Blink;
  118.         plistLDR1 = plistLDR;
  119.         count = 0;
  120.         do
  121.         {
  122.                 count = count + 1;
  123.                 ldr_table_entry = (ULONG64)plistLDR - 0x10;
  124.                 //memset(removeName, 0, 128 * 2);
  125.                 //RtlCopyMemory(removeName, ldr_table_entry->BaseDllName.Buffer, ldr_table_entry->BaseDllName.Length);
  126.                 //_wcsupr(removeName);
  127.                 //if (wcsstr(removeName, L"AACD") != 0 || wcsstr(removeName, L"ABCD") != 0 || wcsstr(removeName, L"ACCD") != 0)//如果是我们要摘链的模块就进行摘链
  128.                 //{
  129.                 //        KdPrint(("find and remove"));
  130.                 //        plistLDR->Flink->Blink = plistLDR->Blink;//让前一个节点的后指针指向我的后一个节点
  131.                 //        plistLDR->Blink->Flink = plistLDR->Flink;//让后一个节点的前指针指向我的前一个节点
  132.                 //        break;
  133.                 //}
  134.                 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));
  135.                 plistLDR = plistLDR->Blink;
  136.         } while (plistLDR1 != plistLDR);
  137.         /*****************遍历x64PEB LDR第三个链表并将指定模块摘链***************************/
  138.         plistLDR = InInitializationOrderModuleList.Blink;
  139.         plistLDR1 = plistLDR;
  140.         count = 0;
  141.         do
  142.         {
  143.                 count = count + 1;
  144.                 ldr_table_entry = (ULONG64)plistLDR - 0x20;
  145.                 //memset(removeName, 0, 128 * 2);
  146.                 //RtlCopyMemory(removeName, ldr_table_entry->BaseDllName.Buffer, ldr_table_entry->BaseDllName.Length);
  147.                 //_wcsupr(removeName);
  148.                 //if (wcsstr(removeName, L"AACD") != 0 || wcsstr(removeName, L"ABCD") != 0 || wcsstr(removeName, L"ACCD") != 0)//如果是我们要摘链的模块就进行摘链
  149.                 //{
  150.                 //        KdPrint(("find and remove"));
  151.                 //        plistLDR->Flink->Blink = plistLDR->Blink;//让前一个节点的后指针指向我的后一个节点
  152.                 //        plistLDR->Blink->Flink = plistLDR->Flink;//让后一个节点的前指针指向我的前一个节点
  153.                 //        break;
  154.                 //}
  155.                 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));
  156.                 plistLDR = plistLDR->Blink;
  157.         } while (plistLDR1 != plistLDR);
  158.         /*****************x64PEB三个链表指定模块摘链完毕***************************/

  159.         //////开始遍历x64环境中的 PEB32三个链表中的模块,X64平台中的32位程序有两个PEB,一个里面保存了X64模块,一个里面保存了X86模块
  160.         ULONG processPEB32=0;
  161.         PPEB_LDR_DATA32  pldr_data32, pldr_dataT32;
  162.         LIST_ENTRY32 InLoadOrderModuleList32;
  163.         LIST_ENTRY32 InMemoryOrderModuleList32;
  164.         LIST_ENTRY32 InInitializationOrderModuleList32;
  165.         PLIST_ENTRY32 plistLDR32, plistLDR132;
  166.         PLDR_DATA_TABLE_ENTRY32 ldr_table_entry32;

  167.         processPEB32 = *(ULONG*)((ULONG64)pebprocess + 0x320);//取得PEB32 //process是ulong64类型
  168.         if (processPEB32==0)
  169.         {
  170.                 KdPrint(("processPEB32 if null \n"));
  171.                 MyKeDetachProcess(pebprocess);
  172.                 return;
  173.         }
  174.         KdPrint(("wow64peb is %x\n", processPEB32));
  175.         pldr_data32 = *(ULONG*)((ULONG)processPEB32 + 0xc);//取得_PEB_LDR_DATA
  176.         InLoadOrderModuleList32 = pldr_data32->InLoadOrderModuleList;//从_PEB_LDR_DATA取得按加载顺序组织的模块链表
  177.         InMemoryOrderModuleList32 = pldr_data32->InMemoryOrderModuleList;//从_PEB_LDR_DATA取得按内存顺序组织的模块链表
  178.         InInitializationOrderModuleList32 = pldr_data32->InInitializationOrderModuleList;
  179.         /**********先处理x64NT32模块中的那份HASH表,此表里面保存的是进程所有已加载的32位模块******/
  180.         PLIST_ENTRY32 pNThash32, pnt32;
  181.         PLDR_DATA_TABLE_ENTRY32 pNTHashTalbeList32;
  182.         plistLDR32 = InLoadOrderModuleList32.Blink;
  183.         plistLDR132 = plistLDR32;
  184.         do
  185.         {
  186.                 ldr_table_entry32 = plistLDR32;
  187.                 memset(removeName, 0, 256 * 2);
  188.                 RtlCopyMemory(removeName, ldr_table_entry32->FullDllName.Buffer, ldr_table_entry32->FullDllName.Length);
  189.                 _wcsupr(removeName);
  190.                 if (wcsstr(removeName, L"NTDLL") != 0)//通过PEB遍历模块,如果找到NT模块就处理里面的HASHTABLE
  191.                 {
  192.                         //64位WIN7环境下syswow64目录下的NT模块基址加偏移0x104800就是那份HASH数组的地址
  193.                         pNThash32 = (PLIST_ENTRY32)((ULONG)ldr_table_entry32->DllBase + 0x104800);//在NTDLL里搜字符串LdrpHashTable可以定位此数组地址
  194.                         KdPrint(("NT base is %x--hashtable is %x\n", ldr_table_entry32->DllBase, pNThash32));
  195.                         //nt模块里的HASHtable是个数组,该数组有32个成员,每个成员是LIST_ENTRY,
  196.                         //每个(LIST_ENTRY)双向链表维护了一组哈希值相同的模块
  197.                         //每个进程中的NT基址是相同的,但是这个hashtalbe是和进程相关的,
  198.                         //也就是说每一个进程有一份独立的hashtalbe
  199.                         for (ULONG i = 0; i < 32; i++, pNThash32++)
  200.                         {
  201.                                 //如果数组中某个(LIST_ENTRY)双向链表成员是空,那么该元素的Blink和Flink的值就是LIST_ENTRY的地址
  202.                                 if (pNThash32->Blink != pNThash32)
  203.                                 {
  204.                                         pnt32 = pNThash32->Blink;
  205.                                         do
  206.                                         {
  207.                                                 pNTHashTalbeList32 = (ULONG)pnt32 - 0x3C;
  208.                                                 if (MmIsAddressValid(pNTHashTalbeList32->FullDllName.Buffer))
  209.                                                 {
  210.                                                         KdPrint(("wow64 nt hush index %d--dll base is %x -size %x --name %S\n", i, pNTHashTalbeList32->DllBase, pNTHashTalbeList32->SizeOfImage,pNTHashTalbeList32->FullDllName.Buffer));
  211.                                                 }
  212.                                                 pnt32 = pnt32->Blink;
  213.                                         } while (pnt32 != pNThash32);//如果某个成员有值就循环遍历
  214.                                 }
  215.                         }
  216.                         break;
  217.                 }
  218.                 plistLDR32 = plistLDR32->Blink;
  219.         } while (plistLDR32 != plistLDR132);

  220.         /*****************遍历x64 PEB32 LDR第一个链表并将指定模块摘链******************************/
  221.         plistLDR32 = InLoadOrderModuleList32.Blink;
  222.         plistLDR132 = plistLDR32;
  223.     count = 0;
  224.         do
  225.         {
  226.                 count = count + 1;
  227.                 ldr_table_entry32 = plistLDR32;
  228.                 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));
  229.                 plistLDR32 = plistLDR32->Blink;
  230.         } while (plistLDR32 != plistLDR132);
  231.         /*****************遍历x64 PEB32 LDR第二个链表并将指定模块摘链***************************/
  232.         plistLDR32 = InMemoryOrderModuleList32.Blink;
  233.         plistLDR132 = plistLDR32;
  234.         count = 0;
  235.         do
  236.         {
  237.                 count = count + 1;
  238.                 ldr_table_entry32 = (ULONG)plistLDR32 - 8;
  239.                 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));
  240.                 plistLDR32 = plistLDR32->Blink;
  241.         } while (plistLDR132 != plistLDR32);
  242.         /*****************遍历x64 PEB32 LDR第三个链表并将指定模块摘链***************************/
  243.         plistLDR32 = InInitializationOrderModuleList32.Blink;
  244.         plistLDR132 = plistLDR32;
  245.         count = 0;
  246.         do
  247.         {
  248.                 count = count + 1;
  249.                 ldr_table_entry32 = (ULONG)plistLDR32 - 0x10;
  250.                 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));
  251.                 plistLDR32 = plistLDR32->Blink;
  252.         } while (plistLDR132 != plistLDR32);
  253.         MyKeDetachProcess(pebprocess);
  254. }
复制代码

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

龙马谷| C/C++辅助教程| 安卓逆向安全| 论坛导航| 免责申明|Archiver|
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表龙马谷立场!
任何人不得以任何方式翻录、盗版或出售本站视频,一经发现我们将追究其相关责任!
我们一直在努力成为最好的编程论坛!
Copyright© 2018-2021 All Right Reserved.
在线客服
快速回复 返回顶部 返回列表