shared library through ctypes
							parent
							
								
									b9edd23af1
								
							
						
					
					
						commit
						204c8c3ce1
					
				
							
								
								
									
										119
									
								
								generation.c
								
								
								
								
							
							
						
						
									
										119
									
								
								generation.c
								
								
								
								
							| 
						 | 
					@ -1,128 +1,69 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					@file generation.c
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
#include <malloc.h>
 | 
					#include <malloc.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <sys/mman.h>
 | 
					#include <sys/mman.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int reproduce(unsigned char *pic_address, int pic_size)
 | 
					int reproduce(void *pic_address, int *pic_size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int return_value = 0;
 | 
					    int status = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (int iter = 0; iter < pic_size; iter++)
 | 
					    printf("{\"address\": \"%p\",\"length\": \"%d\"}\n", pic_address,
 | 
				
			||||||
    {
 | 
					           *pic_size);
 | 
				
			||||||
        printf("%02X", pic_address[iter]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return_value = 1;
 | 
					    status = 1;
 | 
				
			||||||
CLONE_CLEANUP:
 | 
					CLONE_CLEANUP:
 | 
				
			||||||
    if (NULL != pic_address)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        munmap(pic_address, pic_size);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    exit(0);
 | 
					    return status;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int hex_ascii_to_bin(char *hex_string, int hex_len, unsigned char *hex_bin)
 | 
					int generation(void *child, int *child_len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (hex_bin == NULL || hex_string == NULL || hex_len % 2 != 0)
 | 
					    int status = 0;
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char *position = hex_string;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (int index = 0; index - 1 < hex_len; index++)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (*position == NULL) break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for (int offset = 0; offset < 2; offset++, position++)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            unsigned char hex_sort = *position | 0x20;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (hex_sort >= '0' && hex_sort <= '9')
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                hex_sort -= 0x30;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else if (hex_sort <= 'f' && hex_sort >= 'a')
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                hex_sort -= 0x57;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                return 0;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (!offset)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                hex_bin[index] = (hex_sort << 4);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                hex_bin[index] |= hex_sort;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int generation(char *parent_hex, int rand_offset, char rand_flip)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int return_value = 0;
 | 
					 | 
				
			||||||
    int parent_hex_len = strlen(parent_hex);
 | 
					 | 
				
			||||||
    int parent_bin_len = parent_hex_len / 2;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int prot = (PROT_READ | PROT_WRITE | PROT_EXEC);
 | 
					    int prot = (PROT_READ | PROT_WRITE | PROT_EXEC);
 | 
				
			||||||
    int flags = (MAP_ANON | MAP_PRIVATE);
 | 
					    int flags = (MAP_ANON | MAP_PRIVATE);
 | 
				
			||||||
    unsigned char *pic_buffer = mmap(NULL, parent_bin_len, prot, flags, -1, 0);
 | 
					    void *pic_buffer = mmap(NULL, child_len, prot, flags, -1, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (MAP_FAILED == pic_buffer)
 | 
					    if (MAP_FAILED == pic_buffer)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return_value = errno;
 | 
					        status = errno;
 | 
				
			||||||
        goto GEN_CLEANUP;
 | 
					        goto GEN_CLEANUP;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    hex_ascii_to_bin(parent_hex, parent_hex_len, pic_buffer);
 | 
					    memcpy(child, pic_buffer, *child_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pic_buffer[rand_offset] = pic_buffer[rand_offset] ^ rand_flip;
 | 
					    int (*reproduce_function)(void *, int) = reproduce;
 | 
				
			||||||
 | 
					    void (*pic_function)(void *, int *, void *) = pic_buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int (*reproduce_function)(unsigned char *, int) = reproduce;
 | 
					    pic_function(pic_buffer, child_len, reproduce_function);
 | 
				
			||||||
    void (*pic_function)(void *, int, void *) = pic_buffer;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pic_function(pic_buffer, parent_bin_len, reproduce_function);
 | 
					    status = 1;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return_value = 1;
 | 
					 | 
				
			||||||
GEN_CLEANUP:
 | 
					GEN_CLEANUP:
 | 
				
			||||||
    if (NULL != pic_buffer)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        munmap(pic_buffer, parent_bin_len);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return return_value;
 | 
					    return status;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, const char **argv)
 | 
					int gen_fork(void *child, int *child_len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (3 > argc || argv[1] == NULL || argv[2] == NULL || argv[3] == NULL)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        exit(1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char *hex_string = argv[1];
 | 
					 | 
				
			||||||
    int rand_offset = atoi(argv[2]);
 | 
					 | 
				
			||||||
    char rand_flip = atoi(argv[3]);
 | 
					 | 
				
			||||||
    pid_t process_id;
 | 
					    pid_t process_id;
 | 
				
			||||||
    int return_value = 0;
 | 
					    int status = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *child_len = 999;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    process_id = fork();
 | 
					    process_id = fork();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(0 == process_id)
 | 
					    if (0 == process_id)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return_value = generation(hex_string, rand_offset, rand_flip);
 | 
					        status = generation(child, child_len);
 | 
				
			||||||
        if (return_value)
 | 
					        if (status)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            exit(0);
 | 
					            return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										517
									
								
								list.h
								
								
								
								
							
							
						
						
									
										517
									
								
								list.h
								
								
								
								
							| 
						 | 
					@ -1,517 +0,0 @@
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * I grub it from linux kernel source code and fix it for user space
 | 
					 | 
				
			||||||
 * program. Of course, this is a GPL licensed header file.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Here is a recipe to cook list.h for user space program
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * 1. copy list.h from linux/include/list.h
 | 
					 | 
				
			||||||
 * 2. remove
 | 
					 | 
				
			||||||
 *     - #ifdef __KERNE__ and its #endif
 | 
					 | 
				
			||||||
 *     - all #include line
 | 
					 | 
				
			||||||
 *     - prefetch() and rcu related functions
 | 
					 | 
				
			||||||
 * 3. add macro offsetof() and container_of
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * - kazutomo@mcs.anl.gov
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#ifndef _LINUX_LIST_H
 | 
					 | 
				
			||||||
#define _LINUX_LIST_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @name from other kernel headers
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
/*@{*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Get offset of a member
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Casts a member of a structure out to the containing structure
 | 
					 | 
				
			||||||
 * @param ptr        the pointer to the member.
 | 
					 | 
				
			||||||
 * @param type       the type of the container struct this is embedded in.
 | 
					 | 
				
			||||||
 * @param member     the name of the member within the struct.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define container_of(ptr, type, member) ({                      \
 | 
					 | 
				
			||||||
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
 | 
					 | 
				
			||||||
        (type *)( (char *)__mptr - offsetof(type,member) );})
 | 
					 | 
				
			||||||
/*@}*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * These are non-NULL pointers that will result in page faults
 | 
					 | 
				
			||||||
 * under normal circumstances, used to verify that nobody uses
 | 
					 | 
				
			||||||
 * non-initialized list entries.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define LIST_POISON1  ((void *) 0x00100100)
 | 
					 | 
				
			||||||
#define LIST_POISON2  ((void *) 0x00200200)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Simple doubly linked list implementation.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Some of the internal functions ("__xxx") are useful when
 | 
					 | 
				
			||||||
 * manipulating whole lists rather than single entries, as
 | 
					 | 
				
			||||||
 * sometimes we already know the next/prev entries and we can
 | 
					 | 
				
			||||||
 * generate better code by using them directly rather than
 | 
					 | 
				
			||||||
 * using the generic single-entry routines.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct list_head {
 | 
					 | 
				
			||||||
  struct list_head *next, *prev;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define LIST_HEAD_INIT(name) { &(name), &(name) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define LIST_HEAD(name) \
 | 
					 | 
				
			||||||
  struct list_head name = LIST_HEAD_INIT(name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define INIT_LIST_HEAD(ptr) do { \
 | 
					 | 
				
			||||||
  (ptr)->next = (ptr); (ptr)->prev = (ptr); \
 | 
					 | 
				
			||||||
} while (0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Insert a new entry between two known consecutive entries.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This is only for internal list manipulation where we know
 | 
					 | 
				
			||||||
 * the prev/next entries already!
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline void __list_add(struct list_head *new,
 | 
					 | 
				
			||||||
            struct list_head *prev,
 | 
					 | 
				
			||||||
            struct list_head *next)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  next->prev = new;
 | 
					 | 
				
			||||||
  new->next = next;
 | 
					 | 
				
			||||||
  new->prev = prev;
 | 
					 | 
				
			||||||
  prev->next = new;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_add - add a new entry
 | 
					 | 
				
			||||||
 * @new: new entry to be added
 | 
					 | 
				
			||||||
 * @head: list head to add it after
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Insert a new entry after the specified head.
 | 
					 | 
				
			||||||
 * This is good for implementing stacks.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline void list_add(struct list_head *new, struct list_head *head)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  __list_add(new, head, head->next);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_add_tail - add a new entry
 | 
					 | 
				
			||||||
 * @new: new entry to be added
 | 
					 | 
				
			||||||
 * @head: list head to add it before
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Insert a new entry before the specified head.
 | 
					 | 
				
			||||||
 * This is useful for implementing queues.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline void list_add_tail(struct list_head *new, struct list_head *head)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  __list_add(new, head->prev, head);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Delete a list entry by making the prev/next entries
 | 
					 | 
				
			||||||
 * point to each other.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This is only for internal list manipulation where we know
 | 
					 | 
				
			||||||
 * the prev/next entries already!
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline void __list_del(struct list_head * prev, struct list_head * next)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  next->prev = prev;
 | 
					 | 
				
			||||||
  prev->next = next;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_del - deletes entry from list.
 | 
					 | 
				
			||||||
 * @entry: the element to delete from the list.
 | 
					 | 
				
			||||||
 * Note: list_empty on entry does not return true after this, the entry is
 | 
					 | 
				
			||||||
 * in an undefined state.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline void list_del(struct list_head *entry)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  __list_del(entry->prev, entry->next);
 | 
					 | 
				
			||||||
  entry->next = LIST_POISON1;
 | 
					 | 
				
			||||||
  entry->prev = LIST_POISON2;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_del_init - deletes entry from list and reinitialize it.
 | 
					 | 
				
			||||||
 * @entry: the element to delete from the list.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline void list_del_init(struct list_head *entry)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  __list_del(entry->prev, entry->next);
 | 
					 | 
				
			||||||
  INIT_LIST_HEAD(entry);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_move - delete from one list and add as another's head
 | 
					 | 
				
			||||||
 * @list: the entry to move
 | 
					 | 
				
			||||||
 * @head: the head that will precede our entry
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline void list_move(struct list_head *list, struct list_head *head)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
        __list_del(list->prev, list->next);
 | 
					 | 
				
			||||||
        list_add(list, head);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_move_tail - delete from one list and add as another's tail
 | 
					 | 
				
			||||||
 * @list: the entry to move
 | 
					 | 
				
			||||||
 * @head: the head that will follow our entry
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline void list_move_tail(struct list_head *list,
 | 
					 | 
				
			||||||
          struct list_head *head)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
        __list_del(list->prev, list->next);
 | 
					 | 
				
			||||||
        list_add_tail(list, head);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_empty - tests whether a list is empty
 | 
					 | 
				
			||||||
 * @head: the list to test.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline int list_empty(const struct list_head *head)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return head->next == head;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void __list_splice(struct list_head *list,
 | 
					 | 
				
			||||||
         struct list_head *head)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  struct list_head *first = list->next;
 | 
					 | 
				
			||||||
  struct list_head *last = list->prev;
 | 
					 | 
				
			||||||
  struct list_head *at = head->next;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  first->prev = head;
 | 
					 | 
				
			||||||
  head->next = first;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  last->next = at;
 | 
					 | 
				
			||||||
  at->prev = last;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_splice - join two lists
 | 
					 | 
				
			||||||
 * @list: the new list to add.
 | 
					 | 
				
			||||||
 * @head: the place to add it in the first list.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline void list_splice(struct list_head *list, struct list_head *head)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  if (!list_empty(list))
 | 
					 | 
				
			||||||
    __list_splice(list, head);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_splice_init - join two lists and reinitialise the emptied list.
 | 
					 | 
				
			||||||
 * @list: the new list to add.
 | 
					 | 
				
			||||||
 * @head: the place to add it in the first list.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * The list at @list is reinitialised
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static inline void list_splice_init(struct list_head *list,
 | 
					 | 
				
			||||||
            struct list_head *head)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  if (!list_empty(list)) {
 | 
					 | 
				
			||||||
    __list_splice(list, head);
 | 
					 | 
				
			||||||
    INIT_LIST_HEAD(list);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_entry - get the struct for this entry
 | 
					 | 
				
			||||||
 * @ptr:  the &struct list_head pointer.
 | 
					 | 
				
			||||||
 * @type: the type of the struct this is embedded in.
 | 
					 | 
				
			||||||
 * @member: the name of the list_struct within the struct.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define list_entry(ptr, type, member) \
 | 
					 | 
				
			||||||
  container_of(ptr, type, member)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_for_each  - iterate over a list
 | 
					 | 
				
			||||||
 * @pos:  the &struct list_head to use as a loop counter.
 | 
					 | 
				
			||||||
 * @head: the head for your list.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define list_for_each(pos, head) \
 | 
					 | 
				
			||||||
  for (pos = (head)->next; pos != (head); \
 | 
					 | 
				
			||||||
       pos = pos->next)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * __list_for_each  - iterate over a list
 | 
					 | 
				
			||||||
 * @pos:  the &struct list_head to use as a loop counter.
 | 
					 | 
				
			||||||
 * @head: the head for your list.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This variant differs from list_for_each() in that it's the
 | 
					 | 
				
			||||||
 * simplest possible list iteration code, no prefetching is done.
 | 
					 | 
				
			||||||
 * Use this for code that knows the list to be very short (empty
 | 
					 | 
				
			||||||
 * or 1 entry) most of the time.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define __list_for_each(pos, head) \
 | 
					 | 
				
			||||||
  for (pos = (head)->next; pos != (head); pos = pos->next)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_for_each_prev - iterate over a list backwards
 | 
					 | 
				
			||||||
 * @pos:  the &struct list_head to use as a loop counter.
 | 
					 | 
				
			||||||
 * @head: the head for your list.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define list_for_each_prev(pos, head) \
 | 
					 | 
				
			||||||
  for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
 | 
					 | 
				
			||||||
          pos = pos->prev)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_for_each_safe - iterate over a list safe against removal of list entry
 | 
					 | 
				
			||||||
 * @pos:  the &struct list_head to use as a loop counter.
 | 
					 | 
				
			||||||
 * @n:    another &struct list_head to use as temporary storage
 | 
					 | 
				
			||||||
 * @head: the head for your list.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define list_for_each_safe(pos, n, head) \
 | 
					 | 
				
			||||||
  for (pos = (head)->next, n = pos->next; pos != (head); \
 | 
					 | 
				
			||||||
    pos = n, n = pos->next)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_for_each_entry  - iterate over list of given type
 | 
					 | 
				
			||||||
 * @pos:  the type * to use as a loop counter.
 | 
					 | 
				
			||||||
 * @head: the head for your list.
 | 
					 | 
				
			||||||
 * @member: the name of the list_struct within the struct.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define list_for_each_entry(pos, head, member)        \
 | 
					 | 
				
			||||||
  for (pos = list_entry((head)->next, typeof(*pos), member);  \
 | 
					 | 
				
			||||||
       &pos->member != (head);          \
 | 
					 | 
				
			||||||
       pos = list_entry(pos->member.next, typeof(*pos), member))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_for_each_entry_reverse - iterate backwards over list of given type.
 | 
					 | 
				
			||||||
 * @pos:  the type * to use as a loop counter.
 | 
					 | 
				
			||||||
 * @head: the head for your list.
 | 
					 | 
				
			||||||
 * @member: the name of the list_struct within the struct.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define list_for_each_entry_reverse(pos, head, member)      \
 | 
					 | 
				
			||||||
  for (pos = list_entry((head)->prev, typeof(*pos), member);  \
 | 
					 | 
				
			||||||
       &pos->member != (head);  \
 | 
					 | 
				
			||||||
       pos = list_entry(pos->member.prev, typeof(*pos), member))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_prepare_entry - prepare a pos entry for use as a start point in
 | 
					 | 
				
			||||||
 *      list_for_each_entry_continue
 | 
					 | 
				
			||||||
 * @pos:  the type * to use as a start point
 | 
					 | 
				
			||||||
 * @head: the head of the list
 | 
					 | 
				
			||||||
 * @member: the name of the list_struct within the struct.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define list_prepare_entry(pos, head, member) \
 | 
					 | 
				
			||||||
  ((pos) ? : list_entry(head, typeof(*pos), member))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_for_each_entry_continue - iterate over list of given type
 | 
					 | 
				
			||||||
 *      continuing after existing point
 | 
					 | 
				
			||||||
 * @pos:  the type * to use as a loop counter.
 | 
					 | 
				
			||||||
 * @head: the head for your list.
 | 
					 | 
				
			||||||
 * @member: the name of the list_struct within the struct.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define list_for_each_entry_continue(pos, head, member)     \
 | 
					 | 
				
			||||||
  for (pos = list_entry(pos->member.next, typeof(*pos), member);  \
 | 
					 | 
				
			||||||
       &pos->member != (head);  \
 | 
					 | 
				
			||||||
       pos = list_entry(pos->member.next, typeof(*pos), member))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
 | 
					 | 
				
			||||||
 * @pos:  the type * to use as a loop counter.
 | 
					 | 
				
			||||||
 * @n:    another type * to use as temporary storage
 | 
					 | 
				
			||||||
 * @head: the head for your list.
 | 
					 | 
				
			||||||
 * @member: the name of the list_struct within the struct.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define list_for_each_entry_safe(pos, n, head, member)      \
 | 
					 | 
				
			||||||
  for (pos = list_entry((head)->next, typeof(*pos), member),  \
 | 
					 | 
				
			||||||
    n = list_entry(pos->member.next, typeof(*pos), member); \
 | 
					 | 
				
			||||||
       &pos->member != (head);          \
 | 
					 | 
				
			||||||
       pos = n, n = list_entry(n->member.next, typeof(*n), member))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_for_each_entry_safe_continue -  iterate over list of given type
 | 
					 | 
				
			||||||
 *      continuing after existing point safe against removal of list entry
 | 
					 | 
				
			||||||
 * @pos:  the type * to use as a loop counter.
 | 
					 | 
				
			||||||
 * @n:    another type * to use as temporary storage
 | 
					 | 
				
			||||||
 * @head: the head for your list.
 | 
					 | 
				
			||||||
 * @member: the name of the list_struct within the struct.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define list_for_each_entry_safe_continue(pos, n, head, member)     \
 | 
					 | 
				
			||||||
  for (pos = list_entry(pos->member.next, typeof(*pos), member),    \
 | 
					 | 
				
			||||||
    n = list_entry(pos->member.next, typeof(*pos), member);   \
 | 
					 | 
				
			||||||
       &pos->member != (head);            \
 | 
					 | 
				
			||||||
       pos = n, n = list_entry(n->member.next, typeof(*n), member))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * list_for_each_entry_safe_reverse - iterate backwards over list of given type safe against
 | 
					 | 
				
			||||||
 *              removal of list entry
 | 
					 | 
				
			||||||
 * @pos:  the type * to use as a loop counter.
 | 
					 | 
				
			||||||
 * @n:    another type * to use as temporary storage
 | 
					 | 
				
			||||||
 * @head: the head for your list.
 | 
					 | 
				
			||||||
 * @member: the name of the list_struct within the struct.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define list_for_each_entry_safe_reverse(pos, n, head, member)    \
 | 
					 | 
				
			||||||
  for (pos = list_entry((head)->prev, typeof(*pos), member),  \
 | 
					 | 
				
			||||||
    n = list_entry(pos->member.prev, typeof(*pos), member); \
 | 
					 | 
				
			||||||
       &pos->member != (head);          \
 | 
					 | 
				
			||||||
       pos = n, n = list_entry(n->member.prev, typeof(*n), member))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Double linked lists with a single pointer list head.
 | 
					 | 
				
			||||||
 * Mostly useful for hash tables where the two pointer list head is
 | 
					 | 
				
			||||||
 * too wasteful.
 | 
					 | 
				
			||||||
 * You lose the ability to access the tail in O(1).
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct hlist_head {
 | 
					 | 
				
			||||||
  struct hlist_node *first;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct hlist_node {
 | 
					 | 
				
			||||||
  struct hlist_node *next, **pprev;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define HLIST_HEAD_INIT { .first = NULL }
 | 
					 | 
				
			||||||
#define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }
 | 
					 | 
				
			||||||
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
 | 
					 | 
				
			||||||
#define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline int hlist_unhashed(const struct hlist_node *h)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return !h->pprev;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline int hlist_empty(const struct hlist_head *h)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return !h->first;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void __hlist_del(struct hlist_node *n)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  struct hlist_node *next = n->next;
 | 
					 | 
				
			||||||
  struct hlist_node **pprev = n->pprev;
 | 
					 | 
				
			||||||
  *pprev = next;
 | 
					 | 
				
			||||||
  if (next)
 | 
					 | 
				
			||||||
    next->pprev = pprev;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void hlist_del(struct hlist_node *n)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  __hlist_del(n);
 | 
					 | 
				
			||||||
  n->next = LIST_POISON1;
 | 
					 | 
				
			||||||
  n->pprev = LIST_POISON2;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void hlist_del_init(struct hlist_node *n)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  if (n->pprev)  {
 | 
					 | 
				
			||||||
    __hlist_del(n);
 | 
					 | 
				
			||||||
    INIT_HLIST_NODE(n);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  struct hlist_node *first = h->first;
 | 
					 | 
				
			||||||
  n->next = first;
 | 
					 | 
				
			||||||
  if (first)
 | 
					 | 
				
			||||||
    first->pprev = &n->next;
 | 
					 | 
				
			||||||
  h->first = n;
 | 
					 | 
				
			||||||
  n->pprev = &h->first;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* next must be != NULL */
 | 
					 | 
				
			||||||
static inline void hlist_add_before(struct hlist_node *n,
 | 
					 | 
				
			||||||
          struct hlist_node *next)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  n->pprev = next->pprev;
 | 
					 | 
				
			||||||
  n->next = next;
 | 
					 | 
				
			||||||
  next->pprev = &n->next;
 | 
					 | 
				
			||||||
  *(n->pprev) = n;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void hlist_add_after(struct hlist_node *n,
 | 
					 | 
				
			||||||
          struct hlist_node *next)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  next->next = n->next;
 | 
					 | 
				
			||||||
  n->next = next;
 | 
					 | 
				
			||||||
  next->pprev = &n->next;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if(next->next)
 | 
					 | 
				
			||||||
    next->next->pprev  = &next->next;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define hlist_for_each(pos, head) \
 | 
					 | 
				
			||||||
  for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
 | 
					 | 
				
			||||||
       pos = pos->next)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define hlist_for_each_safe(pos, n, head) \
 | 
					 | 
				
			||||||
  for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
 | 
					 | 
				
			||||||
       pos = n)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * hlist_for_each_entry - iterate over list of given type
 | 
					 | 
				
			||||||
 * @tpos: the type * to use as a loop counter.
 | 
					 | 
				
			||||||
 * @pos:  the &struct hlist_node to use as a loop counter.
 | 
					 | 
				
			||||||
 * @head: the head for your list.
 | 
					 | 
				
			||||||
 * @member: the name of the hlist_node within the struct.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define hlist_for_each_entry(tpos, pos, head, member)      \
 | 
					 | 
				
			||||||
  for (pos = (head)->first;          \
 | 
					 | 
				
			||||||
       pos && ({ prefetch(pos->next); 1;}) &&      \
 | 
					 | 
				
			||||||
    ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
 | 
					 | 
				
			||||||
       pos = pos->next)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * hlist_for_each_entry_continue - iterate over a hlist continuing after existing point
 | 
					 | 
				
			||||||
 * @tpos: the type * to use as a loop counter.
 | 
					 | 
				
			||||||
 * @pos:  the &struct hlist_node to use as a loop counter.
 | 
					 | 
				
			||||||
 * @member: the name of the hlist_node within the struct.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define hlist_for_each_entry_continue(tpos, pos, member)     \
 | 
					 | 
				
			||||||
  for (pos = (pos)->next;            \
 | 
					 | 
				
			||||||
       pos && ({ prefetch(pos->next); 1;}) &&      \
 | 
					 | 
				
			||||||
    ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
 | 
					 | 
				
			||||||
       pos = pos->next)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * hlist_for_each_entry_from - iterate over a hlist continuing from existing point
 | 
					 | 
				
			||||||
 * @tpos: the type * to use as a loop counter.
 | 
					 | 
				
			||||||
 * @pos:  the &struct hlist_node to use as a loop counter.
 | 
					 | 
				
			||||||
 * @member: the name of the hlist_node within the struct.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define hlist_for_each_entry_from(tpos, pos, member)       \
 | 
					 | 
				
			||||||
  for (; pos && ({ prefetch(pos->next); 1;}) &&      \
 | 
					 | 
				
			||||||
    ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
 | 
					 | 
				
			||||||
       pos = pos->next)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
 | 
					 | 
				
			||||||
 * @tpos: the type * to use as a loop counter.
 | 
					 | 
				
			||||||
 * @pos:  the &struct hlist_node to use as a loop counter.
 | 
					 | 
				
			||||||
 * @n:    another &struct hlist_node to use as temporary storage
 | 
					 | 
				
			||||||
 * @head: the head for your list.
 | 
					 | 
				
			||||||
 * @member: the name of the hlist_node within the struct.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define hlist_for_each_entry_safe(tpos, pos, n, head, member)      \
 | 
					 | 
				
			||||||
  for (pos = (head)->first;          \
 | 
					 | 
				
			||||||
       pos && ({ n = pos->next; 1; }) &&         \
 | 
					 | 
				
			||||||
    ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
 | 
					 | 
				
			||||||
       pos = n)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,2 +1,5 @@
 | 
				
			||||||
#! /usr/bin/env sh
 | 
					#! /usr/bin/env sh
 | 
				
			||||||
apt-get install -y clang libssl-dev nasm
 | 
					apt-get install -y \
 | 
				
			||||||
 | 
					  clang \
 | 
				
			||||||
 | 
					  libssl-dev \
 | 
				
			||||||
 | 
					  nasm
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,51 +1,44 @@
 | 
				
			||||||
#! /usr/bin/env python3
 | 
					#! /usr/bin/env python3
 | 
				
			||||||
# encoding: utf-8
 | 
					
 | 
				
			||||||
 | 
					from random import randint
 | 
				
			||||||
 | 
					import binascii
 | 
				
			||||||
 | 
					import ctypes
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import shutil
 | 
					 | 
				
			||||||
import subprocess
 | 
					import subprocess
 | 
				
			||||||
import binascii
 | 
					 | 
				
			||||||
import random
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Sins():
 | 
					class Sins:
 | 
				
			||||||
    logger = logging.getLogger()
 | 
					    seed = bytes()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, parent, seed=None, run_dir=None):
 | 
					    def __init__(self, *, parent: str, seed: str=str(), run_dir: str=str()):
 | 
				
			||||||
        self.parent = os.path.abspath(parent)
 | 
					        self.parent = ctypes.CDLL(parent)
 | 
				
			||||||
        if not os.path.isfile(parent):
 | 
					        self.parent.gen_fork.restype = ctypes.c_int
 | 
				
			||||||
            raise ValueError('Invalid executable image path.')
 | 
					        self.parent.gen_fork.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.seed = os.path.abspath(seed)
 | 
					        if seed:
 | 
				
			||||||
 | 
					            with open(seed, 'rb') as seed_file:
 | 
				
			||||||
 | 
					                self.seed = seed_file.read()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.run_dir = os.path.abspath(run_dir)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not os.path.isdir(self.run_dir):
 | 
					 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
                os.mkdir(self.run_dir)
 | 
					            os.mkdir(run_dir)
 | 
				
			||||||
            except:
 | 
					        except FileNotFoundError or PermissionError:
 | 
				
			||||||
                self.run_dir = os.path.dirname(self.seed)
 | 
					            run_dir = os.path.dirname(self.seed)
 | 
				
			||||||
 | 
					        except FileExistsError:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        shutil.copy2(self.seed, self.run_dir)
 | 
					        self.run_dir = run_dir
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        parsed = (self.parent, self.seed, self.run_dir)
 | 
					 | 
				
			||||||
        self.logger.info('init path: {}'.format(parsed))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        paths = (self.seed,)
 | 
					 | 
				
			||||||
        while True:
 | 
					 | 
				
			||||||
            for path in paths:
 | 
					 | 
				
			||||||
                scrap_path = os.path.join(self.run_dir, path)
 | 
					 | 
				
			||||||
                if os.path.isfile(scrap_path):
 | 
					 | 
				
			||||||
        child = self.generation(
 | 
					        child = self.generation(
 | 
				
			||||||
                        self.parent,
 | 
					            parent=self.parent,
 | 
				
			||||||
                        scrap_path,
 | 
					            scrap=self.seed,
 | 
				
			||||||
                        self.run_dir
 | 
					            cwd=self.run_dir)
 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
                    if child:
 | 
					 | 
				
			||||||
                        print(child)
 | 
					 | 
				
			||||||
            # paths = sorted(os.listdir(self.run_dir))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def scrap_recent(self, run_dir):
 | 
					        if child:
 | 
				
			||||||
 | 
					            logging.info(child)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def scrap_recent(self, *, run_dir: str)->str:
 | 
				
			||||||
        scraps = sorted(os.listdir(run_dir))
 | 
					        scraps = sorted(os.listdir(run_dir))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if scraps:
 | 
					        if scraps:
 | 
				
			||||||
| 
						 | 
					@ -53,27 +46,20 @@ class Sins():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return None
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def generation(self, parent, scrap, cwd):
 | 
					    def generation(self, *, parent: ctypes.CDLL, scrap: bytes, cwd: str):
 | 
				
			||||||
        with open(scrap, 'rb') as scrap_file:
 | 
					        offset = randint(0, len(scrap))
 | 
				
			||||||
            scrap_bin = scrap_file.read()
 | 
					        flip = randint(0, 255)
 | 
				
			||||||
 | 
					        scrap_len = len(scrap)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        scrap_hex = binascii.b2a_hex(scrap_bin).upper()
 | 
					        logging.info('scrap_length [{}]'.format(scrap_len))
 | 
				
			||||||
        offset = random.randint(0, len(scrap_hex))
 | 
					        logging.info('scrap\n{}'.format(binascii.b2a_hex(scrap)))
 | 
				
			||||||
        flip = random.randint(0, 255)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.logger.debug(
 | 
					        status = parent.gen_fork(scrap, scrap_len)
 | 
				
			||||||
            'generation: {}'.format((parent, scrap_hex, offset, flip, cwd))
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        proc = subprocess.run(
 | 
					        logging.info('status {}'.format(status))
 | 
				
			||||||
            [parent, scrap_hex, str(offset), str(flip)],
 | 
					        logging.info('scrap_length [{}]'.format(scrap_len))
 | 
				
			||||||
            cwd=cwd,
 | 
					        logging.info('scrap\n{}'.format(binascii.b2a_hex(scrap)))
 | 
				
			||||||
            stdout=subprocess.PIPE
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if proc.stdout:
 | 
					 | 
				
			||||||
            child_hex = binascii.a2b_hex(proc.stdout)
 | 
					 | 
				
			||||||
            return child_hex
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def hex_dumps(scrap_dir):
 | 
					def hex_dumps(scrap_dir):
 | 
				
			||||||
| 
						 | 
					@ -103,8 +89,7 @@ if __name__ == '__main__':
 | 
				
			||||||
    import sys
 | 
					    import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    parser = argparse.ArgumentParser(
 | 
					    parser = argparse.ArgumentParser(
 | 
				
			||||||
        description='position independent code (PIC) mutation experiment.'
 | 
					        description='position independent code (PIC) mutation experiment.')
 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    parser.add_argument('--verbose', '-v', action='count')
 | 
					    parser.add_argument('--verbose', '-v', action='count')
 | 
				
			||||||
    parser.add_argument('-build', action='store_true',
 | 
					    parser.add_argument('-build', action='store_true',
 | 
				
			||||||
                        help='build parent and seed PIC image, exit.')
 | 
					                        help='build parent and seed PIC image, exit.')
 | 
				
			||||||
| 
						 | 
					@ -113,8 +98,8 @@ if __name__ == '__main__':
 | 
				
			||||||
    parser.add_argument('-logfile', help='log to file.')
 | 
					    parser.add_argument('-logfile', help='log to file.')
 | 
				
			||||||
    parser.add_argument('-seed', default='build/seed.asm.2.o',
 | 
					    parser.add_argument('-seed', default='build/seed.asm.2.o',
 | 
				
			||||||
                        help='path to PIC image.')
 | 
					                        help='path to PIC image.')
 | 
				
			||||||
    parser.add_argument('-parent', default='build/generation',
 | 
					    parser.add_argument('-parent', default='build/libgeneration.so',
 | 
				
			||||||
                        help='path to parent process.')
 | 
					                        help='path to generation lib.')
 | 
				
			||||||
    parser.add_argument('-dir', default='sandbox',
 | 
					    parser.add_argument('-dir', default='sandbox',
 | 
				
			||||||
                        help='path to execution directory.')
 | 
					                        help='path to execution directory.')
 | 
				
			||||||
    parser.add_argument('-dumps', action='store_true',
 | 
					    parser.add_argument('-dumps', action='store_true',
 | 
				
			||||||
| 
						 | 
					@ -122,27 +107,19 @@ if __name__ == '__main__':
 | 
				
			||||||
    args = parser.parse_args()
 | 
					    args = parser.parse_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    logger = logging.getLogger()
 | 
					    logger = logging.getLogger()
 | 
				
			||||||
    formatter = logging.Formatter(
 | 
					    logger.setLevel(logging.DEBUG) if args.verbose else logger.setLevel(logging.INFO)
 | 
				
			||||||
        '# %(asctime)s %(levelname)s\n%(message)s\n'
 | 
					    formatter = logging.Formatter('# %(filename)s:%(lineno)s\n%(message)s')
 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if args.verbose:
 | 
					    stream_handler = logging.StreamHandler()
 | 
				
			||||||
        logger.setLevel(logging.DEBUG)
 | 
					    stream_handler.setFormatter(formatter)
 | 
				
			||||||
    else:
 | 
					    logger.addHandler(stream_handler)
 | 
				
			||||||
        print('Verbose not set, running in silence.')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if args.logfile:
 | 
					    if args.logfile:
 | 
				
			||||||
        file_handler = logging.FileHandler(args.logfile, 'a')
 | 
					        file_handler = logging.FileHandler(args.logfile, 'a')
 | 
				
			||||||
        file_handler.setFormatter(formatter)
 | 
					        file_handler.setFormatter(formatter)
 | 
				
			||||||
        logger.setLevel(logging.DEBUG)
 | 
					 | 
				
			||||||
        logger.addHandler(file_handler)
 | 
					        logger.addHandler(file_handler)
 | 
				
			||||||
    else:
 | 
					 | 
				
			||||||
        stream_handler = logging.StreamHandler()
 | 
					 | 
				
			||||||
        stream_handler.setFormatter(formatter)
 | 
					 | 
				
			||||||
        logger.setLevel(logging.INFO)
 | 
					 | 
				
			||||||
        logger.addHandler(stream_handler)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    logger.info('run: {}'.format(args))
 | 
					    logging.info(args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if args.provision:
 | 
					    if args.provision:
 | 
				
			||||||
        provision = ['sudo', 'sh', 'provision-ubuntu.sh']
 | 
					        provision = ['sudo', 'sh', 'provision-ubuntu.sh']
 | 
				
			||||||
| 
						 | 
					@ -155,9 +132,10 @@ if __name__ == '__main__':
 | 
				
			||||||
    elif args.build:
 | 
					    elif args.build:
 | 
				
			||||||
        waf = [sys.executable, 'waf.py', 'build']
 | 
					        waf = [sys.executable, 'waf.py', 'build']
 | 
				
			||||||
        waf_proc = subprocess.run(waf)
 | 
					        waf_proc = subprocess.run(waf)
 | 
				
			||||||
        logger.info(waf_proc.stdout)
 | 
					        logging.info(waf_proc.stdout)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    elif args.dumps:
 | 
					    elif args.dumps:
 | 
				
			||||||
        hex_dumps(args.dir)
 | 
					        hex_dumps(args.dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        sins = Sins(parent=args.parent, seed=args.seed, run_dir=args.dir)
 | 
					        sins = Sins(parent=args.parent, seed=args.seed, run_dir=args.dir)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue