MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Как получить все заголовки/названия разделов ресурсов PE файла (.exe)?"
Answer 767413
В среде Windows - c помощью функции EnumResourceTypes. Технически, это называется не заголовками, а типами ресурсов: стандарт PE определяет структуру секции ресурсов как дерево произвольной вложенности, но на практике используется три уровня - Type, Name и Language. То, что на картинке - это Type.
При использовании функции следует учесть следующее:
Предварительно нужно загрузить изучаемый модуль в память процесса. Предпочтительно для этого использовать функцию
LoadLibraryEx
с флагомLOAD_LIBRARY_AS_DATAFILE
. При такой загрузке не выполняется никакой код из этого модуля, что позволяет улучшить производительность, обойти ограничение на загрузку 64-битных модулей в 32-битные процессы, а также уменьшает шансы наткнуться на очередную уязвимость и выполнить чей-то вредоносный код в своем процессе.Тип ресурса может определяться как строкой (обычно, для нестандартных ресурсов) так и идентификатором (обычно, для стандартных типов ресурсов). Чтобы их различать и получать осмысленные значения для каждого случая, нужно взять из заголовочных файлов Windows SDK специальные макросы:
IS_INTRESOURCE
,GET_RESOURCE_ID
,GET_RESOURCE_NAME
. Однако, для нестандартных ресурсов, определяемых идентификатором, строковое представление имени получить не получится - его знает только сама изучаемая программа.Вспомогательный класс для получения списка типов ресурсов (топорная реализация только для примера, не используйте статические переменные для промежуточных результатов в реальных проектах!):
using System; using System.Collections.Generic; using System.Windows.Forms; using System.Runtime.InteropServices; using System.IO; public static class Resources { /* Источник: http://www.pinvoke.net/default.aspx/kernel32.EnumResourceNames */ [DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags); public delegate bool EnumResTypeProc(IntPtr hModule, IntPtr lpszType, IntPtr lParam); [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] static extern bool EnumResourceTypes(IntPtr hModule, EnumResTypeProc lpEnumFunc, IntPtr lParam); public static bool IS_INTRESOURCE(IntPtr value) { if (((uint)value) > ushort.MaxValue) return false; return true; } public static uint GET_RESOURCE_ID(IntPtr value)//преобразование указателя в ID ресурса { if (IS_INTRESOURCE(value) == true) return (uint)value; throw new System.NotSupportedException("value is not an ID!"); } public static string GET_RESOURCE_NAME(IntPtr value)//преобразование указателя в имя ресурса { if (IS_INTRESOURCE(value) == true) return value.ToString(); return Marshal.PtrToStringUni((IntPtr)value); } /** ************************************************************ */ public static List<string> ResourceTypes = new List<string>();//список для промежуточного хранения строк public static bool EnumProc(IntPtr hModule, IntPtr lpszType, IntPtr lParam) { if (ResourceTypes == null) ResourceTypes = new List<string>(); string str; if (IS_INTRESOURCE(lpszType))//ресурс определяется ID { str = ((ResType)GET_RESOURCE_ID(lpszType)).ToString();//преобразование ID в строку } else { str = GET_RESOURCE_NAME(lpszType);//ресурс определяется именем } ResourceTypes.Add(str);//добавление строки в список return true; } /// <summary> /// Получение списка типов ресурсов для модуля /// </summary> public static List<string> GetResourceTypes(string file) { //загрузим модуль... IntPtr h = LoadLibraryEx(file, IntPtr.Zero, LoadLibraryFlags.LOAD_LIBRARY_AS_DATAFILE); if (h == IntPtr.Zero) throw new ApplicationException("LoadLibraryEx failed!"); ResourceTypes = new List<string>();//очистка списка EnumResourceTypes(h, EnumProc, IntPtr.Zero);//запуск процесса перечисления ресурсов return ResourceTypes; } /** ************************************************************ */ } [System.Flags] public enum LoadLibraryFlags : uint { ZERO = 0, DONT_RESOLVE_DLL_REFERENCES = 0x00000001, LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010, LOAD_LIBRARY_AS_DATAFILE = 0x00000002, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040, LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020, LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 0x00000200, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x00000100, LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800, LOAD_LIBRARY_SEARCH_USER_DIRS = 0x00000400, LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008 } /// <summary> /// Идентификаторы для типов стандартных ресурсов /// </summary> public enum ResType : uint { CURSOR = 1, BITMAP = 2, ICON = 3, MENU = 4, DIALOG = 5, STRING = 6, FONTDIR = 7, FONT = 8, ACCELERATOR = 9, RCDATA = 10, MESSAGETABLE = 11, GROUP_CURSOR = 12, GROUP_ICON = 14, VERSION = 16, DLGINCLUDE = 17, PLUGPLAY = 19, VXD = 20, ANICURSOR = 21, ANIICON = 22, HTML = 23, MANIFEST = 24 }
Пример использования:
List<string> lst = Resources.GetResourceTypes("c:\\windows\\notepad.exe"); StringBuilder sb = new StringBuilder(300); foreach (var x in lst) sb.AppendLine(x); if (lst.Count == 0) MessageBox.Show("No resources"); else MessageBox.Show(sb.ToString(),"Resource types");
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.