Просмотр исходного кода

* attempt at the xanga decoder. roughly 50% success.

* fonts useful to the xanga decoder. x_* fonts are convert'ed with -blur 3.


git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/pwntcha/trunk@453 92316355-f0b4-4df1-b90c-862c8a59935f
master
sam 20 лет назад
Родитель
Сommit
adfa585fc4
14 измененных файлов: 135 добавлений и 31 удалений
  1. Двоичные данные
      share/font_comic_24_az_messed.bmp
  2. Двоичные данные
      share/font_comic_32_az.bmp
  3. Двоичные данные
      share/font_freemonobold_24_az.bmp
  4. Двоичные данные
      share/font_freemonobold_32_az.bmp
  5. Двоичные данные
      share/font_freesansbold_32_az.bmp
  6. Двоичные данные
      share/font_freesansbold_36_az_messed.bmp
  7. Двоичные данные
      share/x_font_comic_24_az_messed.bmp
  8. Двоичные данные
      share/x_font_comic_32_az.bmp
  9. Двоичные данные
      share/x_font_freemonobold_24_az.bmp
  10. Двоичные данные
      share/x_font_freemonobold_32_az.bmp
  11. Двоичные данные
      share/x_font_freesansbold_32_az.bmp
  12. Двоичные данные
      share/x_font_freesansbold_36_az_messed.bmp
  13. +1
    -0
      src/main.c
  14. +134
    -31
      src/xanga.c

Двоичные данные
share/font_comic_24_az_messed.bmp Просмотреть файл

До После

Двоичные данные
share/font_comic_32_az.bmp Просмотреть файл

До После

Двоичные данные
share/font_freemonobold_24_az.bmp Просмотреть файл

До После

Двоичные данные
share/font_freemonobold_32_az.bmp Просмотреть файл

До После

Двоичные данные
share/font_freesansbold_32_az.bmp Просмотреть файл

До После

Двоичные данные
share/font_freesansbold_36_az_messed.bmp Просмотреть файл

До После

Двоичные данные
share/x_font_comic_24_az_messed.bmp Просмотреть файл

До После

Двоичные данные
share/x_font_comic_32_az.bmp Просмотреть файл

До После

Двоичные данные
share/x_font_freemonobold_24_az.bmp Просмотреть файл

До После

Двоичные данные
share/x_font_freemonobold_32_az.bmp Просмотреть файл

До После

Двоичные данные
share/x_font_freesansbold_32_az.bmp Просмотреть файл

До После

Двоичные данные
share/x_font_freesansbold_36_az_messed.bmp Просмотреть файл

До После

+ 1
- 0
src/main.c Просмотреть файл

@@ -209,6 +209,7 @@ int main(int argc, char *argv[])
}

printf("%s\n", result);
fflush(stdout);
free(result);
}



+ 134
- 31
src/xanga.c Просмотреть файл

@@ -19,41 +19,18 @@
#include "common.h"

static void fill_white_holes(struct image *img);
static void find_glyphs(struct image *img);

static char *result;

/* Main function */
char *decode_xanga(struct image *img)
{
static struct font *font1 = NULL, *font2 = NULL, *font3 = NULL;
struct image *tmp;
char *result;

if(!font1)
{
font1 = font_load_variable("font_freemonobold_32_az.bmp",
"abcdefghijklmnopqrstuvwxyz");
if(!font1)
exit(1);
}

if(!font2)
{
font2 = font_load_variable("font_freemonobold_32_az.bmp",
"abcdefghijklmnopqrstuvwxyz");
if(!font2)
exit(1);
}

if(!font3)
{
font3 = font_load_variable("font_freemonobold_32_az.bmp",
"abcdefghijklmnopqrstuvwxyz");
if(!font3)
exit(1);
}

/* Xanga captchas have 7 characters */
result = malloc(8 * sizeof(char));
strcpy(result, " ");
/* Xanga captchas have 6 characters */
result = malloc(7 * sizeof(char));
strcpy(result, " ");

tmp = image_dup(img);
image_save(tmp, "xanga1.bmp");
@@ -64,20 +41,26 @@ image_save(tmp, "xanga1.bmp");
image_save(tmp, "xanga2.bmp");
fill_white_holes(tmp);
// filter_fill_holes(tmp);
filter_smooth(tmp);
//filter_median(tmp);
image_save(tmp, "xanga3.bmp");
//filter_detect_lines(tmp);
// filter_median(tmp);
//image_save(tmp, "xanga4.bmp");
filter_equalize(tmp, 128);
// filter_equalize(tmp, 128);
filter_contrast(tmp);
image_save(tmp, "xanga4.bmp");
return NULL;

#if 0
/* Detect small objects to guess image orientation */
filter_median(tmp);
filter_equalize(tmp, 200);

/* Invert rotation and find glyphs */
filter_median(tmp);
#endif
find_glyphs(tmp);
image_save(tmp, "xanga5.bmp");

/* Clean up our mess */
image_free(tmp);
@@ -130,3 +113,123 @@ static void fill_white_holes(struct image *img)
image_free(tmp);
}

