I've decompiled a custom router ELF binary using Hex-Rays and have recently come across the following function in the binary:
pkt_hdr_t *__cdecl pkt_hdr_from_frame(frame_t *frame, uint16_t *remaining)
{
uint16_t *remaininga; // [xsp+10h] [xbp+10h]
frame_t *framea; // [xsp+18h] [xbp+18h]
uint16_t frame_sz; // [xsp+26h] [xbp+26h]
framea = frame;
remaininga = remaining;
if ( !frame || !remaining )
return 0LL;
frame_sz = ntohs(frame->sz.inner);
if ( frame_sz <= 1u )
return 0LL;
*remaininga = frame_sz - 2;
return (pkt_hdr_t *)&framea[1];
}
While it's a pretty short piece of code, I'll appreciate it if the role of remaining
and the return
line can be figured out. I know that a frame is created from a packet by appending the length of a packet to the beginning of it and the length field is 2 bytes long itself. This seems related to remaining
which is a pointer to a 16 bit (2 byte) unsigned integer. According to the line before return
it seems to me that initially the value pointed to by remaining
is the length of the frame, i.e., length of packet + 2 bytes of length field but the function pkt_hdr_from_frame
removes those 2 bytes and returns a pointer to the field in the frame located after the packet-length field (which is the beginning of the packet itself). Nevertheless, I'm confused with framea[1]
as I don't understand the indexing here, especially considering the fact that the frame_t
type is unknown to me. Thank you for your help!
EDIT 1: IDA Pro Local Types tab gives (Ordinal, Name, Size, Sync, Description) as
31 frame_t 00000002 struct {uint16_n sz;uint8_t data[];}
63 _pkt_hdr_t 00000002 struct {pkt_flags_t flags;msg_type_t msgtype;}
64 pkt_hdr_t 00000002 typedef _pkt_hdr_t