An Aside: Outlined RISCV-32 Register Preservation and Ghidra

I somewhat recently stumbled upon a somewhat annoying pattern while traversing a RISCV-32 program. It looked just a little like this in the Listing:

	     **************************************************************
	     *                          FUNCTION                          *
	     **************************************************************
	     undefined example_fn()
undefined         <UNASSIGNED>   <RETURN>
	     example                                    
ef b2 86 fb     jal        t0,prologue_stub_t0                              void prologue_stub_t0(void)
			    <...SNIP...>
6f b0 86 f9     j          epilogue_stub_ret                                void epilogue_stub_ret(void)

And like this in the Decompiler:

void example_fn(undefined1 *param_1,int param_2)

{
  int iVar1;
  undefined4 uVar1;
  undefined4 uVar2;

  iVar1 = prologue_stub_t0();
  
  uVar1 = 0x12;
  if (iVar1 == extraout_a1){
    uVar1 = 0x17;
  }
  
  uVar2 = epilogue_stub_ret(uVar1);
  return uVar2;
}

So where were these jalr, and j instructions going? To outlined callee-saved register preservation and restoration:

Read more →

Corroding Defenses: Modern Implant Design

1.0.0 - Introduction

Two years ago (2023) CISA published The Urgent Need for Memory Safety in Software Products where they recommended Rust as a memory-safe and performant replacement for C and C++.

This begs the question, surely a “modern” implant design calls for a “modern” memory safe language? Is this even advisable?

While I answered neither of these questions here. It did confirm to me that, while not always straight forward, a full PIC implant in Rust is both possible and potentially more maintainable than its “unsafe” (who are we kidding here, this is all going to be unsafe anyway) counterparts.

Read more →