From d8f8cd5415b448e0969b39e9e0bad5d0350bdcae Mon Sep 17 00:00:00 2001 From: user Date: Wed, 23 Oct 2019 17:41:22 -0400 Subject: move off rand-selfmod --- .gitmodules | 3 - biscuit | 1 - intellect.cpp | 162 ------------------------------------ makefile | 2 - random.cpp | 108 ------------------------ starts/random-selfmod/intellect.cpp | 162 ++++++++++++++++++++++++++++++++++++ starts/random-selfmod/makefile | 2 + starts/random-selfmod/random.cpp | 108 ++++++++++++++++++++++++ 8 files changed, 272 insertions(+), 276 deletions(-) delete mode 100644 .gitmodules delete mode 160000 biscuit delete mode 100644 intellect.cpp delete mode 100644 makefile delete mode 100644 random.cpp create mode 100644 starts/random-selfmod/intellect.cpp create mode 100644 starts/random-selfmod/makefile create mode 100644 starts/random-selfmod/random.cpp diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 57ff75b..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "biscuit"] - path = biscuit - url = https://github.com/xloem/biscuit.git diff --git a/biscuit b/biscuit deleted file mode 160000 index 2ed6efe..0000000 --- a/biscuit +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2ed6efe8847a4f076c5559122b1dd0a0fb94513d diff --git a/intellect.cpp b/intellect.cpp deleted file mode 100644 index 7991878..0000000 --- a/intellect.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// The extreme of Trial Exploration and Self Coding -// brainstorm_by(assembly code,running it) - -// the advantage of assembly code is that it is very easy to serialize -// the advantage of random self-modification is that it is very easy to make -// propose this is the first AI karl makes, and it runs in a safe isolated box, on its own -// how to judge success? does-not-crash? -// have to teach it learning. first is to not crash. then is to output requested string, likely copied from request. run it until it outputs requested string. -// it's stupid enough to be safe if run in an isolated box. -// due to how fast it should be to make this, let's finish barebones first, and then merge. XO computer likely doesn't have read-only-execute problem. - -// the below is a brief attempt to make an intellect by random self-modification. it does not run. -// DO NOT RUN THIS UNLESS YOU KNOW WHAT YOU ARE DOING - -#include -#include -#include -#include - -#include -//#include -#include -#include -#include -#include -#include - -using namespace std; - -// Signal Catching has the problem of how to resume execution generally. -// So we propose to fork a new process, and switch to it if it works. -// This will take forming a simple communication method between the processes. -// We can also compile a whole new program to learn, copying our source. - -// TODO: Currently implementing fork/exec. changed approach - -// TODO: make sure to run inside a vm once it does something - -// TODO: try out rewriting and recompiling code, rather than forking ram - -class RamGetter -{ -public: - RamGetter() - { - randfile = open("/dev/urandom", O_RDONLY); - if (randfile <= 0) throw 0; - } - ~RamGetter() - { - close(randfile); - } - void * getRandAddr(size_t len) - { - // TODO: this is a heuristic for picking an inner memory location, and learning what doesn't work; could be used in learning concept - void * blkp; - do { - uint32_t blk; - int ct = read(randfile, &blk, sizeof(blk)); - if (ct < sizeof(blk)) throw 0; - blkp = reinterpret_cast(blk); - // fork here. check length - pid_t forkpid = fork(); - if (forkpid == -1) throw "failed to fork"; - if (forkpid == 0) { - // child: test ram - volatile uint8_t tst; - for (size_t i = 0; i < len; ++ i) { - tst = ((uint8_t*)blkp)[i]; - } - } else { - // parent: wait for child - int status; - wait(&status); - if(WIFCONTINUED(status)) { - // child succeeded, so we can stop - // TODO: need a way to indicate child success - exit(0); - } else { - // child failed, so we keep going, but TODO: failure is not stored - continue; - } - } - } while (isbad(blkp)); - return blkp; - } - void markbad(void *bad) - { - bad = (void*)((long)(bad) & ~0xfff); - badpages.insert(bad); - cout << "Bad: " << bad << endl; - } - bool isbad(void *chk) - { - chk = (void*)((long)(chk) & ~0xfff); - return badpages.count(chk); - } - -private: - int randfile; - set badpages; - // TODO: some concern that the badpages set will allocate on the heap. - // maybe let's use a stack-based storage back for it (allocator) -}; - - -uint8_t someram[0x10000000]; // when this is removed, heap moves to 64-bit? -struct instruction { - void * verb; - void * object1; - void * object2; - void * attr; - void * result; -}; - -int main() { - // reference process memory - // all of it, please - RamGetter selfmem; // an object to access RAM with - - // TODO: try making an instruction list - - void * mem = 0; - // make a loop - while (true) { - // TODO: move fork/exec into this loop, outside of RamGetter - - // we propose copying some blocks to other blocks, randomly - // need blocksize, how about 4 // TODO: that's kinda small, maybe random instead? - void *blk1, *blk2; - blk1 = selfmem.getRandAddr(4); - blk2 = selfmem.getRandAddr(4); - memmove(blk1, blk2, 4); - - // continue the loop forever - // run it - } - // end when the loop is done =) - - // /proc/pid/maps shows the addresses of allocated memory - // /proc/pid/mem provides access to this memory - // ^-- will error when wrong part is read - // just load straight; error is recoverable, just a refusal - // no need to map file, can just catch segfaults? - - /* - FILE *maps; - char pathbuf[1024]; - snprintf("/proc/%d/maps", sizeof(pathbuf), pid); - open(pathbuf, O_RDONLY); - - snprintf("/proc/%d/mem", sizeof(pathbuf), pid); - void * procmem = mmap(0, length, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED - */ - /* - try { - int e = *(int*)39; - } catch(...) { - throw; - } - */ -} diff --git a/makefile b/makefile deleted file mode 100644 index 9475287..0000000 --- a/makefile +++ /dev/null @@ -1,2 +0,0 @@ -intellect: intellect.cpp - g++ -ggdb -std=c++11 intellect.cpp -Wl,--print-map diff --git a/random.cpp b/random.cpp deleted file mode 100644 index afdf4c7..0000000 --- a/random.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// let's try to make it very simple - -#include -#include -#include -#include - -// 1. write a function to randomly put data in a buffer -// [apparently one loaded from a file] - -#define MAPFNAME "random.bin" - -pid_t child = 0; -bool child_terminated = false; -void handleSigChld(int) -{ - child_terminated = true; -} - -static unsigned long long * count; - -void random(int mapfd, int randfd, void *addr) -{ - pid_t pid = getpid(); - - // *count is shared and stored - for (*count = 0; ; ++ *count) { - unsigned long long old_count = *count; - - // if successful child, update & kill parent - if (getpid() != pid) { - msync(addr + pos, size, MS_SYNC | MS_INVALIDATE); - - kill(pid, SIGTERM); - pid = getpid(); - - // add data to git. - system("git add " MAPFNAME); - system("git commit -m selfmod"); - } - - // handle crashes with fork() - child = fork(); - if (child == 0) { - // we are new child process - // self-modify by 1-8 bytes - uint16_t pos; - uint8_t size; - read(randfd, &pos, sizeof(pos)); - read(randfd, &size, sizeof(size)); - size = (size & 0x7) + 1; // self-modify by 1-8 bytes - read(randfd, addr + pos, size); - // loop - } else { - // old process: make sure new process succeeds within 1s - time_t then = time(0); - for (;;) { - if (child_terminated || time(0) > then) { - // child did not succeed - kill(child, SIGTERM); - child_terminated = false; - // try again - break; - } - if (old_count < *count + 1) { - // incremented count by 1: success; hand off to child - return; - } - } - } - } -} - -void random_tail() { -} - -void main() -{ - // handle SIGCHLD by setting a global flag - struct sigaction sigchld; - sigchld.sa_handler = handleSigChld; - sigchld.sa_flags = SA_NOCLDWAIT; - sigaction(SIGCHLD, &sigchld, NULL); - - int fd = open(MAPFNAME, O_RDWR); - if (fd == -1 && errno == ENOENT) { - // does not exist yet - fd = open("random.bin", O_RDWR | O_CREAT); - // 2. seed the buffer with the function that puts random data in it - count = 0; - write(fd, &count, sizeof(count)); - write(fd, &random, &random_tail - &random); - } - - int randfd = open("/dev/random", O_RDONLY); - - // a buffer of 1 gig working space; random data will fill it - void *buf = mmap(NULL, - 0x40000000, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_32BIT, - fd, - 0; - - // 3. execute the buffer - void (*buf_as_func)(void*) = (void*)((uint8_t*)buf + count); - buf_as_func(mapfname, mapfd, randfd, buf); -} diff --git a/starts/random-selfmod/intellect.cpp b/starts/random-selfmod/intellect.cpp new file mode 100644 index 0000000..7991878 --- /dev/null +++ b/starts/random-selfmod/intellect.cpp @@ -0,0 +1,162 @@ +// The extreme of Trial Exploration and Self Coding +// brainstorm_by(assembly code,running it) + +// the advantage of assembly code is that it is very easy to serialize +// the advantage of random self-modification is that it is very easy to make +// propose this is the first AI karl makes, and it runs in a safe isolated box, on its own +// how to judge success? does-not-crash? +// have to teach it learning. first is to not crash. then is to output requested string, likely copied from request. run it until it outputs requested string. +// it's stupid enough to be safe if run in an isolated box. +// due to how fast it should be to make this, let's finish barebones first, and then merge. XO computer likely doesn't have read-only-execute problem. + +// the below is a brief attempt to make an intellect by random self-modification. it does not run. +// DO NOT RUN THIS UNLESS YOU KNOW WHAT YOU ARE DOING + +#include +#include +#include +#include + +#include +//#include +#include +#include +#include +#include +#include + +using namespace std; + +// Signal Catching has the problem of how to resume execution generally. +// So we propose to fork a new process, and switch to it if it works. +// This will take forming a simple communication method between the processes. +// We can also compile a whole new program to learn, copying our source. + +// TODO: Currently implementing fork/exec. changed approach + +// TODO: make sure to run inside a vm once it does something + +// TODO: try out rewriting and recompiling code, rather than forking ram + +class RamGetter +{ +public: + RamGetter() + { + randfile = open("/dev/urandom", O_RDONLY); + if (randfile <= 0) throw 0; + } + ~RamGetter() + { + close(randfile); + } + void * getRandAddr(size_t len) + { + // TODO: this is a heuristic for picking an inner memory location, and learning what doesn't work; could be used in learning concept + void * blkp; + do { + uint32_t blk; + int ct = read(randfile, &blk, sizeof(blk)); + if (ct < sizeof(blk)) throw 0; + blkp = reinterpret_cast(blk); + // fork here. check length + pid_t forkpid = fork(); + if (forkpid == -1) throw "failed to fork"; + if (forkpid == 0) { + // child: test ram + volatile uint8_t tst; + for (size_t i = 0; i < len; ++ i) { + tst = ((uint8_t*)blkp)[i]; + } + } else { + // parent: wait for child + int status; + wait(&status); + if(WIFCONTINUED(status)) { + // child succeeded, so we can stop + // TODO: need a way to indicate child success + exit(0); + } else { + // child failed, so we keep going, but TODO: failure is not stored + continue; + } + } + } while (isbad(blkp)); + return blkp; + } + void markbad(void *bad) + { + bad = (void*)((long)(bad) & ~0xfff); + badpages.insert(bad); + cout << "Bad: " << bad << endl; + } + bool isbad(void *chk) + { + chk = (void*)((long)(chk) & ~0xfff); + return badpages.count(chk); + } + +private: + int randfile; + set badpages; + // TODO: some concern that the badpages set will allocate on the heap. + // maybe let's use a stack-based storage back for it (allocator) +}; + + +uint8_t someram[0x10000000]; // when this is removed, heap moves to 64-bit? +struct instruction { + void * verb; + void * object1; + void * object2; + void * attr; + void * result; +}; + +int main() { + // reference process memory + // all of it, please + RamGetter selfmem; // an object to access RAM with + + // TODO: try making an instruction list + + void * mem = 0; + // make a loop + while (true) { + // TODO: move fork/exec into this loop, outside of RamGetter + + // we propose copying some blocks to other blocks, randomly + // need blocksize, how about 4 // TODO: that's kinda small, maybe random instead? + void *blk1, *blk2; + blk1 = selfmem.getRandAddr(4); + blk2 = selfmem.getRandAddr(4); + memmove(blk1, blk2, 4); + + // continue the loop forever + // run it + } + // end when the loop is done =) + + // /proc/pid/maps shows the addresses of allocated memory + // /proc/pid/mem provides access to this memory + // ^-- will error when wrong part is read + // just load straight; error is recoverable, just a refusal + // no need to map file, can just catch segfaults? + + /* + FILE *maps; + char pathbuf[1024]; + snprintf("/proc/%d/maps", sizeof(pathbuf), pid); + open(pathbuf, O_RDONLY); + + snprintf("/proc/%d/mem", sizeof(pathbuf), pid); + void * procmem = mmap(0, length, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED + */ + /* + try { + int e = *(int*)39; + } catch(...) { + throw; + } + */ +} diff --git a/starts/random-selfmod/makefile b/starts/random-selfmod/makefile new file mode 100644 index 0000000..9475287 --- /dev/null +++ b/starts/random-selfmod/makefile @@ -0,0 +1,2 @@ +intellect: intellect.cpp + g++ -ggdb -std=c++11 intellect.cpp -Wl,--print-map diff --git a/starts/random-selfmod/random.cpp b/starts/random-selfmod/random.cpp new file mode 100644 index 0000000..afdf4c7 --- /dev/null +++ b/starts/random-selfmod/random.cpp @@ -0,0 +1,108 @@ +// let's try to make it very simple + +#include +#include +#include +#include + +// 1. write a function to randomly put data in a buffer +// [apparently one loaded from a file] + +#define MAPFNAME "random.bin" + +pid_t child = 0; +bool child_terminated = false; +void handleSigChld(int) +{ + child_terminated = true; +} + +static unsigned long long * count; + +void random(int mapfd, int randfd, void *addr) +{ + pid_t pid = getpid(); + + // *count is shared and stored + for (*count = 0; ; ++ *count) { + unsigned long long old_count = *count; + + // if successful child, update & kill parent + if (getpid() != pid) { + msync(addr + pos, size, MS_SYNC | MS_INVALIDATE); + + kill(pid, SIGTERM); + pid = getpid(); + + // add data to git. + system("git add " MAPFNAME); + system("git commit -m selfmod"); + } + + // handle crashes with fork() + child = fork(); + if (child == 0) { + // we are new child process + // self-modify by 1-8 bytes + uint16_t pos; + uint8_t size; + read(randfd, &pos, sizeof(pos)); + read(randfd, &size, sizeof(size)); + size = (size & 0x7) + 1; // self-modify by 1-8 bytes + read(randfd, addr + pos, size); + // loop + } else { + // old process: make sure new process succeeds within 1s + time_t then = time(0); + for (;;) { + if (child_terminated || time(0) > then) { + // child did not succeed + kill(child, SIGTERM); + child_terminated = false; + // try again + break; + } + if (old_count < *count + 1) { + // incremented count by 1: success; hand off to child + return; + } + } + } + } +} + +void random_tail() { +} + +void main() +{ + // handle SIGCHLD by setting a global flag + struct sigaction sigchld; + sigchld.sa_handler = handleSigChld; + sigchld.sa_flags = SA_NOCLDWAIT; + sigaction(SIGCHLD, &sigchld, NULL); + + int fd = open(MAPFNAME, O_RDWR); + if (fd == -1 && errno == ENOENT) { + // does not exist yet + fd = open("random.bin", O_RDWR | O_CREAT); + // 2. seed the buffer with the function that puts random data in it + count = 0; + write(fd, &count, sizeof(count)); + write(fd, &random, &random_tail - &random); + } + + int randfd = open("/dev/random", O_RDONLY); + + // a buffer of 1 gig working space; random data will fill it + void *buf = mmap(NULL, + 0x40000000, + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_32BIT, + fd, + 0; + + // 3. execute the buffer + void (*buf_as_func)(void*) = (void*)((uint8_t*)buf + count); + buf_as_func(mapfname, mapfd, randfd, buf); +} -- cgit v1.2.3