示例#1
0
        public static unsafe List <uint> GetStaticImportNameOffsets(byte[] fileBytes, string arch)
        {
            // This function walks the PE header to get the offset of the Import Address Table
            // (IAT) and then resolves the imports' names
            fixed(byte *ptr_data = fileBytes)
            {
                // Initial validation
                UnsafeHelpers.IMAGE_DOS_HEADER *dos_header = (UnsafeHelpers.IMAGE_DOS_HEADER *)ptr_data;
                if (dos_header->e_magic != UnsafeHelpers.IMAGE_DOS_SIGNATURE)
                {
                    Console.WriteLine("[-] Magic bytes don't match");
                    return(null);
                }

                // We'll split here because much of the work we need to do uses offsets from the NT headers
                if (arch == "x64")
                {
                    UnsafeHelpers.IMAGE_NT_HEADERS64 *nt_header = (UnsafeHelpers.IMAGE_NT_HEADERS64 *)(ptr_data + dos_header->e_lfanew);
                    if (nt_header->Signature != UnsafeHelpers.IMAGE_NT_SIGNATURE)
                    {
                        Console.WriteLine("[-] NT Header signature mismatch");
                        return(null);
                    }
                    IMAGE_DATA_DIRECTORY *DataDirectory = (IMAGE_DATA_DIRECTORY *)(&nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);

                    // Safety check in case others fail. This will happen on x86 EXEs and some .NET assemblies.
                    uint itRVA = DataDirectory->VirtualAddress;
                    if (itRVA == 0)
                    {
                        Console.WriteLine("[!] Import Table RVA is 0. Something is wrong...");
                        return(null);
                    }

                    // Do the conversion from the RVA to the offsets we'll need to do some math
                    Offset iatOffsets = RvaToOffset(nt_header, null, itRVA, "IAT");

                    // Math to get the true offset to the name of the DLL
                    // https://ired.team/miscellaneous-reversing-forensics/pe-file-header-parser-in-c++#pimage_import_descriptor
                    uint offset = iatOffsets.RawOffset + (itRVA - iatOffsets.RVA);
                    UnsafeHelpers.IMAGE_IMPORT_DESCRIPTOR *firstModule = (UnsafeHelpers.IMAGE_IMPORT_DESCRIPTOR *)(ptr_data + offset);

                    List <uint> nameOffsets = new List <uint>();
                    while (firstModule->Name != 0)
                    {
                        uint trueOffset = 0 + iatOffsets.RawOffset + (firstModule->Name - iatOffsets.RVA);
                        nameOffsets.Add(trueOffset);
                        firstModule++;
                    }

                    return(nameOffsets);
                }
                else // x86
                {
                    UnsafeHelpers.IMAGE_NT_HEADERS32 *nt_header = (UnsafeHelpers.IMAGE_NT_HEADERS32 *)(ptr_data + dos_header->e_lfanew);
                    if (nt_header->Signature != UnsafeHelpers.IMAGE_NT_SIGNATURE)
                    {
                        Console.WriteLine("[-] NT Header signature mismatch");
                        return(null);
                    }
                    UnsafeHelpers.IMAGE_DATA_DIRECTORY *DataDirectory = (UnsafeHelpers.IMAGE_DATA_DIRECTORY *)(&nt_header->OptionalHeader.DataDirectory[UnsafeHelpers.IMAGE_DIRECTORY_ENTRY_IMPORT]);

                    // Safety check in case others fail. This will happen on x86 EXEs and some .NET assemblies.
                    uint itRVA = DataDirectory->VirtualAddress;
                    if (itRVA == 0)
                    {
                        Console.WriteLine("[!] Import Table RVA is 0. Something is wrong...");
                        return(null);
                    }

                    // Do the conversion from the RVA to the offsets we'll need to do some math
                    Offset iatOffsets = RvaToOffset(null, nt_header, itRVA, "IAT");

                    // Math to get the true offset to the name of the DLL
                    // https://ired.team/miscellaneous-reversing-forensics/pe-file-header-parser-in-c++#pimage_import_descriptor
                    uint offset = iatOffsets.RawOffset + (itRVA - iatOffsets.RVA);
                    UnsafeHelpers.IMAGE_IMPORT_DESCRIPTOR *firstModule = (UnsafeHelpers.IMAGE_IMPORT_DESCRIPTOR *)(ptr_data + offset);

                    //uint nameOffset = 0 + rdataRawOffset + (firstModule->Name - rdataRVA);

                    List <uint> nameOffsets = new List <uint>();
                    while (firstModule->Name != 0)
                    {
                        uint trueOffset = 0 + iatOffsets.RawOffset + (firstModule->Name - iatOffsets.RVA);
                        nameOffsets.Add(trueOffset);
                        firstModule++;
                    }

                    return(nameOffsets);
                }
            }
        }
