module exploit #( parameter DELAY_FRAMES = 234 // 27,000,000 (27Mhz) / 115200 Baud rate ) ( // exploit input clk_in, output power_tx, output [5:0] led, // uart input clk, input btn1, input uart_rx, output uart_tx ); ////////// EXPLOIT localparam INSTRUCTION_OFFSET = 100; // da official exploit code localparam EXPLOIT_BYTES = {8'h5D,8'h5D,8'h5D,8'h5D}; //// glitch logic localparam EXPLOIT_BYTES_LEN = $bits(EXPLOIT_BYTES)-1; // $bits() seems to work // https://www.linkedin.com/pulse/bits-clog2-size-uses-differences-muhammed-kawser-ahmed localparam LEDS_ON = 0; localparam LEDS_OFF = 6'b111111; reg [1:0] power_tx_reg = 1; reg [1:0] led_run = 1; reg [1:0] rst = 0; reg [1:0] running = 1; reg [5:0] ledCounter = 0; reg [23:0] instruction_counter = 0; reg [23:0] exploit_tx_count = 0; reg [EXPLOIT_BYTES_LEN:0] exploit_bytes_reg = EXPLOIT_BYTES; always @(posedge clk_in) begin if(rst == 1) begin running = 1; power_tx_reg = 1; rst = 0; end if(instruction_counter == INSTRUCTION_OFFSET) begin power_tx_reg = 0; rst = 1; end if(running == 1) begin if(instruction_counter >= INSTRUCTION_OFFSET && instruction_counter <= INSTRUCTION_OFFSET+EXPLOIT_BYTES_LEN) begin led_run <= 1; end else begin led_run <= 0; end if(led_run == 1) begin ledCounter <= ledCounter + 1; if(ledCounter == LEDS_OFF) begin ledCounter <= LEDS_ON; end end if(instruction_counter == INSTRUCTION_OFFSET+EXPLOIT_BYTES_LEN) begin ledCounter <= LEDS_ON; rst = 1; running = 0; end instruction_counter <= instruction_counter + 1; end end //// uart rx // uart shit ganked from https://raw.githubusercontent.com/lushaylabs/tangnano9k-series-examples/ // of https://learn.lushaylabs.com localparam HALF_DELAY_WAIT = (DELAY_FRAMES / 2); reg [3:0] rxState = 0; reg [12:0] rxCounter = 0; reg [7:0] dataIn = 0; reg [2:0] rxBitNumber = 0; reg byteReady = 0; localparam RX_STATE_IDLE = 0; localparam RX_STATE_START_BIT = 1; localparam RX_STATE_READ_WAIT = 2; localparam RX_STATE_READ = 3; localparam RX_STATE_STOP_BIT = 5; always @(posedge clk) begin case (rxState) RX_STATE_IDLE: begin if (uart_rx == 0) begin rxState <= RX_STATE_START_BIT; rxCounter <= 1; rxBitNumber <= 0; byteReady <= 0; end end RX_STATE_START_BIT: begin if (rxCounter == HALF_DELAY_WAIT) begin rxState <= RX_STATE_READ_WAIT; rxCounter <= 1; end else rxCounter <= rxCounter + 1; end RX_STATE_READ_WAIT: begin rxCounter <= rxCounter + 1; if ((rxCounter + 1) == DELAY_FRAMES) begin rxState <= RX_STATE_READ; end end RX_STATE_READ: begin rxCounter <= 1; dataIn <= {uart_rx, dataIn[7:1]}; rxBitNumber <= rxBitNumber + 1; if (rxBitNumber == 3'b111) rxState <= RX_STATE_STOP_BIT; else rxState <= RX_STATE_READ_WAIT; end RX_STATE_STOP_BIT: begin rxCounter <= rxCounter + 1; if ((rxCounter + 1) == DELAY_FRAMES) begin rxState <= RX_STATE_IDLE; rxCounter <= 0; byteReady <= 1; end end endcase end //// uart tx reg [3:0] txState = 0; reg [24:0] txCounter = 0; reg [1:0] txPinRegister = 1; reg [2:0] txBitNumber = 0; reg [3:0] txByteCounter = 0; localparam MEMORY_LENGTH = 5; localparam TX_STATE_IDLE = 0; localparam TX_STATE_START_BIT = 1; localparam TX_STATE_WRITE = 2; localparam TX_STATE_STOP_BIT = 3; localparam TX_STATE_DEBOUNCE = 4; always @(posedge clk) begin case (txState) TX_STATE_IDLE: begin if (btn1 == 0) begin txState <= TX_STATE_START_BIT; txCounter <= 0; txByteCounter <= 0; end else begin txPinRegister <= 1; end end TX_STATE_START_BIT: begin txPinRegister <= 0; if ((txCounter + 1) == DELAY_FRAMES) begin txState <= TX_STATE_WRITE; txBitNumber <= 0; txCounter <= 0; end else txCounter <= txCounter + 1; end TX_STATE_WRITE: begin txPinRegister <= exploit_bytes_reg[txBitNumber]; if ((txCounter + 1) == DELAY_FRAMES) begin if (txBitNumber == 7) begin txState <= TX_STATE_STOP_BIT; end else begin txState <= TX_STATE_WRITE; txBitNumber <= txBitNumber + 1; end txCounter <= 0; end else txCounter <= txCounter + 1; end TX_STATE_STOP_BIT: begin txPinRegister <= 1; if ((txCounter + 1) == DELAY_FRAMES) begin if (txByteCounter == MEMORY_LENGTH - 1) begin txState <= TX_STATE_DEBOUNCE; end else begin txByteCounter <= txByteCounter + 1; txState <= TX_STATE_START_BIT; end txCounter <= 0; end else txCounter <= txCounter + 1; end TX_STATE_DEBOUNCE: begin if (txCounter == 23'b111111111111111111) begin if (btn1 == 1) txState <= TX_STATE_IDLE; end else txCounter <= txCounter + 1; end endcase end // assigns to output assign led = ledCounter; assign power_tx = power_tx_reg; assign uart_tx = txPinRegister; endmodule