Kirokyri

C8.1

Nov 27th, 2020
564
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <string.h>
  5.  
  6. #include <unistd.h>
  7. #include <crypt.h>
  8. #include <time.h>
  9.  
  10. #include <pthread.h>
  11. #include <semaphore.h>
  12.  
  13. typedef enum
  14. {
  15.     BM_ITER,
  16.     BM_REC,
  17. } brute_mode_t;
  18.  
  19. typedef enum                                                                //
  20. {
  21.     RM_SINGLE,
  22.     RM_MULTI,
  23. } run_mode_t;
  24.  
  25. typedef struct config_t {
  26.     brute_mode_t brute_mode;
  27.     run_mode_t run_mode;                                              //
  28.     int length;
  29.     char * alphabet;
  30.     char * hash;
  31. } config_t;
  32.  
  33. typedef struct task_t {
  34.     char password[8];
  35. } task_t;
  36.  
  37. typedef struct queue_t {
  38.     task_t queue[8];
  39.     int head, tail;
  40.     pthread_mutex_t head_mutex, tail_mutex;
  41.     sem_t empty, full;
  42. } queue_t;
  43.  
  44. typedef struct {
  45.     config_t * config;
  46.     task_t found;
  47.     queue_t queue;
  48. } pc_context_t;
  49.  
  50. typedef bool (*password_handler_t) (void * context, char * password);
  51.  
  52. void queue_init (queue_t * queue)
  53. {
  54.     queue->head = 0;
  55.     queue->tail = 0;
  56.     pthread_mutex_init (&queue->head_mutex, NULL);
  57.     pthread_mutex_init (&queue->tail_mutex, NULL);
  58.     sem_init (&queue->empty, 0, sizeof (queue->queue) / sizeof (queue->queue[0]));
  59.     sem_init (&queue->full, 0, 0);
  60. }
  61.  
  62. void queue_push (queue_t * queue, task_t * task)
  63. {
  64.     //7
  65.     sem_wait (&queue->empty);
  66.     pthread_mutex_lock (&queue->tail_mutex);
  67.     queue->queue[queue->tail] = *task;
  68.     if (++queue->tail == sizeof (queue->queue) / sizeof (queue->queue[0]))
  69.         queue->tail = 0;
  70.     pthread_mutex_unlock (&queue->tail_mutex);
  71.     sem_post (&queue->full);
  72.  
  73. }
  74.  
  75. void queue_pop (queue_t * queue, task_t * task)
  76. {
  77.     //7
  78.     sem_wait(&queue->full);
  79.     pthread_mutex_lock (&queue->head_mutex);
  80.     *task = queue->queue[queue->head];
  81.     if (++queue->head == sizeof (queue->queue) / sizeof (queue->queue[0]))
  82.         queue->head = 0;
  83.     pthread_mutex_unlock (&queue->head_mutex);
  84.     sem_post (&queue->empty);
  85. }
  86.  
  87. bool rec(config_t* config, char* password, int pos, password_handler_t password_handler, void * context)
  88. {
  89.     int i;
  90.     if (pos >= config->length)
  91.     {
  92.         if (password_handler (context, password))
  93.         {
  94.             return (true);
  95.         }
  96.     }
  97.     else
  98.     {
  99.         for (i = 0; config->alphabet[i]; ++i)
  100.         {
  101.             password[pos] = config->alphabet[i];
  102.             if (rec (config, password, pos + 1, password_handler, context))
  103.                 return (true);
  104.         }
  105.     }
  106.     return (false);
  107. }
  108.  
  109. void rec_wrapper(config_t* config, char* password, password_handler_t password_handler, void * context)
  110. {
  111.     rec (config, password, 0, password_handler, context);
  112. }
  113.  
  114. void iter(config_t* config, char* password, password_handler_t password_handler, void * context)
  115. {
  116.     int alph_length_1 = strlen(config->alphabet) - 1;
  117.     int idx[config->length];
  118.     int i;
  119.  
  120.     for (i = 0; i < config->length; i++)
  121.     {
  122.         idx[i] = 0;
  123.         password[i] = config->alphabet[0];
  124.     }
  125.  
  126.     for (;;)
  127.     {
  128.          if (password_handler (context, password))
  129.             break;
  130.         for (i = config->length - 1; (i >= 0) && (idx[i] == alph_length_1); i--)
  131.         {
  132.             idx[i] = 0;
  133.             password[i] = config->alphabet[0];
  134.         }
  135.  
  136.         if (i < 0)
  137.             break;
  138.  
  139.         password[i] = config->alphabet[++idx[i]];
  140.     }
  141. }
  142.  
  143. void parse_params(config_t* config, int argc, char* argv[])
  144. {
  145.     for (;;)
  146.     {
  147.         int opt = getopt(argc, argv, "a:l:h:irsm");                         //
  148.         if (opt == -1)
  149.             break;
  150.         switch (opt)
  151.         {
  152.         case 's':
  153.             config->run_mode = RM_SINGLE;                                //
  154.             break;
  155.  
  156.         case 'm':
  157.             config->run_mode = RM_MULTI;                                 //
  158.             break;
  159.  
  160.         case 'i':
  161.             config->brute_mode = BM_ITER;
  162.             break;
  163.  
  164.         case 'r':
  165.             config->brute_mode = BM_REC;
  166.             break;
  167.  
  168.         case 'a':
  169.             config->alphabet = optarg;
  170.             break;
  171.  
  172.         case 'h':
  173.             config->hash = optarg;
  174.             break;
  175.  
  176.         case 'l':
  177.             config->length = atoi(optarg);
  178.             break;
  179.  
  180.         default:
  181.             break;
  182.         }
  183.     }
  184. }
  185.  
  186. bool print_password (config_t * config, char * password)
  187. {
  188.     printf ("%s\n", password);
  189.     return (false);
  190. }
  191.  
  192. bool check_password (void * context, char * password)
  193. {
  194.     config_t * config = context;
  195.     char * hash = crypt (password, config->hash);
  196.     printf ("%s %s %s\n","hash in check", hash, password);
  197.     //printf ("%s %s\n", "config_hash in check", config->hash);
  198.     int cmp = strcmp (hash, config->hash);
  199.     return (0 == cmp);
  200. }
  201.  
  202. void run_single (config_t * config, char * password)
  203. {
  204.     switch (config->brute_mode)
  205.     {
  206.         case BM_ITER:
  207.             iter (config, password, check_password, config);
  208.             break;
  209.         case BM_REC:
  210.             rec_wrapper(config, password, check_password, config);
  211.             break;
  212.     }
  213. }
  214.  
  215. void * consumer (void * arg)
  216. {
  217.     pc_context_t * pc_context = arg;
  218.     for (;;)
  219.     {
  220.         task_t task;
  221.         queue_pop (&pc_context->queue, &task);
  222.         printf ("consumer task password %s\n", task.password);
  223.         if (check_password (pc_context->config, task.password))
  224.         {
  225.             pc_context->found = task;
  226.         }
  227.     }
  228. }
  229.  
  230. bool push_to_queue (void * context, char * password)
  231. {
  232.     pc_context_t * pc_context = context;
  233.     task_t task;
  234.     strcpy (task.password, password);
  235.     queue_push (&pc_context->queue, &task);
  236.     return (pc_context->found.password[0]);
  237. }
  238.  
  239. void run_multi (config_t * config, char * password)
  240. {
  241.     pc_context_t pc_context;
  242.     pc_context.config = config;
  243.     printf ("%s %s\n", "pc_context_config_in_multi", pc_context.config->hash);
  244.     //int num_cpu = sysconf (_SC_NPROCESSORS_ONLN);
  245.     int num_cpu = 1;
  246.     int i;
  247.    
  248.     pc_context.found.password[0] = 0;
  249.     queue_init (&pc_context.queue);
  250.    
  251.     for (i = 0; i < num_cpu; ++i)
  252.     {
  253.         pthread_t id;
  254.         pthread_create (&id, NULL, consumer, &pc_context);
  255.     }
  256.    
  257.     switch (config->brute_mode)
  258.     {
  259.         case BM_ITER:
  260.             iter (config, password, push_to_queue, &pc_context);
  261.             break;
  262.         case BM_REC:
  263.             rec_wrapper(config, password, push_to_queue, &pc_context);
  264.             break;
  265.     }
  266.     //password = pc_context.found.password;
  267.     password = strdup (pc_context.found.password);
  268. }
  269.  
  270. int main(int argc, char* argv[])
  271. {
  272.     config_t config =
  273.     {
  274.         .run_mode = RM_SINGLE,                                           //
  275.         .brute_mode = BM_ITER,
  276.         .alphabet = "01",
  277.         .length = 6,
  278.         .hash = strdup (crypt ("110110", "11")),
  279.         //.hash = "11G3BJNEUV/Pk",
  280.     };
  281.    
  282.     parse_params(&config, argc, argv);
  283.  
  284.     char password[config.length + 1];
  285.     password[config.length] = 0;
  286.    
  287.     switch (config.run_mode)
  288.     {
  289.         case RM_SINGLE:
  290.             run_single (&config, password);
  291.             break;
  292.         case RM_MULTI:
  293.             run_multi (&config, password);
  294.     }
  295.    
  296.     printf ("%s\n", password);
  297.     return (EXIT_SUCCESS);
  298. }
RAW Paste Data