diff --git a/src/Makefile.am b/src/Makefile.am index d9cdb0c..156a5c6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,6 +13,7 @@ pwntcha_SOURCES = \ scode.c \ slashdot.c \ vbulletin.c \ + xanga.c \ test.c pwntcha_CFLAGS = $(ADDITIONAL_CFLAGS) -Wall -O6 pwntcha_LDFLAGS = $(ADDITIONAL_LDFLAGS) diff --git a/src/main.c b/src/main.c index e626197..44043b5 100644 --- a/src/main.c +++ b/src/main.c @@ -146,6 +146,8 @@ int main(int argc, char *argv[]) result = decode_slashdot(img); else if(!strcmp(mode, "vbulletin")) result = decode_vbulletin(img); + else if(!strcmp(mode, "xanga")) + result = decode_xanga(img); else { if(img->width == 155 && img->height == 50) @@ -163,6 +165,11 @@ int main(int argc, char *argv[]) dprintf("autodetected phpBB captcha\n"); result = decode_phpbb(img); } + else if(img->width == 170 && img->height == 50) + { + dprintf("autodetected Xanga captcha\n"); + result = decode_xanga(img); + } else if(img->height <= 40 && count < 10) { dprintf("autodetected scode/trencaspammers captcha\n"); diff --git a/src/xanga.c b/src/xanga.c new file mode 100644 index 0000000..165772d --- /dev/null +++ b/src/xanga.c @@ -0,0 +1,131 @@ +/* + * xanga.c: decode Xanga captchas + * $Id$ + * + * Copyright: (c) 2005 Sam Hocevar + * This program is free software; you can redistribute it and/or + * modify it under the terms of the Do What The Fuck You Want To + * Public License as published by Banlu Kemiyatorn. See + * http://sam.zoy.org/projects/COPYING.WTFPL for more details. + */ + +#include +#include +#include +#include +#include + +#include "config.h" +#include "common.h" + +static struct image *fill_white_holes(struct image *img); +static struct image *rotate(struct image *img); +static struct image *cut_cells(struct image *img); +static struct image *find_glyphs(struct image *img); + +/* Our macros */ +#define FACTOR 1 +#define FONTNAME "font_xanga.png" // use with FACTOR = 1 +//#define FONTNAME "font.png" // use with FACTOR = 2 +//#define FONTNAME "font_dilated.png" // use with FACTOR = 2 +static struct image *font = NULL; + +/* Global stuff */ +struct { int xmin, ymin, xmax, ymax; } objlist[100]; +int objects, first, last; +char *result; + +/* Main function */ +char *decode_xanga(struct image *img) +{ + struct image *tmp1, *tmp2, *tmp3, *tmp4, *tmp5, *tmp6, *tmp7; + + /* Initialise local data */ + objects = 0; + first = -1; + last = -1; + + /* Xanga captchas have 7 characters */ + result = malloc(8 * sizeof(char)); + strcpy(result, " "); + +image_save(img, "xanga1.bmp"); + /* Clean image a bit */ +// tmp1 = filter_equalize(img, 200); + tmp1 = filter_contrast(img); + //tmp1 = filter_detect_lines(img); +image_save(tmp1, "xanga2.bmp"); + tmp2 = fill_white_holes(tmp1); +// tmp2 = filter_fill_holes(tmp1); +image_save(tmp2, "xanga3.bmp"); + //tmp3 = filter_detect_lines(tmp2); +// tmp3 = filter_median(tmp2); +//image_save(tmp3, "xanga4.bmp"); + tmp3 = filter_equalize(tmp2, 128); +image_save(tmp3, "xanga4.bmp"); +return NULL; + + /* Detect small objects to guess image orientation */ + tmp3 = filter_median(tmp2); + tmp4 = filter_equalize(tmp3, 200); + + /* Invert rotation and find glyphs */ + tmp5 = rotate(tmp2); + tmp6 = filter_median(tmp5); + + /* Clean up our mess */ + image_free(tmp1); + image_free(tmp2); + image_free(tmp3); + image_free(tmp4); + image_free(tmp5); + image_free(tmp6); + image_free(tmp7); + + /* aaaaaaa means decoding failed */ + if(!strcmp(result, "aaaaaaa")) + result[0] = '\0'; + + return result; +} + +/* The following functions are local */ + +static struct image *fill_white_holes(struct image *img) +{ + struct image *dst; + int x, y, i; + int r, g, b; + + dst = image_new(img->width, img->height); + + for(y = 0; y < img->height; y++) + for(x = 0; x < img->width; x++) + { + getpixel(img, x, y, &r, &g, &b); + setpixel(dst, x, y, r, g, b); + } + + for(y = 1; y < img->height - 1; y++) + for(x = 1; x < img->width - 1; x++) + { + int count = 0; + getpixel(img, x, y, &r, &g, &b); + if(r <= 16) + continue; + getpixel(img, x + 1, y, &r, &g, &b); + count += r; + getpixel(img, x - 1, y, &r, &g, &b); + count += r; + getpixel(img, x, y + 1, &r, &g, &b); + count += r; + getpixel(img, x, y - 1, &r, &g, &b); + count += r; + if(count > 600) + continue; + setpixel(dst, x, y, count / 5, count / 5, count / 5); + } + + return dst; +} +