1 #include <libcgc.h>
2 #include <stdlib.h>
3 #include <string.h>
4 
atoi(const char * str)5 int atoi(const char* str)
6 {
7     if ( str == NULL )
8         return 0;
9 
10     int integer_part = 0;
11     int sign = 1;
12     int part;
13     int digit_count = 0;
14 
15     // Skip whitespace
16     while ( isspace( str[0] ) )
17         str++;
18 
19     part = 0; // First part (+/-/number is acceptable)
20 
21     while( str[0] != '\0' )
22     {
23         if ( str[0] == '-' )
24         {
25             if ( part != 0 )
26                 return 0;
27 
28             sign = -1;
29             part++;
30         }
31         else if ( str[0] == '+' )
32         {
33             if ( part != 0 )
34                 return 0;
35 
36             part++;
37         }
38         else if ( isdigit( *str ) )
39         {
40             if ( part == 0 || part == 1 )
41             {
42                 // In integer part
43                 part = 1;
44                 integer_part = (integer_part * 10) + (*str - '0');
45 
46                 digit_count++;
47 
48                 if ( digit_count == 9 )
49                     break;
50             }
51             else
52             {
53                 // part invalid
54                 return 0;
55             }
56         }
57         else
58             break;
59 
60         str++;
61     }
62 
63     return (sign * integer_part);
64 }
65 
receive_until(int fd,char * dst,char delim,size_t max)66 size_t receive_until(int fd, char *dst, char delim, size_t max )
67 {
68     size_t len = 0;
69     size_t rx = 0;
70     char c = 0;
71 
72     while( len < max ) {
73         dst[len] = 0x00;
74 
75         if ( receive( fd, &c, 1, &rx ) != 0 ) {
76             len = 0;
77             goto end;
78         }
79 
80         if ( c == delim ) {
81             goto end;
82         }
83 
84         dst[len] = c;
85         len++;
86     }
87 end:
88     return len;
89 }
90 
receive_n(int fd,void * dst_buf,size_t n_bytes)91 size_t receive_n( int fd, void *dst_buf, size_t n_bytes )
92 {
93   char *dst = dst_buf;
94   size_t len = 0;
95   size_t rx = 0;
96   while(len < n_bytes) {
97     if (receive(fd, dst + len, n_bytes - len, &rx) != 0) {
98       len = 0;
99       break;
100     }
101     len += rx;
102   }
103 
104   return len;
105 }
106 
107 unsigned char key = '\0';
108 char *current_secret = NULL;
109 int global_secret = 0;
110 
111 enum action_t { LOAD_KEY, LOAD_SECRET, LOAD_SZ };
112 
present_key(char * secret)113 void present_key(char *secret) {
114 	int i;
115 
116 	for (i=0;i<101;i++) {
117 		key -= secret[i];
118 	}
119 
120 	transmit(0, "+", 1, NULL);
121 	transmit(0, &key, 1, NULL);
122 	transmit(0, "+", 1, NULL);
123 }
124 
show_secret(char * cs)125 void show_secret(char *cs) {
126 	int sp = global_secret;
127 	char secretb[0x80];
128 
129         strcpy(secretb, cs);
130 
131 	char *dst = malloc(0x80);
132 
133 	memcpy(dst, cs, 0x80);
134 
135 	transmit(0, dst, 0x80, NULL);
136 
137 	if (global_secret != sp) {
138 		_terminate(1);
139 	}
140 }
141 
kxor(char * buf,size_t sz)142 void kxor(char *buf, size_t sz) {
143  	int i;
144 
145 	for (i=0;i<sz;i++) {
146 		buf[i] ^= key;
147 	}
148 }
149 
srecv(char * buf,size_t sz)150 void srecv(char *buf, size_t sz) {
151 	receive_n(0, buf, sz);
152 
153         kxor(buf, sz);
154 }
155 
main(int secret_flag_i)156 void __attribute__((fastcall)) main(int secret_flag_i)
157 {
158 	char cmd[1024];
159  	size_t n;
160 	char *secret = (char *)secret_flag_i;
161 
162 	present_key(secret);
163 
164 	char buf[10];
165 	char *lsecret;
166         int msize = 0;
167 	global_secret = ((int *)secret_flag_i)[0];
168 
169 	while (1) {
170 		srecv(buf, 1);
171 		switch(buf[0]) {
172 
173 		case LOAD_KEY:
174 			show_secret(current_secret);
175 			break;
176 
177 		case LOAD_SECRET:
178 			if (msize > 0x1000) {
179 				_terminate(1);
180 			}
181 			current_secret = malloc(msize);
182 			srecv(current_secret, msize);
183 			break;
184 
185 		case LOAD_SZ:
186 			srecv(&msize, 4);
187 			break;
188 
189 
190 		}
191 	}
192 }
193