Няшная / Говнокод #20141 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
  88. 88
  89. 89
  90. 90
  91. 91
  92. 92
  93. 93
  94. 94
  95. 95
#include <stdio.h>
#include <string.h>
#include <stdlib.h>


int digits(char **arr_ptr, void **func_ptr)
{
	char *a = *arr_ptr;
	if (*a == '9')
	{
		if ( *(func_ptr-1) == NULL )
		{
			return 0;
		}
		else
		{
			*a = '0';
			return ( *(int(*)(char **, void **)) *(func_ptr-1) )(arr_ptr-1,func_ptr-1);
		}
	}
	(*a)++;
	return 1;
}

int az_AZ(char **arr_ptr, void **func_ptr)
{
	char *a = *arr_ptr;
	if (*a == 'z')
	{
		*a = 'A';
		return 1;
	}
	if (*a == 'Z')
	{
		if ( *(func_ptr-1) == NULL )
		{
			return 0;
		}
		else
		{
			*a = 'a';
			return ( *(int(*)(char **, void **)) *(func_ptr-1) )(arr_ptr-1,func_ptr-1);
		}
	}
	(*a)++;
	return 1;
}


int main(void)
{
	char a[] = "$#hui"; // $ - azAZ ; # - 1234567890
	size_t len = strlen(a);

	char **char_ptr_arr = malloc(sizeof(char *) * len);
	char **char_ptr_arr_p = char_ptr_arr;

	void **func_ptr = malloc(sizeof(void *) * (len+1));
	func_ptr[0] = NULL;
	void **func_ptr_p = func_ptr+1;


	char *i = a;
	while (*i != 0)
	{
		if (*i == '$')
		{
			*char_ptr_arr_p = i;
			char_ptr_arr_p++;
			*func_ptr_p = (void *)az_AZ;
			func_ptr_p++;
			*i = 'a';
		}
		else if (*i == '#')
		{
			*char_ptr_arr_p = i;
			char_ptr_arr_p++;
			*func_ptr_p = (void *)digits;
			func_ptr_p++;
			*i = '0';
		}
		i++;
	}

	printf("%s ", a);
	while (( *(int(*)(char **, void **)) *(func_ptr_p-1) )(char_ptr_arr_p-1,func_ptr_p-1) != 0 )
	{
		printf("%s ", a);
	}
	printf("%s\n", a);
	fflush(stdout);
	free(char_ptr_arr);
	free(func_ptr);
	return 0;
}

Перебиралка всех кобенаций паролей по маске на сишке, где функции через стек из указателей на функции друг друга вызывают через воиды.

http://govnokod.ru/20137#comment333406 отсюда:
Надо конечно typedef всунуть для функции, но там жопа с рекурсивным определением функции X = (int()(char **, X **))
По сути, надо чтобы функция в качестве аргумента принимала указатель того же типа, что и та сама функция, а такое рекурсивное определение типа в Си нельзя делать

Запостил: j123123 j123123, (Updated )

