Skip to content

Instantly share code, notes, and snippets.

/cpu.cpp Secret

Created March 2, 2014 05:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save anonymous/1094c6a7d0e405ba93f3 to your computer and use it in GitHub Desktop.
Save anonymous/1094c6a7d0e405ba93f3 to your computer and use it in GitHub Desktop.
my gist at 2014-03-02 00:36:43 -0500
#include "cpu.h"
#include <iostream>
using namespace std;
typedef unsigned int uint;
typedef unsigned char uchar;
cpu::cpu()
{
}
cpu::cpu(std::string Code, std::string UserKey, std::string FullString)
{
this->Code = Code;
this->Pc = 0; //reset vector at 0
for(int ii = 0; ii < NUM_REG; ii++)
{
this->R[ii] = 0;
}
for(int ii = 0; ii < MEM_SIZE; ii++)
{
this->Memory[ii] = 0;
}
FillMemory(UserKey, FullString);
}
cpu::~cpu()
{
}
void cpu::FillMemory(std::string UserKey, std::string FullString)
{
for(int ii = 0; ii < 8; ii++)
{
Memory[ii] = UserKey[ii];
}
for(int ii = 0; ii < 16; ii++)
{
Memory[8+ii] = FullString[ii];
}
}
uint cpu::GetT6()
{
return R[14];
}
uint cpu::GetT7()
{
return R[15];
}
uint cpu::hexval(char ch)
{
switch(ch)
{
case 'a':
case 'A':
return 10;
case 'b':
case 'B':
return 11;
case 'c':
case 'C':
return 12;
case 'd':
case 'D':
return 13;
case 'e':
case 'E':
return 14;
case 'f':
case 'F':
return 15;
default:
return (uint)(ch-'0');
}
}
uint cpu::hextoint(std::string hex)
{
uint retval = 0;
int string_length = hex.length();
for(int ii = 0; ii < string_length; ii++)
{
char ch = hex[(string_length - ii) - 1];
uint multiplier = 1;
uint chint = hexval(ch);
for(int jj = 0; jj < ii; jj++)
{
multiplier *= 16;
}
retval += chint * multiplier;
}
return retval;
}
instruction cpu::interpretinstruction()
{
instruction result;
if(this->Pc > (this->Code.length() - 4))
{
result.opcode = 255;
return result; //halt opcode because it's not enough to construct a complete instruction
}
result.opcode = (hextoint(this->Code.substr(this->Pc, 2))) >> 2; //bits 0-5
result.rs = (hextoint(this->Code.substr(this->Pc + 1, 2)) >> 1) & 0x1F; //bits 6-10
result.rt = (hextoint(this->Code.substr(this->Pc + 2, 2))) & 0x1F; //bits 11-15
result.rd = hextoint(this->Code.substr(this->Pc + 4, 2)) >> 3; //bits 16-20
result.shift = (hextoint(this->Code.substr(this->Pc + 5, 2)) >> 2) &0x1F; //bits 21-25
result.funct = hextoint(this->Code.substr(this->Pc + 6, 2)) & 0x3F; //bits 26-31
result.immediate = hextoint(this->Code.substr(this->Pc + 4, 4)); //bits 16-31
result.address = hextoint(this->Code.substr(this->Pc + 1, 7)) & 0x3FFFFF; //bits 0-25
this->Pc += 8;
return result;
}
int cpu::NumberOfSetBits(uint i)
{
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}
void cpu::Execute()
{
instruction instr;
while((instr = interpretinstruction()).opcode != 255)
{
uint diff = 0;
switch (instr.opcode)
{
case 0x00: //R-Type operations
{
switch (instr.funct) //different R-Types all have the same opcode
{
case 0x20: //add
case 0x21: //addu
{
uint initial = this->R[instr.rd];
this->R[instr.rd] = this->R[instr.rs] + this->R[instr.rt];
diff = NumberOfSetBits(initial ^ this->R[instr.rd]);
break;
}
case 0x24: //and
{
uint initial = this->R[instr.rd];
this->R[instr.rd] = this->R[instr.rs] & this->R[instr.rt];
diff = NumberOfSetBits(initial ^ this->R[instr.rd]);
break;
}
case 0x1A: //div
case 0x1B: //divu
{
this->Lo = this->R[instr.rs] / this->R[instr.rt];
this->Hi = this->R[instr.rs] % this->R[instr.rt];
break;
}
case 0x08: //jr
{
uint initial = this->R[instr.rs];
this->Pc = this->R[instr.rs];
diff = NumberOfSetBits(initial ^ this->Pc);
break;
}
case 0x10: //mfhi
{
this->R[instr.rd] = this->Hi;
break;
}
case 0x12: //mflo
{
this->R[instr.rd] = this->Lo;
break;
}
case 0x18: //mult
case 0x19: //multu
{
this->Lo = this->R[instr.rs] * this->R[instr.rt];
break;
}
case 0x27: //nor
{
uint initial = this->R[instr.rd];
this->R[instr.rd] = ~(this->R[instr.rs] | this->R[instr.rt]);
diff = NumberOfSetBits(initial ^ this->R[instr.rd]);
break;
}
case 0x26: //xor
{
uint initial = this->R[instr.rd];
this->R[instr.rd] = this->R[instr.rs] ^ this->R[instr.rt];
diff = NumberOfSetBits(initial ^ this->R[instr.rd]);
break;
}
case 0x25: //or
{
uint initial = this->R[instr.rd];
this->R[instr.rd] = this->R[instr.rs] | this->R[instr.rt];
diff = NumberOfSetBits(initial ^ this->R[instr.rd]);
break;
}
case 0x2A: //slt
{
uint initial = this->R[instr.rd];
this->R[instr.rd] = 0;
if(this->R[instr.rs] < this->R[instr.rt])
{
this->R[instr.rd] = 1;
}
diff = NumberOfSetBits(initial ^ this->R[instr.rd]);
break;
}
case 0x2B: //sltu
{
uint initial = this->R[instr.rd];
this->R[instr.rd] = 0;
if((uint)this->R[instr.rs] < (uint)this->R[instr.rt])
{
this->R[instr.rd] = 1;
}
diff = NumberOfSetBits(initial ^ this->R[instr.rd]);
break;
}
case 0x00: //sll
{
uint initial = this->R[instr.rd];
this->R[instr.rd] = this->R[instr.rt] << instr.shift;
diff = NumberOfSetBits(initial ^ this->R[instr.rd]);
break;
}
case 0x02: //srl
{
uint initial = this->R[instr.rd];
this->R[instr.rd] = this->R[instr.rt] >> instr.shift;
diff = NumberOfSetBits(initial ^ this->R[instr.rd]);
break;
}
case 0x03: //sra (omg, hax)
{
uint initial = this->R[instr.rd];
bool hax = false;
if((this->R[instr.rt] & 0x8000000) != 0)
{
hax = true;
}
this->R[instr.rd] = this->R[instr.rt] >> instr.shift;
if(hax)
{
int andme = -1;
andme = andme << (32 - instr.shift);
this->R[instr.rd] &= andme;
}
diff = NumberOfSetBits(initial ^ this->R[instr.rd]);
break;
}
case 0x22: //sub
{
uint initial = this->R[instr.rd];
this->R[instr.rd] = this->R[instr.rs] - this->R[instr.rt];
diff = NumberOfSetBits(initial ^ this->R[instr.rd]);
break;
}
case 0x23: //subu
{
uint initial = this->R[instr.rd];
this->R[instr.rd] = (int)((uint)this->R[instr.rs] - (uint)this->R[instr.rt]);
diff = NumberOfSetBits(initial ^ this->R[instr.rd]);
break;
}
default: //i don't know what the user tried to do here
{
break;
}
}
}
break;
case 0x02: //j
{
uint initial = this->Pc;
this->Pc = ((this->Pc & 0xf0000000) | (instr.address << 2));
diff = NumberOfSetBits(initial ^ this->Pc);
break;
}
case 0x03: //jal
{
uint initial = this->Pc;
uint initial2 = this->R[31];
this->R[31] = this->Pc; //load up the linking register
this->Pc = ((this->Pc & 0xf0000000) | (instr.address << 2));
diff = NumberOfSetBits(initial ^ this->Pc);
diff += NumberOfSetBits(initial2 ^ this->R[31]);
break;
}
case 0x04: //beq branches are absolute in this cpu
{
uint initial = this->Pc;
if(this->R[instr.rs] == this->R[instr.rt])
{
this->Pc = instr.immediate << 3;
}
diff = NumberOfSetBits(initial ^ this->Pc);
break;
}
case 0x05: //bne this is not done the "mips way" branches are absolute here
{
uint initial = this->Pc;
if(this->R[instr.rs] != this->R[instr.rt])
{
this->Pc = instr.immediate << 3;
}
diff = NumberOfSetBits(initial ^ this->Pc);
break;
}
case 0x08: //addi
case 0x09: //addiu
{
uint initial = this->R[instr.rt];
this->R[instr.rt] = this->R[instr.rs] + instr.immediate;
diff = NumberOfSetBits(initial ^ this->R[instr.rt]);
break;
}
case 0x0A: //slti
case 0x0B: //sltiu
{
uint initial = this->R[instr.rt];
if(this->R[instr.rs] < this->R[instr.immediate])
{
this->R[instr.rt] = 1;
}
else
{
this->R[instr.rt] = 0;
}
diff = NumberOfSetBits(initial ^ this->R[instr.rt]);
break;
}
case 0x0C: //andi
{
uint initial = this->R[instr.rt];
this->R[instr.rt] = this->R[instr.rs] & instr.immediate;
diff = NumberOfSetBits(initial ^ this->R[instr.rt]);
break;
}
case 0x0D: //ori
{
uint initial = this->R[instr.rt];
this->R[instr.rt] = this->R[instr.rs] | instr.immediate;
diff = NumberOfSetBits(initial ^ this->R[instr.rt]);
break;
}
case 0x23: //lw
{
uint initial = this->R[instr.rt];
this->R[instr.rt] = (this->Memory[instr.immediate + instr.rs + 3]) +
(this->Memory[instr.immediate + instr.rs + 2] << 8) +
(this->Memory[instr.immediate + instr.rs + 1] << 16) +
(this->Memory[instr.immediate + instr.rs] << 24);
diff = NumberOfSetBits(initial ^ this->R[instr.rt]);
break;
}
case 0x24: //lbu
{
uint initial = this->R[instr.rt];
this->R[instr.rt] = this->Memory[instr.immediate + instr.rs];
diff = NumberOfSetBits(initial ^ this->R[instr.rt]);
break;
}
case 0x25: //lhu
{
uint initial = this->R[instr.rt];
this->R[instr.rt] = (this->Memory[instr.immediate + instr.rs] << 8) + (this->Memory[instr.immediate + instr.rs + 1]);
diff = NumberOfSetBits(initial ^ this->R[instr.rt]);
break;
}
case 0x28: //sb
{
uint initial = this->Memory[instr.immediate + instr.rs];
this->Memory[instr.immediate + instr.rs] = (uchar)(this->R[instr.rt] & 0xFF);
diff = NumberOfSetBits(initial ^ this->Memory[instr.immediate + instr.rs]);
break;
}
case 0x29: //shu
{
int stored = this->R[instr.rt];
char ch[2];
ch[0] = (stored >> 8) & 0xFF;
ch[1] = stored & 0xFF;
for(int ii = 0; ii < 2; ii++)
{
diff += NumberOfSetBits(ch[ii] ^ this->Memory[instr.immediate + instr.rs + ii]);
this->Memory[instr.immediate + instr.rs + ii] = ch[ii];
}
break;
}
case 0x2B: //sw
{
int stored = this->R[instr.rt];
char ch[4];
ch[0] = stored >> 24 & 0xFF;
ch[1] = (stored >> 16) & 0xFF;
ch[2] = (stored >> 8) & 0xFF;
ch[3] = stored & 0xFF;
for(int ii = 0; ii < 4; ii++)
{
diff += NumberOfSetBits(ch[ii] ^ this->Memory[instr.immediate + instr.rs + ii]);
this->Memory[instr.immediate + instr.rs + ii] = ch[ii];
}
break;
}
default:
break;
}
cout << diff << "," << ends;
this->R[0] = 0; //hardwired to 0. this is as close as I can get to that :-)
}
cout << "0" << endl;
}
#ifndef __CPU__
#define __CPU__
#include <string>
#include "instruction.h"
#define NUM_REG 32
#define MEM_SIZE 8196
class cpu
{
typedef unsigned int uint;
typedef unsigned char uchar;
public:
cpu();
cpu(std::string Code, std::string UserKey, std::string FullString);
~cpu();
void Execute();
uint GetT6();
uint GetT7();
private:
uint R[NUM_REG]; //32
uint Hi;
uint Lo;
uchar Memory[MEM_SIZE];
uint Pc;
instruction instr;
std::string Code;
std::string UserKey;
uint hexval(char ch);
uint hextoint(std::string hex);
instruction interpretinstruction();
void FillMemory(std::string UserKey, std::string FullString);
int NumberOfSetBits(uint i);
};
#endif
require 'sinatra'
require 'shellwords'
set :public_folder, File.dirname(__FILE__) + '/static'
set :bind, '0.0.0.0'
get "/u/:username" do
exec = `./graph #{Shellwords.shellescape(params[:username])}`
m = exec.split(",")
str = "var myData = new Array("
count = 0
m.each{|ii|
if ii[1..-1].length == 0
x = "0"
else
x = ii[1..-1]
end
s = "[#{count},#{x}],"
str << s
count = count + 1
}
str = str[0..-2]
str << ");"
@data = str
erb :index
end
#include "instruction.h"
instruction::instruction()
{
}
instruction::instruction(uint opcode, uint rs, uint rt, uint rd, uint immediate,
uint shift, uint funct, uint address)
{
this->opcode = opcode;
this->rs = rs;
this->rt = rt;
this->rd = rd;
this->immediate = immediate;
this->shift = shift;
this->funct = funct;
this->address = address;
}
instruction::~instruction()
{
}
#ifndef __INSTRUCTION__
#define __INSTRUCTION__
#include <iostream>
class instruction
{
typedef unsigned int uint;
public:
instruction();
instruction(uint opcode, uint rs, uint rt, uint rd, uint immediate,
uint shift,uint funct, uint address);
~instruction();
uint opcode;
uint rs;
uint rt;
uint rd;
uint immediate;
uint shift;
uint funct;
uint address;
};
#endif
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include "cpu.h"
using namespace std;
typedef unsigned int uint;
typedef unsigned char uchar;
void printusage(char*);
void printconstraints(char*);
bool check(int, int, int, int);
int main(int argc, char** argv)
{
if(argc < 2)
{
printusage(argv[0]);
exit(1);
}
int namelen = strlen(argv[1]);
if(namelen < 16)
{
printconstraints(argv[1]);
exit(1);
}
// int tok1 = strtoul(argv[2], NULL, 0);
// int tok2 = strtoul(argv[3], NULL, 0);
std::string username(argv[1]);
// std::string fullkey = std::string(username.rbegin(), username.rend());
std::string fullkey = "AAAAAAAAAAAAAAAA";
cpu* libdrm = new cpu("000048202129009E00094a002129003700094a002129007900094a00212900b900005020000040208c1800088C17000C8C1600108c0b00148c0f00008c0e000401094020000ea1000298a02001c89820000e914202579020027288260234882601f17820000fa1000296a02001e89820000f9142024b9020027288260234882601d1702020100020214a000115500010", username, fullkey);
libdrm->Execute();
uint t6 = libdrm->GetT6();
uint t7 = libdrm->GetT7();
delete libdrm;
/*
if(check(t6, t7, tok1, tok2))
{
std::cout << "*<:-)" << std::endl;
}
else
{
std::cout << ":-(" << std::endl;
}
*/
return 0;
}
bool check(int t6, int t7, int tok1, int tok2)
{
uint temp1 = tok1 ^ 0x31333337;
uchar ch1 = ((tok2 & 0xFF000000) >> 24);
uchar ch2 = ((tok2 & 0x00FF0000) >> 16);
uchar ch3 = ((tok2 & 0x0000FF00) >> 8);
uchar ch4 = (tok2 & 0x000000FF);
uint temp2 = ch2 << 24;
temp2 |= (ch3 << 16);
temp2 |= (ch1 << 8);
temp2 |= (ch4);
if(t6 == temp1 && t7 == temp2)
{
return true;
}
return false;
}
void printusage(char* progname)
{
std::cout << "usage: " << progname << " <username>" << std::endl;
}
void printconstraints(char* username)
{
std::cout << "error: " << username << " is not a valid username" << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment