I apologise if this is going off-topic but I wanted to explain a bit... As long as we don't completely hijack the thread with answering further questions about NTAPI function stubs and MS Edge protection then it should be okay, so I'll leave this as my final response on the topic of MS Edge protection. Quick analysis explaining below:
Here is where the functions you listed trace down to:
OpenProcess = ntdll.dll!NtOpenProcess
VirtualAlloc/Ex = ntdll.dll!NtAllocateVirtualMemory
WriteProcessMemory = ntdll.dll!NtWriteVirtualMemory
Then you have the thread NTAPI functions such as: RtlCreateUserThread & NtCreateThreadEx (both present in ntdll.dll, exported by ntoskrnl.exe).
LoadLibrary function will go down to the NTAPI Loader functions ("Ldr"), such as LdrLoadDll (which will then use functions like LdrpLoadDll).
Here is the function prologue of NtAllocateVirtualMemory (x64):
Code:
4C 8B D1 mov r10,rcx
B8 18 00 00 00 mov eax,18h
F6 04 25 08 03 FE 7F 01 test byte ptr [7FFE0308h],1
75 03 jne 00007FFDD22B5155
0F 05 syscall
C3 ret
Here is the function prologue of NtWriteVirtualMemory (x64):
Code:
0F 1F 84 00 00 00 00 00 nop dword ptr [rax+rax]
4C 8B D1 mov r10,rcx
B8 3A 00 00 00 mov eax,3Ah
F6 04 25 08 03 FE 7F 01 test byte ptr [7FFE0308h],1
75 03 jne 00007FFDD22B5595
0F 05 syscall
C3 ret
Here is the function prologue of NtOpenProcess (x64):
Code:
4C 8B D1 mov r10,rcx
B8 26 00 00 00 mov eax,26h
F6 04 25 08 03 FE 7F 01 test byte ptr [7FFE0308h],1
75 03 jne 00007FFDD22B5315
0F 05 syscall
C3 ret
I don't think I need to check the disassembly of any others, you may have already noticed the pattern for most of these functions (some don't follow the pattern like LdrLoadDll but the NT functions seem to follow the pattern). What they do is they move the system ID of the function into the EAX register and then syscall/sysenter is used (depends on the process architecture).
SYSENTER/SYSCALL is the instruction for user-mode -> kernel-mode transition, therefore the function execution is carried across to kernel-mode. When you call Win32 functions like WriteProcessMemory it will ALWAYS trace back to the NTAPI function stub (for that specific function - in this case it would be NtWriteVirtualMemory), and then it will carry execution over to kernel-mode for the call (via sysenter/syscall for example).
In kernel-mode there won't be a checkup within the function of NtWriteVirtualMemory (or even deeper than this) which will automatically block (e.g. via 0xC0000022 return) if the PID of the target process is for MS Edge (e.g. get process ID from the ProcessHandle parameter (type HANDLE) and then compare to the PID of MS Edge)...
Let's say that there IS indeed some sort of checkup within kernel32.dll specifically for MS Edge, don't you think this would be really badly done? All it would take is a few lines of code for someone to bypass it via using the NTAPI function which the WIn32 function traced backed too. It would just be insecure and inefficient to do it via modifying the functions within kernel32.dll (or even the NTAPI function prologues - system calls!... Kernel-Mode would be best, most preferably via the documented callback methods).
------------------------------------------------------
I will give a few quick methods which programs can utilise to prevent the DLL injection (no self-protection is full-proof):
- Local hook to LdrLoadDll - then in the callback you auto-block all DLLs not from the Windows directory or from your own program files installation directory (or wherever you installed your software - but make sure it's a protected directory against files being added without permission or this can be easily exploited to be bypassed).
- Kernel-mode callback to PsSetLoadImageNotifyRoutine and then you check the DLL (image) being loaded into your PE (which is running in memory). I believe some AVs do this also, not all of them will... AVs can use this to monitor load attempts of DLLs into processes altogether, though.
MS Edge is not a "protected" process by Windows, either. One of the best defences against DLL/any injection attacks is preventing a handle to your process from being able to be obtained - almost every single popular AV product out on the market will utilise ObRegisterCallbacks (for both handle creation & duplication, and same for the threads of the process) for this.
Thanks for reading and enjoy...
