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) |         try: | ||||||
|  |             os.mkdir(run_dir) | ||||||
|  |         except FileNotFoundError or PermissionError: | ||||||
|  |             run_dir = os.path.dirname(self.seed) | ||||||
|  |         except FileExistsError: | ||||||
|  |             pass | ||||||
| 
 | 
 | ||||||
|         if not os.path.isdir(self.run_dir): |         self.run_dir = run_dir | ||||||
|             try: |  | ||||||
|                 os.mkdir(self.run_dir) |  | ||||||
|             except: |  | ||||||
|                 self.run_dir = os.path.dirname(self.seed) |  | ||||||
| 
 | 
 | ||||||
|         shutil.copy2(self.seed, self.run_dir) |         child = self.generation( | ||||||
|  |             parent=self.parent, | ||||||
|  |             scrap=self.seed, | ||||||
|  |             cwd=self.run_dir) | ||||||
| 
 | 
 | ||||||
|         parsed = (self.parent, self.seed, self.run_dir) |         if child: | ||||||
|         self.logger.info('init path: {}'.format(parsed)) |             logging.info(child) | ||||||
| 
 | 
 | ||||||
|         paths = (self.seed,) |     def scrap_recent(self, *, run_dir: str)->str: | ||||||
|         while True: |  | ||||||
|             for path in paths: |  | ||||||
|                 scrap_path = os.path.join(self.run_dir, path) |  | ||||||
|                 if os.path.isfile(scrap_path): |  | ||||||
|                     child = self.generation( |  | ||||||
|                         self.parent, |  | ||||||
|                         scrap_path, |  | ||||||
|                         self.run_dir |  | ||||||
|                     ) |  | ||||||
|                     if child: |  | ||||||
|                         print(child) |  | ||||||
|             # paths = sorted(os.listdir(self.run_dir)) |  | ||||||
| 
 |  | ||||||
|     def scrap_recent(self, run_dir): |  | ||||||
|         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
	
	 JoYo
						JoYo