ExploitBuilder 0.1.0

A exploit builder for quick exploit development
Documentation
use crate::CPU::Endian;


#[derive (Clone, Copy, Debug, Eq, PartialEq)]
pub enum Mips32Register
{
	ZERO = 0,
	AT = 1,
	V0 = 2,
	V1 = 3,
	A0 = 4,
	A1 = 5,
	A2 = 6,
	A3 = 7,
	T0 = 8,
	T1 = 9,
	T2 = 10,
	T3 = 11,
	T4 = 12,
	T5 = 13,
	T6 = 14,
	T7 = 15,
	S0 = 16,
	S1 = 17,
	S2 = 18,
	S3 = 19,
	S4 = 20,
	S5 = 21,
	S6 = 22,
	S7 = 23,
	T8 = 24,
	T9 = 25,
	K0 = 26,
	K1 = 27,
	GP = 28,
	SP = 29,
	FP = 30,
	RA = 31,
}

impl TryFrom<usize> for Mips32Register
{
	type Error = ();

	fn try_from (value: usize) -> Result<Self, Self::Error>
	{
		match value
		{
			x if x == Self::ZERO as usize => Ok(Self::ZERO),
			x if x == Self::AT as usize => Ok(Self::AT),
			x if x == Self::V0 as usize => Ok(Self::V0),
			x if x == Self::V1 as usize => Ok(Self::V1),
			x if x == Self::A0 as usize => Ok(Self::A0),
			x if x == Self::A1 as usize => Ok(Self::A1),
			x if x == Self::A2 as usize => Ok(Self::A2),
			x if x == Self::A3 as usize => Ok(Self::A3),
			x if x == Self::T0 as usize => Ok(Self::T0),
			x if x == Self::T1 as usize => Ok(Self::T1),
			x if x == Self::T2 as usize => Ok(Self::T2),
			x if x == Self::T3 as usize => Ok(Self::T3),
			x if x == Self::T4 as usize => Ok(Self::T4),
			x if x == Self::T5 as usize => Ok(Self::T5),
			x if x == Self::T6 as usize => Ok(Self::T6),
			x if x == Self::T7 as usize => Ok(Self::T7),
			x if x == Self::S0 as usize => Ok(Self::S0),
			x if x == Self::S1 as usize => Ok(Self::S1),
			x if x == Self::S2 as usize => Ok(Self::S2),
			x if x == Self::S3 as usize => Ok(Self::S3),
			x if x == Self::S4 as usize => Ok(Self::S4),
			x if x == Self::S5 as usize => Ok(Self::S5),
			x if x == Self::S6 as usize => Ok(Self::S6),
			x if x == Self::S7 as usize => Ok(Self::S7),
			x if x == Self::T8 as usize => Ok(Self::T8),
			x if x == Self::T9 as usize => Ok(Self::T9),
			x if x == Self::K0 as usize => Ok(Self::K0),
			x if x == Self::K1 as usize => Ok(Self::K1),
			x if x == Self::GP as usize => Ok(Self::GP),
			x if x == Self::SP as usize => Ok(Self::SP),
			x if x == Self::FP as usize => Ok(Self::FP),
			x if x == Self::RA as usize => Ok(Self::RA),
			_ => Err(()),
		}
	}
}


#[derive (Clone, Copy, Debug, Eq, PartialEq)]
pub enum Mips32InstructionOpcode
{
	REG = 0b000000,
	ADDI = 0b001000,
	ADDIU = 0b001001,
	SLTI = 0b001010,
	SLTIU = 0b001011,
	ANDI = 0b001100,
	ORI = 0b001101,
	XORI = 0b001110,
	LUI = 0b001111,
	LB = 0b100000,
	LH = 0b100001,
	LW = 0b100011,
	LHU = 0b100101,
	SH = 0b101001,
	SW = 0b101011,
	SB = 0b101000,
	BEQ = 0b000100,
	BNE = 0b000101,
}


#[derive (Clone, Copy, Debug, Eq, PartialEq)]
pub enum Mips32InstructionFunctionCode
{
	SYSCALL = 0b001100,
	SYNC = 0x001111,
	MFHI = 0b010000,
	MTHI = 0b010001,
	MFLO = 0b010010,
	MTLO = 0b010011,
	MULT = 0b011000,
	MULTU = 0b011001,
	DIV = 0b011010,
	DIVU = 0b011011,
	ADD = 0b100000,
	ADDU = 0b100001,
	SUB = 0b100010,
	SUBU = 0b100011,
	AND = 0b100100,
	OR = 0b100101,
	XOR = 0b100110,
	NOR = 0b100111,
	SLT = 0b101010,
	SLTU = 0b101011,
}


