Luigi Auriemma

aluigi.org (ARCHIVE-ONLY FORUM!)
It is currently 19 Jul 2012 17:54

All times are UTC [ DST ]





Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 28 posts ] 
Author Message
 Post subject: proxocket - some questions
PostPosted: 28 Apr 2009 14:58 

Joined: 27 Apr 2009 20:14
Posts: 19
Ok, I've been fiddling around with proxocket and it looks like something I could use. I am trying to modify incoming (recv) packets on the fly. I would like to either block a packet entirely, or change the content of a packet, based on a string it contains.

My next question involves send packets. Does proxocket re-calculates checksum of send packets on the fly, which have been modified also based on a string it might contain?

I have been using WPE Pro and even though I am new to it as well, it doesn't seem to have these two features that I suspect proxocket might have.

TIA


Top
 Profile  
 
 
 Post subject: Re: proxocket - some questions
PostPosted: 28 Apr 2009 15:47 

Joined: 13 Aug 2007 21:44
Posts: 4068
Location: http://aluigi.org
proxocket works at API level so any low level TCP/IP stuff like checksum calculation, 3way handshake, handling of the IDs and so on is done by the operating system, just like if you use "send(sock, "hello", 5, 0)" in a program.

if you refer to custom checksums used at protocol level like for example the CRC32 used in teamspeak, obviously you must implement and handle it by hand modifying the outgoing packet and the field where the crc32 is located inside it.


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 28 Apr 2009 16:36 

Joined: 27 Apr 2009 20:14
Posts: 19
Thank you, I appreciate the answer, although most of that went over my head as I am pretty much a n00b at packet editing :)

So let me rephrase and be more clear, I hope you can bare with me one more time:

Can proxocket be used to do the following:

1. Block a Recv packet entirely based on a string it contains?
2. Edit/modify a Recv packet on the fly based on a string it contains?
3. Edit/modify a Send packet sent by an application without me initiating the sending.
3a. If yes, can the length info be changed so its accurate with the new (modified) length of the new packet.

TIA


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 28 Apr 2009 17:24 

Joined: 13 Aug 2007 21:44
Posts: 4068
Location: http://aluigi.org
1) almost yes, example:
Code:
int myrecv(SOCKET s, u_char *buf, int len, int flags) {
    if(SEARCH_THE_STRING(buf, YOUR_STRING)) {
        return(0);
    }
    return(len);
}
note that the main program could quit if it receives a return value minor/equal than zero.
proxocket doesn't have a solution for blocking completely a recv containing undesiderated data because it returns directly the return value returned here, and in any case must be returned a value.
this problem doesn't exist with connection-less protocols like UDP because is possible to return 0, while on TCP 0 means connection lost or some problems.

2) yes, example:
Code:
int myrecv(SOCKET s, u_char *buf, int len, int flags) {
    if(SEARCH_THE_STRING(buf, YOUR_STRING)) {
        len = sprintf(buf, "this is my data");
    }
    return(len);
}


3 and 3a) yes, example:
Code:
int mysend(SOCKET s, u_char **retbuf, int len, int flags) {
    u_char  *buf = *retbuf; // do NOT touch this

    len = sprintf(buf, "this is my data");

    // or if buf can't be modified or it's not enough big:
    // len = 100000
    // buf = malloc(len);
    // memset(buf, 'A', len);

    *retbuf = buf;  // do NOT touch this
    return(len);
}


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 28 Apr 2009 17:54 

Joined: 27 Apr 2009 20:14
Posts: 19
Thank you aluigi, I'm off to fiddle with myproxocket.c now and hope for the best


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 29 Apr 2009 16:20 

Joined: 27 Apr 2009 20:14
Posts: 19
aluigi wrote:
2) yes, example:
Code:
int myrecv(SOCKET s, u_char *buf, int len, int flags) {
    if([b]SEARCH_THE_STRING[/b](buf, YOUR_STRING)) {
        len = sprintf(buf, "this is my data");
    }
    return(len);
}


Ok, I'm guessing that SEARCH_THE_STRING is actually the find_replace_string in myproxocket.c, right?
Also, when compiling the exemple above, I'm getting "too few arguments" error.
It compiles fine when I use this piece of code, which is more like to your exemple code from the myproxocket.c, but it doesnt seem to do the job:
Code:
int myrecv(SOCKET s, u_char *buf, int len, int flags) {
    if(find_replace_string(buf, &len, "AAAAAA", NULL)) {
        len = sprintf(buf, "BBBBBB");
    }
    return(len);



What am I doing wrong?


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 29 Apr 2009 16:48 

Joined: 13 Aug 2007 21:44
Posts: 4068
Location: http://aluigi.org
with SEARCH_THE_STRING I referred to your preferred searching code, so yes you can use also find_replace_string without problems :)

