diff --git a/src/Makefile.am b/src/Makefile.am index 5dbe48a..e58628f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,7 +3,15 @@ NULL = bin_PROGRAMS = pwntcha pwntcha_CFLAGS = $(ADDITIONAL_CFLAGS) -Wall -O6 pwntcha_LDFLAGS = $(ADDITIONAL_LDFLAGS) -pwntcha_SOURCES = main.c image.c filters.c common.h slashdot.c phpbb.c test.c +pwntcha_SOURCES = \ + main.c \ + image.c \ + filters.c \ + common.h \ + phpbb.c \ + scode.c \ + slashdot.c \ + test.c if USE_OPENCV ADDITIONAL_CFLAGS = `opencv-config --cflags` diff --git a/src/main.c b/src/main.c index 2c8ea86..b9688d4 100644 --- a/src/main.c +++ b/src/main.c @@ -31,12 +31,11 @@ int debug = 1; int main(int argc, char *argv[]) { char *mode = "auto"; - - argv0 = argv[0]; - int c; int digit_optind = 0; + argv0 = argv[0]; + for(;;) { int this_option_optind = optind ? optind : 1; @@ -122,6 +121,8 @@ int main(int argc, char *argv[]) result = decode_test(img); else if(!strcmp(mode, "phpbb")) result = decode_phpbb(img); + else if(!strcmp(mode, "scode")) + result = decode_scode(img); else if(!strcmp(mode, "slashdot")) result = decode_slashdot(img); else @@ -131,6 +132,11 @@ int main(int argc, char *argv[]) dprintf("autodetecting phpBB captcha\n"); result = decode_phpbb(img); } + else if(img->height == 25) + { + dprintf("autodetecting scode captcha\n"); + result = decode_scode(img); + } else if(img->height == 69) { dprintf("autodetecting slashdot captcha\n"); diff --git a/src/scode.c b/src/scode.c new file mode 100644 index 0000000..04a26ba --- /dev/null +++ b/src/scode.c @@ -0,0 +1,144 @@ +/* + * scode.c: decode scode captchas + * $Id$ + * + * Copyright: (c) 2004 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 "config.h" +#include "common.h" + +static char find_glyph(struct image *img, int xmin, int xmax); + +/* Main function */ +char *decode_scode(struct image *img) +{ + char *result; + int stats[256]; + int x, y, i, incell = 0, cur = 0, xmin = 0; + int r, g, b; + struct image *tmp1; + + /* allocate enough place */ + result = malloc(1024 * sizeof(char)); + + /* Detect background: first 3 lines */ + for(i = 0; i < 256; i++) + stats[i] = 0; + + for(y = 0; y < 3; y++) + for(x = 0; x < img->width; x++) + { + getpixel(img, x, y, &r, &g, &b); + stats[r]++; + } + + /* Set non-background colours to 0 */ + tmp1 = 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); + if(stats[r]) + setpixel(tmp1, x, y, 255, 255, 255); + else + setpixel(tmp1, x, y, 0, 0, 0); + } + + /* Decode glyphs */ + for(x = 0; x < img->width; x++) + { + int found = 0; + for(y = 0; y < img->height; y++) + { + getpixel(tmp1, x, y, &r, &g, &b); + if(!r) + { + found = 1; + break; + } + } + if(found && !incell) + { + incell = 1; + xmin = x; + } + else if(!found && incell) + { + incell = 0; + /* Find glyph */ + result[cur++] = find_glyph(tmp1, xmin, x); + } + } + + image_free(tmp1); + + result[cur] = 0; + return result; +} + +static char find_glyph(struct image *img, int xmin, int xmax) +{ + int ymin = -1, ymax = -1; + int x, y, count = 0; + int r, g, b; + + /* Compute vertical bounds of glyph */ + for(y = 0; y < img->height; y++) + { + int found = 0; + for(x = xmin; x < xmax; x++) + { + getpixel(img, x, y, &r, &g, &b); + if(!r) + { + found = 1; + break; + } + } + if(found) + { + if(ymin == -1) + ymin = y; + else + ymax = y + 1; + } + } + + for(x = xmin; x < xmax; x++) + { + for(y = ymin; y < ymax; y++) + { + getpixel(img, x, y, &r, &g, &b); + if(!r) + count += y - ymin; + } + } + + switch(count) + { + case 162: return '0'; + case 131: return '1'; + case 150: return '2'; + case 139: return '3'; + case 155: return '4'; + case 159: return '5'; + case 181: return '6'; + case 90: return '7'; + case 180: return '8'; + case 170: return '9'; + default: + dprintf("don't know about checksum %i\n", count); + return '?'; + } +} + diff --git a/src/slashdot.c b/src/slashdot.c index 518a705..a377139 100644 --- a/src/slashdot.c +++ b/src/slashdot.c @@ -34,7 +34,7 @@ int objects, first, last; char *result; /* Main function */ -char * decode_slashdot(struct image *img) +char *decode_slashdot(struct image *img) { struct image *tmp1, *tmp2, *tmp3, *tmp4, *tmp5, *tmp6, *tmp7; diff --git a/src/test.c b/src/test.c index f7f5c59..f6443f5 100644 --- a/src/test.c +++ b/src/test.c @@ -28,7 +28,7 @@ int objects, first, last; char *result; /* Main function */ -char * decode_test(struct image *img) +char *decode_test(struct image *img) { struct image *tmp1, *tmp2, *tmp3, *tmp4, *tmp5, *tmp6, *tmp7;