#[derive (Clone, Copy, Debug, Eq, PartialEq)]
pub struct Mips32RTypeInstruction
{
	opcode: Mips32InstructionOpcode,
	rs: Mips32Register,
	rt: Mips32Register,
	rd: Mips32Register,
	shamt: usize,
	funct: Mips32InstructionFunctionCode,
}

impl Mips32RTypeInstruction
{
	pub fn New (opcode: Mips32InstructionOpcode, rs: Mips32Register, rt: Mips32Register, rd: Mips32Register, shamt: usize, funct: Mips32InstructionFunctionCode) -> Self
	{
		Self
		{
			opcode,
			rs,
			rt,
			rd,
			shamt,
			funct,
		}
	}

	pub fn ToByteArray (&self, endian: Endian) -> Vec<u8>
	{
		let op = (self.opcode as usize)&0b111111;
		let rs = (self.rs as usize)&0b11111;
		let rt = (self.rt as usize)&0b11111;
		let rd = (self.rd as usize)&0b11111;
		let shamt = self.shamt&0b11111;
		let funct = (self.funct as usize)&0b111111;

		let code: u32 = ((op<<26) | (rs<<21) | (rt<<16) | (rd<<11) | (shamt<<6) | funct) as u32;

		if endian == Endian::BIG
		{
			code.to_be_bytes ().to_vec ()
		}
		else
		{
			code.to_le_bytes ().to_vec ()
		}
	}

	pub fn ToAssemblySource (&self) -> String
	{
		unimplemented! ();
	}
}


#[derive (Clone, Copy, Debug, Eq, PartialEq)]
pub struct Mips32ITypeInstruction
{
	opcode: Mips32InstructionOpcode,
	rs: Mips32Register,
	rt: Mips32Register,
	addrImm: u16,
}

impl Mips32ITypeInstruction
{
	pub fn New (opcode: Mips32InstructionOpcode, rs: Mips32Register, rt: Mips32Register, addrImm: u16) -> Self
	{
		Self
		{
			opcode,
			rs,
			rt,
			addrImm,
		}
	}

	pub fn ToByteArray (&self, endian: Endian) -> Vec<u8>
	{
		let op = (self.opcode as usize)&0b111111;
		let rs = (self.rs as usize)&0b11111;
		let rt = (self.rt as usize)&0b11111;

		let code: u32 = ((op<<26) | (rs<<21) | (rt<<16) | self.addrImm as usize) as u32;

		if endian == Endian::BIG
		{
			code.to_be_bytes ().to_vec ()
		}
		else
		{
			code.to_le_bytes ().to_vec ()
		}
	}

	pub fn ToAssemblySource (&self) -> String
	{
		unimplemented! ();
	}
}


#[derive (Clone, Copy, Debug, Eq, PartialEq)]
pub struct Mips32JTypeInstruction
{
	opcode: Mips32InstructionOpcode,
	targetAddress: usize,
}

impl Mips32JTypeInstruction
{
	pub fn New (opcode: Mips32InstructionOpcode, targetAddress: usize) -> Self
	{
		Self
		{
			opcode,
			targetAddress,
		}
	}

	// always in big endian
	pub fn ToByteArray (&self, endian: Endian) -> Vec<u8>
	{
		let op = (self.opcode as usize)&0b111111;
		let targetAddress = self.targetAddress&0b1111_1111_1111_1111_1111_1111_11;

		let code: u32 = ((op<<26) | targetAddress) as u32;

		if endian == Endian::BIG
		{
			code.to_be_bytes ().to_vec ()
		}
		else
		{
			code.to_le_bytes ().to_vec ()
		}
	}

	pub fn ToAssemblySource (&self) -> String
	{
		unimplemented! ();
	}
}


#[derive (Clone, Copy, Debug, Eq, PartialEq)]
pub enum Mips32Instruction
{
	RType(Mips32RTypeInstruction),
	IType(Mips32ITypeInstruction),
	JType(Mips32JTypeInstruction),
}

impl Mips32Instruction
{
	pub fn ToByteArray (&self, endian: Endian) -> Vec<u8>
	{
		match self
		{
			Self::RType(instruction) => instruction.ToByteArray (endian),
			Self::IType(instruction) => instruction.ToByteArray (endian),
			Self::JType(instruction) => instruction.ToByteArray (endian),
		}
	}

	pub fn ToAssemblySource (&self) -> String
	{
		match self
		{
			Self::RType(instruction) => instruction.ToAssemblySource (),
			Self::IType(instruction) => instruction.ToAssemblySource (),
			Self::JType(instruction) => instruction.ToAssemblySource (),
		}
	}
}