the error there is that find_replace_string returns a NULL if the string is found in "search only" mode (don't ask me why I chosed to return a NULL if the string was found because I don't have idea of what I had in mind that day).

so basically it's enoug that you use "if(!find_replace_string" (note the '!').


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 29 Apr 2009 17:10 

Joined: 27 Apr 2009 20:14
Posts: 19
aluigi wrote:
(note the '!').


Yea, I took ! away because the code didnt work so I thought it might be that. Now I know it has to be there, but what am I doing wrong?

If I compile this:
Code:
int myrecv(SOCKET s, u_char *buf, int len, int flags) {
    if(!find_replace_string(buf, &len, "AAAAAA", NULL)) {
        len = sprintf(buf, "BBBBBB");
    }
    return(len);
}

It compiles fine, and after putting the .dll's in firefox.exe folder I still get 'AAAAAA' in my browser and not 'BBBBBB'. I know at this point I might be a pain in the ass but if you have some patience left can you please write the exact code I should be using.
Thanx


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 29 Apr 2009 17:27 

Joined: 13 Aug 2007 21:44
Posts: 4068
Location: http://aluigi.org
I have tried it here with firefox and just this same thread and it works since all the incoming blocks of data containing AAAAAA have been replaced with the 6 'B's.

have you added the proxocket's ws2_32.dll file in the firefox folder with myproxocket.dll?

do you use vista? in this case you should modify the following registry key:
"HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Image File Execution Options\DevOverrideEnable" to 1


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 29 Apr 2009 18:07 

Joined: 27 Apr 2009 20:14
Posts: 19
aluigi wrote:
have you added the proxocket's ws2_32.dll file in the firefox folder with myproxocket.dll?

Yes

aluigi wrote:
do you use vista?

No

I have removed every other my* function from proxocket.c and left everything else untouched except the myrecv function which is:
Code:
int myrecv(SOCKET s, u_char *buf, int len, int flags) {
    if(!find_replace_string(buf, &len, "AAAAAA", NULL)) {
        len = sprintf(buf, "BBBBBB");
    }
    return(len);
}



So the whole proxocket.c looks like this (I have removed the commented stuff in the beginning):
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock.h>
#include <windows.h>



unsigned int str2ip(unsigned char *data) {
    unsigned    a, b, c, d;

    if(!data[0]) return(0);
    sscanf(data, "%u.%u.%u.%u", &a, &b, &c, &d);
    return((a & 0xff) | ((b & 0xff) << 8) | ((c & 0xff) << 16) | ((d & 0xff) << 24));
}



unsigned char *ip2str(unsigned int ip) {
    static unsigned char  data[16];

    sprintf(data, "%hhu.%hhu.%hhu.%hhu",
        (ip & 0xff), ((ip >> 8) & 0xff), ((ip >> 16) & 0xff), ((ip >> 24) & 0xff));
    return(data);
}


unsigned short net16(unsigned short num) {
    int         endian = 1; // big endian

    if(!*(char *)&endian) return(num);
    return((num << 8) | (num >> 8));
}



unsigned int net32(unsigned int num) {
    int         endian = 1; // big endian

    if(!*(char *)&endian) return(num);
    return(((num & 0xff000000) >> 24) |
           ((num & 0x00ff0000) >>  8) |
           ((num & 0x0000ff00) <<  8) |
           ((num & 0x000000ff) << 24));
}



#define htons       net16
#define ntohs       net16
#define htonl       net32
#define ntohl       net32
#define inet_ntoa   ip2str
#define inet_addr   str2ip



    /* code which adds Winsock support to your hook, so you can use the original functions everytime you want! */

static HMODULE wsock = NULL;
static WINAPI int (*real_connect)(SOCKET s, const struct sockaddr *name, int namelen) = NULL;
static WINAPI SOCKET (*real_accept)(SOCKET s, const struct sockaddr *name, int *namelen) = NULL;
static WINAPI int (*real_bind)(SOCKET s, const struct sockaddr *name, int namelen) = NULL;
static WINAPI int (*real_close)(SOCKET s) = NULL;
static WINAPI int (*real_recv)(SOCKET s, char *buf, int len, int flags) = NULL;
static WINAPI int (*real_recvfrom)(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen) = NULL;
static WINAPI int (*real_send)(SOCKET s, char *buf, int len, int flags) = NULL;
static WINAPI int (*real_sendto)(SOCKET s, char *tbuf, int len, int flags, const struct sockaddr *to, int tolen) = NULL;



