Create a gist now

Instantly share code, notes, and snippets.

@danrl /gp.c
Created Jun 17, 2013

Embed
What would you like to do?
2013 def con ctf grandprix
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
/* constants */
#define NO_WAY 0
#define OK 1
/* data structures */
struct node {
char d;
int y;
int x;
struct node *s;
struct node *l;
struct node *r;
};
/* globals */
char recvbuf[1024] = { 0 };
static void exit_err(const char *msg)
{
printf("error: %s\n", msg);
exit(EXIT_FAILURE);
}
/* helper functions */
/*
* x 12345
* y |-----|
* 1 | |
* 2 | |
* 3 | |
* 4 | |
* 5 | |
* 6 | |
* 7 | |
* 8 | |
* 9 | u |
* |-----|
*/
static char getyx(int y, int x)
{
int offset = 1;
offset += y * 8;
offset += x - 1;
return (char) recvbuf[offset];
}
static int getupos(void)
{
for (int i=1; i < 6; i++)
if (getyx(9, i) == 'u')
return i;
return -1;
}
static struct node *make_node(int y, int x)
{
struct node *ptr;
if (y < 1 || y > 9 || x < 1 || x > 5)
return NULL;
ptr = malloc(sizeof(struct node));
ptr->d = getyx(y, x);
ptr->y = y;
ptr->x = x;
return ptr;
}
static void build_tree (struct node *nd)
{
nd->l = make_node(nd->y -1, nd->x -1);
if (nd->l)
build_tree(nd->l);
nd->s = make_node(nd->y -1, nd->x);
if (nd->s)
build_tree(nd->s);
nd->r = make_node(nd->y -1, nd->x +1);
if (nd->r)
build_tree(nd->r);
}
int walk_tree (struct node *nd)
{
printf("%c", nd->d);
if (nd->d != ' ')
return NO_WAY;
if (nd->y == 1)
return OK;
if (nd->s && walk_tree(nd->s) == OK)
return OK;
if (nd->l && walk_tree(nd->l) == OK)
return OK;
if (nd->r && walk_tree(nd->r) == OK)
return OK;
return NO_WAY;
}
char find_way (struct node *nd)
{
if (nd->s && walk_tree(nd->s) == OK)
return 's';
if (nd->l && walk_tree(nd->l) == OK)
return 'l';
if (nd->r && walk_tree(nd->r) == OK)
return 'r';
return 's';
}
static struct node *free_tree(struct node *nd)
{
if (!nd)
return NULL;
nd->l = free_tree(nd->l);
nd->s = free_tree(nd->s);
nd->r = free_tree(nd->r);
return NULL;
}
struct node *root = NULL;
int main(int argc, char *argv[])
{
int err = 0;
int sfd = 0;
int n = 0;
int run = 0;
char sbuf[2] = { '\n' };
struct sockaddr_in srvaddr;
sfd = socket(AF_INET, SOCK_STREAM, 0);
if (sfd < 0)
exit_err("socket");
memset(&srvaddr, 0, sizeof(srvaddr));
srvaddr.sin_family = AF_INET;
srvaddr.sin_port = htons(2038);
err = inet_pton(AF_INET, "50.16.11.51", &srvaddr.sin_addr);
if (err <= 0)
exit_err("pton");
err = connect(sfd, (struct sockaddr *) &srvaddr, sizeof(srvaddr));
if (err < 0)
exit_err("connect");
while ((n = read(sfd, recvbuf, sizeof(recvbuf) -1)) > 0) {
recvbuf[n] = 0;
if (n == 60) {
write(sfd, "\n", 1);
} else if (n == 88) {
printf("round %d: ", ++run);
root = make_node(9, getupos());
root->d = ' ';
build_tree(root);
sbuf[0] = find_way(root);
write(sfd, sbuf, sizeof(sbuf));
root = free_tree(root);
printf("->%c\n", sbuf[0]);
} else {
fputs(recvbuf, stdout);
}
}
if (n < 0)
exit_err("read");
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment