// this method returns the hash of Amsi.dll code section. static String getSectionHeaderofAmsi(PeHeaderReader amsiReader, Boolean inMemory, byte[] amsiModule) { PeHeaderReader.IMAGE_SECTION_HEADER[] amsiSection = amsiReader.ImageSectionHeaders; int codeSectionPointer; for (int count = 0; count < amsiSection.Length; count++) { char[] sectionName = amsiSection[count].Name; if (sectionName[0] == '.' && sectionName[1] == 't' && sectionName[2] == 'e' && sectionName[3] == 'x' && sectionName[4] == 't') { if (inMemory) { codeSectionPointer = (int)amsiSection[count].VirtualAddress; } else { codeSectionPointer = (int)amsiSection[count].PointerToRawData; } int SizeOfRawData = (int)amsiSection[count].SizeOfRawData; byte[] amsiCodeSection = new byte[SizeOfRawData]; Array.Copy(amsiModule, codeSectionPointer, amsiCodeSection, 0, SizeOfRawData); return(calculateHash(amsiCodeSection)); } } return("error"); }
// this method checks if any section of AmsiDll is tampered with by comparing the hash static Boolean AmsiIntegrityCheck(IntPtr processHandle, IntPtr amsiModuleHandle, String onDiskAmsiCodehash) { MODULEINFO amsiDLLInfo = new MODULEINFO(); GetModuleInformation(processHandle, amsiModuleHandle, out amsiDLLInfo, (uint)(Marshal.SizeOf(typeof(MODULEINFO)))); byte[] inMemoryAmsiDLL = new byte[amsiDLLInfo.SizeOfImage]; int bytesRead = 0; ReadProcessMemory(processHandle, amsiModuleHandle, inMemoryAmsiDLL, inMemoryAmsiDLL.Length, ref bytesRead); PeHeaderReader amsiReader = new PeHeaderReader(inMemoryAmsiDLL); String inMemoryAmsiCodehash = getSectionHeaderofAmsi(amsiReader, true, inMemoryAmsiDLL); if (inMemoryAmsiCodehash.Equals(onDiskAmsiCodehash)) { Console.WriteLine("hash matches"); } else { Console.WriteLine("Hash does not match"); } return(false); }
static void Main(string[] args) { PeHeaderReader amsiReader = new PeHeaderReader("C:/Windows/System32/amsi.dll"); byte[] amsiModule = amsiReader.allBytes; String onDiskAmsiCodehash = getSectionHeaderofAmsi(amsiReader, false, amsiModule); ManagementEventWatcher eventWatcher = new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace")); eventWatcher.EventArrived += new EventArrivedEventHandler(newEvent); listOfProcessId = new LinkedList <int>(); semaphore = new Semaphore(1, 1); eventWatcher.Start(); while (true) { Thread.Sleep(5000); semaphore.WaitOne(); LinkedListNode <int> headPointer = listOfProcessId.First; if (headPointer == null) { Console.WriteLine("Empty"); } while (headPointer != null) { LinkedListNode <int> nextPointer = headPointer.Next; checkForBypassEvidence(headPointer, onDiskAmsiCodehash); headPointer = nextPointer; } semaphore.Release(); } }