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
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
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP