龙马谷

 找回密码
 立即注册

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课
以下是天马阁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实现原理及防护思路
查看: 1249|回复: 0

[C++源码] x64的内核重载源码

[复制链接]

21

主题

0

回帖

26

积分

编程入门

Rank: 1

龙马币
52

x64的内核重载源码,参照x86写的   望大牛们指点。

ReX64.h
  1. #pragma once
  2. #include <ntifs.h>
  3. #include <ntimage.h>
  4. #include <intrin.h>

  5. PVOID pNewBuffer = nullptr;
  6. typedef struct _SYSTEM_SERVICE_TABLE    //SSDT结构
  7. {
  8.     PVOID serviceTableBase;
  9.     PVOID serviceCounterTableBase;
  10.     ULONGLONG numberofServices;
  11.     PVOID paramTableBase;
  12. }SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE;

  13. typedef struct _BaseAddr_Size
  14. {
  15.     DWORD_PTR mMoudleBaseAddress;
  16.     DWORD_PTR mMoudleSizeOf;
  17. }BaseAddr_Size, *PBaseAddr_Size;
  18. #pragma once
  19. #include <ntifs.h>
  20. #include <ntimage.h>
  21. #include <intrin.h>

  22. PVOID pNewBuffer = nullptr;
  23. typedef struct _SYSTEM_SERVICE_TABLE    //SSDT结构
  24. {
  25.     PVOID serviceTableBase;
  26.     PVOID serviceCounterTableBase;
  27.     ULONGLONG numberofServices;
  28.     PVOID paramTableBase;
  29. }SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE;

  30. typedef struct _BaseAddr_Size
  31. {
  32.     DWORD_PTR mMoudleBaseAddress;
  33.     DWORD_PTR mMoudleSizeOf;
  34. }BaseAddr_Size, *PBaseAddr_Size;

  35. typedef struct _PE
  36. {
  37.     IMAGE_DOS_HEADER DosHeader;
  38.     IMAGE_NT_HEADERS32 NtHeaders;
  39.     IMAGE_SECTION_HEADER SectionHeader;
  40. }PE, *pPE;

  41. typedef struct _LDR_DATA_TABLE_ENTRY
  42. {
  43.     struct _LIST_ENTRY InLoadOrderLinks;                                    //0x0
  44.     struct _LIST_ENTRY InMemoryOrderLinks;                                  //0x8
  45.     struct _LIST_ENTRY InInitializationOrderLinks;                          //0x10
  46.     VOID* DllBase;                                                          //0x18
  47.     VOID* EntryPoint;                                                       //0x1c
  48.     ULONG SizeOfImage;                                                      //0x20
  49.     struct _UNICODE_STRING FullDllName;                                     //0x24
  50.     struct _UNICODE_STRING BaseDllName;                                     //0x2c
  51.     ULONG Flags;                                                            //0x34
  52.     USHORT LoadCount;                                                       //0x38
  53.     USHORT TlsIndex;                                                        //0x3a
  54.     union
  55.     {
  56.         struct _LIST_ENTRY HashLinks;                                       //0x3c
  57.         struct
  58.         {
  59.             VOID* SectionPointer;                                           //0x3c
  60.             ULONG CheckSum;                                                 //0x40
  61.         }u;
  62.     };
  63.     union
  64.     {
  65.         ULONG TimeDateStamp;                                                //0x44
  66.         VOID* LoadedImports;                                                //0x44
  67.     };
  68.     VOID* EntryPointActivationContext;                                      //0x48
  69.     VOID* PatchInformation;                                                 //0x4c
  70. }LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;//0x50 bytes (sizeof)

  71. EXTERN_C{
  72.     VOID UnLoad(PDRIVER_OBJECT pDriver);
  73.     NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg);
  74. }
  75. NTSTATUS GetKernelImageBase_1(IN PDRIVER_OBJECT pDriver, IN PUNICODE_STRING szMoudeName, OUT PBaseAddr_Size mBeseAddrOfSize);
  76. PVOID GetNewKernelBuffer_1(IN PUNICODE_STRING pStrKernelPathName);
  77. VOID RepirRelocTable(IN DWORD_PTR uNewModule, IN DWORD_PTR uOldModule);
  78. NTSTATUS RepirSSDT(IN PDRIVER_OBJECT pDriver, IN ULONG64 pNewKernelBuffer, IN ULONG64 uOldModule);
  79. NTSTATUS GetSSDT(IN PDRIVER_OBJECT pdriver, OUT PVOID* addr); //通过链表找到ssdt
  80. ReX64.cpp
  81. [mw_shl_code=cpp,true]#pragma once
  82. #include "ReX64Knrl.h"


  83. #pragma warning (disable:4310)
  84. VOID UnLoad(PDRIVER_OBJECT pDriver)
  85. {
  86.     UNREFERENCED_PARAMETER(pDriver);
  87.     if (pNewBuffer) ExFreePool(pNewBuffer);
  88. }

  89. NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
  90. {
  91.     UNREFERENCED_PARAMETER(pReg);
  92.     pDriver->DriverUnload = UnLoad;
  93.     DbgBreakPoint();
  94.     NTSTATUS status = STATUS_UNSUCCESSFUL;
  95.     UNICODE_STRING szMoudleName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
  96.     BaseAddr_Size sz = { 0 };   
  97.     status= GetKernelImageBase_1(pDriver, &szMoudleName, &sz);
  98.     if (NT_SUCCESS(status))
  99.     {
  100.         DbgPrintEx(77, 0, "GetKernelImageBase_1 sucess!\n");
  101.     }
  102.     else
  103.     {
  104.         DbgPrintEx(77, 0, "GetKernelImageBase_1 Faild!\n");
  105.         return STATUS_UNSUCCESSFUL;
  106.     }

  107.     UNICODE_STRING szFileName = RTL_CONSTANT_STRING(L"\\??\\C:\\Windows\\system32\\ntoskrnl.exe");//ntdll.dll   //\\??\\C:\\WINDOWS\\system32\\ntkrnlpa.exe
  108.     PVOID pNewKernelBuffer = GetNewKernelBuffer_1(&szFileName);
  109.     if (!MmIsAddressValid(pNewKernelBuffer))
  110.     {
  111.         DbgPrintEx(77, 0, "pNewKernelBuffer is faild");
  112.         return STATUS_UNSUCCESSFUL;
  113.     }
  114.     DbgPrintEx(77, 0, "pNewKernelBuffer is: %llx", pNewKernelBuffer);
  115.     //基址重定位
  116.     RepirRelocTable((DWORD_PTR)pNewKernelBuffer, sz.mMoudleBaseAddress);

  117.     //系统服务表重定位
  118.     status = RepirSSDT(pDriver, (ULONG64)pNewKernelBuffer, sz.mMoudleBaseAddress);
  119.     if (NT_SUCCESS(status))
  120.     {
  121.         DbgPrintEx(77, 0, "RepirSSDT sucess!\n");
  122.     }
  123.     else
  124.     {
  125.         DbgPrintEx(77, 0, "RepirSSDT Faild!\n");
  126.         return STATUS_UNSUCCESSFUL;
  127.     }

  128.     //>>>>>>>>  插入HOOK  代码

  129.     return STATUS_SUCCESS;
  130. }

  131. //[获取当前内核模块基址_1]
  132. NTSTATUS GetKernelImageBase_1(IN PDRIVER_OBJECT pDriver, IN PUNICODE_STRING szMoudeName, OUT PBaseAddr_Size mBeseAddrOfSize)
  133. {
  134.     PLIST_ENTRY pCurrObject = (PLIST_ENTRY)pDriver->DriverSection;
  135.     PLIST_ENTRY pNextObject = pCurrObject->Flink;
  136.     PLDR_DATA_TABLE_ENTRY szTemp = nullptr;
  137.     while (pCurrObject != pNextObject)
  138.     {
  139.         szTemp = (PLDR_DATA_TABLE_ENTRY)pNextObject;
  140.         if (RtlCompareUnicodeString(&szTemp->BaseDllName, szMoudeName, TRUE) == NULL)
  141.         {
  142.             mBeseAddrOfSize->mMoudleBaseAddress = (DWORD_PTR)(szTemp->DllBase);
  143.             mBeseAddrOfSize->mMoudleSizeOf = szTemp->SizeOfImage;
  144.             DbgPrintEx(77, 0, "DllBase:0x%llX SizeOfImage:0x%X  BaseDllName:%wZ FullDllName:%wZ ", szTemp->DllBase, szTemp->SizeOfImage, szTemp->BaseDllName, szTemp->FullDllName);
  145.             return STATUS_SUCCESS;
  146.         }
  147.         pNextObject = pNextObject->Flink;
  148.     }
  149.     return STATUS_UNSUCCESSFUL;
  150. }

  151. // [1、获取新的内核模块虚拟缓存]
  152. PVOID GetNewKernelBuffer_1(IN PUNICODE_STRING pStrKernelPathName)
  153. {
  154.     PE pe = { 0 };
  155.     HANDLE hFile = NULL;
  156.     OBJECT_ATTRIBUTES objectAttributes = { 0 };
  157.     IO_STATUS_BLOCK ioStatusBlock = { 0 };
  158.     InitializeObjectAttributes(&objectAttributes, pStrKernelPathName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
  159.     NTSTATUS ntStatus = ZwCreateFile(&hFile, GENERIC_READ, &objectAttributes, &ioStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL,
  160.         FILE_SHARE_READ, FILE_OPEN_IF, FILE_NON_DIRECTORY_FILE, NULL, 0);
  161.     if (!NT_SUCCESS(ntStatus))
  162.     {
  163.         KdPrint(("ZwCreateFile错误:%x\n", ntStatus));
  164.         return NULL;
  165.     }
  166.     LARGE_INTEGER fileOffset = { 0 };
  167.     fileOffset.QuadPart = 0;
  168.     //读取DOS头
  169.     ntStatus = ZwReadFile(hFile, NULL, NULL, NULL, &ioStatusBlock, &pe.DosHeader, sizeof(IMAGE_DOS_HEADER), &fileOffset, NULL);
  170.     if (!NT_SUCCESS(ntStatus))
  171.     {
  172.         KdPrint(("ZwReadFile错误:%x\n", ntStatus));
  173.         goto exit;
  174.     }
  175.     fileOffset.QuadPart += pe.DosHeader.e_lfanew;
  176.     //读取NT头
  177.     ntStatus = ZwReadFile(hFile, NULL, NULL, NULL, &ioStatusBlock, &pe.NtHeaders, sizeof(IMAGE_NT_HEADERS), &fileOffset, NULL);
  178.     if (!NT_SUCCESS(ntStatus))
  179.     {
  180.         KdPrint(("ZwReadFile错误:%x\n", ntStatus));
  181.         goto exit;
  182.     }

  183.     pNewBuffer = ExAllocatePool(NonPagedPool, pe.NtHeaders.OptionalHeader.SizeOfImage);
  184.     if (pNewBuffer == NULL)
  185.     {
  186.         KdPrint(("pNewBuffer错误\n"));
  187.         goto exit;
  188.     }
  189.     PVOID pTempBuffer = pNewBuffer;
  190.     RtlCopyMemory(pTempBuffer, &pe.DosHeader, sizeof(IMAGE_DOS_HEADER));
  191.     pTempBuffer = (PVOID)((DWORD_PTR)pTempBuffer + pe.DosHeader.e_lfanew);
  192.     RtlCopyMemory(pTempBuffer, &pe.NtHeaders, sizeof(IMAGE_NT_HEADERS));
  193.     fileOffset.QuadPart += sizeof(IMAGE_NT_HEADERS);
  194.     pTempBuffer = (PVOID)((DWORD_PTR)pTempBuffer + sizeof(IMAGE_NT_HEADERS));
  195.     //读取节表
  196.     ntStatus = ZwReadFile(hFile, NULL, NULL, NULL, &ioStatusBlock, pTempBuffer, (sizeof(IMAGE_SECTION_HEADER) * pe.NtHeaders.FileHeader.NumberOfSections), &fileOffset, NULL);
  197.     if (!NT_SUCCESS(ntStatus))
  198.     {
  199.         KdPrint(("ZwReadFile错误:%x\n", ntStatus));
  200.         pNewBuffer = nullptr;
  201.         goto exit;
  202.     }
  203.     PIMAGE_SECTION_HEADER pTempSectionHeader = (PIMAGE_SECTION_HEADER)pTempBuffer;

  204.     //读取节内容
  205.     for (ULONG32 uCount = 0; uCount < pe.NtHeaders.FileHeader.NumberOfSections; uCount++)
  206.     {
  207.         pTempBuffer = (PVOID)((DWORD_PTR)pNewBuffer + pTempSectionHeader->VirtualAddress);
  208.         fileOffset.QuadPart = pTempSectionHeader->PointerToRawData;
  209.         ntStatus = ZwReadFile(hFile, NULL, NULL, NULL, &ioStatusBlock, pTempBuffer, pTempSectionHeader->SizeOfRawData, &fileOffset, NULL);
  210.         if (!NT_SUCCESS(ntStatus))
  211.         {
  212.             KdPrint(("ZwReadFile错误:%x\n", ntStatus));
  213.             pNewBuffer = nullptr;
  214.             goto exit;
  215.         }
  216.         pTempSectionHeader++;
  217.     }
  218. exit:
  219.     if (hFile) ZwClose(hFile);
  220.     //if (pNewBuffer) ExFreePool(pNewBuffer);   
  221.     return pNewBuffer;
  222. }

  223. //修复重定位表
  224. VOID RepirRelocTable(IN DWORD_PTR uNewModule,IN DWORD_PTR uOldModule)
  225. {
  226.     UNREFERENCED_PARAMETER(uOldModule);
  227.     PIMAGE_DOS_HEADER pDosHeader = NULL;
  228.     PIMAGE_NT_HEADERS pNtHeaders = NULL;
  229.     PIMAGE_BASE_RELOCATION pRelocation = NULL;
  230.     PIMAGE_DATA_DIRECTORY pData = NULL;

  231.     pDosHeader = (PIMAGE_DOS_HEADER)uNewModule;
  232.     pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)pDosHeader + pDosHeader->e_lfanew);
  233.     pData = pNtHeaders->OptionalHeader.DataDirectory;
  234.     //定位重定位表
  235.     pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)uNewModule + pData[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
  236.     //由于新的内核里面的全局变量地址都是用的老的 所以要加上它们之间的偏移量 就等于我们新的内核全局变量地址   
  237.     DWORD_PTR uOffset = uNewModule - pNtHeaders->OptionalHeader.ImageBase;      //需要改正的偏移
  238.     while (pRelocation->VirtualAddress != 0 && pRelocation->SizeOfBlock != 0 && pRelocation->VirtualAddress != 01)
  239.     {
  240.         LONG32 uNumOfRelocs = (pRelocation->SizeOfBlock - 8) / 2;  //取得重定位数量
  241.         PUSHORT pUShort = (PUSHORT)((DWORD_PTR)pRelocation + 8);
  242.         for (DWORD_PTR uCount = 0; uCount < uNumOfRelocs; uCount++, pUShort++)
  243.         {
  244.             if (((*pUShort) >> 12) == IMAGE_REL_BASED_DIR64)
  245.             {
  246.                 PULONG64 pUlong32 = (PULONG64)(((*pUShort) & 0x0FFF) + pRelocation->VirtualAddress + uNewModule);
  247.                 *pUlong32 += uOffset;   //改好数据写入目的地址
  248.             }
  249.         }
  250.         pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD_PTR)pRelocation + pRelocation->SizeOfBlock);
  251.     }
  252. }

  253. //修复新的系统服务表
  254. NTSTATUS RepirSSDT(IN PDRIVER_OBJECT pDriver, IN ULONG64 pNewKernelBuffer, IN ULONG64 uOldModule)
  255. {
  256.     ULONG64 g_uOffset = pNewKernelBuffer - uOldModule;
  257.     PVOID szAddr = nullptr;
  258.     NTSTATUS status = GetSSDT(pDriver, &szAddr);
  259.     if (!NT_SUCCESS(status))
  260.     {
  261.         DbgPrintEx(77, 0, "GetSSDT Faile!\n");
  262.         return STATUS_UNSUCCESSFUL;
  263.     }
  264.     PSYSTEM_SERVICE_TABLE   m_pOldSSDT = { 0 };
  265.     m_pOldSSDT = (PSYSTEM_SERVICE_TABLE)szAddr;
  266.     PSYSTEM_SERVICE_TABLE m_pNewSSDT = (PSYSTEM_SERVICE_TABLE)((ULONGLONG)m_pOldSSDT + g_uOffset);
  267.     m_pNewSSDT->numberofServices = m_pOldSSDT->numberofServices;
  268.     ULONG64 m_uOffset = (ULONG64)m_pOldSSDT->serviceTableBase - uOldModule;
  269.     m_pNewSSDT->serviceTableBase = (PULONG32)(pNewKernelBuffer + m_uOffset);

  270.     m_uOffset = ((ULONGLONG)m_pOldSSDT->serviceCounterTableBase - uOldModule);
  271.     m_pNewSSDT->serviceCounterTableBase = (PULONG32)(pNewKernelBuffer + m_uOffset);
  272.     m_uOffset = ((ULONGLONG)m_pOldSSDT->paramTableBase - uOldModule);
  273.     m_pNewSSDT->paramTableBase = (PCHAR)(pNewKernelBuffer + m_uOffset);
  274.     RtlCopyMemory((PULONGLONG)m_pNewSSDT->paramTableBase, (PULONGLONG)m_pOldSSDT->paramTableBase, (ULONG64)m_pNewSSDT->numberofServices);//复制参数
  275.     m_uOffset = (ULONG64)m_pNewSSDT->serviceTableBase - pNewKernelBuffer;
  276.     //计算ssdt表中函数地址  注:win10 ssdt表中函数地址为:高28位为偏移 低4位为参数个数-4   不足4个参数时为零
  277.     for (ULONG32 uCount = 0; uCount < m_pNewSSDT->numberofServices; uCount++)
  278.     {
  279.         ((PULONG32)(UCHAR*)(m_pNewSSDT->serviceTableBase))[uCount] = (ULONG32)((((PULONG32)(UCHAR*)(m_pNewSSDT->serviceTableBase))[uCount] - m_uOffset) << 4) + (((CHAR)((UCHAR*)(m_pNewSSDT->paramTableBase))[uCount]) >> 2);
  280.     }
  281.     return STATUS_SUCCESS;
  282. }

  283. NTSTATUS GetSSDT(IN PDRIVER_OBJECT pdriver, OUT PVOID* addr)  //通过链表找到ssdt
  284. {
  285.     PLDR_DATA_TABLE_ENTRY entry = (PLDR_DATA_TABLE_ENTRY)pdriver->DriverSection;
  286.     PLDR_DATA_TABLE_ENTRY head = entry;
  287.     UNICODE_STRING temp = { 0 };
  288.     RtlInitUnicodeString(&temp, L"ntoskrnl.exe");
  289.     PCHAR start = NULL;
  290.     ULONG size = 0;
  291.     do
  292.     {  //通过链表找到ntoskrnl.exe   内核文件。
  293.         if (RtlCompareUnicodeString(&temp, &entry->BaseDllName, TRUE) == NULL)
  294.         {
  295.             //DbgPrintEx(DPFLTR_IHVDRIVER_ID, 0, "%wZ\n", &entry->BaseDllName);
  296.             start = (PCHAR)entry->DllBase;
  297.             size = entry->SizeOfImage;
  298.             break;
  299.         }
  300.         entry = (PLDR_DATA_TABLE_ENTRY)entry->InLoadOrderLinks.Flink;
  301.     } while (entry != head);
  302.     for (ULONG i = 0; i < size; i++)
  303.     {
  304.         if (MmIsAddressValid(start))
  305.         {
  306.             if (*start == (CHAR)0x4c && *(CHAR*)(start + 1) == (CHAR)0x8d && *(CHAR*)(start + 2) == (CHAR)0x15)  //注:必需强制转换字符串类型
  307.             {
  308.                 start += 7;
  309.                 if (MmIsAddressValid(start))
  310.                 {
  311.                     if (*start == (CHAR)0x4c && *(CHAR*)(start + 1) == (CHAR)0x8d && *(CHAR*)(start + 2) == (CHAR)0x1d)
  312.                     {
  313.                         *(PULONGLONG)addr = *(PULONG)(start - 4) + (ULONGLONG)start;
  314.                         return STATUS_SUCCESS;
  315.                     }
  316.                 }
  317.             }
  318.         }
  319.         if (MmIsAddressValid(start))
  320.         {
  321.             start++;
  322.         }
  323.     }
  324.     return STATUS_UNSUCCESSFUL;
  325. }
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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