Adding EzLogic challenge of 0ctf on. Will add sim guide later.

This commit is contained in:
Tempest 2024-12-21 21:44:09 +07:00
parent d2610bfbe1
commit 9e22bdef3b
22 changed files with 9962 additions and 0 deletions

1404
0ctf/EzLogic/EzLogic.vvp Normal file

File diff suppressed because it is too large Load Diff

1519
0ctf/EzLogic/EzLogic_tb.vcd Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
`ifdef verilator3
`else
`timescale 1 ps / 1 ps
`endif
//
// BUFG primitive for Xilinx FPGAs
// Compatible with Verilator tool (www.veripool.org)
// Copyright (c) 2019-2022 Frédéric REQUIN
// License : BSD
//
/*verilator coverage_off*/
module BUFG
(
input I,
output O /* verilator clocker */
);
assign O = I;
endmodule
/*verilator coverage_on*/

View File

@ -0,0 +1,38 @@
`ifdef verilator3
`else
`timescale 1 ps / 1 ps
`endif
//
// CARRY4 primitive for Xilinx FPGAs
// Compatible with Verilator tool (www.veripool.org)
// Copyright (c) 2019-2022 Frédéric REQUIN
// License : BSD
//
/* verilator coverage_off */
module CARRY4
(
// Carry cascade input
input wire CI,
//
input wire CYINIT,
// Carry MUX data input
input wire [3:0] DI,
// Carry MUX select line
input wire [3:0] S,
// Carry out of each stage of the chain
output wire [3:0] CO,
// Carry chain XOR general data out
output wire [3:0] O
);
wire _w_CO0 = S[0] ? CI | CYINIT : DI[0];
wire _w_CO1 = S[1] ? _w_CO0 : DI[1];
wire _w_CO2 = S[2] ? _w_CO1 : DI[2];
wire _w_CO3 = S[3] ? _w_CO2 : DI[3];
assign CO = { _w_CO3, _w_CO2, _w_CO1, _w_CO0 };
assign O = S ^ { _w_CO2, _w_CO1, _w_CO0, CI | CYINIT };
endmodule
/* verilator coverage_on */

View File

@ -0,0 +1,69 @@
`ifdef verilator3
`else
`timescale 1 ps / 1 ps
`endif
//
// FDCE primitive for Xilinx FPGAs
// Compatible with Verilator tool (www.veripool.org)
// Copyright (c) 2019-2022 Frédéric REQUIN
// License : BSD
//
/* verilator coverage_off */
module FDCE
#(
parameter [0:0] IS_C_INVERTED = 1'b0,
parameter [0:0] IS_D_INVERTED = 1'b0,
parameter [0:0] IS_CLR_INVERTED = 1'b0,
parameter [0:0] INIT = 1'b0
)
(
// Clock
input wire C,
// Clock enable
input wire CE,
// Asynchronous clear
input wire CLR,
// Data in
input wire D,
// Data out
output wire Q
);
reg _r_Q;
wire _w_CLR = CLR ^ IS_CLR_INVERTED;
wire _w_D = D ^ IS_D_INVERTED;
initial begin : INIT_STATE
_r_Q = INIT[0];
end
generate
if (IS_C_INVERTED) begin : GEN_CLK_NEG
always @(negedge C or posedge _w_CLR) begin
if (_w_CLR) begin
_r_Q <= 1'b0;
end
else if (CE) begin
_r_Q <= _w_D;
end
end
end
else begin : GEN_CLK_POS
always @(posedge C or posedge _w_CLR) begin
if (_w_CLR) begin
_r_Q <= 1'b0;
end
else if (CE) begin
_r_Q <= _w_D;
end
end
end
endgenerate
assign Q = _r_Q;
endmodule
/* verilator coverage_on */

View File

@ -0,0 +1,21 @@
`ifdef verilator3
`else
`timescale 1 ps / 1 ps
`endif
//
// GND primitive for Xilinx FPGAs
// Compatible with Verilator tool (www.veripool.org)
// Copyright (c) 2019-2022 Frédéric REQUIN
// License : BSD
//
/* verilator coverage_off */
module GND
(
output wire G
);
assign G = 1'b0;
endmodule
/* verilator coverage_on */

View File