void init_myproxocket(void) {   // in this example I use this function for loading the real sockets function in case we want to use them
    char    winpath[MAX_PATH];

    if(wsock) return;

    GetSystemDirectory(winpath, sizeof(winpath));
    strcat(winpath, "\\ws2_32.dll");

    wsock = LoadLibrary(winpath);
    if(!wsock) return;

    real_connect   = (void *)GetProcAddress(wsock, "connect");
    real_accept    = (void *)GetProcAddress(wsock, "accept");
    real_bind      = (void *)GetProcAddress(wsock, "bind");
    real_close     = (void *)GetProcAddress(wsock, "close");
    real_recv      = (void *)GetProcAddress(wsock, "recv");
    real_recvfrom  = (void *)GetProcAddress(wsock, "recvfrom");
    real_send      = (void *)GetProcAddress(wsock, "send");
    real_sendto    = (void *)GetProcAddress(wsock, "sendto");
}



void free_myproxocket(void) {
    if(wsock) {
        FreeLibrary(wsock);
        wsock = NULL;
    }
}



    // this function can be used also to know only if a string exists or not, it's enough to use NULL instead of new like in the example in myrecv
unsigned char *find_replace_string(unsigned char *buf, int *len, unsigned char *old, unsigned char *new) {
    int     i,
            tlen,
            oldlen,
            newlen,
            found;
    unsigned char
            *nbuf,
            *p;

    found  = 0;
    oldlen = strlen(old);
    tlen   = *len - oldlen;

    for(i = 0; i <= tlen; i++) {
        if(!strnicmp(buf + i, old, oldlen)) found++;
    }
    if(!found) return(buf); // nothing to change

    if(!new) return(NULL);  // if we want to know only if the searched string has been found, we will get NULL if yes
    newlen = strlen(new);

    if(newlen <= oldlen) {  // if the length of new string is equal/minor than the old one don't waste space for another buffer
        nbuf = buf;
    } else {                // allocate the new size
        nbuf = malloc(*len + ((newlen - oldlen) * found));
    }

    p = nbuf;
    for(i = 0; i <= tlen;) {
        if(!strnicmp(buf + i, old, oldlen)) {
            memcpy(p, new, newlen);
            p += newlen;
            i += oldlen;
        } else {
            *p++ = buf[i];
            i++;
        }
    }
    while(i < *len) {
        *p++ = buf[i];
        i++;
    }
    *len = p - nbuf;
    return(nbuf);
}





int myrecv(SOCKET s, u_char *buf, int len, int flags) {
    if(!find_replace_string(buf, &len, "AAAAAA", NULL)) {
        len = sprintf(buf, "BBBBBB");
    }
    return(len);
}




BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {
    switch(fdwReason) {
        case DLL_PROCESS_ATTACH: {
            DisableThreadLibraryCalls(hinstDLL);
            init_myproxocket(); // put your init here
            break;
        }
        case DLL_PROCESS_DETACH: {
            free_myproxocket(); // put anything to free here
            break;
        }
        default: break;
    }
    return(TRUE);
}


When I compile it and put the dll's in the folder there are no .cap files. When I remove proxocket.dll I get the .cap files. I wonder what is wrong?


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 29 Apr 2009 19:01 

Joined: 13 Aug 2007 21:44
Posts: 4068
Location: http://aluigi.org
the error is in the name of the file, it must be myproxocket.c/dll.


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 29 Apr 2009 19:06 

Joined: 27 Apr 2009 20:14
Posts: 19
I wish that was that easy :)

No, of course its myproxocket.dll I just typed it wrong here. I hope we can solve this


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 29 Apr 2009 19:11 

Joined: 13 Aug 2007 21:44
Posts: 4068
Location: http://aluigi.org
the fact that the cap files are not generated means that the dll has been correctly loaded so why you say it doesn't work?
remember that recv() works with the blocks of data received from the network so you can't be able (for example) to block an entire web page, that's why if you try to load this current URL with firefox+myproxocket.dll the resulted page looks truncated in some parts (the blocks of data received by recv which contains the AAAAAA string you used in your posts).


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 29 Apr 2009 19:56 

