Hi Hacker
There is a long discussion on the EDR evasion techniques available in many communities. I am interested in writing this in my blog and making this become very easy to understand. Now let see how EDRs do their analyses by hijacking the API Syscall flow. I am using Bitdefender for this tutorial
Initially if you run the application without bitdefender, the function will look like below. Normal syscall stub will usually start with this four bytes 4c 8b d1 b8

When the EDR is installed on the operating system then it will do inline patching into windows syscall stub. Lets take an example of NtAdjustPrivilegesToken that will look like this after bitdefender is installed


So the idea of EDR inline patching into syscall stub is to make the application API call come into the EDR detection engine first before the actual API process is served so that the EDR place a jump statement at the very beginning of every syscall like the image above
,
Below is simple illustration before and after of EDR hook. NtReadVirtualMemory starts with opcodes e9 0f 64 f8 rather than 4c 8b d1 b8, meaning it’s most likely hooked
NtWriteVirtualMemory starts with opcodes 4c 8b d1 b8, meaning it has not been hooked

Below is a C code to check the EDR hook.
#include <iostream>
#include <Windows.h>
int main()
{
PDWORD functionAddress = (PDWORD)0;
// Get ntdll base address
HMODULE libraryBase = LoadLibraryA("ntdll");
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)libraryBase;
PIMAGE_NT_HEADERS imageNTHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)libraryBase + dosHeader->e_lfanew);
// Locate export address table
DWORD_PTR exportDirectoryRVA = imageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
PIMAGE_EXPORT_DIRECTORY imageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD_PTR)libraryBase + exportDirectoryRVA);
// Offsets to list of exported functions and their names
PDWORD addresOfFunctionsRVA = (PDWORD)((DWORD_PTR)libraryBase + imageExportDirectory->AddressOfFunctions);
PDWORD addressOfNamesRVA = (PDWORD)((DWORD_PTR)libraryBase + imageExportDirectory->AddressOfNames);
PWORD addressOfNameOrdinalsRVA = (PWORD)((DWORD_PTR)libraryBase + imageExportDirectory->AddressOfNameOrdinals);
int iterator = 0;
// Iterate through exported functions of ntdll
for (DWORD i = 0; i < imageExportDirectory->NumberOfNames; i++)
{
// Resolve exported function name
DWORD functionNameRVA = addressOfNamesRVA[i];
DWORD_PTR functionNameVA = (DWORD_PTR)libraryBase + functionNameRVA;
char* functionName = (char*)functionNameVA;
// Find the exported function from the DLL
DWORD_PTR functionAddressRVA = 0;
functionAddressRVA = addresOfFunctionsRVA[addressOfNameOrdinalsRVA[i]];
functionAddress = (PDWORD)((DWORD_PTR)libraryBase + functionAddressRVA);
// Good Syscal should start with these 4 bytes
char syscallPrologue[4] = { 0x4c, 0x8b, 0xd1, 0xb8 };
// Only interested in Nt|Zw functions
if (strncmp(functionName, (char*)"Nt", 2) == 0 || strncmp(functionName, (char*)"Zw", 2) == 0)
{
// Get the first 4 bytes of the function
if (memcmp(functionAddress, syscallPrologue, 4) != 0) {
printf("Rio find hook here: %s : %p\n", functionName, functionAddress);
iterator++;
}
}
else {
if (memcmp(functionAddress, syscallPrologue, 4) == 0) {
printf("------ > Rio cannot find hook at this API: %s : %p\n", functionName, functionAddress);
}
}
}
printf("No Hooked Syscall %d", iterator);
return 0;
}
The output of the above application is below

Hi Rio
Where should i start learning in order to reach your level of expertise skills? Is windows internal by Pavel Yosifovich a good start?
Can you post some links for learning path such as step 1. Learn X, step 2. Learn Y?
Thank you million
Hi Pavel,
The learning curve for malware or reverse engineering are very high and very intense 🙂 . I learn from the very basic where I did a small coding in C/C++ and open it in IDA to understand the flow. I took some classes too from various vendors