Extracting IP from getaddrinfo name

Abstract
This brief put up paperwork monitoring down the IP tackle location and worth resolved by the getaddrinfo
perform name with the assistance of x64dbg.
Instruments
To comply with alongside you have to to construct 32-bit WinSock server and client supplied by Microsoft and x64dbg.
Getaddrinfo
The getaddrinfo
perform resolves the supplied hostname to the IP tackle and its prototype is:
INT WSAAPI getaddrinfo(
[in, optional] PCSTR pNodeName,
[in, optional] PCSTR pServiceName,
[in, optional] const ADDRINFOA *pHints,
[out] PADDRINFOA *ppResult
);
The third parameter handed to getaddrinfo
is the pointer to the addrinfo
construction that comprises information in regards to the socket kind the caller helps. And the fourth parameter is the pointer to the place the tackle of the returned addrinfo
construction might be saved after the getaddrinfo
execution. The addrinfo
construction is outlined like so:
typedef struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
char *ai_canonname;
struct sockaddr *ai_addr;
struct addrinfo *ai_next;
} ADDRINFOA, *PADDRINFOA;
The sockaddr
construction for TCP/IP seems to be like this:
struct sockaddr {
ushort sa_family;
char sa_data[14];
};
struct sockaddr_in {
brief sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
Getaddrinfo and x64dbg
Now let’s begin the server app supplied by MSDN and open the shopper app in x64dbg.
To offer the command line arguments to the shopper app in x64dbg I up to date the main input parameters earlier than the principle began to execute. The argc
worth was modified from 0x1
to 0x2
and the command line saved in argv
was up to date to seem like this path_to_client.exe localhost
:
Now we are able to step into foremost and comply with alongside till we hit the decision to getaddrinfo
which is preceded by the call to ZeroMemory
making ready the hints
buffer:
As soon as ZeroMemory
(or memset operating behind the scene) is executed now we have a hints
buffer of kind addrinfo
that must be populated earlier than we execute getaddrinfo
:
Now the parameters for getaddrinfo
are pushed on the stack. Within the picture beneath 0x009FFCF0
will retailer the tackle of the addrinfo res
construction, 0x009FFCBC
shops the hints
buffer that was populated above, 0x00437B80
shops the port worth and the final parameter pushed on the stack is 0x00000000
since we might be resolving the localhost
hostname:
After the getaddrinfo
execution the 0x009FFCF0
tackle shops the tackle of the returned res
construction of kind addrinfo
(0x00EA1D28
):
Let’s comply with it in reminiscence and break down the information returned:
(4 bytes) int ai_flags; 00 00 00 00
int ai_family; 02 00 00 00 (AF_INET)
int ai_socktype; 01 00 00 00 (SOCK_STREAM)
int ai_protocol; 06 00 00 00 (TCP)
size_t ai_addrlen; 10 00 00 00 (16 bytes)
char *ai_canonname; 00 00 00 00
struct sockaddr *ai_addr; 58 7E EA 00 (0x00EA7E58)
struct sockaddr *ai_next; 00 00 00 00
The returned IP tackle is saved in ai_addr
member of the addrinfo
construction at reminiscence tackle 0x00EA7E58
so we have to comply with it in reminiscence to get the precise IP tackle worth:
Information saved at aforementioned 0x00EA7E58
reminiscence tackle symbolize the sockaddr
structure for TCP/IP. Let’s break it down too:
brief sin_family; 02 00
u_short sin_port; 69 87 (hex worth for our 27015 default port)
struct in_addr sin_addr; 7F 00 00 01 (IP worth in hex type)
char sin_zero[8]
So 0x7F000001
is the returned IP worth however it’s in hex type and we in all probability wish to convert it:
0x7F000001 binary type is:
01111111 00000000 00000000 00000001
or should you convert every 8 bits into decimal
127 0 0 1
So right here you go. The localhost
hostname was resolved to 127.0.0.1
IP as anticipated by the decision to getaddrinfo
=)