@ -0,0 +1,6 @@
module IBUF(
input wire I,
output wire O
);
assign O = I;
endmodule

View File

@ -0,0 +1,24 @@
`ifdef verilator3
`else
`timescale 1 ps / 1 ps
`endif
//
// LUT1 primitive for Xilinx FPGAs
// Compatible with Verilator tool (www.veripool.org)
// Copyright (c) 2019-2022 Frédéric REQUIN
// License : BSD
//
/* verilator coverage_off */
module LUT1
#(
parameter [1:0] INIT = 2'b00
)
(
input wire I0,
output wire O
);
assign O = INIT[I0];
endmodule
/* verilator coverage_on */

View File

@ -0,0 +1,26 @@
`ifdef verilator3
`else
`timescale 1 ps / 1 ps
`endif
//
// LUT2 primitive for Xilinx FPGAs
// Compatible with Verilator tool (www.veripool.org)
// Copyright (c) 2019-2022 Frédéric REQUIN
// License : BSD
//
/* verilator coverage_off */
module LUT2
#(
parameter [3:0] INIT = 4'b0000
)
(
input wire I0, I1,
output wire O
);
wire [1:0] _w_idx = { I1, I0 };
assign O = INIT[_w_idx];
endmodule
/* verilator coverage_on */

View File

@ -0,0 +1,26 @@
`ifdef verilator3
`else
`timescale 1 ps / 1 ps
`endif
//
// LUT3 primitive for Xilinx FPGAs
// Compatible with Verilator tool (www.veripool.org)
// Copyright (c) 2019-2022 Frédéric REQUIN
// License : BSD
//
/* verilator coverage_off */
module LUT3
#(
parameter [7:0] INIT = 8'b00000000
)
(
input wire I0, I1, I2,
output wire O
);
wire [2:0] _w_idx = { I2, I1, I0 };
assign O = INIT[_w_idx];
endmodule
/* verilator coverage_on */

View File

@ -0,0 +1,26 @@
`ifdef verilator3
`else
`timescale 1 ps / 1 ps
`endif
//
// LUT4 primitive for Xilinx FPGAs
// Compatible with Verilator tool (www.veripool.org)
// Copyright (c) 2019-2022 Frédéric REQUIN
// License : BSD
//
/* verilator coverage_off */
module LUT4
#(
parameter [15:0] INIT = 16'h0000
)
(
input wire I0, I1, I2, I3,
output wire O
);
wire [3:0] _w_idx = { I3, I2, I1, I0 };
assign O = INIT[_w_idx];
endmodule
/* verilator coverage_on */

View File

@ -0,0 +1,26 @@
`ifdef verilator3
`else
`timescale 1 ps / 1 ps
`endif
//
// LUT5 primitive for Xilinx FPGAs
// Compatible with Verilator tool (www.veripool.org)
// Copyright (c) 2019-2022 Frédéric REQUIN
// License : BSD
//
/* verilator coverage_off */
module LUT5
#(
parameter [31:0] INIT = 32'h00000000
)
(
input wire I0, I1, I2, I3, I4,
output wire O
);
wire [4:0] _w_idx = { I4, I3, I2, I1, I0 };
assign O = INIT[_w_idx];
endmodule
/* verilator coverage_on */

View File

@ -0,0 +1,26 @@
`ifdef verilator3
`else
`timescale 1 ps / 1 ps
`endif
//
// LUT6 primitive for Xilinx FPGAs
// Compatible with Verilator tool (www.veripool.org)
// Copyright (c) 2019-2022 Frédéric REQUIN
// License : BSD
//
/* verilator coverage_off */
module LUT6
#(
parameter [63:0] INIT = 64'h0000000000000000
)
(
input wire I0, I1, I2, I3, I4, I5,
output wire O
);
wire [5:0] _w_idx = { I5, I4, I3, I2, I1, I0 };
assign O = INIT[_w_idx];
endmodule
/* verilator coverage_on */

View File

@ -0,0 +1,17 @@
`ifdef verilator3
`else
`timescale 1 ps / 1 ps
`endif
/* verilator coverage_off */
module MUXF7
(
input wire I0, I1, S,
output wire O
);
wire [1:0] w_data = { I1, I0 };
assign O = w_data[S];
endmodule
/* verilator coverage_on */

View File

@ -0,0 +1,17 @@
`ifdef verilator3
`else
`timescale 1 ps / 1 ps
`endif
/* verilator coverage_off */
module MUXF8
(
input wire I0, I1, S,
output wire O
);
wire [1:0] w_data = { I1, I0 };
assign O = w_data[S];
endmodule
/* verilator coverage_on */

View File

@ -0,0 +1,6 @@
module OBUF(
input wire I,
output wire O
);
assign O = I;
endmodule

View File

@ -0,0 +1,21 @@
`ifdef verilator3
`else
`timescale 1 ps / 1 ps
`endif
//
// VCC primitive for Xilinx FPGAs
// Compatible with Verilator tool (www.veripool.org)
// Copyright (c) 2019-2022 Frédéric REQUIN
// License : BSD
//
/* verilator coverage_off */
module VCC
(
output wire P
);
assign P = 1'b1;
endmodule
/* verilator coverage_on */

Binary file not shown.

View File

@ -0,0 +1,91 @@
`timescale 1us / 100ns
module EzLogic_tb #(
parameter FLAG_TO_TEST = "o0",
parameter N = 42
)();
reg clk;
reg rst_n;
reg valid_in;
reg start;
reg [7:0] data_in;
reg [6:0] counter;
reg [6:0] counter2;
wire [7:0] data_out;
wire valid_out;
reg [0:8*N-1] data_out_all;
wire success;
wire [7:0] flag_test_arr [0:N-1];
genvar i;
generate
for (i=0;i<N;i=i+1) begin
assign flag_test_arr[N-1-i] = FLAG_TO_TEST[(i*8)+:8];
end
endgenerate
EzLogic_top inst(
.clk(clk),
.rst_n(rst_n),
.data_in(data_in),
.valid_in(valid_in),
.data_out(data_out),
.valid_out(valid_out)
);
initial begin
$dumpfile("EzLogic_tb.vcd");
$dumpvars(0, EzLogic_tb);
clk = 0;
rst_n = 0;
data_in = 0;
valid_in = 0;
counter = 0;
counter2 = 0;
start = 0;
data_out_all = 0;
#4
rst_n = 1;
start = 1;
@(negedge start);
#4
if (success) begin
$display("Great! You've found the correct flag!");
end
else begin
$display("Binary Data: %b", data_out_all);
$display("Binary Data: %b", data_std);
$display("Hexadecimal Data: %h", data_out_all);
$display("Haha, try again!");
end
#20
$finish();
end
always @(posedge clk) begin
if (start == 1) begin
if (counter < N) begin
counter <= counter + 1;
data_in <= flag_test_arr[counter];
valid_in <= 1;
end
else begin
data_in <= 0;
valid_in <= 0;
start <= 0;
end
end
end
always @(posedge clk) begin
if (valid_out) begin
counter2 <= counter2 + 1;
data_out_all[(counter2)*8 +: 8] <= data_out;
end
end
wire [0:8*N-1] data_std = 'h30789d5692f2fe23bb2c5d9e16406653b6cb217c952998ce17b7143788d949952680b4bce4c30a96c753;
assign success = (data_std == data_out_all);
always #1 clk = ~clk;
endmodule

View File

@ -0,0 +1,270 @@
// Copyright 1986-2020 Xilinx, Inc. All Rights Reserved.
// --------------------------------------------------------------------------------
// Tool Version: Vivado v.2020.2 (win64) Build 3064766 Wed Nov 18 09:12:45 MST 2020
// Date : Sat Aug 31 17:14:12 2024
// Host : DESKTOP-9V3OCBF running 64-bit major release (build 9200)
// Command : write_verilog -force EzLogic_top_synth.v
// Design : EzLogic_top
// Purpose : This is a Verilog netlist of the current design or from a specific cell of the design. The output is an
// IEEE 1364-2001 compliant Verilog HDL file that contains netlist information obtained from the input
// design files.
// Device : xc7z010iclg225-1L
// --------------------------------------------------------------------------------
`timescale 1 ps / 1 ps
(* STRUCTURAL_NETLIST = "yes" *)
module EzLogic_top
(clk,
rst_n,
data_in,
valid_in,
data_out,
valid_out);
input clk;
input rst_n;
input [7:0]data_in;
input valid_in;
output [7:0]data_out;
output valid_out;
wire \<const0> ;
wire \<const1> ;
wire clk;
wire clk_IBUF;
wire clk_IBUF_BUFG;
wire [7:0]data_in;
wire [7:0]data_in_IBUF;
wire [7:0]data_out;
wire [7:0]data_out_OBUF;
wire \data_reg[3]_i_2_n_0 ;
wire \data_reg[3]_i_3_n_0 ;
wire \data_reg[3]_i_4_n_0 ;
wire \data_reg[3]_i_5_n_0 ;
wire \data_reg[7]_i_2_n_0 ;
wire \data_reg[7]_i_3_n_0 ;
wire \data_reg[7]_i_4_n_0 ;
wire \data_reg[7]_i_5_n_0 ;
wire \data_reg[7]_i_6_n_0 ;
wire \data_reg_reg[3]_i_1_n_0 ;
wire \data_reg_reg[3]_i_1_n_1 ;
wire \data_reg_reg[3]_i_1_n_2 ;
wire \data_reg_reg[3]_i_1_n_3 ;
wire \data_reg_reg[7]_i_1_n_1 ;
wire \data_reg_reg[7]_i_1_n_2 ;
wire \data_reg_reg[7]_i_1_n_3 ;
wire [7:0]p_0_in;
wire rst_n;
wire rst_n_IBUF;
wire valid_in;
wire valid_in_IBUF;
wire valid_out;
wire valid_out_OBUF;
GND GND
(.G(\<const0> ));
VCC VCC
(.P(\<const1> ));
BUFG clk_IBUF_BUFG_inst
(.I(clk_IBUF),
.O(clk_IBUF_BUFG));
IBUF clk_IBUF_inst
(.I(clk),
.O(clk_IBUF));
IBUF \data_in_IBUF[0]_inst
(.I(data_in[0]),
.O(data_in_IBUF[0]));
IBUF \data_in_IBUF[1]_inst
(.I(data_in[1]),
.O(data_in_IBUF[1]));
IBUF \data_in_IBUF[2]_inst
(.I(data_in[2]),
.O(data_in_IBUF[2]));
IBUF \data_in_IBUF[3]_inst
(.I(data_in[3]),
.O(data_in_IBUF[3]));
IBUF \data_in_IBUF[4]_inst
(.I(data_in[4]),
.O(data_in_IBUF[4]));
IBUF \data_in_IBUF[5]_inst
(.I(data_in[5]),
.O(data_in_IBUF[5]));
IBUF \data_in_IBUF[6]_inst
(.I(data_in[6]),
.O(data_in_IBUF[6]));
IBUF \data_in_IBUF[7]_inst
(.I(data_in[7]),
.O(data_in_IBUF[7]));
OBUF \data_out_OBUF[0]_inst
(.I(data_out_OBUF[0]),
.O(data_out[0]));
OBUF \data_out_OBUF[1]_inst
(.I(data_out_OBUF[1]),
.O(data_out[1]));
OBUF \data_out_OBUF[2]_inst
(.I(data_out_OBUF[2]),
.O(data_out[2]));
OBUF \data_out_OBUF[3]_inst
(.I(data_out_OBUF[3]),
.O(data_out[3]));
OBUF \data_out_OBUF[4]_inst
(.I(data_out_OBUF[4]),
.O(data_out[4])); OBUF \data_out_OBUF[5]_inst
(.I(data_out_OBUF[5]),
.O(data_out[5]));
OBUF \data_out_OBUF[6]_inst
(.I(data_out_OBUF[6]),
.O(data_out[6]));
OBUF \data_out_OBUF[7]_inst
(.I(data_out_OBUF[7]),
.O(data_out[7]));
LUT2 #(
.INIT(4'h6))
\data_reg[3]_i_2
(.I0(data_out_OBUF[5]),
.I1(data_in_IBUF[3]),
.O(\data_reg[3]_i_2_n_0 ));
LUT2 #(
.INIT(4'h6))
\data_reg[3]_i_3
(.I0(data_out_OBUF[6]),
.I1(data_in_IBUF[2]),
.O(\data_reg[3]_i_3_n_0 ));
LUT2 #(
.INIT(4'h6))
\data_reg[3]_i_4
(.I0(data_out_OBUF[2]),
.I1(data_in_IBUF[1]),
.O(\data_reg[3]_i_4_n_0 ));
LUT2 #(
.INIT(4'h6))
\data_reg[3]_i_5
(.I0(data_out_OBUF[4]),
.I1(data_in_IBUF[0]),
.O(\data_reg[3]_i_5_n_0 ));
LUT1 #(
.INIT(2'h1))
\data_reg[7]_i_2
(.I0(rst_n_IBUF),
.O(\data_reg[7]_i_2_n_0 ));
LUT2 #(
.INIT(4'h6))
\data_reg[7]_i_3
(.I0(data_out_OBUF[7]),
.I1(data_in_IBUF[7]),
.O(\data_reg[7]_i_3_n_0 ));
LUT2 #(
.INIT(4'h6))
\data_reg[7]_i_4
(.I0(data_out_OBUF[0]),
.I1(data_in_IBUF[6]),
.O(\data_reg[7]_i_4_n_0 ));
LUT2 #(
.INIT(4'h6))
\data_reg[7]_i_5
(.I0(data_out_OBUF[3]),
.I1(data_in_IBUF[5]),
.O(\data_reg[7]_i_5_n_0 ));
LUT2 #(
.INIT(4'h6))
\data_reg[7]_i_6
(.I0(data_out_OBUF[1]),
.I1(data_in_IBUF[4]),
.O(\data_reg[7]_i_6_n_0 ));
FDCE #(
.INIT(1'b0))
\data_reg_reg[0]
(.C(clk_IBUF_BUFG),
.CE(valid_in_IBUF),
.CLR(\data_reg[7]_i_2_n_0 ),
.D(p_0_in[0]),
.Q(data_out_OBUF[0]));
FDCE #(
.INIT(1'b0))
\data_reg_reg[1]
(.C(clk_IBUF_BUFG),
.CE(valid_in_IBUF),
.CLR(\data_reg[7]_i_2_n_0 ),
.D(p_0_in[1]),
.Q(data_out_OBUF[1]));
FDCE #(
.INIT(1'b0))
\data_reg_reg[2]
(.C(clk_IBUF_BUFG),
.CE(valid_in_IBUF),
.CLR(\data_reg[7]_i_2_n_0 ),
.D(p_0_in[2]),
.Q(data_out_OBUF[2]));
FDCE #(
.INIT(1'b0))
\data_reg_reg[3]
(.C(clk_IBUF_BUFG),
.CE(valid_in_IBUF),
.CLR(\data_reg[7]_i_2_n_0 ),
.D(p_0_in[3]),
.Q(data_out_OBUF[3]));
(* ADDER_THRESHOLD = "35" *)
CARRY4 \data_reg_reg[3]_i_1
(.CI(\<const0> ),
.CO({\data_reg_reg[3]_i_1_n_0 ,\data_reg_reg[3]_i_1_n_1 ,\data_reg_reg[3]_i_1_n_2 ,\data_reg_reg[3]_i_1_n_3 }),
.CYINIT(\<const0> ),
.DI({data_out_OBUF[5],data_out_OBUF[6],data_out_OBUF[2],data_out_OBUF[4]}),
.O(p_0_in[3:0]),
.S({\data_reg[3]_i_2_n_0 ,\data_reg[3]_i_3_n_0 ,\data_reg[3]_i_4_n_0 ,\data_reg[3]_i_5_n_0 }));
FDCE #(
.INIT(1'b0))
\data_reg_reg[4]
(.C(clk_IBUF_BUFG),
.CE(valid_in_IBUF),
.CLR(\data_reg[7]_i_2_n_0 ),
.D(p_0_in[4]),
.Q(data_out_OBUF[4]));
FDCE #(
.INIT(1'b0))
\data_reg_reg[5]
(.C(clk_IBUF_BUFG),
.CE(valid_in_IBUF),
.CLR(\data_reg[7]_i_2_n_0 ),
.D(p_0_in[5]),
.Q(data_out_OBUF[5]));
FDCE #(
.INIT(1'b0))
\data_reg_reg[6]
(.C(clk_IBUF_BUFG),
.CE(valid_in_IBUF),
.CLR(\data_reg[7]_i_2_n_0 ),
.D(p_0_in[6]),
.Q(data_out_OBUF[6]));
FDCE #(
.INIT(1'b0))
\data_reg_reg[7]
(.C(clk_IBUF_BUFG),
.CE(valid_in_IBUF),
.CLR(\data_reg[7]_i_2_n_0 ),
.D(p_0_in[7]),
.Q(data_out_OBUF[7]));
(* ADDER_THRESHOLD = "35" *)
CARRY4 \data_reg_reg[7]_i_1
(.CI(\data_reg_reg[3]_i_1_n_0 ),
.CO({\data_reg_reg[7]_i_1_n_1 ,\data_reg_reg[7]_i_1_n_2 ,\data_reg_reg[7]_i_1_n_3 }),
.CYINIT(\<const0> ),
.DI({\<const0> ,data_out_OBUF[0],data_out_OBUF[3],data_out_OBUF[1]}),
.O(p_0_in[7:4]),
.S({\data_reg[7]_i_3_n_0 ,\data_reg[7]_i_4_n_0 ,\data_reg[7]_i_5_n_0 ,\data_reg[7]_i_6_n_0 }));
IBUF rst_n_IBUF_inst
(.I(rst_n),
.O(rst_n_IBUF));
IBUF valid_in_IBUF_inst
(.I(valid_in),
.O(valid_in_IBUF));
OBUF valid_out_OBUF_inst
(.I(valid_out_OBUF),
.O(valid_out));
FDCE #(
.INIT(1'b0))
valid_out_reg
(.C(clk_IBUF_BUFG),
.CE(\<const1> ),
.CLR(\data_reg[7]_i_2_n_0 ),
.D(valid_in_IBUF),
.Q(valid_out_OBUF));
endmodule

50
0ctf/EzLogic/readme.md Normal file
View File

@ -0,0 +1,50 @@
# EzLogic
## Problem
Our task is to reverse engineer a flag checker implemented on an **FPGA**.The hardware system is constructed from a **netlist** synthesized by Xilinx Vivado, where the netlist serves a role similar to assembly language in the software domain, representing a lower-level, more hardware-specific description. The netlist is described using **Verilog**, enabling convenient simulation of the system.
## Knowledge
If you find yourself new to Verilog or digital integrated circuit design, that's completely fine. We're here to help with a recommended Verilog syntax tutorial and an official manual covering all the foundational components used in the netlist.
- Verilog Syntax: https://www.chipverify.com/tutorials/verilog
- FPGA Design Elements: https://docs.amd.com/r/en-US/ug953-vivado-7series-libraries/Design-Elements
## Simulation
For system simulation, you can choose one of the following tools:
- [Xilinx Vivado](https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools.html) (free version is enough)
- [Icarus Verilog](https://github.com/steveicarus/iverilog) and [gtkwave](http://gtkwave.sourceforge.net/) (open-source software)
### Using Vivado
1. Install Vivado HL WebPACK version (must select Zynq 7000 series boards support)
2. Create a project (just click "next" to the end, nothing is needed to configure)
3. In "sources" window, add the Verilog files (*.v) to **simulation sources**
4. Run simulation (run until stops)
5. Watch the value of signal `success` or check the output message in "Tcl Console"
### Using Icarus Verilog
1. Installing iverilog and gtkwave
```
sudo apt-get install iverilog gtkwave
```
2. Compilation
Note: Zynq 7000 FPGA primitives (FDCE, LUT, ...) are not supported by iverilog, so behavioral models for these components are provided for simulation purposes.
```
iverilog -s EzLogic_tb -o EzLogic.vvp ./problem/EzLogic_top_synth.v ./problem/EzLogic_tb.v ./behavioral\ models/*.v
```
If successful, you can see `EzLogic.vvp` file in the folder.
3. Running the Simulation
```
vvp EzLogic.vvp
```
The results of the check are printed on the terminal.
4. Viewing in Graph Form
If you want to check internal signals, just use gtkwave.
```
gtkwave EzLogic.vcd
```
## Hints
- A schematic printout is included in `schematic` folder, which can greatly assist you in understanding the data pathways and program logic. (Only for EzLogic)
- Variable names are auto-generated by Vivado Synthesizer and don't necessarily mean anything; don't be confused by the names.

File diff suppressed because it is too large Load Diff