source: pwntcha/trunk/src/ticketmaster.c @ 1003

Last change on this file since 1003 was 1003, checked in by sam, 8 years ago
  • Started working on ticketmaster captcha.
  • Property svn:keywords set to Id
File size: 5.1 KB
Line 
1/*
2 * ticketmaster.c: decode ticketmaster captchas
3 * $Id: ticketmaster.c 1003 2006-07-16 15:07:04Z sam $
4 *
5 * Copyright: (c) 2006 Sam Hocevar <sam@zoy.org>
6 *   This program is free software; you can redistribute it and/or
7 *   modify it under the terms of the Do What The Fuck You Want To
8 *   Public License as published by Banlu Kemiyatorn. See
9 *   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
10 */
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <limits.h>
16
17#include "config.h"
18#include "common.h"
19
20#define WIDTH 290
21#define HEIGHT 80
22
23int grid_y[HEIGHT], grid_x[WIDTH];
24
25int dx_top[WIDTH], dy_top[WIDTH];
26int dx_bottom[WIDTH], dy_bottom[WIDTH];
27
28int perturbation_color(struct image *img, int x, int y);
29int real_color(struct image *img, int x, int y);
30
31int detect_grid(struct image *img);
32int detect_lines(struct image *img, int top);
33
34static inline int fastgetgray(struct image *img, int x, int y)
35{
36    int r, g, b;
37    getpixel(img, x, y, &r, &g, &b);
38    return (r + g + b + 1) / 3;
39}
40
41/* Main function */
42char *decode_ticketmaster(struct image *img)
43{
44    struct image *tmp;
45    int x, y;
46
47    if(detect_grid(img))
48        pwnprint("image has vertical grid\n");
49
50    detect_lines(img, 1);
51    detect_lines(img, 0);
52
53    tmp = image_dup(img);
54
55    /* Remove perturbations */
56    for(y = 1; y < HEIGHT - 1; y++)
57    {
58        for(x = 1; x < WIDTH - 1; x++)
59        {
60            int i, j, ok = 1;
61
62            if(perturbation_color(img, x, y) != 0)
63                continue;
64
65            for(j = -1; j <= 1; j++)
66            {
67                for(i = -1; i <= 1; i++)
68                {
69                    if(i == 0 && j == 0)
70                        continue;
71
72                    if(real_color(img, x + i, y + j)
73                         != perturbation_color(img, x + i, y + j))
74                        goto lol;
75                }
76            }
77
78            if(!ok)
79                continue;
80
81            setpixel(tmp, x, y, 255, 255, 255);
82
83lol: continue;
84        }
85    }
86
87    /* Lol, display lines */
88    for(x = 1; x < WIDTH - 1; x++)
89    {
90        if(dy_top[x])
91            for(y = 0; y < HEIGHT; y++)
92            {
93                int newx = (x * 1024 + dx_top[x] + (y * dy_top[x])) / 1024;
94                setpixel(tmp, newx, y, 0, 255, 0);
95            }
96
97        if(dy_bottom[x])
98            for(y = 0; y < HEIGHT; y++)
99            {
100                int newx = (x * 1024 + dx_bottom[x] + (y * dy_bottom[x])) / 1024;
101                setpixel(tmp, newx, (HEIGHT - y - 1), 0, 255, 0);
102            }
103    }
104
105image_save(tmp, "ticketmaster-output.bmp");
106    image_free(tmp);
107
108    return strdup("lol");
109}
110
111int real_color(struct image *img, int x, int y)
112{
113    return fastgetgray(img, x, y) < 40 ? 0 : 255;
114}
115
116int perturbation_color(struct image *img, int x, int y)
117{
118    if(grid_x[x]) return 0;
119
120    if(grid_y[y]) return 0;
121
122    return 255;
123}
124
125int detect_lines(struct image *img, int top)
126{
127    int x, y, i, j;
128
129    int dx, dy;
130    int *mydx, *mydy;
131
132    if(top)
133    {
134        mydx = dx_top;
135        mydy = dy_top;
136    }
137    else
138    {
139        mydx = dx_bottom;
140        mydy = dy_bottom;
141    }
142
143    /* Detect top-bottom line candidates */
144    for(x = 0; x < WIDTH; x++)
145    {
146        int candidate = 0, worstmissed;
147
148        y = top ? 0 : HEIGHT - 3;
149        for(j = 0; j < 3; j++)
150        {
151            for(i = -1; i <= 1; i++)
152            {
153                if(fastgetgray(img, x + i, y + j) < 40)
154                {
155                    candidate++;
156                    break;
157                }
158            }
159        }
160
161        if(candidate < 3)
162            continue;
163
164        mydx[x] = mydy[x] = 0;
165
166        worstmissed = 30;
167
168        /* Refine slope, in 1/1024th of a pixel steps */
169        for(dx = -1024; dx < 1024; dx += 128)
170        {
171            for(dy = 700; dy < 1300; dy += 16)
172            {
173                int missed = 0;
174
175                for(y = 0; y < HEIGHT; y++)
176                {
177                    int newx = (x * 1024 + dx + (y * dy)) / 1024;
178                    int gray = fastgetgray(img, newx, top ? y : (HEIGHT - y - 1));
179
180                    if(gray > 40)
181                    {
182                        missed++;
183
184                        if(missed >= worstmissed)
185                            break;
186                    }
187                }
188
189                if(missed < worstmissed)
190                {
191                    worstmissed = missed;
192                    mydx[x] = dx;
193                    mydy[x] = dy;
194                }
195            }
196        }
197
198        if(worstmissed == 30)
199            continue;
200
201        pwnprint("found a line at %i (+ %i), slope %i/1024\n", x, mydx[x], mydy[x]);
202    }
203
204    return 1;
205}
206
207int detect_grid(struct image *img)
208{
209    int x, y;
210
211    int lines = 0, columns = 0;
212
213    memset(grid_y, 0, sizeof(grid_y));
214    memset(grid_x, 0, sizeof(grid_x));
215
216    for(y = 0; y < HEIGHT; y++)
217    {
218        for(x = 0; x < WIDTH; x++)
219        {
220            if(fastgetgray(img, x, y) < 40)
221            {
222                grid_x[x]++;
223                grid_y[y]++;
224            }
225        }
226    }
227
228    for(y = 0; y < HEIGHT; y++)
229        if((grid_y[y] = (grid_y[y] > WIDTH * 90 / 100))) lines++;
230
231    for(x = 0; x < WIDTH; x++)
232        if((grid_x[x] = (grid_x[x] > HEIGHT * 90 / 100))) columns++;
233
234    return lines * columns > 3 * 20;
235}
236
Note: See TracBrowser for help on using the repository browser.