23rd December, 2006

A Simple Python CPU Emulator /--evilbitz   

Emulators in computer science are computer software that emulates an environment for another software to run, it may include some hardware devices as well, but if a complete environment is emulated that it will be usually called a virtual machine. An example for such enironment is DOSEMU, a DOS operating system environment which is emulated and designed to run on top of Linux operating system. The core for any software emulator is the CPU emulation part, many virtual machines uses the CPU that the bochs project had created, it can run x86, AMD64, and PPC software.

I played a bit with emulators in the past, and I created a simple python CPU emulator that emulates “flat” assembly code that can be defined by a configuration file. In this post I’ll describe its features, how does it work and what can be achieved by using it.

Simple Python CPU Emulator

The CPU emulator itself has a couple of runtime variables that are being used by the parsers, it moves line by line over the assembly that you tell it to emulate, and if the current assembly line matches a pattern (defined in the configuration line) then it evaluates another pattern, according to the run-time state of the CPU registers.

The configuration file of the emulator has two parts, it defines the registers that the cpu holds and the instructions that the emulated CPU can execute. The design is very simple and elegant, when the emulator initializes it prepares an opcode python dictionary. For instance, the opcode INC is defined as follows in the configuration file:

INC $reg1 | $reg1 += 1

When the parser encounters that configuration line, it adds the following key => value to the dictionary:

opcodes["INC (.*?)"] = “cpu[execed.group(1)] += 1″

Where cpu[execed.group(1)] is the run-time CPU register that is matched by the CPU emulator parser. When the parser reads a new assembly line, it first moves through all the keys of the opcodes dictionary, and tries to do a regular expression match. If it finds one, then the value of the dictionary is being simply evaluated. Here is the source code of the emulation loop:

01: while (cur_op_line < end_of_ops):
02: opcode = a_ops[cur_op_line]
03: execed, ptrn = get_exec(opcode)
04: if (execed):
05: if a_verbosity: print "%d:\t%s" % (cur_op_line+1, opcode)
06: exec(opcodes[ptrn])
07: else:
08: print "[-] havn't found a match for", opcode
09:
10: cur_op_line += 1

A Riddle For Fun

My friend Imri gave me this riddle when he took a course in complexity at the Tel Aviv University.

You a have a CPU with 4 registers (r0 through r3) and 3 basic opcodes that works as described:

  • INC reg – increases the value of reg by 1
  • DEC reg – decreases the value of reg by 1
  • TEST reg, line – if reg != 0 then start executing opcodes at the specified line

Download the source code, it comes ready with the configuration file for this exercise, and write a program that will end the execution when one of the registers contains the value 144.

  • The CPU starts when all the registers are initialized to zero.
  • The program length must not exceed 20 instructions.

Have pun! :-)



Posted in design, programming | 2 Comments

Top »
"If you can't join them, beat them!"
Search Evilbitz: