Enter /home/dragon with Ghidra

Setting up ghidra to be able to understand xtensa opcodes

Learning ghidra

Background

Baseline

The code

#pragma oncetypedef struct my_type
{
char my_char;
int my_int;
char my_string[8];
} my_type;

hello_ghidra.c

void one_ptr_arg(my_type *t){
t->my_int=t->my_int+10;
}
int one_arg(int my_arg){
char buffer[8];
int i;
my_type silly;
silly.my_int=4;
for (i = 0; i < my_arg; ++i) {
buffer[i]=0x32;
}
one_ptr_arg(&silly);
printf("My_arg=%d,%s",my_arg,buffer);
printf("silly.my_int=%d\n",silly.my_int);
return (silly.my_int);
}
int three_args(int arg1,int arg2,int arg3) {
return(arg1+arg2+arg3);
}
void two_args(int my_arg,my_type *t)
{
int my_local = my_arg + 2;
int i;
printf("my_int=%d\n",t->my_int);
for (i = 0; i < my_local; ++i) {
printf("i = %d\n", i);
}
int ret=one_arg(my_arg);
printf("ret=%d\n",ret);
ret=three_args(my_local,2,3);
printf("ret=%d\n",ret);
}
void app_main(void)                       
{
my_type test = {
.my_int = 4
};
two_args(2,&test);
int ret=two_args_one_ret(2,3);
printf("Restarting now. %d\n",ret);
}

Roundtrip with ghidra

three_args

int three_args(int arg1,int arg2,int arg3) {
return(arg1+arg2+arg3);
}
0x400e2ae8 <three_args> entry a1, 32
<three_args+3> add.n a2, a2, a3
<three_args+5> add.n a2, a2, a4
0x400e2ad3 <three_args+7> retw.n

Windowed ABI

a0 = return address 
a1 = stack pointer (alias sp)
a2 = first argument and result of call (in simple cases)
a3–7 = second through sixth arguments of call (in simple cases).

Fake registers

One_arg()

int one_arg(int my_arg)
{
int i;
char buffer [8];
my_type silly;

silly.my_int = 4;
i = 0;
while (i < my_arg) {
buffer[i] = '2';
i = i + 1;
}
one_ptr_arg(&silly);
printf(s_My_arg=%d,%s_ram_3f402cc0,my_arg,buffer);
printf(s_silly.my_int=%d_ram_3f402cd0,silly.my_int,buffer);
return silly.my_int;
}

Two_args()

void two_args(int my_arg,my_type *t)
{
int ret;
int my_local;

my_local = my_arg + 2;
printf(s_my_int=%d_ram_3f402ce4,t->my_int);
ret = 0;
while (ret < my_local) {
printf(s_i_=_%d_ram_3f402cf0,ret);
ret = ret + 1;
}
ret = one_arg(my_arg);
printf(s_ret=%d_ram_3f402cf8,ret);
ret = three_args(my_local,2,3);
printf(s_ret=%d_ram_3f402cf8,ret,3);
return;
}

app_main()

two_args(2,&test);
ret = two_args_one_ret(2,3);
printf(s_Restarting_now._%d_ram_3f402da4,ret,pcVar1,puVar2);
reent_p = __getreent();
fflush((FILE *)reent_p->_stdout);
esp_restart();

Conclusion

--

--

--

Software Engineer.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Prism(API Mock Server) With Docker

Deep Dive on Looker: Liquid Parameter and Templated Filters — Acrotrend Solutions

SAP Tutorial: Serving Data from an On Premise System in a CAP Java Application (Part 5)

Creating Manager classes with Singleton pattern

Engraved in the subconscious

10 Things I wish I knew before testing my Rails Application with rspec for the first time [Part 2]

FlutterForce — #Week 13

Wanted: Chief Technology Officer (CTO) for Dataverse Startup

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Olof Astrand

Olof Astrand

Software Engineer.

More from Medium

ESP32 Web Server For Room Monitoring

Testing Serial Sensor on ESP32

Room Monitoring and Controlling System with ESP32 Web Server and MS5611 Sensor

Project 5: ESP32 Output Display & PWM