TransWikia.com

What does this custom piece of frame manipulation code from a router binary do?

Reverse Engineering Asked on January 6, 2021

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

One Answer

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

Correct answer by blabb on January 6, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP