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