以下代码有缓存溢出, 请帮忙指出, 多谢~
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <strings.h>
#include <sys/time.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/uio.h>
#include <stdarg.h>
#include <errno.h>
#ifndef USE_MMAP
#define USE_MMAP
#endif
#ifdef USE_MMAP
#include <sys/mman.h>
#define START_ADDR (void *) 0x55385C00
#endif
#ifdef __CYGWIN__
#include “getopt.h”
#endif
/* Binary code for HLT (halt) instruction */
#define HALT_INSTR 0xF4
#define NORMAL_CNT 1
#define NORMAL_BUFFER_SIZE 32
uint32_t cookie = 0xDEADBEEF;
/*——————————————————————–*/
//global variable declaration
struct aconnexion {
int nfd;
char bufcon[1000];
int buflen;
long starttime;
} con[32];
int listen_port = 9010, fdc;
struct timeval tv;
struct tm *ptm;
fd_set origfds;
struct sockaddr_in srv;
/***************************************************************************
function : reverse_string
Description : reverse a string
Parameters : dest (destination buffer)
src (source buffer)
Local : string_leng, j
Returned value : none
***************************************************************************/
void reverse_string ( char *dest, char *src) {
int string_leng = strlen (src);
int j;
for (j=(string_leng -1);j>=0; j–) {
*(dest++) = src[j]; }
}
/***************************************************************************
function : close_connec
Description : close a connection
Parameters : aconnec (the connection to close)
Globals : origfds
Local : none
Returned value : none
***************************************************************************/
void close_connec(struct aconnexion *connec) {
FD_CLR((*connec).nfd, &origfds);
close((*connec).nfd);
(*connec).nfd =-1;
}
/***************************************************************************
function : check_error
Description : check if an error occured
Parameters : errorbuf (buffer to store a string reporting the error)
nb (number to check)
lw (if no error, nb = lw)
Globals : none
Local : none
Returned value : 0 if error else 1
***************************************************************************/
int check_error (char *errorbuf, int nb, int lw) {
if (nb == -1) {
sprintf (errorbuf, “Error while writing the response, check your connection, err# : %d\n”, errno);
return 1;
} else if (nb < lw) {
strcpy (errorbuf, “Response partially sent !!\n”);
return 1;
} else {
return 0;
}
}
/***************************************************************************
function : processbuf
Description : treate the received data and send a response back
Parameters : fdnb (decriptor of a connection)
buf (received data)
paramlen (number of string to reverse)
pstart (position of the first string)
Globals : none
Local : errorbuf, err, bufrep_pos, i, nbytew, revstring, bufrep
Returned value : 0 if an error occurred, 1 else
***************************************************************************/
int processbuf(int fdnb, char *buf, int paramlen, char *pstart) {
int nbytew,err;
char errorbuf[200];
char revstring[21], *bufrep_pos;
char bufrep[2000];
int i;
pstart++;
for (i=0;i<2000;i++) bufrep[i]=0;
for (i=0;i<21;i++) revstring[i]=0;
//store the beginning of the response in bufrep
snprintf(bufrep, 2000, buf);
// change to REP
bufrep[2] = ‘P’;
bufrep[3] = ‘|’;
bufrep_pos= bufrep + 4;
i= 4;
while (*(buf+i)!= 0) { *(revstring+i- 4) = *(buf+i); i++;}
strncpy(bufrep_pos, revstring, 2);
//reverse string and fill bufrep with the result
bufrep_pos += strlen(bufrep_pos);
for (i=0;i<paramlen; i++) {
*bufrep_pos = ‘|’;
bufrep_pos++;
reverse_string (revstring, pstart);
pstart += 21;
snprintf(bufrep_pos, 21, revstring);
bufrep_pos += 20;
}
//send the response and check for errors
nbytew = write(fdnb, bufrep, strlen(bufrep));
err = check_error(errorbuf, nbytew, strlen(bufrep));
if (err == 1) printf (errorbuf);
return (err);
}
/***************************************************************************
function : server
Description : listen to a socket and treate REV request
Parameters : argc, argv
Globals : all
Local : check below
Returned value : 0 if an error occured
***************************************************************************/
int server() {
int fd, paramlen, i, freepos, chkpass;
const int optval =1;
fd_set readfds;
int maxfds, next, count, nbyte, int_pos;
struct sockaddr_in cli;
struct timeval s_timeout;
int cli_len;
char *start_param_pos, *paramlen_pos;
int paramlen_offset;
//create a socket
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1) {printf(“error while creating the socket\n”);return(0);}
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1){
printf(“Error while setting socket option, errno: %d\n”, errno);
}
srv.sin_family = AF_INET;
srv.sin_port = htons(listen_port);
srv.sin_addr.s_addr = htonl(INADDR_ANY);
//bind the socket
if (bind (fd, (struct sockaddr*) &srv, sizeof(srv)) == -1) {
printf(“error while binding %d\n”, errno);return(0);}
//listen
if (listen (fd, 10)<0) {
printf(“error while trying to listen\n”);return(0);}
maxfds = fd;
FD_ZERO(&origfds);
FD_SET(fd, &origfds);
next=0;
s_timeout.tv_sec = 1;
s_timeout.tv_usec = 0;
printf(“server on\n”);
//check for request
while (1) {
bcopy (&origfds, &readfds, sizeof (origfds));
select (maxfds +1, &readfds, 0, 0, &s_timeout);
if (FD_ISSET(fd, &readfds)) {
if (next < 31) {
printf(“new connexion\n”);
cli_len = sizeof(cli);
con[next++].nfd = accept (fd, (struct sockaddr*) &cli, &cli_len);
if (con[next-1].nfd<0) {
printf(“error while accepting %d\n”, errno);return(0);
}
if (con[next-1].nfd > maxfds) maxfds = con[next-1].nfd;
gettimeofday(&tv, NULL);
con[next-1].starttime = tv.tv_sec;
bzero(con[next-1].bufcon, 1000);
con[next-1].buflen = 0;
FD_SET(con[next-1].nfd, &origfds);
} else {
return (0);
}
}
//check existing connection
for (count=0;count<next;count++) {
if (con[count].nfd <0) continue;
if (FD_ISSET(con[count].nfd, &readfds)) {
nbyte = 0;
nbyte = read(con[count].nfd, &((con[count].bufcon)[con[count].buflen]), 999 – con[count].buflen );
con[count].buflen += nbyte;
if (nbyte == 0) {
// client has closed the connection
close_connec(&(con[count]));
}else{
//replace | by 0
for (i=0;i<con[count].buflen; i++)
if ((con[count].bufcon)[i] == ‘|’) (con[count].bufcon)[i]=0;
chkpass = 0; int_pos = 0;
//check if the request has a valid format
if (strncmp(con[count].bufcon, “REV”, 3) ==0) {
paramlen_pos = con[count].bufcon;
while(*paramlen_pos++ != 0);
paramlen_offset =(int) (paramlen_pos – con[count].bufcon);
paramlen = atoi( &((con[count].bufcon)[paramlen_offset]));
start_param_pos = &((con[count].bufcon)[paramlen_offset]);
while(*start_param_pos != 0) start_param_pos++;
int_pos = (int)( start_param_pos – (con[count].bufcon));
if (paramlen > 47) { // 47*21 + 4 = 993
bzero(con[count].bufcon, 1000);
con[count].buflen = 0;
}
if ((paramlen != 0)&&
((con[count].buflen – int_pos) == paramlen*21)) {
chkpass = 1;
for (i=1; i<paramlen; i++)
if (*(start_param_pos + 21*i) != ‘\0′) chkpass = 0;
}
}else {
bzero(con[count].bufcon, 1000);
con[count].buflen = 0;
}
if ((con[count].buflen - int_pos) > paramlen*21) {
bzero(con[count].bufcon, 1000);
}
if ((con[count].buflen - int_pos) >= paramlen*21) {
con[count].buflen = 0;
}
if (chkpass) {
//process the request
processbuf(con[count].nfd,con[count].bufcon, paramlen, start_param_pos);
bzero(con[count].bufcon, 1000);
}
gettimeofday(&tv, NULL);
con[count].starttime = tv.tv_sec;
}
}
}
//check if some connections have been idling for more than 5 seconds
gettimeofday(&tv, NULL);
for (count=0;count<next;count++) {
if (con[count].nfd <0) continue;
if ( (tv.tv_sec – con[count].starttime) > 5) {
close_connec(&(con[count]));
}
}
//sort the array “con”
if (next == 10 % 11) {
freepos = 0;
for (i=0; i<next; i++) {
if (con[i].nfd >= 0) {
if (freepos == i) {freepos++;}
else {
con[freepos++] = con[i];
con[i].nfd = -1;
}
}
}
next = freepos;
}
}
close (fd);
return 1;
}
/* New version of launching code.
Optionally uses MMAP to generate stable stack position */
/* Must put context information in global variables,
since stack will get messed up */
int global_nitro = 0;
int global_offset = 0;
volatile void *stack_top;
volatile void *global_save_stack = NULL;
/* This function makes it possible to shift stack to mapped region */
void launcher(int nitro, int offset)
{
#ifdef USE_MMAP
void *new_stack;
#endif
global_nitro = nitro;
global_offset = offset;
#ifdef USE_MMAP
#define STACK_SIZE 0×100000
new_stack = mmap(START_ADDR, STACK_SIZE, PROT_EXEC|PROT_READ|PROT_WRITE,
MAP_PRIVATE | MAP_GROWSDOWN | MAP_ANONYMOUS,
0, 0);
if (new_stack == MAP_FAILED) {
fprintf(stderr, “Internal error. Couldn’t use mmap\n”);
exit(1);
}
stack_top = new_stack + STACK_SIZE – 8;
asm(“movl %%esp,%%eax ; movl %1,%%esp ; movl %%eax,%0″
: “=r” (global_save_stack)
: “r” (stack_top)
: “%eax”
);
#endif
server();
// launch(global_nitro, global_offset);
#ifdef USE_MMAP
asm(“movl %0,%%esp”
:
: “r” (global_save_stack)
);
munmap(new_stack, STACK_SIZE);
#endif
}
int main(int argc, char** argv) {
int cookie_tweak = 0;
int nitro = 0; /* Run in unstable mode? */
int i;
int *offsets;
int cnt = NORMAL_CNT;
char c;
// set up random stack offsets for nitro mode
srandom(cookie);
cookie_tweak = random() & 0xFF8;
offsets = (int *) calloc(cnt, sizeof(int));
for (i = 0; i < cnt-2; i++)
offsets[i] = random() & 0×38;
if (cnt >= 2)
offsets[cnt-2] = 0×38;
offsets[cnt-1] = 0;
for (i = 0; i < cnt; i++)
launcher(nitro, offsets[i]+cookie_tweak);
return 0;
}
>> 本文固定链接: http://www.vcgood.com/archives/2030