Mitch
21st November 2013, 21:32
I have been trying to sent rcon status to a client. It works, but when you do this your server can't receive and send any packets.
(I also got a problem with converting the port correctly. That is why i am converting a ip+port to net address.)
case 1203:
{
#if COD_VERSION == COD2_1_3
typedef enum {
NA_BOT,
NA_BAD, // an address lookup failed
NA_LOOPBACK,
NA_BROADCAST,
NA_IP,
NA_IPX,
NA_BROADCAST_IPX
} netadrtype_t;
typedef struct {
netadrtype_t type;
char ip[4];
char ipx[10];
unsigned short port;
} netadr_t;
typedef struct {
bool allowoverflow; // if false, do a Com_Error
bool overflowed; // set to true if the buffer size failed (with allowoverflow set)
bool oob; // set to true if the buffer size failed (with allowoverflow set)
char *data;
int maxsize;
int cursize;
int readcount;
int bit; // for bitwise reads and writes
} msg_t;
char *cmd;
int clientNum;
int helper = 0;
helper += stackGetParamString(1, &cmd); // todo: is string?
helper += stackGetParamInt(2, &clientNum);
if (helper < 2)
{
printf_hide("scriptengine> wrongs args for: SV_ConnectionlessPacket(): at least 2 arg\n");
return stackReturnInt(0);
}
char * ip = (char *)malloc(64);
snprintf(ip, 64, "%s", "ip:port");
netadr_t * from;
void (*NET_StringToAdr)( const char *s, netadr_t *a );
(*(int *)&NET_StringToAdr) = 0x0806CD98;
NET_StringToAdr(ip, from);
char *message = (char *)malloc(1024);
message[0] = -1;
message[1] = -1;
message[2] = -1;
message[3] = -1;
message[4] = 0;
strcat (message, cmd);
printf("Message: %s\n", message);
msg_t * msg;
msg->data = message;
msg->maxsize = 131072;
msg->cursize = strlen(msg->data)+1;
msg->readcount = 0;
msg->allowoverflow = false;
msg->overflowed = false;
msg->oob = false;
msg->bit = 0;
netadr_t adr = *from;
void (*SV_ConnectionlessPacket)( netadr_t from, msg_t * msg );
(*(int *)&SV_ConnectionlessPacket) = 0x0809594E;
SV_ConnectionlessPacket(adr, msg);
return stackPushInt(1);
#else
return stackPushInt(0);
#endif
}
My function hook
short ShortSwap (short l)
{
char b1,b2;
b1 = l&255;
b2 = (l>>8)&255;
return (b1<<8) + b2;
}
const char *NET_AdrToString (netadr_t a)
{
static char s[64];
if (a.type == NA_LOOPBACK) {
strcpy(s, "loopback");
} else if (a.type == NA_BOT) {
strcpy(s, "bot");
} else if (a.type == NA_IP) {
sprintf(s, "%d.%d.%d.%d:%d", (unsigned char)a.ip[0], (unsigned char)a.ip[1], (unsigned char)a.ip[2], (unsigned char)a.ip[3], ShortSwap(a.port));
} else {
sprintf(s, "%ix%ix%ix%i.%ix%ix%ix%ix%ix%ix:%hu",
(unsigned char)a.ipx[0], (unsigned char)a.ipx[1], (unsigned char)a.ipx[2], (unsigned char)a.ipx[3], (unsigned char)a.ipx[4], (unsigned char)a.ipx[5], (unsigned char)a.ipx[6], (unsigned char)a.ipx[7], (unsigned char)a.ipx[8], (unsigned char)a.ipx[9],ShortSwap(a.port));
}
return s;
}
void hook_ServerCommand( netadr_t from, msg_t *msg )
{
char * d = msg->data;
const char * (*NET_AdrToString)( netadr_t a );
(*(int *)&NET_AdrToString) = 0x0806B1D4; // this one works better than my own version
printf("From %s\n", NET_AdrToString (from) );
//printf("Max size: %d\n", msg->maxsize);
//printf("Read count: %d\n", msg->readcount);
//printf("Cur size: %d\n", msg->cursize);
//printf("Bit: %d\n", msg->bit);
//printf("Ood: %d\n", msg->oob);
//printf("allowoverflow: %d\n", msg->allowoverflow);
//printf("overflowed: %d\n", msg->overflowed);
strncpy(d, &d[4], msg->cursize);
printf("Data: %s\n", msg->data);
}
cracking_hook_function(0x08097188, (int)hook_ServerCommand); // SVC_RemoteCommand
cracking_hook_function(0x0809594E, (int)hook_ServerCommand); // SV_ConnectionlessPacket
(all the function addresses are for cod2 1.3)
Printing your own message in console doesn't work either. (same result)
char * ip = (char *)malloc(64);
snprintf(ip, 64, "%s", "ip:28960");
printf("IP: %s\n", ip);
char *message = (char *)malloc(1024);
snprintf(message, 1008, "print\n%s", msg);
printf("Message: %s\n", message);
netadr_t * from;
void (*NET_StringToAdr)( const char *s, netadr_t *a );
(*(int *)&NET_StringToAdr) = 0x0806CD98;
NET_StringToAdr(ip, from);
const char * (*NET_AdrToString)( netadr_t a );
(*(int *)&NET_AdrToString) = 0x0806B1D4; // this one works better than my own version
printf("From %s\n", NET_AdrToString (*from) );
void (*NET_OutOfBandPrint)( netsrc_t sock, netadr_t adr, const char *msg );
(*(int *)&NET_OutOfBandPrint) = 0x0806C8CC;
NET_OutOfBandPrint(NS_SERVER, *from, message);
(I also got a problem with converting the port correctly. That is why i am converting a ip+port to net address.)
case 1203:
{
#if COD_VERSION == COD2_1_3
typedef enum {
NA_BOT,
NA_BAD, // an address lookup failed
NA_LOOPBACK,
NA_BROADCAST,
NA_IP,
NA_IPX,
NA_BROADCAST_IPX
} netadrtype_t;
typedef struct {
netadrtype_t type;
char ip[4];
char ipx[10];
unsigned short port;
} netadr_t;
typedef struct {
bool allowoverflow; // if false, do a Com_Error
bool overflowed; // set to true if the buffer size failed (with allowoverflow set)
bool oob; // set to true if the buffer size failed (with allowoverflow set)
char *data;
int maxsize;
int cursize;
int readcount;
int bit; // for bitwise reads and writes
} msg_t;
char *cmd;
int clientNum;
int helper = 0;
helper += stackGetParamString(1, &cmd); // todo: is string?
helper += stackGetParamInt(2, &clientNum);
if (helper < 2)
{
printf_hide("scriptengine> wrongs args for: SV_ConnectionlessPacket(): at least 2 arg\n");
return stackReturnInt(0);
}
char * ip = (char *)malloc(64);
snprintf(ip, 64, "%s", "ip:port");
netadr_t * from;
void (*NET_StringToAdr)( const char *s, netadr_t *a );
(*(int *)&NET_StringToAdr) = 0x0806CD98;
NET_StringToAdr(ip, from);
char *message = (char *)malloc(1024);
message[0] = -1;
message[1] = -1;
message[2] = -1;
message[3] = -1;
message[4] = 0;
strcat (message, cmd);
printf("Message: %s\n", message);
msg_t * msg;
msg->data = message;
msg->maxsize = 131072;
msg->cursize = strlen(msg->data)+1;
msg->readcount = 0;
msg->allowoverflow = false;
msg->overflowed = false;
msg->oob = false;
msg->bit = 0;
netadr_t adr = *from;
void (*SV_ConnectionlessPacket)( netadr_t from, msg_t * msg );
(*(int *)&SV_ConnectionlessPacket) = 0x0809594E;
SV_ConnectionlessPacket(adr, msg);
return stackPushInt(1);
#else
return stackPushInt(0);
#endif
}
My function hook
short ShortSwap (short l)
{
char b1,b2;
b1 = l&255;
b2 = (l>>8)&255;
return (b1<<8) + b2;
}
const char *NET_AdrToString (netadr_t a)
{
static char s[64];
if (a.type == NA_LOOPBACK) {
strcpy(s, "loopback");
} else if (a.type == NA_BOT) {
strcpy(s, "bot");
} else if (a.type == NA_IP) {
sprintf(s, "%d.%d.%d.%d:%d", (unsigned char)a.ip[0], (unsigned char)a.ip[1], (unsigned char)a.ip[2], (unsigned char)a.ip[3], ShortSwap(a.port));
} else {
sprintf(s, "%ix%ix%ix%i.%ix%ix%ix%ix%ix%ix:%hu",
(unsigned char)a.ipx[0], (unsigned char)a.ipx[1], (unsigned char)a.ipx[2], (unsigned char)a.ipx[3], (unsigned char)a.ipx[4], (unsigned char)a.ipx[5], (unsigned char)a.ipx[6], (unsigned char)a.ipx[7], (unsigned char)a.ipx[8], (unsigned char)a.ipx[9],ShortSwap(a.port));
}
return s;
}
void hook_ServerCommand( netadr_t from, msg_t *msg )
{
char * d = msg->data;
const char * (*NET_AdrToString)( netadr_t a );
(*(int *)&NET_AdrToString) = 0x0806B1D4; // this one works better than my own version
printf("From %s\n", NET_AdrToString (from) );
//printf("Max size: %d\n", msg->maxsize);
//printf("Read count: %d\n", msg->readcount);
//printf("Cur size: %d\n", msg->cursize);
//printf("Bit: %d\n", msg->bit);
//printf("Ood: %d\n", msg->oob);
//printf("allowoverflow: %d\n", msg->allowoverflow);
//printf("overflowed: %d\n", msg->overflowed);
strncpy(d, &d[4], msg->cursize);
printf("Data: %s\n", msg->data);
}
cracking_hook_function(0x08097188, (int)hook_ServerCommand); // SVC_RemoteCommand
cracking_hook_function(0x0809594E, (int)hook_ServerCommand); // SV_ConnectionlessPacket
(all the function addresses are for cod2 1.3)
Printing your own message in console doesn't work either. (same result)
char * ip = (char *)malloc(64);
snprintf(ip, 64, "%s", "ip:28960");
printf("IP: %s\n", ip);
char *message = (char *)malloc(1024);
snprintf(message, 1008, "print\n%s", msg);
printf("Message: %s\n", message);
netadr_t * from;
void (*NET_StringToAdr)( const char *s, netadr_t *a );
(*(int *)&NET_StringToAdr) = 0x0806CD98;
NET_StringToAdr(ip, from);
const char * (*NET_AdrToString)( netadr_t a );
(*(int *)&NET_AdrToString) = 0x0806B1D4; // this one works better than my own version
printf("From %s\n", NET_AdrToString (*from) );
void (*NET_OutOfBandPrint)( netsrc_t sock, netadr_t adr, const char *msg );
(*(int *)&NET_OutOfBandPrint) = 0x0806C8CC;
NET_OutOfBandPrint(NS_SERVER, *from, message);