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

Last change on this file since 445 was 445, checked in by Sam Hocevar, 18 years ago
  • don't duplicate picture in filter functions.
  • removed OLE code; it doesn't work and won't be needed.
  • Property svn:keywords set to Id
File size: 3.7 KB
Line 
1/*
2 * vbulletin.c: decode vbulletin captchas
3 * $Id: vbulletin.c 445 2005-01-10 11:23:38Z 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 "font_vbulletin.png"
21static struct image *font = NULL;
22
23/* Main function */
24char *decode_vbulletin(struct image *img)
25{
26    char all[] = "2346789ABCDEFGHJKLMNPRTWXYZ";
27    char *result;
28    struct image *tmp;
29    int limits[6] = { 26, 53, 80, 107, 134, 160 };
30    int x, y, r, g, b, i, j;
31
32    if(!font)
33    {
34        char fontname[BUFSIZ];
35        sprintf(fontname, "%s/%s", share, FONTNAME);
36        font = image_load(fontname);
37        if(!font)
38        {
39            fprintf(stderr, "cannot load font %s\n", fontname);
40            exit(-1);
41        }
42    }
43
44    /* vBulletin captchas have 6 characters */
45    result = malloc(7 * sizeof(char));
46    strcpy(result, "      ");
47
48    /* half the captchas are inverse video; we set them back to normal */
49    tmp = image_dup(img);
50    getpixel(tmp, 0, 0, &r, &g, &b);
51    if(r < 50)
52        filter_equalize(tmp, 128);
53    else
54        filter_equalize(tmp, -128);
55
56    /* Remove garbage around the cells */
57    for(x = 0; x < tmp->width; x++)
58    {
59        for(y = 0; y < 15; y++)
60            setpixel(tmp, x, y, 255, 255, 255);
61        for(y = 45; y < tmp->height; y++)
62            setpixel(tmp, x, y, 255, 255, 255);
63    }
64
65    for(x = 0; x < tmp->width; x++)
66    {
67        for(i = 0; i < 6; i++)
68            if(x == limits[i])
69                break;
70        if(i == 6)
71            for(y = 15; y < 45; y++)
72                setpixel(tmp, x, y, 255, 255, 255);
73        else
74            x += 11;
75    }
76
77    filter_black_stuff(tmp);
78    filter_black_stuff(tmp);
79
80    /* Fill letters in gray */
81    for(x = 26; x < 172; x++)
82    {
83        getpixel(tmp, x, 15, &r, &g, &b);
84        if(r == 0)
85            filter_flood_fill(tmp, x, 15, 127, 0, 255);
86    }
87
88    /* Find remaining black parts and remove them */
89    for(x = 26; x < 172; x++)
90        for(y = 15; y < 45; y++)
91        {
92            getpixel(tmp, x, y, &r, &g, &b);
93            if(r == 0)
94                filter_flood_fill(tmp, x, y, 255, 255, 255);
95        }
96
97    /* Fill letters in black */
98    for(x = 26; x < 172; x++)
99    {
100        getpixel(tmp, x, 44, &r, &g, &b);
101        if(r == 127)
102            filter_flood_fill(tmp, x, 44, 0, 0, 0);
103    }
104
105    /* Find remaining gray parts and remove them */
106    for(x = 26; x < 172; x++)
107        for(y = 15; y < 45; y++)
108        {
109            getpixel(tmp, x, y, &r, &g, &b);
110            if(r == 127)
111                filter_flood_fill(tmp, x, y, 255, 255, 255);
112        }
113
114    /* Guess all glyphs */
115    for(i = 0; i < 6; i++)
116    {
117        struct image *new = image_dup(tmp);
118        int mindist = INT_MAX, min = -1;
119        filter_crop(new, limits[i], 15, limits[i] + 11, 45);
120        for(j = 0; j < 27; j++)
121        {
122            int dist = 0;
123            for(y = 0; y < new->height; y++)
124                for(x = 0; x < new->width; x++)
125                {
126                    int r2, g2, b2;
127                    getpixel(font, 12 * j + x, y, &r, &g, &b);
128                    getpixel(new, x, y, &r2, &g2, &b2);
129                    dist += (r - r2) * (r - r2);
130                }
131            if(dist < mindist)
132            {
133                mindist = dist;
134                min = j;
135            }
136        }
137        image_free(new);
138        result[i] = all[min];
139    }
140
141    image_free(tmp);
142
143    return result;
144}
145
Note: See TracBrowser for help on using the repository browser.