socket for shared pipe

master
JoYo 2017-07-21 15:19:23 -04:00
parent 204c8c3ce1
commit 6fd526ec2b
3 changed files with 176 additions and 46 deletions

View File

@ -1,28 +1,61 @@
/* /*
@file generation.c @file generation.c
*/ */
#include <arpa/inet.h>
#include <errno.h> #include <errno.h>
#include <malloc.h> #include <malloc.h>
#include <string.h> #include <string.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/socket.h>
#include <unistd.h> #include <unistd.h>
int reproduce(void *pic_address, int *pic_size) #define MAX_LEN 1024
#define PORT 5000
int reproduce(void *pic_address, int pic_size)
{ {
int status = 0; int status = 0;
printf("{\"address\": \"%p\",\"length\": \"%d\"}\n", pic_address, printf("{\"address\":\"%p\",\"size\":\"%d\"}\n", pic_address, pic_size);
*pic_size);
struct sockaddr_in server;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
int sock = socket(AF_INET, SOCK_STREAM, 0);
status = connect(sock, (struct sockaddr *)&server, sizeof(server));
status = send(sock, pic_address, pic_size, 0);
status = 1; status = 1;
CLONE_CLEANUP: CLONE_CLEANUP:
if (sock)
{
close(sock);
}
return status; return status;
} }
int generation(void *child, int *child_len) int generation(void)
{ {
int status = 0; int status = 0;
char reply[MAX_LEN];
struct sockaddr_in server;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
int sock = socket(AF_INET, SOCK_STREAM, 0);
printf("connecting\n");
status = connect(sock, (struct sockaddr *)&server, sizeof(server));
status = recv(sock, reply, MAX_LEN, 0);
int child_len = (int)reply;
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);
@ -34,36 +67,55 @@ int generation(void *child, int *child_len)
goto GEN_CLEANUP; goto GEN_CLEANUP;
} }
memcpy(child, pic_buffer, *child_len); int iter = child_len;
while (1)
{
status = recv(sock, reply, MAX_LEN, 0);
if (!status)
{
break;
}
if ((status + iter) > child_len)
{
break;
}
memcpy(&pic_buffer[iter - child_len], reply, status);
iter -= status;
}
int (*reproduce_function)(void *, int) = reproduce; int (*reproduce_function)(void *, int) = reproduce;
void (*pic_function)(void *, int *, void *) = pic_buffer; void (*pic_function)(void *, int, void *) = pic_buffer;
pic_function(pic_buffer, child_len, reproduce_function); pic_function(pic_buffer, child_len, reproduce_function);
status = 1; status = 1;
GEN_CLEANUP: GEN_CLEANUP:
if (sock)
{
close(sock);
}
return status; return status;
} }
int gen_fork(void *child, int *child_len) int main(int argc, const char **argv)
{ {
pid_t process_id; pid_t process_id;
int status = 0; int status = 0;
*child_len = 999;
return 0;
process_id = fork(); process_id = fork();
if (0 == process_id) if (0 == process_id)
{ {
status = generation(child, child_len); status = generation();
if (status) if (status)
{ {
return 0; return 1;
} }
} }

138
run.py
View File

@ -1,21 +1,82 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
from datetime import datetime
from random import randint from random import randint
from threading import Thread, Lock
from time import sleep
import binascii import binascii
import ctypes
import logging import logging
import os import os
import socket
import subprocess import subprocess
logging.getLogger(__name__) logging.getLogger(__name__)
class Sins:
class Server:
children = list()
host = ('127.0.0.1', 5000)
sock = socket.socket()
sock.bind(host)
sock.listen(1)
client = None
def __init__(self):
self.lock = Lock()
self.thread = Thread(target=self.recv)
self.thread.start()
def __enter__(self):
self.client, address = self.sock.accept()
logging.info('address [{}]'.format(address))
return self
def __exit__(self, *args):
return
def __del__(self):
self.sock.shutdown(socket.SHUT_RD)
self.sock.close()
def recv(self, size: int=int()) -> list:
while self.client:
try:
child = self.client.recv(size)
except OSError as error:
logging.error('socket error [{}]'.format(error))
break
if not child:
continue
self.lock.acquire()
self.children.append((child, datetime.utcnow()))
self.lock.release()
logging.info('recevied child')
def send(self, data: bytes):
if not self.client:
raise BrokenPipeError('client connection missing')
self.client.sendall(data)
@property
def children(self):
if not self.children:
return None
children = self.children
self.children = list()
return children
class Genorator:
seed = bytes() seed = bytes()
def __init__(self, *, parent: str, seed: str=str(), run_dir: str=str()): def __init__(self, *, parent: str, seed: str=str(), run_dir: str=str()):
self.parent = ctypes.CDLL(parent) self.parent = os.path.abspath(parent)
self.parent.gen_fork.restype = ctypes.c_int
self.parent.gen_fork.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
if seed: if seed:
with open(seed, 'rb') as seed_file: with open(seed, 'rb') as seed_file:
@ -30,13 +91,13 @@ class Sins:
self.run_dir = run_dir self.run_dir = run_dir
child = self.generation( parent_args = {
parent=self.parent, 'parent': self.parent,
scrap=self.seed, 'scrap': self.seed,
cwd=self.run_dir) 'cwd': self.run_dir}
if child: self.thread = Thread(target=self.generation, kwargs=parent_args)
logging.info(child) self.thread.start()
def scrap_recent(self, *, run_dir: str) -> str: def scrap_recent(self, *, run_dir: str) -> str:
scraps = sorted(os.listdir(run_dir)) scraps = sorted(os.listdir(run_dir))
@ -46,20 +107,30 @@ class Sins:
return None return None
def generation(self, *, parent: ctypes.CDLL, scrap: bytes, cwd: str): def generation(self, *, parent: str, scrap: bytes, cwd: str):
offset = randint(0, len(scrap)) offset = randint(0, len(scrap))
flip = randint(0, 255) flip = randint(0, 255)
scrap_len = len(scrap)
logging.info('scrap_length [{}]'.format(scrap_len))
logging.info('scrap\n{}'.format(binascii.b2a_hex(scrap))) logging.info('scrap\n{}'.format(binascii.b2a_hex(scrap)))
status = parent.gen_fork(scrap, scrap_len) cmd = [parent]
logging.info(cmd)
logging.info('status {}'.format(status)) proc = subprocess.Popen(
logging.info('scrap_length [{}]'.format(scrap_len)) [parent],
logging.info('scrap\n{}'.format(binascii.b2a_hex(scrap))) cwd=cwd)
with Server() as server:
server.send(bytes(len(scrap)))
server.send(scrap)
logging.info('child send')
server.recv()
children = server.children
if children:
raise Exception(children)
def hex_dumps(scrap_dir): def hex_dumps(scrap_dir):
@ -84,6 +155,19 @@ def hex_dumps(scrap_dir):
file_out.writelines('\'\\x{:02X}\',\n'.format(each)) file_out.writelines('\'\\x{:02X}\',\n'.format(each))
def provision():
provision = ['sudo', 'sh', 'provision-ubuntu.sh']
prov_proc = subprocess.run(provision)
os.environ['CC'] = 'clang'
waf = [sys.executable, 'waf.py', 'configure']
waf_proc = subprocess.run(waf)
def build():
waf = [sys.executable, 'waf.py', 'build']
waf_proc = subprocess.run(waf)
if __name__ == '__main__': if __name__ == '__main__':
import argparse import argparse
import sys import sys
@ -98,7 +182,7 @@ 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/libgeneration.so', parser.add_argument('-parent', default='build/generation.elf',
help='path to generation lib.') 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.')
@ -107,7 +191,8 @@ if __name__ == '__main__':
args = parser.parse_args() args = parser.parse_args()
logger = logging.getLogger() logger = logging.getLogger()
logger.setLevel(logging.DEBUG) if args.verbose else logger.setLevel(logging.INFO) logger.setLevel(
logging.DEBUG) if args.verbose else logger.setLevel(logging.INFO)
formatter = logging.Formatter('# %(filename)s:%(lineno)s\n%(message)s') formatter = logging.Formatter('# %(filename)s:%(lineno)s\n%(message)s')
stream_handler = logging.StreamHandler() stream_handler = logging.StreamHandler()
@ -122,20 +207,13 @@ if __name__ == '__main__':
logging.info(args) logging.info(args)
if args.provision: if args.provision:
provision = ['sudo', 'sh', 'provision-ubuntu.sh'] provision()
prov_proc = subprocess.run(provision)
os.environ['CC'] = 'clang'
waf = [sys.executable, 'waf.py', 'configure']
waf_proc = subprocess.run(waf)
elif args.build: elif args.build:
waf = [sys.executable, 'waf.py', 'build'] build()
waf_proc = subprocess.run(waf)
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) gen = Genorator(parent=args.parent, seed=args.seed, run_dir=args.dir)

View File

@ -14,9 +14,9 @@ def configure(conf):
def build(bld): def build(bld):
bld.shlib( bld.program(
source='generation.c', source='generation.c',
target='generation', target='generation.elf',
cflags=['-g', '-std=gnu11'] cflags=['-g', '-std=gnu11']
) )
bld(features='asm', source='seed.asm', target='seed') bld(features='asm', source='seed.asm', target='seed')