默认情况下,TOPCODER的SRM和TCO等比赛在查看别人代码的时候(challeng-
ing phrase 或练习时候看别人代码)是不允许拷贝代码的。这样如果我们想在本
地测试一下别人代码得一个一个的敲。这非常的不方便。
这个程序使用方法:
1 编译该程序
1)下载Winpcap 库,设置VC的路径,使得VC能找到winpcap的lib和include目
录
2)在project->setting->link 下面,添加wpcap.lib 和 ws2_32.lib库
3)用VC编译即可
2 运行该程序
1)运行程序(需要管理员权限),选择你TOPCODER ARENA使用的网卡
2)正常情况下,会有START WORKING ... 提示
3)打开ARENA,点击别人代码后,该程序会自动弹出记事本,里面有代码,
如最下面的图所示
#define HAVE_REMOTE
#include <pcap.h>
#include <stdio.h>
#include <time.h>
#include <windows.h>
#define for if(1)for
#include <string.h>
#include <pcap.h>
#define _ARP_ 1
#define _IP_ 2
#define _TCP_ 4
#define _UDP_ 8
#define _ICMP_ 16
#define _IP6_ 32
#define ETH_ALEN 6
typedef unsigned short uint16_t;
typedef unsigned char u_int8_t;
typedef unsigned short u_int16_t;
typedef unsigned int u_int32_t;
struct EtherHdr
{
u_int8_t ether_dhost[ETH_ALEN]; //48 bit mac address
u_int8_t ether_shost[ETH_ALEN];
uint16_t ether_type; //packet tyoe id field
//0800 ip
//0806 arp
//86dd ipv6
};
struct IpHdr
{
u_int8_t ver_ihl;
u_int8_t tos;
u_int16_t tot_len;
u_int16_t id;
u_int16_t frag_off;
u_int8_t ttl;
u_int8_t protocol;
u_int16_t check;
u_int32_t saddr;
u_int32_t daddr;
};
struct TcpHdr
{
u_int16_t th_sport;
u_int16_t th_dport;
u_int32_t th_seq;
u_int32_t th_ack;
u_int8_t th_off; //data offset
u_int8_t th_flags;
u_int16_t th_win;
u_int16_t th_sum;
u_int16_t th_urp;
};
char *code = 0;
int code_index = 0;
int
off (u_char offset)
{
return (offset >> 2);
}
u_char char1[] =
{
'M', 'a', 'c', 'h', 'i', 'n', 'e', 0x20, 'L', 'e', 'a', 'r',
'n', 'i', 'n', 'g', 0x00, 0x00, 0x00, 0x00, 0x11, 0x7f, 0xff,
0xff, 0xff, 0x00, 0x00, '*' };
int
checkstr (const u_char * packet, int size, int lastlen)
{
if (lastlen > 0)
{
int i = 0;
while (lastlen >= 0 && i < size)
{
//printf("%c",packet[i]);
code[code_index++] = packet[i];
i++;
lastlen--;
}
if (lastlen <= 0)
{
code[code_index] = 0;
printf ("\n------------------------end------------------------\n");
static int file_id = 0;
char filename[100];
itoa (file_id++, filename, 100);
strcat (filename, ".txt");
FILE * fp = fopen (filename, "w");
for (int iii = 0; iii < code_index; ++iii)
fprintf (fp, "%c", code[iii]);
long ttt = time (0);
fprintf (fp, "\n//%s\n", ctime (&ttt));
printf ("code saved to file %s, opening it...\n", filename);
ShellExecute (0, "open", "notepad", filename, 0, SW_SHOW);
fclose (fp);
delete[]code;
}
return lastlen;
}
int flag = -1;
for (int i = 0; i < size - 27; ++i)
{
int j = 0;
int ii = i;
for (; j < 27; ++j, ++ii)
{
if (packet[ii] != char1[j])
{
if (j > 15)
printf ("MISMATCH [%02x,%02x] \n", packet[ii], char1[j]);
break;
}
//else fprintf(stdio,"MATCHING... %d [%02x,%02x]------------\n",j,packet[ii],char1[j]);
}
if (j >= 26)
{
flag = i;
break;
}
}
if (flag != -1)
{
//fprintf(stdio,"\nPOSSIBLE STARTING POINT OF CODE FOUND!\n");
int i = flag;
while (i < size && packet[i] != 0x7f)
++i;
i += 11;
printf ("\n----------%s --- by %s---------", packet + i,
packet + i + (*((u_char *) (packet + i - 1))) + 37);
i += (*((u_char *) (packet + i - 1))) + 36;
i += (*((u_char *) (packet + i))) + 1;
i += 5;
int length = 0;
length |= packet[i] << 8;
length |= packet[i + 1];
printf ("code length: %d bytes ---------\n", length);
i += 2;
code = new char[length + 10];
code_index = 0;
memset (code, 0, sizeof (code));
while (length >= 0 && i < size)
{
//printf("%c",packet[i]);
code[code_index++] = packet[i];
i++;
length--;
}
return length;
}
else
return -1;
}
int
main ()
{
printf ("README:\n"
"This program is used to crack the limitation of TOPCODER competition rules "
"\nin challenging phrase. By default users can only view other people's code"
"\nbut cannot copy them. This would be quite inconvinient if we want to test"
"\nthe other people's codes locally.\n" "\n"
"This program sniffs the packets transfered to TOPCODER ANENA and automati-\n"
"cally regenerate the code.\n"
"With this program you can easily test the other people's codes.\n"
"Currently this program only support \"Direct Connection\" connection option \n"
"of TOPCODER ANENA.\n"
"\nAny bugs or problems please contact [email protected]\n"
"GOOD LUCK!\n"
"-----------------------------------------------------------------------------\n");
pcap_if * devs;
int ninterface = 0;
char errbuf[1024];
int ret = pcap_findalldevs_ex (PCAP_SRC_IF_STRING, NULL, &devs, errbuf);
if (ret == -1 || devs == 0)
{
perror ("pcap_findalldevs");
return 0;
}
int elist_i = 0;
for (pcap_if * d = devs; d != NULL; d = d->next)
{
printf ("%d. %s", ++elist_i, d->name);
if (d->description)
printf ("\n\t(%s)\n", d->description);
else
printf (" (No description available)\n");
}
printf ("Please select the interface you are using:");
int nsel;
scanf ("%d", &nsel);
char interface_name[100];
if (nsel <= elist_i)
{
int tmp = 1;
pcap_if * d = devs;
for (d = devs; d != NULL && tmp < nsel; d = d->next)
++tmp;
if (d)
strcpy (interface_name, d->name);
else
{
printf ("The interface you have selected is invalid!\n");
interface_name[0] = 0;
return 0;
}
}
printf ("You have selected %s\n", interface_name);
pcap_t * handle =
pcap_open (interface_name, 65535, 0 /*no promisc */ , 20, 0, errbuf);
if (!handle)
{
printf ("pcap_open_live failed.\n");
return 0;
}
else
printf ("OPEN DEVICE SUCCEED\n");
bpf_program fp;
bpf_u_int32 maskp, netp;
ret = pcap_lookupnet (interface_name, &netp, &maskp, errbuf);
if (ret == -1)
{
perror ("pcap_lookupnet");
return 0;
}
char filter[2800] = "port 5001 and src host 66.37.210.86";
if (pcap_compile (handle, &fp, filter, 0, netp) == -1)
{
perror ("pcap_compile");
return 0;
}
if (pcap_setfilter (handle, &fp) == -1)
{
perror ("pcap_setfilter");
return 0;
}
unsigned int oldseq = -1;
int lastlen = -1;
printf ("Initializing....\nEVERYTHING IS OK. START WORKING ... \n");
while (1)
{
pcap_pkthdr hdr;
const u_char *packet;
packet = pcap_next (handle, &hdr);
if (hdr.len < 14 + 20 + 20 || hdr.len > 65535 || packet == 0)
continue;
// else printf("packet fetched hdr.len = %d\n",hdr.len);
EtherHdr * ether = (EtherHdr *) packet;
if (ether->ether_type == 0x0008)
{
//fprintf(stdio,"packet captured \n");
IpHdr * iphdr = (IpHdr *) (packet + 14);
TcpHdr * tcphdr = 0;
//printf("packet captured-------------\n");
if (iphdr->protocol == IPPROTO_TCP)
{
// printf("\nTCP packet!\n");
tcphdr = (TcpHdr *) (packet + 14 + 20);
if (tcphdr->th_sport == htons (5001))
{
if (oldseq != -1 && ntohl (tcphdr->th_seq) <= oldseq)
{
// printf("bad data! th_seq = %d, ignored!\n", ntohl(tcphdr->th_seq));
continue;
}
}
}
else
{
// printf("NOT TCP PACKET\n");
continue;
}
//printf("----------------\n");
oldseq = ntohl (tcphdr->th_seq);
packet = (u_char *) (packet + 14 + 20 + off (tcphdr->th_off));
int n = hdr.len - 14 - 20 - off (tcphdr->th_off);
printf ("begin analyzing packet ... \n");
lastlen = checkstr (packet, n, lastlen);
oldseq = ntohl (tcphdr->th_seq);
}
else
printf ("ether_type = %x\n", ether->ether_type);
}
}