static void find_glyphs(struct image *img)
{
#define FONTS 6
static struct font *fonts[FONTS];
static char *files[] =
{
"x_font_freemonobold_32_az.bmp", "abcdefghijklmnopqrstuvwxyz",
"x_font_freemonobold_24_az.bmp", "abcdefghijklmnopqrstuvwxyz",
"x_font_freesansbold_32_az.bmp", "abcdefghijklmnopqrstuvwxyz",
//"x_font_freeserifbold_32_az.bmp", "abcdefghijklmnopqrstuvwxyz",
"x_font_comic_32_az.bmp", "abcdefghijklmnopqrstuvwxyz",
"x_font_comic_24_az_messed.bmp", "abcdefghijklmnopqrstuvwxyz",
"x_font_freesansbold_36_az_messed.bmp", "abcdefghijklmnopqrstuvwxyz",
};
struct image *tmp;
int x, y, i = 0, f;
int r, g, b;
int xmin, xmax, ymin, ymax, startx = 10, cur = 0;
int bestdist, bestfont, bestx, besty, bestch;

for(f = 0; f < FONTS; f++)
{
if(!fonts[f])
{
fonts[f] = font_load_variable(files[f * 2], files[f * 2 + 1]);
if(!fonts[f])
exit(1);
//filter_smooth(fonts[f]->img);
//filter_contrast(fonts[f]->img);
}
}

tmp = 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(tmp, x, y, 255, g, 255);
}

while(cur < 6)
{
/* Try to find 1st letter */
bestdist = INT_MAX;
for(f = 0; f < FONTS; f++) for(i = 0; i < fonts[f]->size; i++)
{
int localmin = INT_MAX, localx, localy;
int sqr;
if(fonts[f]->glyphs[i].c == 'l' || fonts[f]->glyphs[i].c == 'z')
continue;
xmin = fonts[f]->glyphs[i].xmin - 5;
ymin = fonts[f]->glyphs[i].ymin - 3;
xmax = fonts[f]->glyphs[i].xmax + 5;
ymax = fonts[f]->glyphs[i].ymax + 3;
sqr = sqrt(xmax - xmin);
for(y = -15; y < 15; y++)
//for(x = startx; x < startx + 15; x++)
for(x = 22 - (xmax - xmin) / 2 + 25 * cur; x < 28 - (xmax - xmin) / 2 + 25 * cur; x++)
{
int z, t, dist;
dist = 0;
for(t = 0; t < ymax - ymin; t++)
for(z = 0; z < xmax - xmin; z++)
{
int r2;
getgray(fonts[f]->img, xmin + z, ymin + t, &r);
getgray(img, x + z, y + t, &r2);
if(r < r2)
dist += (r - r2) * (r - r2);
else
dist += (r - r2) * (r - r2) * 3 / 4;
}
// printf("%i %i -> %i\n", x, y, dist);
// dist /= (xmax - xmin);
// dist = dist / sqrt((ymax - ymin) * (xmax - xmin)) / (xmax - xmin);
dist = dist / (xmax - xmin) / sqr;
// dist = dist * 128 / fonts[f]->glyphs[i].count;
if(dist < localmin)
{
localmin = dist;
localx = x;
localy = y;
}
}
//fprintf(stderr, "%i (%i,%i)\n", localmin, localx - startx, localy);
if(localmin < bestdist)
{
//printf(" bestch is now %i (%c) in font %i\n", i, fonts[f]->glyphs[i].c, f);
bestdist = localmin;
bestfont = f;
bestx = localx;
besty = localy;
bestch = i;
}
}
//printf("%i (%c) in font %i\n", i, fonts[bestfont]->glyphs[bestch].c, bestfont);
//printf("%i < %i < %i\n", 10 + 25 * cur, bestx, 30 + 25 * cur);

/* Draw best glyph in picture (debugging purposes) */
xmin = fonts[bestfont]->glyphs[bestch].xmin - 5;
ymin = fonts[bestfont]->glyphs[bestch].ymin - 3;
xmax = fonts[bestfont]->glyphs[bestch].xmax + 5;
ymax = fonts[bestfont]->glyphs[bestch].ymax + 3;
for(y = 0; y < ymax - ymin; y++)
for(x = 0; x < xmax - xmin; x++)
{
getpixel(fonts[bestfont]->img, xmin + x, ymin + y, &r, &g, &b);
if(r > 128) continue;
setpixel(tmp, bestx + x, besty + y, r, g, b);
}

startx = bestx + xmax - xmin;
result[cur++] = fonts[bestfont]->glyphs[bestch].c;
}

image_swap(img, tmp);
image_free(tmp);
}


Загрузка…
Отмена
Сохранить