source: pwntcha/trunk/src/vbulletin/decoder.c @ 2317

Last change on this file since 2317 was 2317, checked in by Sam Hocevar, 13 years ago
  • Preparing a huge PWNtcha reorganisation. First step: put each decoder in its own subdirectory.
  • Property svn:keywords set to Id
File size: 3.5 KB
Line 
1/*
2 * vbulletin.c: decode vbulletin captchas
3 * $Id: decoder.c 2317 2008-04-26 08:41:35Z sam $
4 *
5 * Copyright: (c) 2005 Sam Hocevar <sam@zoy.org>
6 *  This program is free software. It comes without any warranty, to
7 *  the extent permitted by applicable law. You can redistribute it
8 *  and/or modify it under the terms of the Do What The Fuck You Want
9 *  To Public License, Version 2, as published by Sam Hocevar. See
10 *  http://sam.zoy.org/wtfpl/COPYING for more details.
11 */
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <limits.h>
17
18#include "config.h"
19#include "common.h"
20
21/* Main function */
22char *decode_vbulletin(struct image *img)
23{
24    static struct font *font = NULL;
25    char *result;
26    struct image *tmp;
27    int limits[6] = { 26, 53, 80, 107, 134, 160 };
28    int x, y, r, g, b, i, j;
29
30    if(!font)
31    {
32        font = font_load_fixed("font_vbulletin.png",
33                               "2346789ABCDEFGHJKLMNPRTWXYZ");
34        if(!font)
35            exit(-1);
36    }
37
38    /* vBulletin captchas have 6 characters */
39    result = malloc(7 * sizeof(char));
40    strcpy(result, "      ");
41
42    /* half the captchas are inverse video; we set them back to normal */
43    tmp = image_dup(img);
44    getpixel(tmp, 0, 0, &r, &g, &b);
45    if(r < 50)
46        filter_threshold(tmp, 128);
47    else
48        filter_threshold(tmp, -128);
49
50    /* Remove garbage around the cells */
51    for(x = 0; x < tmp->width; x++)
52    {
53        for(y = 0; y < 15; y++)
54            setpixel(tmp, x, y, 255, 255, 255);
55        for(y = 45; y < tmp->height; y++)
56            setpixel(tmp, x, y, 255, 255, 255);
57    }
58
59    for(x = 0; x < tmp->width; x++)
60    {
61        for(i = 0; i < 6; i++)
62            if(x == limits[i])
63                break;
64        if(i == 6)
65            for(y = 15; y < 45; y++)
66                setpixel(tmp, x, y, 255, 255, 255);
67        else
68            x += 11;
69    }
70
71    filter_black_stuff(tmp);
72    filter_black_stuff(tmp);
73
74    /* Fill letters in gray */
75    for(x = 26; x < 172; x++)
76    {
77        getpixel(tmp, x, 15, &r, &g, &b);
78        if(r == 0)
79            filter_flood_fill(tmp, x, 15, 127, 0, 255);
80    }
81
82    /* Find remaining black parts and remove them */
83    for(x = 26; x < 172; x++)
84        for(y = 15; y < 45; y++)
85        {
86            getpixel(tmp, x, y, &r, &g, &b);
87            if(r == 0)
88                filter_flood_fill(tmp, x, y, 255, 255, 255);
89        }
90
91    /* Fill letters in black */
92    for(x = 26; x < 172; x++)
93    {
94        getpixel(tmp, x, 44, &r, &g, &b);
95        if(r == 127)
96            filter_flood_fill(tmp, x, 44, 0, 0, 0);
97    }
98
99    /* Find remaining gray parts and remove them */
100    for(x = 26; x < 172; x++)
101        for(y = 15; y < 45; y++)
102        {
103            getpixel(tmp, x, y, &r, &g, &b);
104            if(r == 127)
105                filter_flood_fill(tmp, x, y, 255, 255, 255);
106        }
107
108    /* Guess all glyphs */
109    for(i = 0; i < 6; i++)
110    {
111        int mindist = INT_MAX, min = -1;
112        for(j = 0; j < font->size; j++)
113        {
114            int dist = 0;
115            for(y = 0; y < 30; y++)
116                for(x = 0; x < 11; x++)
117                {
118                    int r2, g2, b2;
119                    getpixel(font->img, 12 * j + x, y, &r, &g, &b);
120                    getpixel(tmp, limits[i] + x, 15 + y, &r2, &g2, &b2);
121                    dist += (r - r2) * (r - r2);
122                }
123            if(dist < mindist)
124            {
125                mindist = dist;
126                min = j;
127            }
128        }
129        result[i] = font->glyphs[min].c;
130    }
131
132    image_free(tmp);
133
134    return result;
135}
136
Note: See TracBrowser for help on using the repository browser.