diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cmd.go | 20 | ||||
-rw-r--r-- | src/config.go | 76 | ||||
-rw-r--r-- | src/init.go | 230 | ||||
-rw-r--r-- | src/logic.go | 17 | ||||
-rw-r--r-- | src/main.go | 27 | ||||
-rw-r--r-- | src/run.go | 84 | ||||
-rw-r--r-- | src/structs.go | 49 |
7 files changed, 0 insertions, 503 deletions
diff --git a/src/cmd.go b/src/cmd.go deleted file mode 100644 index a17da4a..0000000 --- a/src/cmd.go +++ /dev/null @@ -1,20 +0,0 @@ -package main - -import ( - "github.com/radare/r2pipe-go" - "github.com/sirupsen/logrus" -) - -func r2cmd(r2p *r2pipe.Pipe, input string) string { - - logrus.Tracef("> %s", input) - - // send a command - buf1, err := r2p.Cmd(input) - if err != nil { - panic(err) - } - - // return the result of the command as a string - return buf1 -} diff --git a/src/config.go b/src/config.go deleted file mode 100644 index 706d29e..0000000 --- a/src/config.go +++ /dev/null @@ -1,76 +0,0 @@ -package main - -import ( - "flag" - "time" - - "github.com/sirupsen/logrus" -) - -// parseConfig parses the config needed to start the game -func parseConfig() Config { - - // bot configs - arch := flag.String("arch", "x86", "bot architecture (mips|arm|x86)") - bits := flag.Int("bits", 32, "bot bitness (8|16|32|64)") - maxProgSize := flag.Int("maxProgSize", 64, "the maximum bot size") - memPerBot := flag.Int("memPerBot", 512, "the amount of memory each bot should add to the arena") - gameRoundDuration := flag.Duration("t", 250*time.Millisecond, "The duration of a round") - - v := flag.Bool("v", false, "info") - vv := flag.Bool("vv", false, "debug") - vvv := flag.Bool("vvv", false, "trace") - - // parse the flags - flag.Parse() - - if *v == true { - logrus.SetLevel(logrus.InfoLevel) - } else if *vv == true { - logrus.SetLevel(logrus.DebugLevel) - } else if *vvv == true { - logrus.SetLevel(logrus.TraceLevel) - } else { - logrus.SetLevel(logrus.WarnLevel) - } - - // parse all trailing command line arguments as path to bot sourcecode - amountOfBots := flag.NArg() - - memsize := amountOfBots * *memPerBot - - logrus.WithFields(logrus.Fields{ - "mem per bot": *memPerBot, - "amountOfBots": amountOfBots, - "memsize": memsize, - }).Infof("Loaded config") - - // define a config to return - config := Config{ - Arch: *arch, - Bits: *bits, - Memsize: memsize, - MaxProgSize: *maxProgSize, - AmountOfBots: amountOfBots, - GameRoundDuration: *gameRoundDuration, - } - - return config -} - -// define bots defines the bots given via command line arguments -func defineBots(config *Config) { - - logrus.Info("Defining the bots") - - // define a list of bots by parsing the command line arguments one by one - var bots []Bot - for i := 0; i < config.AmountOfBots; i++ { - bot := Bot{ - Path: flag.Arg(i), - } - bots = append(bots, bot) - } - - config.Bots = bots -} diff --git a/src/init.go b/src/init.go deleted file mode 100644 index ee6db87..0000000 --- a/src/init.go +++ /dev/null @@ -1,230 +0,0 @@ -package main - -import ( - "fmt" - "math/rand" - "strings" - "time" - - r2pipe "github.com/radare/r2pipe-go" - "github.com/sirupsen/logrus" -) - -func buildBots(config *Config) { - - logrus.Info("Building all bots") - - // build all the bots - for i := 0; i < config.AmountOfBots; i++ { - buildBot(i, config) - } -} - -// buildBot builds the bot located at the given path. -func buildBot(i int, config *Config) { - - logrus.Debugf("Building bot %d", i) - - // open radare without input for building the bot - r2p1, err := r2pipe.NewPipe("--") - if err != nil { - panic(err) - } - defer r2p1.Close() - - // Compile a warrior using rasm2 - // - // This uses the given architecture, the given bitness and the given path in - // rasm2 to compile the bot - botPath := config.Bots[i].Path - radareCommand := fmt.Sprintf("rasm2 -a %s -b %d -f %s", config.Arch, config.Bits, botPath) - botSource := r2cmd(r2p1, radareCommand) - - config.Bots[i].Source = botSource -} - -// init initializes the arena -func initArena(config *Config) *r2pipe.Pipe { - - logrus.Info("Initializing the arena") - logrus.Debugf("Allocating %d bytes of memory...", config.Memsize) - - // allocate memory - r2p, err := r2pipe.NewPipe(fmt.Sprintf("malloc://%d", config.Memsize)) - if err != nil { - panic(err) - } - - logrus.Info("Memoy successfully allocated") - - // define the architecture and the bitness - _ = r2cmd(r2p, fmt.Sprintf("e asm.arch = %s", config.Arch)) - _ = r2cmd(r2p, fmt.Sprintf("e asm.bits = %d", config.Bits)) - - // enable colors - // _ = r2cmd(r2p, "e scr.color = 0") - _ = r2cmd(r2p, "e scr.color = 3") - _ = r2cmd(r2p, "e scr.color.args = true") - _ = r2cmd(r2p, "e scr.color.bytes = true") - _ = r2cmd(r2p, "e scr.color.grep = true") - _ = r2cmd(r2p, "e scr.color.ops = true") - _ = r2cmd(r2p, "e scr.bgfill = true") - _ = r2cmd(r2p, "e scr.color.pipe = true") - _ = r2cmd(r2p, "e scr.utf8 = true") - - // hex column width - _ = r2cmd(r2p, "e hex.cols = 32") - - // initialize ESIL VM state - logrus.Debug("Initializing the ESIL VM") - _ = r2cmd(r2p, "aei") - - // initialize ESIL VM stack - logrus.Debug("Initializing the ESIL Stack") - _ = r2cmd(r2p, "aeim") - - // return the pipe - return r2p -} - -// genRandomOffsets returns random offsets for all bots -// This is used to get the offset the bots are initially placed in -func genRandomOffsets(config *Config) { - - logrus.Info("Generating random bot offsets") - - // define the amount of bots, an array to store the offsets in and a counter - // to store the amount of tries it took to find a random positon for the bots - var amountOfBots int = len(config.Bots) - var offsets []int - var roundCounter int = 0 - - // seed the random number generator - rand.Seed(time.Now().UTC().UnixNano()) - - for { - - // reset the offsets array - offsets = []int{} - - // define a random address - // | ------------------------------------- | ----- | - // | generate an address in this space - address := rand.Intn(config.Memsize - config.MaxProgSize) - logrus.Tracef("%d", address) - - // for all bots, try to generate another random address after the intially - // generated address and test if it fits in memory - for i := 0; i < amountOfBots; i++ { - - // append the address to the offsets array - offsets = append(offsets, address) - - // define a min and max bound - // - // | ------|-|----------------------------------|-| - // | | | in this space | | - // a b c d e - // - // a = 0x0 - // b = address - // c = address + config.MaxProcSize (min) - // d = config.Memsize - config.MaxProgSize (max) - // e = config.Memsize - min := address + config.MaxProgSize - max := config.Memsize - config.MaxProgSize - - // if the new minimum bound is bigger or equal to the maximum bound, - // discard this try and start with a fresh new initial address - if min >= max { - roundCounter++ - break - } - - // generate a new address in the [min, max) range defined above - address = rand.Intn(max-min) + min - logrus.Tracef("%d", address) - - // If there isn't enough space inbetween the address and the biggest - // possible address, as in, the biggest possible bot can't fit in that - // space, discard and start with a new fresh initial address - if (config.Memsize-config.MaxProgSize)-address < config.MaxProgSize { - roundCounter++ - break - } - } - - // if the needed amount of offsets has been found, break out of the infinite loop - if len(offsets) == amountOfBots { - break - } - } - - logrus.Infof("Initial bot positions found after %d tries", roundCounter) - - // debug print all offsets - var fields0 logrus.Fields = make(logrus.Fields) - for i := 0; i < len(offsets); i++ { - fields0[fmt.Sprintf("%d", i)] = offsets[i] - } - logrus.WithFields(fields0).Debug("Offsets") - - // shuffle the offsets - rand.Shuffle(len(offsets), func(i, j int) { - offsets[i], offsets[j] = offsets[j], offsets[i] - }) - - // debug print the shuffled offsets - var fields1 logrus.Fields = make(logrus.Fields) - for i := 0; i < len(offsets); i++ { - fields1[fmt.Sprintf("%d", i)] = offsets[i] - } - logrus.WithFields(fields1).Debug("Shuffled offsets") - - config.RandomOffsets = offsets -} - -// place the bot in the arena at the given address -func placeBot(r2p *r2pipe.Pipe, bot Bot, address int) { - _ = r2cmd(r2p, fmt.Sprintf("wx %s @ %d", bot.Source, address)) -} - -func placeBots(r2p *r2pipe.Pipe, config *Config) { - - logrus.Info("Placing the bots in the arena") - - // place each bot in the arena - for bot := 0; bot < len(config.Bots); bot++ { - - // get the address where the bot should be placed - address := config.RandomOffsets[bot] - - // Place the bot in the arena - logrus.Debugf("[i] Placing bot %d at %d", bot, address) - placeBot(r2p, config.Bots[bot], address) - - logrus.Debugf("\n%s", r2cmd(r2p, fmt.Sprintf("pd 0x8 @ %d", address))) - - // store the initial address of the bot in the according struct field - config.Bots[bot].Addr = address - - // define the instruction point and the stack pointer - _ = r2cmd(r2p, fmt.Sprintf("aer PC=%d", config.Bots[bot].Addr)) - _ = r2cmd(r2p, fmt.Sprintf("aer SP=SP+%d", config.Bots[bot].Addr)) - - // dump the registers of the bot for being able to switch inbetween them - // This is done in order to be able to play one step of each bot at a time, - // but sort of in parallel - initialRegisers := strings.Replace(r2cmd(r2p, "aerR"), "\n", ";", -1) - config.Bots[bot].Regs = initialRegisers - } -} - -func defineErrors(r2p *r2pipe.Pipe) { - // handle errors in esil - _ = r2cmd(r2p, "e cmd.esil.todo=f theend=1") - _ = r2cmd(r2p, "e cmd.esil.trap=f theend=1") - _ = r2cmd(r2p, "e cmd.esil.intr=f theend=1") - _ = r2cmd(r2p, "e cmd.esil.ioer=f theend=1") - _ = r2cmd(r2p, "f theend=0") -} diff --git a/src/logic.go b/src/logic.go deleted file mode 100644 index 5bc6461..0000000 --- a/src/logic.go +++ /dev/null @@ -1,17 +0,0 @@ -package main - -import ( - "log" - - "github.com/radare/r2pipe-go" -) - -func dead(r2p *r2pipe.Pipe, botid int) bool { - status := r2cmd(r2p, "?v 1+theend") - - if status != "" && status != "0x1" { - log.Printf("[!] Bot %d has died", botid) - return true - } - return false -} diff --git a/src/main.go b/src/main.go deleted file mode 100644 index d5e0107..0000000 --- a/src/main.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -func main() { - - // initialize the game by parsing the config, defining the bots, building the - // bots and generating random offsets where the bots should be placed in - // memory - config := parseConfig() - defineBots(&config) - buildBots(&config) - genRandomOffsets(&config) - - // initialize the arena (allocate memory + initialize the ESIL VM & stack) - r2p := initArena(&config) - - // place the bots in the arena - placeBots(r2p, &config) - - // if an error occurs (interrupt, ioerror, trap, ...), the ESIL VM should set - // a flag that can be used to determine if a player has died - defineErrors(r2p) - - // run the actual game - runGame(r2p, &config) - - r2p.Close() -} diff --git a/src/run.go b/src/run.go deleted file mode 100644 index fb3c249..0000000 --- a/src/run.go +++ /dev/null @@ -1,84 +0,0 @@ -package main - -import ( - "fmt" - "os" - "strings" - "time" - - "github.com/radare/r2pipe-go" - "github.com/sirupsen/logrus" -) - -// StepIn steps in and stores the state of the registers for the given bot -func stepIn(r2p *r2pipe.Pipe) { - _ = r2cmd(r2p, "aes") -} - -// switchPlayer returns the id of the next Player -func switchPlayer(r2p *r2pipe.Pipe, currentPlayer int, config *Config) int { - - // calculate the index of the nextPlayer - nextPlayer := (currentPlayer + 1) % config.AmountOfBots - - return nextPlayer -} - -func arena(r2p *r2pipe.Pipe, config *Config, id, gen int) string { - var res string = "" - - // clear the screen - res += "\x1b[2J\x1b[0;0H" - // res += fmt.Sprintf("%s\n", r2cmd(r2p, "?eg 0 0")) - - // print some general information such as the current user and the round the - // game is in - ip := fmt.Sprintf("%s\n", r2cmd(r2p, "aer~eip")) - res += fmt.Sprintf("Round: %d \t\t User: %d \t\t ip: %s\n", gen, id, ip) - - // print the memory space - res += fmt.Sprintf("%s\n", r2cmd(r2p, "pxa 0x400 @ 0")) - // res += fmt.Sprintf("%s\n", r2cmd(r2p, fmt.Sprintf("pd 0x10 @ %d", config.Bots[id].Addr))) - - // res += fmt.Sprintf("%s\n", r2cmd(r2p, "prc 0x200 @ 0")) - - return res -} - -// runGame actually runs the game (surprise!) -func runGame(r2p *r2pipe.Pipe, config *Config) { - - // start the competition - var botid int = 0 - var round int = 0 - for true { - - // load the registers - r2cmd(r2p, config.Bots[botid].Regs) - - // Step - stepIn(r2p) - - // store the regisers - registers := r2cmd(r2p, "aerR") - registersStripped := strings.Replace(registers, "\n", ";", -1) - config.Bots[botid].Regs = registersStripped - - logrus.Info(arena(r2p, config, botid, round)) - - if dead(r2p, botid) == true { - logrus.Warnf("DEAD (round %d)", round) - os.Exit(1) - } - - // switch players, if the new botid is 0, a new round has begun - botid = switchPlayer(r2p, botid, config) - if botid == 0 { - round++ - } - - // sleep only a partial of the total round time, as a round is made up of - // the movements of multiple bots - time.Sleep(config.GameRoundDuration / time.Duration(config.AmountOfBots)) - } -} diff --git a/src/structs.go b/src/structs.go deleted file mode 100644 index c0cddc2..0000000 --- a/src/structs.go +++ /dev/null @@ -1,49 +0,0 @@ -package main - -import "time" - -// Config defines the meta config -type Config struct { - - // Arch defines the architecture the battle should run in - Arch string - - // Bits defines the bitness - Bits int - - // Memsize defines the arena size - Memsize int - - // MaxProgSize defines the maximal bot size - MaxProgSize int - - // Bots defines a list of bots to take part in the battle - Bots []Bot - - // AmountOfBots defines the amount of bots taking part in the tournament - AmountOfBots int - - // RandomOffsets defines the offset in memory where the bots should be placed - RandomOffsets []int - - // GameRoundTime defines the length of a gameround - GameRoundDuration time.Duration -} - -// Bot defines a bot -type Bot struct { - - // Path defines the path to the source of the bot - Path string - - // Source defines the source of the bot after being compiled with rasm2 - Source string - - // Addr defines the initial address the bot is placed at - Addr int - - // Regs defines the state of the registers of the bot - // It is used to store the registers after each round and restore them in the - // next round when the bot's turn has come - Regs string -} |