Zero length array in variable length structures

00000000 struct struct_1 // sizeof=0x4;variable_size
00000000 {                                       // XREF: seg002:00811A12/r
00000000                                         // seg002:00811A16/r
00000000     __int16 type;
00000002     __int16 length;
00000004     __int16 data[];
00000004 };

I created a variable-length structure. However, when I want to apply it to data with empty array, it treats the immediately following data as array elements of the data structure.

It functions normally when expanded. The issue occurs when collapsed. It should appear as follows:

seg002:00811A12                 struct_1 <14Ah, 0F101h>
seg002:00811A16                 struct_1 <0E0D3h, 888Dh>
seg002:00811A1A                 db  36h ; 6
seg002:00811A1B                 db    7

I don’t know how to fix this.

AFAIK this is expected behavior per IDA’s variable-length structure design—IDA cannot infer VLA size, so you must always explicitly specify it.

From the VLA tutorial: “since the structure size cannot be calculated by IDA we need to specify the desired structure size by selecting an area to convert to a structure. Another way to specify the size would be to use the * hotkey. In all cases, you need to tell IDA the exact size.”

Workaround (manual):

  1. Position cursor at 0x00811A12
  2. Select exactly 4 bytes (drag to 0x00811A15, or press * and enter 4)
  3. Alt+Q → apply struct_1

Repeat for 0x00811A16.

Solution (IDAPython):

import idc
import ida_bytes

def apply_varlen_struct(ea, size, struct_name):
    sid = idc.get_struc_id(struct_name)
    ida_bytes.del_items(ea, ida_bytes.DELIT_SIMPLE, size)
    idc.create_struct(ea, size, sid)

# Base struct only, 0 array elements
apply_varlen_struct(0x00811A12, 4, "struct_1")
apply_varlen_struct(0x00811A16, 4, "struct_1")

For batch processing (if length field encodes element count):

def apply_struct1_auto(ea):
    nelem = ida_bytes.get_word(ea + 2)  # length field
    total_size = 4 + (nelem * 2)
    apply_varlen_struct(ea, total_size, "struct_1")

The dual-struct approach (separate struct_1_base without VLA) also works but adds maintenance overhead.

Workaround (manual):

  1. Position cursor at 0x00811A12
  2. Select exactly 4 bytes (drag to 0x00811A15, or press * and enter 4)
  3. Alt+Q → apply struct_1

gif
I tried it, but it didn’t work.
I noticed the source text in the tutorial contained structures with empty arrays. However, the tutorial didn’t show how it looks like when expanded or collapsed. So I’m not sure if this is supposed to happen.

gif (2)

If the structure is applied to data exceeding six bytes, it can handle it correctly.

I tried to repro your case but failed. Could you share your i64 file? Thanks!

Sorry, it was my mistake. I was previously using version 9.1. After upgrading to version 9.2, it displays normally now.

2 Likes

In fact, this is not the full truth. If the last field is a 0-sized string literal (e.g.A→ 0 elements), then IDA will try to determine the end of the string when applying the struct.

1 Like