示例#2
0
        public static unsafe List <string> GetDynamicImports(byte[] fileBytes, string arch)
        {
            // This function walks the PE header to get the offset of the Delay-Load Descriptor Table
            // (DLDT) and then resolves the imports' names
            List <string> dynamicModuleNames = new List <string>();

            fixed(byte *ptr_data = fileBytes)
            {
                // Initial validation
                UnsafeHelpers.IMAGE_DOS_HEADER *dos_header = (UnsafeHelpers.IMAGE_DOS_HEADER *)ptr_data;
                if (dos_header->e_magic != UnsafeHelpers.IMAGE_DOS_SIGNATURE)
                {
                    Console.WriteLine("[-] Magic bytes don't match");
                    return(dynamicModuleNames);
                }

                // Get the NT headers
                if (arch == "x64")
                {
                    IMAGE_NT_HEADERS64 *nt_header = (IMAGE_NT_HEADERS64 *)(ptr_data + dos_header->e_lfanew);
                    if (nt_header->Signature != IMAGE_NT_SIGNATURE)
                    {
                        Console.WriteLine("[-] NT Header signature mismatch");
                        return(dynamicModuleNames);
                    }

                    // Get the offset for the delay-load import tables
                    ulong *DataDirectory       = nt_header->OptionalHeader.DataDirectory;
                    IMAGE_DATA_DIRECTORY *dldt = (IMAGE_DATA_DIRECTORY *)(&nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT]);
                    uint dldtRVA = dldt->VirtualAddress;
                    if (dldtRVA == 0) // No delayed imports found
                    {
                        return(dynamicModuleNames);
                    }

                    Offset offsets = RvaToOffset(nt_header, null, dldtRVA, "DLDT");
                    uint   offset  = offsets.RawOffset + (dldtRVA - offsets.RVA);

                    // Iterate over the list of delay-loaded modules
                    IMAGE_DELAY_IMPORT_DESCRIPTOR *firstModule = (UnsafeHelpers.IMAGE_DELAY_IMPORT_DESCRIPTOR *)(ptr_data + offset);

                    while (firstModule->szName != 0)
                    {
                        Offset offsetToNames = RvaToOffset(nt_header, null, firstModule->szName, "szName");
                        uint   offset2       = offsetToNames.RawOffset + (firstModule->szName - offsetToNames.RVA);
                        dynamicModuleNames.Add(Marshal.PtrToStringAnsi((IntPtr)(ptr_data + offset2)));
                        firstModule = (UnsafeHelpers.IMAGE_DELAY_IMPORT_DESCRIPTOR *)((long)firstModule + (long)Marshal.SizeOf(typeof(UnsafeHelpers.IMAGE_DELAY_IMPORT_DESCRIPTOR)));
                    }
                }
                else // x86
                {
                    IMAGE_NT_HEADERS32 *nt_header = (IMAGE_NT_HEADERS32 *)(ptr_data + dos_header->e_lfanew);
                    if (nt_header->Signature != IMAGE_NT_SIGNATURE)
                    {
                        Console.WriteLine("[-] NT Header signature mismatch");
                        return(dynamicModuleNames);
                    }

                    // Get the offset for the delay-load import tables
                    ulong *DataDirectory       = nt_header->OptionalHeader.DataDirectory;
                    IMAGE_DATA_DIRECTORY *dldt = (IMAGE_DATA_DIRECTORY *)(&nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT]);
                    uint dldtRVA = dldt->VirtualAddress;
                    if (dldtRVA == 0) // No delayed imports found
                    {
                        return(dynamicModuleNames);
                    }

                    Offset offsets = RvaToOffset(null, nt_header, dldtRVA, "DLDT");
                    uint   offset  = offsets.RawOffset + (dldtRVA - offsets.RVA);

                    // Iterate over the list of delay-loaded modules
                    IMAGE_DELAY_IMPORT_DESCRIPTOR *firstModule = (IMAGE_DELAY_IMPORT_DESCRIPTOR *)(ptr_data + offset);

                    while (firstModule->szName != 0)
                    {
                        Offset offsetToNames = RvaToOffset(null, nt_header, firstModule->szName, "szName");
                        uint   offset2       = offsetToNames.RawOffset + (firstModule->szName - offsetToNames.RVA);
                        dynamicModuleNames.Add(Marshal.PtrToStringAnsi((IntPtr)(ptr_data + offset2)));
                        firstModule = (IMAGE_DELAY_IMPORT_DESCRIPTOR *)((long)firstModule + (long)Marshal.SizeOf(typeof(UnsafeHelpers.IMAGE_DELAY_IMPORT_DESCRIPTOR)));
                    }
                }

                return(dynamicModuleNames);
            }
        }