| 134 | } |
| 135 | |
| 136 | NTSTATUS Section::CreateKnownDllSection(DllStats& dllStats) { |
| 137 | // Create a known dll system section of our own |
| 138 | NTSTATUS status; |
| 139 | |
| 140 | // Clear the return data (assuming only primitive data types) |
| 141 | memset(&dllStats, 0, sizeof(dllStats)); |
| 142 | |
| 143 | // need to steal a security descriptor from a existing KnownDll - we'll use kernel32 |
| 144 | HANDLE hSectionK32; |
| 145 | |
| 146 | POBJECT_ATTRIBUTES pKernel32Attr{}; |
| 147 | PUNICODE_STRING pObjName{}; |
| 148 | POBJECT_ATTRIBUTES pDllAttr{}; |
| 149 | #ifdef _WIN64 |
| 150 | if (_type == SectionType::Wow) { |
| 151 | UNICODE_STRING name = RTL_CONSTANT_STRING(L"\\KnownDlls32\\kernel32.dll"); |
| 152 | static ObjectAttributes attr(&name, ObjectAttributesFlags::Caseinsensive); |
| 153 | static UNICODE_STRING objName = RTL_CONSTANT_STRING(L"\\KnownDlls32\\" INJECTED_DLL_FILE_NAME32); |
| 154 | UNICODE_STRING path = RTL_CONSTANT_STRING(INJECTED_DLL_NT_PATH_WOW); |
| 155 | static ObjectAttributes dllAttr(&path, ObjectAttributesFlags::Caseinsensive); |
| 156 | pKernel32Attr = &attr; |
| 157 | pObjName = &objName; |
| 158 | pDllAttr = &dllAttr; |
| 159 | } |
| 160 | else |
| 161 | #endif |
| 162 | { |
| 163 | UNICODE_STRING name = RTL_CONSTANT_STRING(L"\\KnownDlls\\kernel32.dll"); |
| 164 | static ObjectAttributes attr(&name, ObjectAttributesFlags::Caseinsensive); |
| 165 | static UNICODE_STRING objName = RTL_CONSTANT_STRING(L"\\KnownDlls\\" INJECTED_DLL_FILE_NAME32); |
| 166 | UNICODE_STRING path = RTL_CONSTANT_STRING(INJECTED_DLL_NT_PATH_WOW); |
| 167 | static ObjectAttributes dllAttr(&path, ObjectAttributesFlags::Caseinsensive); |
| 168 | pKernel32Attr = &attr; |
| 169 | pObjName = &objName; |
| 170 | pDllAttr = &dllAttr; |
| 171 | } |
| 172 | |
| 173 | status = ZwOpenSection(&hSectionK32, READ_CONTROL, pKernel32Attr); |
| 174 | |
| 175 | if (!NT_SUCCESS(status)) { |
| 176 | LogError("ERROR: (0x%X) ZwOpenSection(hSectionK32), PID=%u, sectionType=%c\n", |
| 177 | status, |
| 178 | PsGetCurrentProcessId(), |
| 179 | _type); |
| 180 | return status; |
| 181 | } |
| 182 | |
| 183 | status = STATUS_GENERIC_COMMAND_FAILED; |
| 184 | // INFO: Make our section "permanent", which means that it won't be deleted if all of its handle are closed |
| 185 | // and we will need to call ZwMakeTemporaryObject() on it first to allow it. |
| 186 | |
| 187 | ObjectAttributes objAttr(pObjName, ObjectAttributesFlags::Caseinsensive | ObjectAttributesFlags::Permanent); |
| 188 | |
| 189 | LogInfo("Got KnownDll Ok!\n"); |
| 190 | ULONG size = 0; |
| 191 | for (;;) { |
| 192 | ULONG needSize = 0; |
| 193 | status = ZwQuerySecurityObject(hSectionK32, PROCESS_TRUST_LABEL_SECURITY_INFORMATION | |