Reverse Engineering is no Rocket Science 2

What is this part about?

The following Instructions will be shown:

Write to memory

  • stdu
  • std
  • stw
  • sth
  • stb

Readfrom memory

  • ld
  • lwz
  • lhz
  • lbz

Copy register

  • mr

Branches

  • b
  • bgt
  • ble
  • blr

Others

  • rldicl
  • addi
  • cmpwi
  • extsw

And I will explain something about the memory and we will together reverse a big example.

The Stack

The Stack is mostly used for local variables in a function and to save register, so we don’t destroy data from the function we get called from. The stack gets freed after the function ran through. You can read more about stacks on wikipedia but this is enough to know for our purpose.

What brings the future?

Since I can’t manage to finish this part with the example reversing. I will just show you the upper assembler instructions like the one in part 1 and you got homework. At least this weekend I will finish a complete walkthrough through my example code. Which I will show you. Ignore it and wait for me to finish part 3 or try on your own the fun.

This is the code, you can ask me on twitter if you got a clue what it does ;). It’s untested but basicly a very short code so it should work :). Sorry for the gardient background my mspaint skills are limited.

I will explain parameter detection and so on in part 3 with the code.

exampleCode

The Instructions

stdu (Store Double Word Update)
This is a very complex instruction, which is mostly used for stack initialization.
The value of the register is saved into the defined location and the new location is saved in the register.

The C code may explain it more.

Parameters
1. A Register, which value will be stored to EA (Adress) and it is the destination register for the calculated EA
2. Value for EA calculation
3. Source Register for EA calculation

EA is calculated value + content of register

Our example

stdu %sp, -0x50(%sp)

In C

// Calculate EA
// EAValue is -0x50 in the example
unsigned long long EA = EAValue + sp;
// Save content of sp to EA in Memory
*((unsigned long long*) EA) = sp;
// Update sp
sp = EA;

std (Store Double Word)
Same as stdu but the 1. Parameter value is untouched (not updated).

Parameters
1. A Register, which value will be stored to EA (Adress)
2. Value for EA calculation
3. Source Register for EA calculation

Our example

std %r31, 0x48(%sp)

In C

// Calculate EA
// EAValue is 0x48 in the example
unsigned long long EA = EAValue + sp;
// Save content of r31 to EA in Memory
*((unsigned long long*) EA) = r31;

stw (Store Word)
Same as std but just with a 4 byte value instead of the 8 byte value

Parameters
1. A Register, which value will be stored to EA (Adress)
2. Value for EA calculation
3. Source Register for EA calculation

Our example

stw %r0, 0x34(%sp)

In C

unsigned long long EA = EAValue + sp;
*((unsigned int*) EA) = r0;

sth (Store Half Word)
Like std and stw just 2 byte value. I will shorten this.

Our example

sth %r0, 0x34(%sp)

In C

unsigned long long EA = EAValue + sp;
*((unsigned short*) EA) = r0;

stb (Store Byte)
You will get it by now…

Our example

stb %r10, 0x34(%r20)

In C

unsigned long long EA = EAValue + r20;
*((char*) EA) = r10;

ld (Load Double Word)
The opposite to std it loads the value to the register instead of writing the value from the register to the memory

Parameters
1. A Register, which will get the value from EA (Adress)
2. Value for EA calculation
3. Source Register for EA calculation

Our example

ld %r11, 0x00(%sp)

In C

unsigned long long EA = EAValue + sp;
r11 = *((unsigned long long*) EA);

lwz (Load Word Zero)
The opposite to stw it loads the value to the register instead of writing the value from the register to the memory.
The none used part of the register in this case the upper 32 bits are filled with 0.

Parameters
1. A Register, which will get the value from EA (Adress)
2. Value for EA calculation
3. Source Register for EA calculation

Our example

lwz %r11, 0x10(%r0)

In C

// EAValue is in the example 0x10 to clearify this again
unsigned long long EA = EAValue + r0;
r11 = 0;
r11 += *((unsigned int*) EA);

lhz (Load Half Word Zero)
The opposite to stw it loads the value to the register instead of writing the value from the register to the memory.
The none used part of the register in this case the upper 48 bits are filled with 0.

Parameters
1. A Register, which will get the value from EA (Adress)
2. Value for EA calculation
3. Source Register for EA calculation

Our example

lhz %r11, 0x10(%r0)

In C

// EAValue is in the example 0x10 to clearify this again
unsigned long long EA = EAValue + r0;
r11 = 0;
r11 += *((unsigned short*) EA);

lbz (Load Byte Zero)
The opposite to stw it loads the value to the register instead of writing the value from the register to the memory.
The none used part of the register in this case the upper 56 bits are filled with 0.

