I am coding a driver in order to create an Antivirus. However, I am stuck in reading the import address table from a process.
I have a CreateProcessNotify:
VOID CreateProcNotify(HANDLE ParentId, HANDLE ProcessId, BOOLEAN Create)
{
UNREFERENCED_PARAMETER(ParentId);
UNREFERENCED_PARAMETER(Create);
PEPROCESS Process;
KAPC_STATE Apc;
PVOID ModuleBase;
// From PID to PEPROCESS
PsLookupProcessByProcessId(ProcessId, &Process);
// Attach into the target process' memory
KeStackAttachProcess(Process, &Apc);
ModuleBase = GetModuleBase(Process);
PIMAGE_IMPORT_DESCRIPTOR pImportAddressTable = GetIAT(ModuleBase);
DPrint("Imports of [Meias] are: \n");
DPrint("IAT: %x\n", pImportAddressTable);
// Iterate all Modules Imports
while (pImportAddressTable->Name != 0) {
DPrint("{%s}, ", (PCHAR)((ULONG)ModuleBase + (pImportAddressTable->Name)));
pImportAddressTable++;
}
// Unattach ourselves from the target process' memory
KeUnstackDetachProcess(&Apc);
}
While also having the following functions:
/*Returns the Base of the Process*/
PVOID GetModuleBase(PEPROCESS Process)
{
PVOID ModuleBase;
__try
{
ModuleBase = PsGetProcessSectionBaseAddress(Process);
}
__except (GetExceptionCode())
{
return 0;
}
return ModuleBase;
}
/*Returns the Import Address Table*/
PIMAGE_IMPORT_DESCRIPTOR GetIAT(PVOID ModuleBase)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)ModuleBase;
PIMAGE_NT_HEADERS32 pNtHeader32 = NULL;
PIMAGE_NT_HEADERS64 pNtHeader64 = NULL;
PIMAGE_IMPORT_DESCRIPTOR pIAT = NULL;
if (ModuleBase == 0)
return NULL;
DPrint("ModuleBase: 0x%x\n", pDosHeader);
// If the magic value isn't MZ then isn't a valid PE
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;
pNtHeader32 = (PIMAGE_NT_HEADERS32)((PUCHAR)ModuleBase + pDosHeader->e_lfanew);
pNtHeader64 = (PIMAGE_NT_HEADERS64)((PUCHAR)ModuleBase + pDosHeader->e_lfanew);
// If the image doesn't have a DOS
if ((INT)pNtHeader32 != IMAGE_NT_SIGNATURE)
return NULL;
// Check if is 32 bit
if (pNtHeader32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
pIAT = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)ModuleBase + pNtHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
}
// Check if is 64 bit
else if (pNtHeader64->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
pIAT = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)ModuleBase + pNtHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
}
return pIAT;
}
When debugging with WinDBG:
Using the !analyze -v:
The exception:
The code:
I implemented the GetIAT with the help of this
As you can see the problem is that it isn't getting the IAT properly but I don't know why...
Thanks in advance.
First, it reads the files of a PE structure and loads an executable image into the memory. The other thing it does is to scan the Import Address Table (IAT) of an executable to locate the DLLs and functions that the executable uses and load all these DLLs and map them into the process address space.
The Import Directory Table is a Data Directory located at the beginning of the . idata section. It consists of an array of IMAGE_IMPORT_DESCRIPTOR structures, each one of them is for a DLL.
IAT hooking is a way to run malicious code by modifying the Import Address Table of a specific executable. Consisting of replacing one legitimate function from imported DLL by a malicious one. IAT hooking and inline hooking are generally known as userland rootkits.
The problem was because I was using
if ((INT)pNtHeader32 != IMAGE_NT_SIGNATURE)
return NULL;
When I should be checking the Signature of it:
if ((INT)pNtHeader32->Signature != IMAGE_NT_SIGNATURE)
return NULL;
Done.
The code of IAT function is unreliable. If Import Table Address is 0 it will be a reason for BSOD.
For example, this project (to analyze dependencies; remake of the old legacy software depends.exe) has Import Table Address is 0.
For avoiding BSOD you need to add a check, like this:
...
// Check if is 32 bit
if (pNtHeader32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
if (pNtHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0)
return NULL;
pIAT = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)ModuleBase
+ pNtHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
}
// Check if is 64 bit
else if (pNtHeader64->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
if (pNtHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0)
return NULL;
pIAT = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)ModuleBase + pNtHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
}
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With