Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I load a byte[] array into a structure in C#?

Consider following structure where the length of both username and password is 17:

struct LoginPacket
{
    public int unk1;
    public string username;
    public string password;
}

Also this byte array

00 00 00 00 6A 6D 32 6D 65 00 72 00 7A 76 72 00 98 FD 18 00 A0 68 65 72 65 49 73
70 61 73 73 00 00 00 00 00 FF FF 31 2E 30 30 2E 30 30 00 00 00 C7 9D 72 00 04 00
00 31 2E 31 30 2E 32 37 00 0C 2C F6 24 16 2C F6 24 16

Is it possible to load this byte array into the above structure? There is something called Marshal, but it doesn't quite work for me.

like image 443
jM2.me Avatar asked Oct 20 '25 15:10

jM2.me


1 Answers

Here you are, this answer uses the marshalling system in .NET. The structure itself contains the recipe on how to decipher a byte array. If you can't do that, you need manual code.

void Main()
{
    byte[] bytes = new byte[]
    {
        0x00, 0x00, 0x00, 0x00, 0x6A, 0x6D, 0x32, 0x6D, 0x65, 0x00, 0x72, 0x00, 0x7A, 0x76, 0x72, 0x00, 0x98, 0xFD, 0x18, 0x00, 0xA0, 0x68, 0x65, 0x72, 0x65, 0x49, 0x73,
        0x70, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x31, 0x2E, 0x30, 0x30, 0x2E, 0x30, 0x30, 0x00, 0x00, 0x00, 0xC7, 0x9D, 0x72, 0x00, 0x04, 0x00,
        0x00, 0x31, 0x2E, 0x31, 0x30, 0x2E, 0x32, 0x37, 0x00, 0x0C, 0x2C, 0xF6, 0x24, 0x16, 0x2C, 0xF6, 0x24, 0x16
    };

    var packet = BytesToStructure<LoginPacket>(bytes);
    packet.Dump();
}

static T BytesToStructure<T>(byte[] bytes)
{
    int size = Marshal.SizeOf(typeof(T));
    if (bytes.Length < size)
        throw new Exception("Invalid parameter");

    IntPtr ptr = Marshal.AllocHGlobal(size);
    try
    {
        Marshal.Copy(bytes, 0, ptr, size);
        return (T)Marshal.PtrToStructure(ptr, typeof(T));
    }
    finally
    {
        Marshal.FreeHGlobal(ptr);
    }
}

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet=CharSet.Ansi)]
struct LoginPacket
{
    public int unk1;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=17)]
    public string username;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=17)]
    public string password;
}

When executed in LINQPad you get this:

unk1: 0 
username: jm2me 
password: hereIspass
like image 140
Lasse V. Karlsen Avatar answered Oct 23 '25 04:10

Lasse V. Karlsen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!