Joined: 27 Apr 2009 20:14
Posts: 19
aluigi wrote:
the fact that the cap files are not generated means that the dll has been correctly loaded so why you say it doesn't work?


Ok, I didn't realize that.

Anyway it works now, I should have tested it on this page, instead I tested Googling AAAAAA which made firefox "think" and not returning anything. I hoped that AAAAAA would simply be replaced with BBBBBB but now I see it doesnt work that way, I guess. Is there a way to make it behave like that without truncating so much? Anyway, thank you very much for all your help aluigi, this is a very nice tool.


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 29 Apr 2009 20:05 

Joined: 13 Aug 2007 21:44
Posts: 4068
Location: http://aluigi.org
if you want to make a "replacing" job why not using directly find_replace_string?
Code:
int myrecv(SOCKET s, u_char *buf, int len, int flags) {
    find_replace_string(buf, &len, "AAAAAA", "BBBBBB");
    return(len);
}
remember that BBBBBB must be equal or minor than AAAAAA otherwise find_replace_string needs to allocate a new buffer (the return value of the find_replace_string function) which is wrong because the program (for example firefox) has access only to the original "buf" and so all the modifications must be performed on such buffer.

remember also that due to the segmented receiving of the TCP data explained before (which is just a logical thing of the TCP/IP protocol when handled as a connection so not caused by the operating system, recv or proxocket) if the "AAAAAAA" string is half in one data block and half in another it will be not replaced


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 01 May 2009 12:12 

Joined: 27 Apr 2009 20:14
Posts: 19
Thank you aluigi! That is even better and I use that now.

Now, feel free to cut me off anytime because I know I'm asking too much and I don't want to take up too much of your time.

So answer only if you want to :)

1. What about HEX strings? How do I implement that in the myrecv function?
2. Position offset. I'll give you an example:
lets say this is a string: 0123456789
I recognize this string by the 789 sequence in it. But I want to replace the 234 sequence into e.g. 432.
So in other words: Im interested in a packet with "0123456789" sequence by looking for "789". When I find it I change it so after its modified it looks like this: 0143256789


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 01 May 2009 13:24 

Joined: 13 Aug 2007 21:44
Posts: 4068
Location: http://aluigi.org
in the first case you can still use the same find_replace_string function, the only requirement is that there are no 0x00 bytes in your searched and replaced string: find_replace_string(buf, &len, "\x41\x61\x41\x61", "\x42\x62\x42\x62");

while for the second thing you need to modify find_replace_string or just write a new one (after all find_replace_string was only an example function)


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 15 May 2009 21:09 

Joined: 27 Apr 2009 20:14
Posts: 19
This is an awesome tool, thank you so much aluigi.

I hope I am not bothering you too much. I need a tip on how to modify or block the following (Recv) packet:

0000 00 0f 1f 28 40 cd 00 1d a2 85 61 48 88 64 11 00
0010 0b 64 00 2a 00 21 45 00 00 28 00 00 40 00 30 06
0020 cb 72 42 d1 44 2e 5c 24 9c 3a 1d f2 05 aa cf d2
0030 6f 4c 49 c5 6b 31 50 10 05 b4 13 11 00 00

The two bytes in bold are the crucial ones, but as you already told me, find_replace_string function cant take 0x00 bytes. What would be the best solution for this scenario? As I said, either block the whole packet, or modify it, it doesnt matter, just as long the two 0x00 don't reach the app.

Thanks again


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 15 May 2009 21:41 

Joined: 13 Aug 2007 21:44
Posts: 4068
Location: http://aluigi.org
for technical reasons recv() can't receive fixed amount of bytes, so if I send you 1000 bytes of data through a TCP connections and you call recv() you can receive any amount of bytes between 1 and 1000, that's why is required to use recv() in loop for being 100% sure of receiving the full amount of expected data.

