Ejemplo n.º 1
0
        private void ParseExports()
        {
            _exports = new List <DllExport>();
            try
            {
                IntPtr exports = Win32NativeMethods.ImageDirectoryEntryToDataEx(handle, MappedAsImage,
                                                                                IMAGE_DIRECTORY_ENTRY_EXPORT, out int size, out IntPtr header_ptr);
                if (exports == IntPtr.Zero)
                {
                    return;
                }

                SafeHGlobalBuffer    buffer           = new SafeHGlobalBuffer(exports, size, false);
                ImageExportDirectory export_directory = buffer.Read <ImageExportDirectory>(0);
                if (export_directory.NumberOfFunctions == 0)
                {
                    return;
                }
                IntPtr funcs         = RvaToVA(export_directory.AddressOfFunctions);
                IntPtr names         = RvaToVA(export_directory.AddressOfNames);
                IntPtr name_ordinals = RvaToVA(export_directory.AddressOfNameOrdinals);

                long export_base = buffer.DangerousGetHandle().ToInt64();
                long export_top  = export_base + buffer.Length;

                int[] func_rvas = new int[export_directory.NumberOfFunctions];
                Marshal.Copy(funcs, func_rvas, 0, func_rvas.Length);
                IntPtr[] func_vas = func_rvas.Select(r => r != 0 ? RvaToVA(r) : IntPtr.Zero).ToArray();

                int[] name_rvas = new int[export_directory.NumberOfNames];
                Marshal.Copy(names, name_rvas, 0, name_rvas.Length);
                IntPtr[] name_vas = name_rvas.Select(r => r != 0 ? RvaToVA(r) : IntPtr.Zero).ToArray();

                short[] ordinals = new short[export_directory.NumberOfNames];
                Marshal.Copy(name_ordinals, ordinals, 0, ordinals.Length);

                Dictionary <int, string> ordinal_to_names = new Dictionary <int, string>();
                for (int i = 0; i < name_vas.Length; ++i)
                {
                    string name    = Marshal.PtrToStringAnsi(name_vas[i]);
                    int    ordinal = ordinals[i];
                    ordinal_to_names[ordinal] = name;
                }

                for (int i = 0; i < func_vas.Length; ++i)
                {
                    string forwarder = string.Empty;
                    long   func_va   = func_vas[i].ToInt64();
                    if (func_va >= export_base && func_va < export_top)
                    {
                        forwarder = Marshal.PtrToStringAnsi(func_vas[i]);
                        func_va   = 0;
                    }
                    _exports.Add(new DllExport(ordinal_to_names.ContainsKey(i) ? ordinal_to_names[i] : null,
                                               i + export_directory.Base, func_va, forwarder));
                }
            }
            catch
            {
            }
        }