mirror of
https://github.com/claunia/libexeinfo.git
synced 2025-12-16 19:14:24 +00:00
Add decoding of BeOS resources section. (It's the same on ELF and PEFF).
Thanks to @waddlesplash for pointing me to the structures.
This commit is contained in:
85
libexeinfo/BeOS/Consts.cs
Normal file
85
libexeinfo/BeOS/Consts.cs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
//
|
||||||
|
// Consts.cs
|
||||||
|
//
|
||||||
|
// Author:
|
||||||
|
// Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017-2018 Copyright © Claunia.com
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
namespace libexeinfo.BeOS
|
||||||
|
{
|
||||||
|
static class Consts
|
||||||
|
{
|
||||||
|
internal const int RESOURCES_HEADER_MAGIC = 0x444F1000;
|
||||||
|
|
||||||
|
// String enums not supported in C# *sad*
|
||||||
|
public const string B_AFFINE_TRANSFORM_TYPE = "AMTX";
|
||||||
|
public const string B_ALIGNMENT_TYPE = "ALGN";
|
||||||
|
public const string B_ANY_TYPE = "ANYT";
|
||||||
|
public const string B_ATOM_TYPE = "ATOM";
|
||||||
|
public const string B_ATOMREF_TYPE = "ATMR";
|
||||||
|
public const string B_BOOL_TYPE = "BOOL";
|
||||||
|
public const string B_CHAR_TYPE = "CHAR";
|
||||||
|
public const string B_COLOR_8_BIT_TYPE = "CLRB";
|
||||||
|
public const string B_DOUBLE_TYPE = "DBLE";
|
||||||
|
public const string B_FLOAT_TYPE = "FLOT";
|
||||||
|
public const string B_GRAYSCALE_8_BIT_TYPE = "GRYB";
|
||||||
|
public const string B_INT16_TYPE = "SHRT";
|
||||||
|
public const string B_INT32_TYPE = "LONG";
|
||||||
|
public const string B_INT64_TYPE = "LLNG";
|
||||||
|
public const string B_INT8_TYPE = "BYTE";
|
||||||
|
public const string B_LARGE_ICON_TYPE = "ICON";
|
||||||
|
public const string B_MEDIA_PARAMETER_GROUP_TYPE = "BMCG";
|
||||||
|
public const string B_MEDIA_PARAMETER_TYPE = "BMCT";
|
||||||
|
public const string B_MEDIA_PARAMETER_WEB_TYPE = "BMCW";
|
||||||
|
public const string B_MESSAGE_TYPE = "MSGG";
|
||||||
|
public const string B_MESSENGER_TYPE = "MSNG";
|
||||||
|
public const string B_MIME_TYPE = "MIME";
|
||||||
|
public const string B_MINI_ICON_TYPE = "MICN";
|
||||||
|
public const string B_MONOCHROME_1_BIT_TYPE = "MNOB";
|
||||||
|
public const string B_OBJECT_TYPE = "OPTR";
|
||||||
|
public const string B_OFF_T_TYPE = "OFFT";
|
||||||
|
public const string B_PATTERN_TYPE = "PATN";
|
||||||
|
public const string B_POINTER_TYPE = "PNTR";
|
||||||
|
public const string B_POINT_TYPE = "BPNT";
|
||||||
|
public const string B_PROPERTY_INFO_TYPE = "SCTD";
|
||||||
|
public const string B_RAW_TYPE = "RAWT";
|
||||||
|
public const string B_RECT_TYPE = "RECT";
|
||||||
|
public const string B_REF_TYPE = "RREF";
|
||||||
|
public const string B_RGB_32_BIT_TYPE = "RGBB";
|
||||||
|
public const string B_RGB_COLOR_TYPE = "RGBC";
|
||||||
|
public const string B_SIZE_TYPE = "SIZE";
|
||||||
|
public const string B_SIZE_T_TYPE = "SIZT";
|
||||||
|
public const string B_SSIZE_T_TYPE = "SSZT";
|
||||||
|
public const string B_STRING_TYPE = "CSTR";
|
||||||
|
public const string B_STRING_LIST_TYPE = "STRL";
|
||||||
|
public const string B_TIME_TYPE = "TIME";
|
||||||
|
public const string B_UINT16_TYPE = "USHT";
|
||||||
|
public const string B_UINT32_TYPE = "ULNG";
|
||||||
|
public const string B_UINT64_TYPE = "ULLG";
|
||||||
|
public const string B_UINT8_TYPE = "UBYT";
|
||||||
|
public const string B_VECTOR_ICON_TYPE = "VICN";
|
||||||
|
public const string B_XATTR_TYPE = "XATR";
|
||||||
|
public const string B_NETWORK_ADDRESS_TYPE = "NWAD";
|
||||||
|
public const string B_MIME_STRING_TYPE = "MIMS";
|
||||||
|
public const string B_ASCII_TYPE = "TEXT";
|
||||||
|
}
|
||||||
|
}
|
||||||
206
libexeinfo/BeOS/Resources.cs
Normal file
206
libexeinfo/BeOS/Resources.cs
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace libexeinfo.BeOS
|
||||||
|
{
|
||||||
|
public static class Resources
|
||||||
|
{
|
||||||
|
public static ResourceTypeBlock[] Decode(byte[] data, bool bigEndian = false)
|
||||||
|
{
|
||||||
|
return bigEndian ? ResourceEdoced(data) : ResourceDecode(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ResourceTypeBlock[] ResourceDecode(byte[] data)
|
||||||
|
{
|
||||||
|
uint pos = 0;
|
||||||
|
|
||||||
|
byte[] buffer = new byte[Marshal.SizeOf(typeof(ResourcesHeader))];
|
||||||
|
Array.Copy(data, pos, buffer, 0, buffer.Length);
|
||||||
|
ResourcesHeader header = BigEndianMarshal.ByteArrayToStructureLittleEndian<ResourcesHeader>(buffer);
|
||||||
|
|
||||||
|
if(header.magic != Consts.RESOURCES_HEADER_MAGIC) return null;
|
||||||
|
|
||||||
|
ResourceIndexEntry[] indexes = new ResourceIndexEntry[header.resource_count];
|
||||||
|
pos = header.index_section_offset;
|
||||||
|
buffer = new byte[Marshal.SizeOf(typeof(ResourceIndexSectionHeader))];
|
||||||
|
if(pos + buffer.Length > data.Length) return null;
|
||||||
|
|
||||||
|
Array.Copy(data, pos, buffer, 0, buffer.Length);
|
||||||
|
ResourceIndexSectionHeader indexHeader =
|
||||||
|
BigEndianMarshal.ByteArrayToStructureLittleEndian<ResourceIndexSectionHeader>(buffer);
|
||||||
|
pos += (uint)buffer.Length;
|
||||||
|
|
||||||
|
for(int i = 0; i < header.resource_count; i++)
|
||||||
|
{
|
||||||
|
buffer = new byte[Marshal.SizeOf(typeof(ResourceIndexEntry))];
|
||||||
|
Array.Copy(data, pos, buffer, 0, buffer.Length);
|
||||||
|
indexes[i] = BigEndianMarshal.ByteArrayToStructureLittleEndian<ResourceIndexEntry>(buffer);
|
||||||
|
pos += (uint)buffer.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = indexHeader.info_table_offset;
|
||||||
|
string[] types = new string[header.resource_count];
|
||||||
|
bool terminated = true;
|
||||||
|
string currentType = null;
|
||||||
|
string[] names = new string[header.resource_count];
|
||||||
|
ResourceInfo[] infos = new ResourceInfo[header.resource_count];
|
||||||
|
|
||||||
|
for(int i = 0; i < header.resource_count; i++)
|
||||||
|
{
|
||||||
|
if(terminated)
|
||||||
|
{
|
||||||
|
buffer = new byte[4];
|
||||||
|
Array.Copy(data, pos, buffer, 0, 4);
|
||||||
|
currentType = Encoding.ASCII.GetString(buffer.Reverse().ToArray());
|
||||||
|
terminated = false;
|
||||||
|
pos += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = new byte[Marshal.SizeOf(typeof(ResourceInfo))];
|
||||||
|
Array.Copy(data, pos, buffer, 0, buffer.Length);
|
||||||
|
infos[i] = BigEndianMarshal.ByteArrayToStructureLittleEndian<ResourceInfo>(buffer);
|
||||||
|
pos += (uint)buffer.Length;
|
||||||
|
buffer = new byte[infos[i].name_size - 1];
|
||||||
|
Array.Copy(data, pos, buffer, 0, buffer.Length);
|
||||||
|
names[i] = Encoding.ASCII.GetString(buffer);
|
||||||
|
pos += (uint)(buffer.Length + 1);
|
||||||
|
types[i] = currentType;
|
||||||
|
|
||||||
|
if(BitConverter.ToInt32(data, (int)pos) != -1 ||
|
||||||
|
BitConverter.ToInt32(data, (int)pos + 4) != -1) continue;
|
||||||
|
|
||||||
|
terminated = true;
|
||||||
|
pos += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<string, List<Resource>> rezzes = new Dictionary<string, List<Resource>>();
|
||||||
|
for(int i = 0; i < header.resource_count; i++)
|
||||||
|
{
|
||||||
|
rezzes.TryGetValue(types[i], out List<Resource> thisRezzes);
|
||||||
|
|
||||||
|
if(thisRezzes == null) thisRezzes = new List<Resource>();
|
||||||
|
|
||||||
|
Resource rez = new Resource
|
||||||
|
{
|
||||||
|
id = infos[i].id,
|
||||||
|
index = infos[i].index,
|
||||||
|
name = names[i],
|
||||||
|
data = new byte[indexes[i].size]
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.Copy(data, indexes[i].offset, rez.data, 0, rez.data.Length);
|
||||||
|
|
||||||
|
thisRezzes.Add(rez);
|
||||||
|
rezzes.Remove(types[i]);
|
||||||
|
rezzes.Add(types[i], thisRezzes);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ResourceTypeBlock> result = new List<ResourceTypeBlock>();
|
||||||
|
foreach(KeyValuePair<string, List<Resource>> kvp in rezzes)
|
||||||
|
{
|
||||||
|
ResourceTypeBlock block = new ResourceTypeBlock {type = kvp.Key, resources = kvp.Value.ToArray()};
|
||||||
|
result.Add(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
static ResourceTypeBlock[] ResourceEdoced(byte[] data)
|
||||||
|
{
|
||||||
|
uint pos = 0;
|
||||||
|
|
||||||
|
byte[] buffer = new byte[Marshal.SizeOf(typeof(ResourcesHeader))];
|
||||||
|
Array.Copy(data, pos, buffer, 0, buffer.Length);
|
||||||
|
ResourcesHeader header = BigEndianMarshal.ByteArrayToStructureBigEndian<ResourcesHeader>(buffer);
|
||||||
|
|
||||||
|
if(header.magic != Consts.RESOURCES_HEADER_MAGIC) return null;
|
||||||
|
|
||||||
|
ResourceIndexEntry[] indexes = new ResourceIndexEntry[header.resource_count];
|
||||||
|
pos = header.index_section_offset;
|
||||||
|
buffer = new byte[Marshal.SizeOf(typeof(ResourceIndexSectionHeader))];
|
||||||
|
if(pos + buffer.Length > data.Length) return null;
|
||||||
|
|
||||||
|
Array.Copy(data, pos, buffer, 0, buffer.Length);
|
||||||
|
ResourceIndexSectionHeader indexHeader =
|
||||||
|
BigEndianMarshal.ByteArrayToStructureBigEndian<ResourceIndexSectionHeader>(buffer);
|
||||||
|
pos += (uint)buffer.Length;
|
||||||
|
|
||||||
|
for(int i = 0; i < header.resource_count; i++)
|
||||||
|
{
|
||||||
|
buffer = new byte[Marshal.SizeOf(typeof(ResourceIndexEntry))];
|
||||||
|
Array.Copy(data, pos, buffer, 0, buffer.Length);
|
||||||
|
indexes[i] = BigEndianMarshal.ByteArrayToStructureBigEndian<ResourceIndexEntry>(buffer);
|
||||||
|
pos += (uint)buffer.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = indexHeader.info_table_offset;
|
||||||
|
string[] types = new string[header.resource_count];
|
||||||
|
bool terminated = true;
|
||||||
|
string currentType = null;
|
||||||
|
string[] names = new string[header.resource_count];
|
||||||
|
ResourceInfo[] infos = new ResourceInfo[header.resource_count];
|
||||||
|
|
||||||
|
for(int i = 0; i < header.resource_count; i++)
|
||||||
|
{
|
||||||
|
if(terminated)
|
||||||
|
{
|
||||||
|
buffer = new byte[4];
|
||||||
|
Array.Copy(data, pos, buffer, 0, 4);
|
||||||
|
currentType = Encoding.ASCII.GetString(buffer.ToArray());
|
||||||
|
terminated = false;
|
||||||
|
pos += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = new byte[Marshal.SizeOf(typeof(ResourceInfo))];
|
||||||
|
Array.Copy(data, pos, buffer, 0, buffer.Length);
|
||||||
|
infos[i] = BigEndianMarshal.ByteArrayToStructureBigEndian<ResourceInfo>(buffer);
|
||||||
|
pos += (uint)buffer.Length;
|
||||||
|
buffer = new byte[infos[i].name_size - 1];
|
||||||
|
Array.Copy(data, pos, buffer, 0, buffer.Length);
|
||||||
|
names[i] = Encoding.ASCII.GetString(buffer);
|
||||||
|
pos += (uint)(buffer.Length + 1);
|
||||||
|
types[i] = currentType;
|
||||||
|
|
||||||
|
if(BitConverter.ToInt32(data, (int)pos) != -1 ||
|
||||||
|
BitConverter.ToInt32(data, (int)pos + 4) != -1) continue;
|
||||||
|
|
||||||
|
terminated = true;
|
||||||
|
pos += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<string, List<Resource>> rezzes = new Dictionary<string, List<Resource>>();
|
||||||
|
for(int i = 0; i < header.resource_count; i++)
|
||||||
|
{
|
||||||
|
rezzes.TryGetValue(types[i], out List<Resource> thisRezzes);
|
||||||
|
|
||||||
|
if(thisRezzes == null) thisRezzes = new List<Resource>();
|
||||||
|
|
||||||
|
Resource rez = new Resource
|
||||||
|
{
|
||||||
|
id = infos[i].id,
|
||||||
|
index = infos[i].index,
|
||||||
|
name = names[i],
|
||||||
|
data = new byte[indexes[i].size]
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.Copy(data, indexes[i].offset, rez.data, 0, rez.data.Length);
|
||||||
|
|
||||||
|
thisRezzes.Add(rez);
|
||||||
|
rezzes.Remove(types[i]);
|
||||||
|
rezzes.Add(types[i], thisRezzes);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ResourceTypeBlock> result = new List<ResourceTypeBlock>();
|
||||||
|
foreach(KeyValuePair<string, List<Resource>> kvp in rezzes)
|
||||||
|
{
|
||||||
|
ResourceTypeBlock block = new ResourceTypeBlock {type = kvp.Key, resources = kvp.Value.ToArray()};
|
||||||
|
result.Add(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
205
libexeinfo/BeOS/Structs.cs
Normal file
205
libexeinfo/BeOS/Structs.cs
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
//
|
||||||
|
// Structs.cs
|
||||||
|
//
|
||||||
|
// Author:
|
||||||
|
// Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017-2018 Copyright © Claunia.com
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// Structures thanks to Ingo Weinhold and Haiku
|
||||||
|
namespace libexeinfo.BeOS
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Header of resource data
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct ResourcesHeader
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <see cref="Consts.RESOURCES_HEADER_MAGIC" />
|
||||||
|
/// </summary>
|
||||||
|
public uint magic;
|
||||||
|
/// <summary>
|
||||||
|
/// How many resources are present
|
||||||
|
/// </summary>
|
||||||
|
public uint resource_count;
|
||||||
|
/// <summary>
|
||||||
|
/// Offset to <see cref="ResourceIndexSectionHeader" />
|
||||||
|
/// </summary>
|
||||||
|
public uint index_section_offset;
|
||||||
|
/// <summary>
|
||||||
|
/// Size of the admin section
|
||||||
|
/// </summary>
|
||||||
|
public uint admin_section_size;
|
||||||
|
/// <summary>
|
||||||
|
/// Padding
|
||||||
|
/// </summary>
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)]
|
||||||
|
public uint[] pad;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Header of the resource index, followed by as many <see cref="ResourceIndexEntry" /> as resources are in the file
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct ResourceIndexSectionHeader
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Offset to itself
|
||||||
|
/// </summary>
|
||||||
|
public uint index_section_offset;
|
||||||
|
/// <summary>
|
||||||
|
/// Size in bytes of the whole index section
|
||||||
|
/// </summary>
|
||||||
|
public uint index_section_size;
|
||||||
|
/// <summary>
|
||||||
|
/// Unused
|
||||||
|
/// </summary>
|
||||||
|
public uint unused_data1;
|
||||||
|
/// <summary>
|
||||||
|
/// Offset to an unknown section
|
||||||
|
/// </summary>
|
||||||
|
public uint unknown_section_offset;
|
||||||
|
/// <summary>
|
||||||
|
/// Size in bytes of the unknown section
|
||||||
|
/// </summary>
|
||||||
|
public uint unknown_section_size;
|
||||||
|
/// <summary>
|
||||||
|
/// Unused
|
||||||
|
/// </summary>
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 25)]
|
||||||
|
public uint[] unused_data2;
|
||||||
|
/// <summary>
|
||||||
|
/// Offset to <see cref="ResourceInfoBlock" /> table
|
||||||
|
/// </summary>
|
||||||
|
public uint info_table_offset;
|
||||||
|
/// <summary>
|
||||||
|
/// Sizee of <see cref="ResourceInfoBlock" /> table
|
||||||
|
/// </summary>
|
||||||
|
public uint info_table_size;
|
||||||
|
/// <summary>
|
||||||
|
/// Unused
|
||||||
|
/// </summary>
|
||||||
|
public uint unused_data3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A resource index entry
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct ResourceIndexEntry
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Offset to resource
|
||||||
|
/// </summary>
|
||||||
|
public uint offset;
|
||||||
|
/// <summary>
|
||||||
|
/// Size of resource
|
||||||
|
/// </summary>
|
||||||
|
public uint size;
|
||||||
|
/// <summary>
|
||||||
|
/// Padding
|
||||||
|
/// </summary>
|
||||||
|
public uint pad;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resource information, followed by <see cref="name_size" /> ASCII characters with the name
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||||
|
struct ResourceInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Resource ID
|
||||||
|
/// </summary>
|
||||||
|
public int id;
|
||||||
|
/// <summary>
|
||||||
|
/// Resource index, not related to index table
|
||||||
|
/// </summary>
|
||||||
|
public int index;
|
||||||
|
/// <summary>
|
||||||
|
/// Size of name following this structure
|
||||||
|
/// </summary>
|
||||||
|
public ushort name_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Separator between resource types
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct ResourceInfoSeparator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Must be 0xFFFFFFFF
|
||||||
|
/// </summary>
|
||||||
|
public uint value1;
|
||||||
|
/// <summary>
|
||||||
|
/// Must be 0xFFFFFFFF
|
||||||
|
/// </summary>
|
||||||
|
public uint value2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resource info block, followed by <see cref="ResourceInfoSeparator" /> when the <see cref="info" /> array ends
|
||||||
|
/// </summary>
|
||||||
|
struct ResourceInfoBlock
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// OSType code
|
||||||
|
/// </summary>
|
||||||
|
public uint type;
|
||||||
|
/// <summary>
|
||||||
|
/// Array of <see cref="ResourceInfo" />. Unless a <see cref="ResourceInfoSeparator" /> is found.
|
||||||
|
/// </summary>
|
||||||
|
public ResourceInfo[] info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// End of the resource info table
|
||||||
|
/// </summary>
|
||||||
|
struct ResourceInfoTableEnd
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Resource info table checksum
|
||||||
|
/// </summary>
|
||||||
|
public uint checksum;
|
||||||
|
/// <summary>
|
||||||
|
/// Must be 0
|
||||||
|
/// </summary>
|
||||||
|
public uint terminator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ResourceTypeBlock
|
||||||
|
{
|
||||||
|
public Resource[] resources;
|
||||||
|
public string type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Resource
|
||||||
|
{
|
||||||
|
public byte[] data;
|
||||||
|
public int id;
|
||||||
|
public int index;
|
||||||
|
public string name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -54,6 +54,7 @@ namespace libexeinfo
|
|||||||
public Version[] Versions;
|
public Version[] Versions;
|
||||||
public ResourceNode WindowsResourcesRoot;
|
public ResourceNode WindowsResourcesRoot;
|
||||||
WindowsHeader64 winHeader;
|
WindowsHeader64 winHeader;
|
||||||
|
public BeOS.ResourceTypeBlock[] beosResources;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="T:libexeinfo.PE" /> class.
|
/// Initializes a new instance of the <see cref="T:libexeinfo.PE" /> class.
|
||||||
@@ -385,7 +386,10 @@ namespace libexeinfo
|
|||||||
rsrc.virtualSize = rsrc.sizeOfRawData;
|
rsrc.virtualSize = rsrc.sizeOfRawData;
|
||||||
newSectionHeaders.Add(".rsrc", rsrc);
|
newSectionHeaders.Add(".rsrc", rsrc);
|
||||||
|
|
||||||
// TODO: Decode BeOS resource format
|
buffer = new byte[rsrc.sizeOfRawData];
|
||||||
|
BaseStream.Position = rsrc.pointerToRawData;
|
||||||
|
BaseStream.Read(buffer, 0, buffer.Length);
|
||||||
|
beosResources = BeOS.Resources.Decode(buffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,6 +50,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="AtariST\Enums.cs" />
|
<Compile Include="AtariST\Enums.cs" />
|
||||||
|
<Compile Include="BeOS\Consts.cs" />
|
||||||
|
<Compile Include="BeOS\Resources.cs" />
|
||||||
|
<Compile Include="BeOS\Structs.cs" />
|
||||||
<Compile Include="Enums.cs" />
|
<Compile Include="Enums.cs" />
|
||||||
<Compile Include="GEM\Enums.cs" />
|
<Compile Include="GEM\Enums.cs" />
|
||||||
<Compile Include="GEM\Resources.cs" />
|
<Compile Include="GEM\Resources.cs" />
|
||||||
|
|||||||
Reference in New Issue
Block a user