source: pwntcha/trunk/src/vbulletin.c @ 414

Last change on this file since 414 was 414, checked in by Sam Hocevar, 16 years ago
  • vbulletin captcha support.
  • Property svn:keywords set to Id
File size: 3.6 KB
Line 
1/*
2 * vbulletin.c: decode vbulletin captchas
3 * $Id: vbulletin.c 414 2005-01-04 17:07:22Z sam $
4 *
5 * Copyright: (c) 2005 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 FONTNAME "share/font_vbulletin.png"
21
22/* Main function */
23char *decode_vbulletin(struct image *img)
24{
25    char all[] = "2346789ABCDEFGHJKLMNPRTWXYZ";
26    char *result;
27    struct image *tmp1, *tmp2, *tmp3, *font;
28    int limits[6] = { 26, 53, 80, 107, 134, 160 };
29    int x, y, r, g, b, i, j;
30
31    font = image_load(FONTNAME);
32    if(!font)
33    {
34        fprintf(stderr, "cannot load font %s\n", FONTNAME);
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    getpixel(img, 0, 0, &r, &g, &b);
44    if(r < 50)
45        tmp1 = filter_equalize(img, 128);
46    else
47        tmp1 = filter_equalize(img, -128);
48
49    /* Remove garbage around the cells */
50    for(x = 0; x < img->width; x++)
51    {
52        for(y = 0; y < 15; y++)
53            setpixel(tmp1, x, y, 255, 255, 255);
54        for(y = 45; y < img->height; y++)
55            setpixel(tmp1, x, y, 255, 255, 255);
56    }
57
58    for(x = 0; x < img->width; x++)
59    {
60        for(i = 0; i < 6; i++)
61            if(x == limits[i])
62                break;
63        if(i == 6)
64            for(y = 15; y < 45; y++)
65                setpixel(tmp1, x, y, 255, 255, 255);
66        else
67            x += 11;
68    }
69
70    tmp2 = filter_black_stuff(tmp1);
71    tmp3 = filter_black_stuff(tmp2);
72
73    /* Fill letters in gray */
74    for(x = 26; x < 172; x++)
75    {
76        getpixel(tmp3, x, 15, &r, &g, &b);
77        if(r == 0)
78            filter_flood_fill(tmp3, x, 15, 127, 0, 255);
79    }
80
81    /* Find remaining black parts and remove them */
82    for(x = 26; x < 172; x++)
83        for(y = 15; y < 45; y++)
84        {
85            getpixel(tmp3, x, y, &r, &g, &b);
86            if(r == 0)
87                filter_flood_fill(tmp3, x, y, 255, 255, 255);
88        }
89
90    /* Fill letters in black */
91    for(x = 26; x < 172; x++)
92    {
93        getpixel(tmp3, x, 44, &r, &g, &b);
94        if(r == 127)
95            filter_flood_fill(tmp3, x, 44, 0, 0, 0);
96    }
97
98    /* Find remaining gray parts and remove them */
99    for(x = 26; x < 172; x++)
100        for(y = 15; y < 45; y++)
101        {
102            getpixel(tmp3, x, y, &r, &g, &b);
103            if(r == 127)
104                filter_flood_fill(tmp3, x, y, 255, 255, 255);
105        }
106
107    /* Guess all glyphs */
108    for(i = 0; i < 6; i++)
109    {
110        struct image *new;
111        int mindist = INT_MAX, min = -1;
112        new = filter_crop(tmp3, limits[i], 15, limits[i] + 11, 45);
113        for(j = 0; j < 27; j++)
114        {
115            int dist = 0;
116            for(y = 0; y < new->height; y++)
117                for(x = 0; x < new->width; x++)
118                {
119                    int r2, g2, b2;
120                    getpixel(font, 12 * j + x, y, &r, &g, &b);
121                    getpixel(new, x, y, &r2, &g2, &b2);
122                    dist += (r - r2) * (r - r2);
123                }
124            if(dist < mindist)
125            {
126                mindist = dist;
127                min = j;
128            }
129        }
130        image_free(new);
131        result[i] = all[min];
132    }
133
134    image_free(tmp1);
135    image_free(tmp2);
136    image_free(tmp3);
137    image_free(font);
138
139    return result;
140}
141
Note: See TracBrowser for help on using the repository browser.