Jump to content

DllStructCreate, alignment problem?


j0kky
 Share

Recommended Posts

Hi guys,

I'm trying to do with gethostbyname + inet_ntoa APIs the same thing that @IPAddress1234 macros do.

This is the code in C++:

struct hostent *remoteHost;
struct in_addr addr;
remoteHost = gethostbyname(NULL);
while (remoteHost->h_addr_list[i] != 0) {
    addr.s_addr = *(u_long *) remoteHost->h_addr_list[i++];
    printf("\tIPv4 Address #%d: %s\n", i, inet_ntoa(addr));
} 

I was able to convert it thanks to some old topics, this code returns a 16-bit block IP (192.168.x.x):

TCPStartup()
$pointer = DllCall("Ws2_32.dll", "ptr", "gethostbyname", "short", "")[0]
$hostent = DllStructCreate("ptr h_name; ptr h_aliases; short h_addrtype; short h_length; ptr h_addr_list", $pointer)
$sh_addr_list = DllStructCreate("ptr", DllStructGetData($hostent, "h_addr_list"))
$inaddr = DllStructCreate("ULONG", DllStructGetData($sh_addr_list, 1))
$uint = DllStructGetData($inaddr,1)
ConsoleWrite(DllCall("Ws2_32.dll", "str", "inet_ntoa", "UINT", $uint)[0] & @CRLF)
TCPShutdown()

But I really don't understand why it is necessary to add this intermediate step:

$sh_addr_list = DllStructCreate("ptr", DllStructGetData($hostent, 5))

For example, this code returns a sort of 20-bit block IP (172.x.x.x) with a variable third and fourth octet.

TCPStartup()
$pointer = DllCall("Ws2_32.dll", "ptr", "gethostbyname", "short", "")[0]
$hostent = DllStructCreate("ptr h_name; ptr h_aliases; short h_addrtype; short h_length; ptr h_addr_list", $pointer)
$inaddr = DllStructCreate("ULONG", DllStructGetData($hostent, "h_addr_list"))
$uint = DllStructGetData($inaddr,1)
ConsoleWrite(DllCall("Ws2_32.dll", "str", "inet_ntoa", "UINT", $uint)[0] & @CRLF)
TCPShutdown()

I think it is a problem about the structure alignment but I'm not sure, someone of you can explain it to me?

Thank to all!

Edited by j0kky
Link to comment
Share on other sites

because it's a pointer to a pointer.

so. There is not alignment problem.

saludos

Edited by Danyfirex
Link to comment
Share on other sites

It is clear.

Buuut why is a pointer to a pointer needed? Where is written in MSDN documentation that inet_ntoa needs a pointer to a pointer argument?

EDIT:

In few words, if I didn't try the topic that put me in the right way, how can I write the right code?

Edited by j0kky
Link to comment
Share on other sites

Your way is correct.

h_addr_list is a array of pointers.(C way).

In autoit just jump 4 byte forward.

inet_ntoa need a pointer to in_addr.

h_addr_list are serverals n_addr structure by its pointer.

Saludos

Edited by Danyfirex
Link to comment
Share on other sites

Another thing gethostbyname need a const char *name not a short.

Saludos

Link to comment
Share on other sites

In autoit just jump 4 byte forward.

This is a precious information! And I have never tried it in the Autoit help file.

But I still don't understand why I need to use a pointer to a pointer. Why doesn't it work using just the pointer DllStructGetData($hostent, "h_addr_list")? (first I used this way, as in script 2, but it didn't work)

Sorry for the insistence but I'm realizing I've a lack of knowledge on this topic and I would like to fill it.

Edited by j0kky
Link to comment
Share on other sites

Becuase You're passing the array pointer. not the first array[0] value.

TCPStartup()
$pointer = DllCall("Ws2_32.dll", "ptr", "gethostbyname", "str", "")
$pointer=$pointer[0]
$hostent = DllStructCreate("ptr h_name; ptr h_aliases; short h_addrtype; short h_length;ptr h_addr_list", $pointer)
$sh_addr_list = DllStructCreate("ptr", DllStructGetData($hostent, "h_addr_list")) ;We get the Pointer to an array of addr 
$inaddr = DllStructCreate("ptr", DllStructGetData($sh_addr_list, 1));we get the array[0] ;if you want to get another index just plus 4
$uint = DllStructGetData($inaddr,1)
$ret=DllCall("Ws2_32.dll", "str", "inet_ntoa", "UINT", $uint)
ConsoleWrite( $ret[0] & @CRLF)
TCPShutdown()

Edit:

sfM1xB8.png

saludos

Edited by Danyfirex
Link to comment
Share on other sites

Thank you very much!!! I think I've got it!

Just to resume from your last script:

DllStructGetData($hostent, "h_addr_list") -> "h_addr_list" array, as in C it has the first array element value (h_addr_list[0])

DllStructGetData($sh_addr_list, 1) -> pointer to "h_addr_list" array first element (h_addr_list[0])

Just the last question, I promise :) : in this particular situation, aren't they both equal to h_addr_list[0]?

Link to comment
Share on other sites

DllStructGetData($hostent, "h_addr_list") -> "h_addr_list" array, as in C it has the first array element value (h_addr_list[0])
 
Here I got the Pointer to the pointer(the array). 

 
DllStructGetData($sh_addr_list, 1) should be h_addr_list[0]
 
Saludos

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...