Parameters
1. A Register, which will get the value from EA (Adress)
2. Value for EA calculation
3. Source Register for EA calculation

Our example

lbz %r11, 0x10(%r0)

In C

// EAValue is in the example 0x10 to clearify this again
unsigned long long EA = EAValue + r0;
r11 = 0;
r11 += *((char*) EA);

Now we get to the new instructions which actually does something new

mr (Move Register)
Copies the content from one register to another register

Parameters
1. Destination Register
2. Source Register

Our example

mr %r3, %r0

In C

r3 = r0;

rldicl (Rotate Left Immediate Double Word then Clear Left)
A complex one again…
The Register gets shifted in the Left direction by n bits and anded with a mask. Better look at the C Code.

Parameters
1. Destination Register
2. Source Register
3. Value, how many bits get rotated
4. A bit mask which will be used with and on the shifted Source Value.

Our example

rldicl %r9, %r11, 2, 32

In C

r9 = r11 << 2;
// since our test Value is 32 the lower 32 bits are 1s of the mask.
// 64-n higher bits gets cleared in our example 64-32 = 32 higher bits are 0 of the mask
r9 &= 0b0000000000000000000000000000000011111111111111111111111111111111;

Another example

rldicl %r9, %r11, 8, 16

In C

r9 = r11 << 8;
// since our test Value is 16 the lower 16 bits are 1s of the mask.
// 64-n higher bits gets cleared in our example 64-16 = 48 higher bits are 0 of the mask
r9 &= 0b0000000000000000000000000000000000000000000000001111111111111111;

addi (Add Immediate)
Adds a value to the content of the source register and saves the calculated value to the destination register.

Parameters
1. Destination Register
2. Source Register
3. Value

Our example

addi %r0, %r9, 8

In C

r0 = r9 + 8;

extsw (Extend Sign Word)
Copies the lower 32 bits of the source register to the destination register.
The higher 32 bits of the destination register will be set to the sign bit of the source register

Parameters
1. Destination Register
2. Source Register

Our example

extsw %r0, %r1

In C

r0 = r1
if(r1 & 0b10000000000000000000000000000000 != 0)
r0 |= 0b1111111111111111111111111111111100000000000000000000000000000000;
else
r0 &= 0b0000000000000000000000000000000011111111111111111111111111111111;

b (Branch)
Simply jump to the code at the EA (IDA calculates this for you).

Parameters
1. EA

Our example

b loc_1079C

In C
There is no good way to 100% implement this is in C it is very let’s say context base.

//at the right code of course the label for the branch
//loc_1079C:
goto loc_1079C;

blr (Branch Link Register)
Branches to the Link Register… In a function this is the return; ;).
The value of the return is stored in our CPU in the r3 register.

Our example

blr;

In C

return;

Another example

mr %r3, %r31
blr

In C

return r31;

cmpwi (Compare Word Immediate)

Parameters
1. Compare Register (Holds the compare results, Greater Than, Lower Than, Equal, and so on)
2. Register which content gets compared
3. Value which gets compared to the register content

Our example

cmpwi %cr7, %r0, 7

In C
There is no good way to 100% implement this is in C it is very let’s say context base. We will implement in C this with the given branch to give a proper example look at the bottom 2 ones.

bgt (Branch Greater Than)
Jumps to the code if the compare register has the greater than flag of the last comparison else code execution goes on with the code below the instruction.

Parameters
1. Compare Register (Holds the compare results, Greater Than, Lower Than, Equal, and so on)
2. EA of the code which gets executed if the compare is greater than else the code execution continues just with the next command below this one

Our example

cmpwi %cr7, %r0, 7
bgt %cr7, loc_1234

In C

if(r0 > 7)
{
//     loc_1234's code is here
}

ble (Branch Lower or Equal)
Jumps to the code if the compare register has the lower than or equal flag of the last comparison else code execution goes on with the code below the instruction.

Parameters
1. Compare Register (Holds the compare results, Greater Than, Lower Than, Equal, and so on)
2. EA of the code which gets executed if the compare is lower than or equal else the code execution continues just with the next command below this one

Our example

cmpwi %cr7, %r0, 7
ble %cr7, loc_1234

In C

if(r0 <= 7)
{
//     loc_1234's code is here
}

continue in part 3…

I will show complexer combinations of instructions in the example walkthrough. Hope this is helpful since it is just information, which is not shown in a complexer example for now. 🙂 Wait for part 3 all I can say and hope ^^.

Stay tuned,

KDSBest

Leave a Reply

Your email address will not be published. Required fields are marked *