Комментарии (17) RSS

  • > указатель того же типа, что и та сама функция, а такое рекурсивное определение типа в Си нельзя делать

    Ой я тебя умаляю, в си все можно
    Ответить
    • В машинных кодах все можно, даже ассемблер не позволяет делать особые извраты
      Ответить
      • что это такое можно в машинных кодах, чего нельзя в ассемблере?

        разве что такие опкоды, которые транслятор тупо не знает.
        Ответить
          • тогда это будет не совсем асемблер, а просто "вставка кодов"
            Ответить
        • Пфф, ну например если ты делаешь свой нано-JIT. Если посмотреть на инструкции x86-64 в хексах, то например
          48c7c0010000 - это mov rax, 1
          48c7c1010000 - это mov rcx, 1
          48c7c2010000 - mov rdx, 1
              ^^

          Тут меняется этот с0 c1 c2 байтик
          вот зная особенности кодирования инструкций, можно эффективно из них в рантайме собирать код. Кроме того, есть такие инструкции, которые напрямую не написать на асме. Например mov rax, 0 может быть разной длины. Разное числн нулей
          Ответить
          • В смысле генерить в райнтайме не асмовые мнемоники, а байт коды, и как-то использовать тот факт что mov rax и mov rcx отличаются на 1? Ну, это отлично конечно, но это не значит что "ассемблер не позволяет делать особые извраты".
            Ответить
            • Да, на ассемблере ты это вменяемо не закодируешь, надо разбираться в том, как инструкции кодируются, из кусочков эти штуки делать
              Ответить
            • j123123 не смог найти удачных примеров. А ведь умели же раньше люди писа́ть! Классический пример — прыжок в середину CISC-инструкции, продемонстрированный нашей любимой компанией Борланд:
              http://govnokod.ru/13242
              Ответить
              • Это слишком неинтересный пример, который разве что в вирусне(для запутывания кода) и всяких сплоитах для ROP-ов применяется. К программированию мало отношения имеет. К тому же сам прыжок можно осуществить без всяких машинных кодов, просто сместив метку при джампе
                Ответить
                • Жду интересных примеров.

                  Я пока не могу найти применения трюка с байтом mod-R/M (типа замены mov rax, 1 на mov rcx, 1), кроме как для написания самомодифицирующегося кода или для сокращения кода компилятора (скорее всего, последнее будет экономией на спичках).
                  Ответить
                  • Ну я практически 100% уверен, что в коде ассемблеров (nasm, yasm, fasm этц) такие трюки используются. И в коде эмуляторов, которые эмулируют чужую архитектуру. И в коде дизассемблеров
                    Ответить
                  • Вот еще макросня из-под masm
                    http://www.masmforum.com/board/index.php?topic=1622.msg12575#msg12575
                    https://github.com/dblock/dotnetinstaller/blob/master/ThirdParty/Microsoft/Windows%20SDK%20v6.0/VC/INCLUDE/listing.inc


                    .
                        time "36h,8Dh,64h,24h,00","5 bytes, lea  esp,ss:[esp+00h]   "
                        time "8Dh,9Bh,00,00,00,00","6 bytes, lea  ebx,[ebx+00000000h]"
                        time "8Dh,0A4h,24h,00,00,00,00","7 bytes, lea  esp,[esp+00000000h]"

                    Можно в rasm2 протестировать (из http://radare.org/r/ ) через консолечку
                    $ rasm2 -a x86 -b 32 -d '8d9b00000000'
                    lea ebx, [ebx]
                    $ rasm2 -a x86 -b 32 -d '8d9b00000000''8d9b00000000'
                    lea ebx, [ebx]
                    lea ebx, [ebx]
                    $ rasm2 -a x86 -b 32 'lea ebx, [ebx]'
                    8d1b
                    $ rasm2 -a x86 -b 32 'lea ebx, [ebx+00000000h]'
                    8d1b

                    Ассемблеру нельзя сказать, чтоб он эту длинную говноинструкцию с нулями сделал
                    Ответить
                    • > чтоб он эту длинную говноинструкцию с нулями сделал
                      А зачем нахуя она тебе?

                      Ради места, в которое потом можно будет воткнуть что-то ненулевое?
                      Ответить
                      • Варианты:
                        1. Ради выравнивания следующей инструкции, чтобы НОПы почём зря не вставлять.
                        2. А вдруг у инструкций разной длины пирфоманс разный? Например, на некоторых процессорах INC EAX быстрее, чем ADD EAX, 1, а на некоторых наоборот; на некоторых LOOP @1 быстрее, чем DEC ECX; ECXZ @1, а на некоторых наоборот и т. п.
                        Ответить
  • > ( *(int(*)(char **, void **)) *(func_ptr_p-1) )(char_ptr_arr_p-1,func_ptr_p-1)
    - Кастуй указатели на функцию, блять, на, кастуй указатели.
    - Как я кастовать-то буду?!
    - Вот так вот, быстро, (*)(*)(*)(*)*! Кастуй!
    Ответить

Добавить комментарий

Из-за тебя ушел bormand, guest!

    А не использовать ли нам bbcode?


    8