now after this small premire you can use find_replace_string without problem, indeed it's enough to "move" oldlen and newlen into the arguments of the function and using memcmp like in the following example:
Code:
u_char *find_replace_string(u_char *buf, int *len, u_char *old, int oldlen, u_char *new, int newlen) {
    int     i,
            tlen,
            //oldlen,
            //newlen,
            found;
    u_char  *nbuf,
            *p;

    found  = 0;
    //oldlen = strlen(old);
    tlen   = *len - oldlen;

    for(i = 0; i <= tlen; i++) {
        if(!memcmp(buf + i, old, oldlen)) found++;
    }
    if(!found) return(buf); // nothing to change: return buf or a positive value

    if(!new) return(NULL);  // if we want to know only if the searched string has been found, we will get NULL if YES and buf if NOT!!!
    //newlen = strlen(new);

    if(newlen <= oldlen) {  // if the length of new string is equal/minor than the old one don't waste space for another buffer
        nbuf = buf;
    } else {                // allocate the new size
        nbuf = malloc(*len + ((newlen - oldlen) * found));
    }

    p = nbuf;
    for(i = 0; i <= tlen;) {
        if(!memcmp(buf + i, old, oldlen)) {
            memcpy(p, new, newlen);
            p += newlen;
            i += oldlen;
        } else {
            *p++ = buf[i];
            i++;
        }
    }
    while(i < *len) {
        *p++ = buf[i];
        i++;
    }
    *len = p - nbuf;
    return(nbuf);
}
so you can use any byte inside the strings (0x00 included), it's enough to call find_replace_string(buf, &len, "\x41\x00\x00\x61", 4, "\x42\x62\x00\x62", 4);


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 18 May 2009 11:51 

Joined: 27 Apr 2009 20:14
Posts: 19
Thank you that is great and very helpful.

I have another problem now.

It turns out that I need that string just once to load unmodified. After that one time I want to modify if. I tried something myself with while loop but im not good with programming. So if you have an idea I'd appreciate it very much.

Thanks again.


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 19 May 2009 14:46 

Joined: 13 Aug 2007 21:44
Posts: 4068
Location: http://aluigi.org
uhmmm if I have understood the right thing you could use a global or static var like: "static int initialized = 0;"
then do:
Code:
if(!initialized) {    // first time
    if(!find_replace_string(buf, &len, "\x41\x00\x00\x61", 4, NULL, 0)) {
        initialized = 1;  // found
    }
} else {
    buf = find_replace_string(buf, &len, "\x41\x00\x00\x61", 4, "\x42\x62\x00\x62", 4);
}


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 02 Jul 2009 19:31 

Joined: 27 Apr 2009 20:14
Posts: 19
Hi again aluigi.

Any idea on how I can set condition in find_replace_string to a certain source port?
Thanks


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 03 Jul 2009 10:35 

Joined: 13 Aug 2007 21:44
Posts: 4068
Location: http://aluigi.org
you can add the condition directly inside myrecv/myrecvfrom like the in the examples inside myproxocket.c:
Code:
    if(((struct sockaddr_in *)from)->sin_port == htons(1234)) {
        // do what you want, like find_replace_string and so on
    }


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 25 Oct 2009 14:54 

Joined: 27 Apr 2009 20:14
Posts: 19
Thank you aluigi

I used that and I'm getting compile error:

myproxocket.c: In function `myrecv':
myproxocket.c:157: error: `from' undeclared (first use in this function)
myproxocket.c:157: error: (Each undeclared identifier is reported only once
myproxocket.c:157: error: for each function it appears in.)

What am I overlooking?


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 25 Oct 2009 16:21 

Joined: 13 Aug 2007 21:44
Posts: 4068
Location: http://aluigi.org
it's simply a different variable name, in my example I used "from" so check what you used as argument of the myrecv function.
probably you used "addr" or something similar so change its name (", struct sockaddr *NAME,")


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 25 Oct 2009 19:42 

Joined: 27 Apr 2009 20:14
Posts: 19
hmm, i'm not sure whats wrong...
Lets say this is the function I'm using:

Code:
int myrecv(SOCKET s, u_char *buf, int len, int flags) {
   if(((struct sockaddr_in *)name)->sin_port == htons(1234)) {
       find_replace_string(buf, &len, "AAAAAA", "BBBBBB");
      }
    return(len);
}


I'm not sure what parameters I shoud use instead of "name". I've tried len, buf and flags which all crash Firefox.


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 25 Oct 2009 22:07 

Joined: 13 Aug 2007 21:44
Posts: 4068
Location: http://aluigi.org
you can't use that code in myrecv because the source IP/port is not read there (only recvfrom specifies that field).
so you have 2 options:
- placing that code in myaccept
- importing the getpeername function from the real ws2_32.dll and using it in myrecv but it's not a fast solution


Top
 Profile  
 
 Post subject: Re: proxocket - some questions
PostPosted: 02 Nov 2009 18:29 

Joined: 02 Nov 2009 18:27
Posts: 4
Doesn't work on all mods.(JKII)
And is there another version for jka? or other games?(bin & source)
Thanks


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 28 posts ] 

All times are UTC [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for: