Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions compiler/test_else_return/example.hard.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
.syntax unified
.thumb

.section .text
.global _start
.type _start, %function

_start:
mov r9, #0
mov r10, #1
sub sp, sp, #4
mov r0, #0
str r0, [sp]
add r9, r9, #1
cmp r9, #1
bne countermeasure
ldr r0, [sp, #0]
mov r1, r0
mov r0, #1
cmp r1, r0
mov r0, #0
it eq
moveq r0, #1
cmp r0, #0
beq else_0
add r9, r9, #1
cmp r9, #2
bne countermeasure
mov r0, #44
str r0, [sp]
add r9, r9, #1
cmp r9, #3
bne countermeasure
b endif_0
else_0:
ldr r0, [sp, #0]
mov r1, r0
mov r0, #0
cmp r1, r0
mov r0, #0
it eq
moveq r0, #1
cmp r0, #0
beq else_1
add r9, r9, #1
cmp r9, #2
bne countermeasure
mov r0, #33
str r0, [sp]
add r9, r9, #1
cmp r9, #3
bne countermeasure
b endif_1
else_1:
endif_1:
mov r9, #3
endif_0:
ldr r0, [sp, #0]
mov r7, #1
svc #0
countermeasure:
mov r0, #1
ldr r1, =.Lstr0
mov r2, #14
mov r7, #4
svc #0
mov r0, #77
mov r7, #1
svc #0

.size _start, .-_start

.section .data
.Lstr0:
.ascii "COUNTERMEASURE"
step_counter:
.word 0
fault_msg:
.ascii "Control flow violation detected\n"
_metadata:
.word 0x10000000 @ 0
.word 0xa+3
.word 0xb+8
.word 0x0 @ [r0]
.word 0x00000001 @ value
.word 0x10000000 @ 1
.word 0xa+21
.word 0xb+25
.word 0x0 @ [r0]
.word 0x00000001 @ value
.word 0x10000000 @ 2
.word 0xa+40
.word 0xb+44
.word 0x0 @ [r0]
.word 0x00000001 @ value
60 changes: 60 additions & 0 deletions compiler/test_else_return/example.hard.wh
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
ui32 res;
ui32 stmt;
ui32 bit_shift;
ui32 flip_mask;

fn main(ui32 stmt, ui32 flip_mask) -> ui32 {
ui32 value;
ui32 step_counter;
step_counter = (0 as ui32);
value = (0 as ui32);
if (stmt == (0 as ui32)) {
value = (0 as ui32) ^ flip_mask;
}
step_counter++;
if (step_counter != (1 as ui32)) {
return (77 as ui32);
}
if ( value == (1 as ui32)) {
step_counter++;
if (step_counter != (2 as ui32)) {
return (77 as ui32);
}
value = (44 as ui32);
if (stmt == (1 as ui32)) {
value = (44 as ui32) ^ flip_mask;
}
step_counter++;
if (step_counter != (3 as ui32)) {
return (77 as ui32);
}
}
else {
if ( value == (0 as ui32)) {
step_counter++;
if (step_counter != (2 as ui32)) {
return (77 as ui32);
}
value = (33 as ui32);
if (stmt == (2 as ui32)) {
value = (33 as ui32) ^ flip_mask;
}
step_counter++;
if (step_counter != (3 as ui32)) {
return (77 as ui32);
}
}
step_counter = (3 as ui32);
}
return (value as ui32);
}
stmt = (? as ui32);
bit_shift = (? as ui32);
assume (bit_shift <= (31 as ui32));
assume (bit_shift >= (0 as ui32));
assume (stmt >= (0 as ui32));
assume (stmt <= (3 as ui32));
flip_mask = ((1 as ui32) << bit_shift);

res = main(stmt, flip_mask);
assert(res == (0 as ui32));
3 changes: 1 addition & 2 deletions example_code_for_report/out.s
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,10 @@ else_0:
b endif_1
else_1:
endif_1:
endif_0:
ldr r0, [sp, #0]
mov r7, #1
svc #0
endif_0:
add sp, sp, #4

.size _start, .-_start
_metadata:
Expand Down
4 changes: 2 additions & 2 deletions example_code_for_report/out.wh
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ fn main(ui32 stmt, ui32 flip_mask) -> ui32 {
value = (33 as ui32) ^ flip_mask;
}
}
return (value as ui32);
}
return (value as ui32);
}
stmt = (? as ui32);
bit_shift = (? as ui32);
Expand All @@ -34,4 +34,4 @@ assume (stmt <= (3 as ui32));
flip_mask = ((1 as ui32) << bit_shift);

res = main(stmt, flip_mask);
assert(res == (0 as ui32));
assert(res == (33 as ui32));
12 changes: 8 additions & 4 deletions interpreter/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -962,19 +962,23 @@ impl Interpreter {
}
}

let mut is_sp = false;
if base_reg_name == "sp" {
is_sp = true;
base_addr = self.memory.get_sp();
} else if let Some(reg_num) = base_reg_name.strip_prefix('r') {
let reg_idx: usize = reg_num.parse().expect("Failed to parse register index");
base_addr = self.get_reg(reg_idx) as usize;
}

