tags:

views:

134

answers:

2

What I'm trying to accomplish:

I am making 3000 requests and capturing 8 bytes of that request. I stick the response in:

struct negs
{
    int neg_num;
    char neg_key[9];
};

where neg_num == i (the request number) and memcpy(nego[neg_count].neg_key, recv_data+73,8);

I need to find any duplicate neg_keys in the nego struct. I am trying to use qsort to accomplish this... this is my compare function:

int compare( const void* a, const void* b ){
    negs *ia = *(negs **)a;
    negs *ib = *(negs **)b;
    return memcmp(ia->neg_key, ia->neg_key, 8);
}

and my call to qsort:

    printf("Sizeof = %d"), sizeof(*nego);
    qsort(nego,4,sizeof(*nego),compare);
    printf("Sizeof2 = %d"), sizeof(*nego);

I was planning on just seeing if there is a diff in sizeof after the call but this always returns:

Sizeof = 159218900
Sizeof2 = 4

Am I approaching this the wrong way? any suggestions?


Here is the relevant code that is segfaulting:

char current_key[9];
int key_index = 0;
int dupe_count = 0;

typedef struct {
    int neg_num;
    char neg_key[9];
} negs;

struct negs
{
    int neg_num;
    char neg_key[9];
};



...

int compare( const void* a, const void* b ){
    negs *ia = *(negs **)a;
    negs *ib = *(negs **)b;
    return memcmp(ia->neg_key, ia->neg_key, 8);
}


...


main(int argc, char **argv) {
    char send_smbNego[] = {
0x00,0x00,0x00,0x54,0xFf,0x53
        };

    int neg_count = 0;
    int neg_max = 3000;

    struct negs *nego;



    nego = malloc(neg_max * sizeof(struct negs));
    for (neg_count = 0 ; neg_count < neg_max ; neg_count++){
                if ((sock = open_socket(target, TCP, 445))>=0) {
                        send(sock, send_smbNego, sizeof(send_smbNego), 0);
                        len = recv(sock, recv_data, OUTBUF_LEN, 0);
            if (len > 81) { // This should be changed to look for SMB header: ff534d42 followed by 72 which is SMB Command Negotiate Protocol, followed by 00000000 which indicates success.  The encryption key or challenge token is at offset 73 and is 8 bytes long;
                nego[neg_count].neg_num = neg_count;
                memcpy(current_key, recv_data+73,8);                   
                memcpy(nego[neg_count].neg_key, recv_data+73,8);
                //print_hex("Key 1 = ",nego[neg_count].neg_key,8);
                //printf("\n");
            }

    close(sock);

    }
    print_hex("Key number 0",nego[0].neg_key,8);
    printf("Sizeof = %d"), sizeof(*nego);
    qsort(nego,4,sizeof(*nego),compare);
    printf("Sizeof2 = %d"), sizeof(*nego);



}
}
A: 

You placed the sizeof outside of printf's parantheses. It should be:

printf("Sizeof = %d\n", sizeof(*nego));

However, I don't see what you're trying to accomplish since the sizeof will never change - it is calculated at compile time according to the type of nego.


Regarding your compare function, if nego is an array of struct negs (and not an array of pointers), then you need to cast the parameters to negs *, not to negs**. Additionally, you're currently comparing the first key with itself in the call to memcmp.


Edit: Your segfaulting is caused by your invalid usage of double pointers, as I mentioned. Your compare function should look like this:

int compare( const void* a, const void* b ){
    negs *ia = (negs *)a;
    negs *ib = (negs *)b;
    return memcmp(ia->neg_key, ib->neg_key, 8);
}
interjay
Thank you both very much for the help... I understand now that qsort will simply sort my array of structures and that I'll have to write a loop to check if memcmp(nego[i].key == nego[i+1], 8) ... but I'm not there quite yet. Unfortunately after making the changes suggested I am segfaulting.. specifically, when I fixed the error in the return:return memcmp(ia->neg_key, ib->neg_key, 8);any thoughts as to why this is segfaulting?
wish_it_was_python
@wish_it_was_python: This is because of using `negs**` in the compare function, see my edited answer.
interjay
You don't need the cast: `const negs *ia = a; const negs *ib = b;` works.
Alok
+1  A: 

For starters it looks like:-

return memcmp(ia->neg_key, ia->neg_key, 8);

should be:-

return memcmp(ia->neg_key, ib->neg_key, 8);

You also tell qsort that there are 4 elements in the array to be sorted whereas you have 3000:-

qsort(nego,4,sizeof(*nego),compare);

But most of all qsort won't remove duplicates in the array so even if sizeof() did what you'd like it to do the arrays would still be the same size both before and after the sort.

However for what you want to accomplish sorting is a good first step but you'll then have to go through the array after the sort and look for duplicates by memcmp'ing each element to the next.

Andrew O'Reilly