0

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
1

ntohs basically converts a netshort to hostshort

>>> import socket
>>> print (hex(socket.ntohs(0x1337)))
0x3713
>>> print (hex(socket.ntohs(0x3713)))
0x1337
>>>

it will write back 0x3713-0x2 = 0x3711 or 0x1337 - 0x2 = 0x1335
in the address pointed by remaining if it is > 1u

and return back an address a pointer to pkt_hdr_t

comment edit

no remaining is an incoming pointer
it is a writable address
this function writes back whatever is remaining from the result of ntohs() call - 2 to this pointer
it is like *blah = foo where foo is an unsigned short and blah is a pointer to unsigned short

so it may be called like unsigned short * xyz = 0; pkt_whatever(abc,xyz) { xyz = some unsigned short whose value is 123xxyy }

so on incoming xyz will be holding 0 when it goes out of the function xyz will be holding 123xxyy

3
  • So essentially my interpretation may be right, correct? In particular if the value pointed to by remaining is larger than 1, it will subtract 2 from it and write it to the same location. Also, can you comment on the indexing in framea[1]? Thanks for the brief illustration of ntohs() as well! – Newbie Dec 28 '20 at 16:38
  • no you have a misunderstanding it is an incoming pointer it can be holding garbage or any value it was initialised with and most of the time it would be initialised with 0 and when the function returns it will hold whatever is the result of ntohs()-2 i also edited the answer – blabb Dec 28 '20 at 17:00
  • I'm so sorry, what I said made absolutely no sense. I actually meant what you just mentioned. No matter what the value pointed to by remaining is it will get updated to the value ntohs()-2 if in fact the return value of ntohs() is larger than 1. – Newbie Dec 28 '20 at 17:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.