let effective_addr = ((base_addr as i32) + offset) as usize;
let effective_addr = (base_addr as i32 + offset) as usize;

if effective_addr < self.memory.heap.len() {
self.memory.heap[effective_addr] = value;
} else if effective_addr < self.memory.stack.len() {
if !is_sp{
self.memory.write_heap(effective_addr, value);
self.set_reg(base_addr, value as i32);
} else {
self.memory.stack[effective_addr] = value;
self.memory.write_stack32(effective_addr, value as u32);
}
}

Expand Down
2 changes: 1 addition & 1 deletion testing/config.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
test_folder = "pinny"
plotmode = "save" # show, save or both
plotmode = "both" # show, save or both

injection_points = [
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
Expand Down
30 changes: 28 additions & 2 deletions testing/src/plotenator.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,30 @@ def create_plots(self):
def plot_exhaustive(self):
df = self.db.query_df("SELECT * FROM exhaustive_interpreter_results")

# Group by variant and passed
grouped = df.groupby(["variant", "passed"]).size().unstack(fill_value=0)

# Map the numeric passed values to descriptive labels
passed_labels = {
0: "Faulty",
1: "Normal Execution",
2: "Panicked!",
77: "Countermeasure Activated",
78: "Faulty Jump to Countermeasure"
}

# Rename the columns
grouped = grouped.rename(columns=passed_labels)

# Plot
fig, ax = plt.subplots()
grouped.plot(kind="bar", stacked=False, ax=ax)

ax.set_title("Exhaustive Interpreter - Outcome Distribution")
ax.set_ylabel("Count (log scale)")
ax.set_xlabel("Variant")
ax.set_yscale("log")
ax.legend(title="Passed value")
ax.legend(title="Outcome")

self._style_axes(ax)

Expand All @@ -36,7 +50,19 @@ def plot_guided(self):

grouped = df.groupby(["variant", "passed"]).size().unstack(fill_value=0)

# Map the numeric passed values to descriptive labels
passed_labels = {
0: "Faulty",
1: "Normal Execution",
2: "Panicked!",
77: "Countermeasure Activated",
78: "Faulty Jump to Countermeasure"
}

grouped = grouped.rename(columns=passed_labels)

fig, ax = plt.subplots()

grouped.plot(kind="bar", stacked=False, ax=ax)

ax.set_title("Guided Interpreter - Outcome Distribution")
Expand Down Expand Up @@ -68,4 +94,4 @@ def _style_axes(self, ax):
# text.set_fontweight('bold')
def export_symex_csv(self, output_path):
df = self.db.query_df("SELECT * FROM symex_results")
df.to_csv(output_path, index=False)
df.to_csv(output_path, index=False)
8 changes: 4 additions & 4 deletions testing/src/testrunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,17 +370,17 @@ def _generate_injection_points(self, asm_path):
if len(pc_points) > 0:
if pc_points[0] == "ALL":
for pc in range(1, max_pc):
for bit in range(0, 31):
for bit in range(0, 32):
injection_points.append(f"pc:{pc}:{bit}")
else:
for pc in pc_points:
for bit in range(0, 31):
for bit in range(0, 32):
injection_points.append(f"pc:{pc}:{bit}")

if len(registers) > 0:
for pc in range(1, max_pc):
for reg in registers:
for bit in range(0, 31):
for bit in range(0, 32):
injection_points.append(f"reg:{pc}:{reg}:{bit}")

if len(cpsr_registers) > 0:
Expand Down Expand Up @@ -423,7 +423,7 @@ def _symex_to_injection_points(self, variant, asm_path, minimc_res):
ip = f"reg:{pc}:{reg}:{bit}"
injection_points.append(ip)
for pc in range(start_pc, end_pc+1):
for bit in range(0, 31):
for bit in range(0, 32):
ip = f"pc:{pc}:{bit}"
injection_points.append(ip)
for cpsr in ["n","v","z","c"]:
Expand Down
17 changes: 4 additions & 13 deletions testing/test
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ class Experiment:
plotter = Plotter(self.db)
plots = plotter.create_plots()

print("Running plots...")

plots_dir = os.path.join(self.run_folder, "plots")
os.makedirs(plots_dir, exist_ok=True)
Expand All @@ -102,25 +101,17 @@ class Experiment:
path = os.path.join(plots_dir, f"{name}.svg")
fig.savefig(path, format="svg", bbox_inches="tight")

def show_plot(fig):
"""Handles the rendering and cleanup of the figure."""
plt.figure(fig.number)
plt.show()
plt.close(fig)



# only these remain as plots
if self.plot_mode == "save" or self.plot_mode == "both":
save_plot("exhaustive", plots["exhaustive"])
save_plot("guided", plots["guided"])

if self.plot_mode == "show" or self.plot_mode == "both":
show_plot(plots["exhaustive"])
show_plot(plots["guided"])

plt.show()
for fig in plots.values():
plt.close(fig)

# NEW: symex exported as CSV instead of plot
# symex exported as CSV instead of plot
symex_csv_path = os.path.join(plots_dir, "symex_results.csv")
plotter.export_symex_csv(symex_csv_path)

Expand Down
Loading
Loading