Reversing a program to pseudo c code

View previous topic View next topic Go down

Reversing a program to pseudo c code

Post  BTG on Thu Apr 14, 2011 12:02 pm

Hey guys, BTG here. I'm here by to teach you guys how to reverse engineer a PSP program to MIPS ASM to then translate it to Pseudo-C...
I originally made this tutorial on kidz-axe.co.cc/fourm...
Here it is:

SOME REQUIREMENTS:

C KNOWLEDGE
MIPS ASM NOTE: PSP reads MIPS r4000.
Here is the script of one of my prxs.
It is a very basic sript.
Code:
#include <stdio.h>
#include <pspkernel.h>

PSP_MODULE_INFO("TESTPRX", 0x1000, 1, 1);

#define WELCOME_MESSAGE "Hello from Val\n"

/*---------------- main -----------------*/
int main(int argc, char **argv)
{
  int i;
 
  printf(WELCOME_MESSAGE);

  for(i = 0; i < argc; i++)
  {
      printf("Arg %d: %s\n", i, argv[i]);
  }

  sceKernelSleepThread();

  return 0;
}


/* Exported function returns the address of module_info */
void* getModuleInfo(void)
{
  return (void *) &module_info;
}
3)Get an asm code and others stuffs
We need to use prxtool, a software made by TyRaNiD.
Get it from the svn .
Code:
svn co svn://svn.ps2dev.org/psp/trunk/prxtool
Install it
Code:
cd prxtool
./bootstrap
./configure
make && make install
Now we can start working
Code:
xtool.exe  -m mymodule.prx

Name:    TESTPRX
Attrib:  1000
Version: 1.1
GP:      0000C5E0
This command allows us to know some informations about our prx. We can note prx's name, the attribut and the version :
Code:
PSP_MODULE_INFO("TESTPRX", 0x1000, 1, 1);
We create a text file which contains our ASM's code ans others informations.
First we find functions :
Code:
/*--------------------- module_start: ------------------------*/

; ======================================================
; Subroutine module_start - Address 0x000000AC
; Exported in syslib
module_start:

/*--------------------- getModuleInfo ----------------------*/

; ======================================================
; Subroutine MyLib_563FF2B2 - Address 0x00000280
; Exported in MyLib
MyLib_563FF2B2:

It's pretty easy because there are only two functions.
We start to convert asm to understand the procedure :
For that, we need some informations about instructions set of MIPS r4000. :

You can get informations here with the following links.
lmips.s.
MIPS Instruction Reference
http://www.eas.asu.edu/~cse530/MIPSP..._Lang_Vol2.pdf
http://mentoring.csua.berkeley.edu/f...SReference.pdf
Basic MIPS Instructions

Now here is what you get with prxtool.
A big ASM script.
I also added some notices but they all are in french because I am french and I work with french notices sorry, but nevermind they are not important.
Code:
module_start:
  0x000000AC: 0x3C020000 '...<' - lui        $v0, 0x0      # Evaluation d'expression v0 = 0x00000000
  0x000000B0: 0x27BDFFF0 '...'' - addiu      $sp, $sp, -16  # Stack Pointer : pointeur sur la pile
  0x000000B4: 0x24420000 '..B$' - addiu      $v0, $v0, 0      # v0 = 0
  0x000000B8: 0xAFB10004 '....' - sw        $s1, 4($sp)      # Met le contenu du registre s1 dans la pile (stack)
  0x000000BC: 0xAFB00000 '....' - sw        $s0, 0($sp)      # Met le contenu du registre s0 dans la pile (stack)
  0x000000C0: 0xAFBF0008 '....' - sw        $ra, 8($sp)      # Met le contenu de l'adresse de retour dans la pile (stack)
  0x000000C4: 0x00808021 '!...' - move      $s0, $a0      # met a0 dans le registre s0
  0x000000C8: 0x10400009 '..@.' - beqz      $v0, loc_000000F0  # Si v0 est egal a 0 on va a loc_000000F0
  0x000000CC: 0x00A08821 '!...' - move      $s1, $a1      # met a1 dans le registre s1
  0x000000D0: 0x0C000000 '....' - jal        sub_00000000      # On appelle sub_00000000
  0x000000D4: 0x00000000 '....' - nop            # no operation
  0x000000D8: 0x24020001 '...$' - li        $v0, 1      # v0 = 1

sub_00000000:      ; Refs: 0x00000084 0x000000D0 0x000001D4 0x00000230
  0x00000000: 0x27BDFF90 '...'' - addiu      $sp, $sp, -112  # Pointeur sur la pile
  0x00000004: 0xAFB50064 'd...' - sw        $s5, 100($sp)  # Met le registre temporaire sauvegardé️ s5 dans la pile
  0x00000008: 0xAFB40060 '`...' - sw        $s4, 96($sp)      # Met le registre temporaire sauvegardé️ s4 dans la pile
  0x0000000C: 0xAFB3005C '\...' - sw        $s3, 92($sp)      # Met le registre temporaire sauvegardé️ s3 dans la pile
  0x00000010: 0xAFB20058 'X...' - sw        $s2, 88($sp)      # Met le registre temporaire sauvegardé️ s2 dans la pile
  0x00000014: 0xAFB10054 'T...' - sw        $s1, 84($sp)      # Met le registre temporaire sauvegardé️ s1 dans la pile
  0x00000018: 0xAFB00050 'P...' - sw        $s0, 80($sp)      # Met le registre temporaire sauvegardé️ s0 dans la pile
  0x0000001C: 0xAFBF0068 'h...' - sw        $ra, 104($sp)  # Met l'adresse de retour dans la pile
  0x00000020: 0x0080A021 '!...' - move      $s4, $a0      # On met l'argument a0 dans s4
  0x00000024: 0x00A09821 '!...' - move      $s3, $a1      # On met l'argument a1 dans s3
  0x00000028: 0x0C000F65 'e...' - jal        sub_00003D94      # On appelle sub_00003D94
  0x0000002C: 0x00009021 '!...' - move      $s2, $zr      #
  0x00000030: 0x00008021 '!...' - move      $s0, $zr      #
  0x00000034: 0x03A08821 '!...' - move      $s1, $sp      #
  0x00000038: 0x08000017 '....' - j          loc_0000005C      # On va a loc_0000005C
  0x0000003C: 0x24150013 '...$' - li        $s5, 19      # s5 = 19

Etc...
This method is very tiresome and complicated.
There are others software. pspdasm created by Booster and IDA Pro (not free :/).
Now we use pspdasm :
Code:
pspdasm.exe -f mymodule.prx apilist.txt > output.txt

The content of output.txt gives us a lot of informations on functions used in our prx :
Code:
:Import Functions+-------------------------+--------+--------------------------------+--------+|      LIB NAME          |  NID  |          FUNC NAME            |  ENTRY |+-------------------------+--------+--------------------------------+--------+|IoFileMgrForUser        |42EC03AC|sceIoWrite                      |00003DDC|+-------------------------+--------+--------------------------------+--------+|ModuleMgrForUser        |D675EBB8|sceKernelSelfStopUnloadModule  |00003DE4|+-------------------------+--------+--------------------------------+--------+|SysMemUserForUser        |A291F107|sceKernelMaxFreeMemSize        |00003DEC||SysMemUserForUser        |237DBD4F|sceKernelAllocPartitionMemory  |00003DF4||SysMemUserForUser        |B6D61D02|sceKernelFreePartitionMemory    |00003DFC||SysMemUserForUser        |9D9A5BA1|sceKernelGetBlockHeadAddr      |00003E04|+-------------------------+--------+--------------------------------+--------+|ThreadManForUser        |9ACE131E|sceKernelSleepThread            |00003E0C||ThreadManForUser        |446D8DE6|sceKernelCreateThread          |00003E14||ThreadManForUser        |F475845D|sceKernelStartThread            |00003E1C||ThreadManForUser        |AA73C935|sceKernelExitThread            |00003E24|+-------------------------+--------+--------------------------------+--------+:Export Functions+-------------------------+--------+--------------------------------+--------+|      LIB NAME          |  NID  |          FUNC NAME            | ENTRY  |+-------------------------+--------+--------------------------------+--------+|***** COMMON *****      |D632ACDB|F0_StartModule                  |000000AC||***** COMMON *****      |F01D73A7|M0_ModuleInfo                  |00003EB0|+-------------------------+--------+--------------------------------+--------+|MyLib                    |563FF2B2|MyLib_563ff2b2                  |00000280|+-------------------------+--------+--------------------------------+--------+:Import Functions+-------------------------+--------+--------------------------------+--------+|      LIB NAME          |  NID  |          FUNC NAME            |  ENTRY |+-------------------------+--------+--------------------------------+--------+|IoFileMgrForUser        |42EC03AC|sceIoWrite                      |00003DDC|+-------------------------+--------+--------------------------------+--------+|ModuleMgrForUser        |D675EBB8|sceKernelSelfStopUnloadModule  |00003DE4|+-------------------------+--------+--------------------------------+--------+|SysMemUserForUser        |A291F107|sceKernelMaxFreeMemSize        |00003DEC||SysMemUserForUser        |237DBD4F|sceKernelAllocPartitionMemory  |00003DF4||SysMemUserForUser        |B6D61D02|sceKernelFreePartitionMemory    |00003DFC||SysMemUserForUser        |9D9A5BA1|sceKernelGetBlockHeadAddr      |00003E04|+-------------------------+--------+--------------------------------+--------+|ThreadManForUser        |9ACE131E|sceKernelSleepThread            |00003E0C||ThreadManForUser        |446D8DE6|sceKernelCreateThread          |00003E14||ThreadManForUser        |F475845D|sceKernelStartThread            |00003E1C||ThreadManForUser        |AA73C935|sceKernelExitThread            |00003E24|+-------------------------+--------+--------------------------------+--------+:Export Functions+-------------------------+--------+--------------------------------+--------+|      LIB NAME          |  NID  |          FUNC NAME            | ENTRY  |+-------------------------+--------+--------------------------------+--------+|***** COMMON *****      |D632ACDB|F0_StartModule                  |000000AC||***** COMMON *****      |F01D73A7|M0_ModuleInfo                  |00003EB0|+-------------------------+--------+--------------------------------+--------+|MyLib                    |563FF2B2|MyLib_563ff2b2                  |00000280|+-------------------------+--------+--------------------------------+--------+
But with pspdasm there is an option that is so good to disassemble :

Code:
pspdasm.exe -d -n mymodule.prx> output.txt
The option -n allows us to replace :
Code:
          0x000002E0: 0x0C000F83 '....' - jal        ThreadManForUser_9ACE131E
  0x000002E4: 0x00000000 '....' - nop
by
Code:
jal    sceKernelSleepThread
nop
This is more interresting because we know this function, but the work is always the same.
Well, here we have what we know for the moment :
Code:
/*
* We can already include those two libraries
* pspkernel.h there is the function sceKernel*
* pspiofilemgr.h there is a sceIo function*
*/
#include <pspkernel.h>
#include <pspiofilemgr.h>

/*
* We also knowthe MODULE_INFO, We are in kernel mode (2nd setting)
*/
PSP_MODULE_INFO("TESTPRX", 0x1000, 1, 1);

/*
* First function, it looks like the function standard main()
*/
void module_start(void)
{
}

/*
* After there is the function MyLib_563FF2B2
* Hopefully google helped me, and I got that  MyLib_563FF2B2 is similar than getModuleInfo
* Now I know that this function is called like this, now it looks like easier.
* We still do not know the return function (maybe there is not such a function like this) So we just put void
void getModuleInfo(void)
{
}
We must study the content of each functions, i use prxtool with an another parameter :
Code:
prxtool.exe -n psplibdoc.xml -w -o output1.txt mymodule.prx
The option -n allows us to specify a xml file which contains NIDS, so we obtain name of functions instead of asm code. Let's seek "strings, in our new file, we get others stuffs
Code:
; Strings
0x00003EB4: "TESTPRX"

; Strings
0x00003F0C: "IoFileMgrForUser"
0x00003F24: "ModuleMgrForUser"
0x00003F3C: "SysMemUserForUser"
0x00003F54: "ThreadManForUser"

; Strings
0x00003F90: "user_main"
0x00003F9C: "Hello from Val"
0x00003FB0: "Arg %d: %s\n"
0x00003FBC: "MyLib"
0x00003FC4: "Program aborted."
0x00003FD8: "block"
0x00004018: "(null)" prxtool.exe -n psplibdoc.xml -w -o output1.txt mymodule.prx
0x00004020: "0123456789"
0x0000402C: "01234567"
0x0000403C: "0123456789abcdef"
0x00004054: "0123456789ABCDEF"

; Strings
0x000045B8: "                                                    "
All isn't useful but we keep all ! We don't know what the content of our .c is. I see some lines that i distinguish (in red). These line could be in a C program

P-S:For people who uses IDA Pro, you must change the type of the processor : choose mipsl instead of mipsr !

4) - Time to work ! Gonna to reverse
Well, go go go, we begin to translate asm code into pseudo language, pseudo-C here.
Code:
sub_00000000 {
/*  Mouvements dans la pile - Operations in the stack
sp = sp - 112;              // addiu      $sp, $sp, -112
*(sp + 100) = *s5;      // sw        $s5, 100($sp)
*(sp + 96) = *s4;      // sw        $s4, 96($sp)
*(sp + 92) = *s3;      // sw        $s3, 92($sp)
*(sp + 88) = *s2;      // sw        $s2, 88($sp)
*(sp + 84) = *s1;      // sw        $s1, 84($sp)
*(sp + 80) = *s0;      // sw        $s0, 80($sp)
*(sp + 104) = *ra;      // sw        $ra, 104($sp)
*/
s4 = a0;        // move      $s4, $a0
s3 = a1;        // move      $s3, $a1

sub_00003D94();        // jal        sub_00003D94

s2 = 0;            // move      $s2, $zr
s0 = 0;            // move      $s0, $zr
s1 = sp;        // move      $s1, $sp

loc_0000005C();        // j          loc_0000005C

s5 = 19;        // li        $s5, 19

loc_00000040:
*s1 = *a0;          // sw        $a0, 0($s1)

sub_0000039C();      // jal        sub_0000039C

s2 += 1;          // addiu      $s2, $s2, 1

if(s2 == s5) goto loc_00000068; // beq        $s2, $s5, loc_00000068

s1 += 4;          // addiu      $s1, $s1, 4
v0 += 1;        // addiu      $v0, $v0, 1
s0 = s0 + v0;          // addu      $s0, $s0, $v0

loc_0000005C:
if(v0 < s0)
  s4 = 1;
else
  s4 = 0;

if(v1 < 0) goto loc_00000040;

a0 = s3 + s0;

loc_00000068:
v0 = s2 << 2;
v1 = 0;
v0 = v0 + sp;
v1 += 0;

if(v1 == 0) goto loc_0000008C;

*v0 = 0;
a0 = s2;

sub_00000000();

a1 = sp;

loc_0000008C:
a0 = 0;

sub_0000046C();

a0 = a0 + 15804;
a0 = s2;

sub_0000028C();

a1 = sp;

sub_000004A8();

a0 = v0;
}

/*---------------------------------------------------------*/

module_start {
v0 = 0;

/*  Mouvements dans la pile - Operations in the stack
sp = sp - 16;
v0 = v0 + 0;
*(sp + 4) = *s1;
*sp = *s0;
*(sp + 8) = *ra;
*/

s0 = a0;

if(v0 == 0) goto loc_000000F0;

s1 = a1;

sub_00000000(); // We call sub_00000000()
asm("nop");  // No arguments

v0 = 1;

loc_000000DC:
/*  Mouvements dans la pile - Operations in the stack
*ra = *(sp + 8);
*s1 = *(sp + 4);
*s0 = *sp;
*/

return ra; // v0 ?

/*  Mouvements dans la pile - Operations in the stack
*sp = *sp + 16;
*/

loc_000000F0:
a2 = 0;
v0 = a2 + 0; // v0 = 0

if(v0 == 0) goto loc_00000104; // + link (result in $31)

a2 = 32;
*a2 = *a2;

loc_00000104:
t0 = 0;
v0 = t0 + 0; // v0 = 0

if(v0 == 0) goto loc_00000118; // + link (result in $31)

t0 = 0;
*t0 = *t0;

loc_00000118:
v1 = 0;
v0 = v1 + 0; // v0 = 0

if(v0 == 0) goto c; // c == loc_00000130  >.<

a3 = 4;
*v0 = *v1;
a3 = v0 << 10;

loc_00000130:
a0 = 0;
v0 = a0 + 0; // v0 = 0

if(v0 == 0) goto loc_0000016C; // + link (result in $31)

v0 = 0;
*a0 = *a0;

loc_00000144:
a1 = 0;
a1 = a1 + 0;

sceKernelCreateThread();

t1 = 0;
a0 = v0;
a1 = s0;

sceKernelStartThread();

a2 = s1;

loc_000000DC();

v0 = 0;

loc_0000016C:
loc_00000144();

// Data ref 0x00003F90 "user_main"
a0 = v0 + 16272;
}

/*---------------------------------------------------------*/

sub_00000174 {
/*  Mouvements dans la pile - Operations in the stack
sp = sp - 16;
*(sp + 4) = *s1;
*/

s1 = 0;

*v0 = *(s1 + 17904);
*(sp + 8) = *ra;

if(v0 != 0) goto loc_000001E4;

*sp = *s0;
s0 = 0;
*v0 = *(s0 + 17312);
*v1 = *v0;

if(v1 != 0) goto loc_000001C4; // + link (result in $31)

v0 = 0;
v0 += 4;

loc_000001A8:
return v1; // + link (result in $31)

*(s0 + 17312) = v0;
*v0 = *(s0 + 17312);
*v1 = *v0;

if(v1 != 0) goto loc_000001A8;

v0 += 4;
v0 = 0;

loc_000001C4:
v0 = v0 + 0;

if(v0 == 0) goto loc_000001E0;

v0 = 1;
a0 = 0;

sub_00000000();

a0 = a0 + 17224;
v0 = 1;

loc_000001E0:
*(s1 + 17904) = 0xff & v0;

loc_000001E4:
*ra = *(sp + 8);
*s1 = *(sp + 4);
*s0 = *sp;

return ra;

/*  Mouvements dans la pile - Operations in the stack
sp = sp + 16;
sp = sp - 8;
*sp = *ra;
*ra = *sp;
*/

return ra;

sp = sp + 8;
}

/*---------------------------------------------------------*/

sub_0000020C {
v0 = 0;
sp = sp - 8;
a0 = 0;
a1 = 0;
v0 = v0 + 0;
*sp = *ra;
a0 = a0 + 17224;

if(v0 == 0) goto loc_00000238;

a1 = a1 + 17908;

sub_00000000();

asm("nop");

loc_00000238:
a0 = 0;
*s1 = *(s0 + 17300);
v0 = 0;

if(v1 == 0) goto loc_00000260;

t9 = v0 + 0;
a0 = a0 + 17300;

if(t9 == 0) goto loc_00000260;

*ra = *sp;

return t9;

sp = sp + 8;

loc_00000260:
*ra = *sp;

return ra;

sp = sp + 8;
sp = sp - 7;
*sp = *ra;
*ra = *sp;

return ra;

sp = sp + 8;
}

/*---------------------------------------------------------*/

// MyLib_563FF2B2
getModuleInfo {
v0 = 0;

return ra;

v0 = v0 + 16048;
}

/*---------------------------------------------------------*/

sub_0000028C {
/*  Mouvements dans la pile - Operations in the stack
sp = sp - 24;
*(sp + 8) = s2;
*/

// We save the first argument into s2
s2 = a0;
a0 = 0;

// Data ref 0x00003F9C "Hello from the PRX"
a0 = a0 + 16284; // 16284 = 0x00003F9C

/*  Mouvements dans la pile - Operations in the stack
*sp = *s0;
*(sp + 16) = *ra;
*(sp + 12) = *s3;
*(sp + 4) = *s1;
*/

sub_000003C4(); // We call this function with argument a0 = 0x00003F9C
      // This function seems to be printf()

// We save the 2nd argument into s0
s0 = a1;

if(s0 <= 0) goto loc_000002E0;    // Test if the 2nd argument is <= 0
            // If yes : sceKernelSleepThread()
            // Else we continue

s1 = 0;
s3 = 0;

loc_000002C4:
// The three arguments after are for the function calling
// argument 3
*a2 = *s0;
// argument 2
a1 = s1;

// Data ref 0x00003FB0 "Arg %d: %s\n"
// argument 1
a0 = s3 + 16304;// 16304 = 0x00003FB0

sub_00000308(); // Function called with 3 arguments a0, a1 et a2
      // a0 = 0x00003FB0
      // a1 = s1 = 0
      // *a2 = *s0
      // This function seems to be printf()

s1 = s1 + 1;    // = s1++

// Loop ?!
// s1 = i
// s2 = argc
// Test if i != argc
if(s2 != s1) goto loc_000002C4;

// s0 = a1
s0 = s0 + 4;

loc_000002E0:
sceKernelSleepThread();  // We call sceKernelSleepThread();
asm("nop");      // No arguments

/*  Mouvements dans la pile - Operations in the stack
*ra = *(sp + 16);
*s3 = *(sp + 12);
*s2 = *(sp + 8);
*s1 = *(sp + 4);
*s0 = *sp;
*/

v0 = 0;

return ra;    // ra = v0 = 0
      // return 0;

sp = sp + 24;
}

/*---------------------------------------------------------*/

sub_00000308 {
sp = sp - 48;
v0 = sp + 20;

*(sp + 20) = *a1;
a1 = v0;

*(sp + 8) = *ra;
*(sp + 24) = *a2;
*(sp + 28) = *a3;
*(sp + 32) = *t0;
*(sp + 36) = *t1;
*(sp + 40) = *t2;
*(sp + 44) = *t3;

sub_00000348();

*sp = *v0;

*ra = *(sp + 8);

return ra;

sp = sp + 48;
}

/*---------------------------------------------------------*/

sub_00000348 {
sp = sp - 16;
*(sp + 4) = *s1;

s1 = 0;
a2 = a0;
a3 = a1;

a0 = s1 + 17932;
a1 = 4096;
*(sp + 8) = *ra;

sub_000005A4();

*sp = *s0;
s0 = v0;
a1 = s1 + 17932;
a0 = 1;

sceIoWrite();

a2 = v0;
v0 = s0;

*ra = *(sp + 8);
*s1 = *(sp + 4);
*s0 = *sp;

return ra;

sp = sp + 16;
}

/*---------------------------------------------------------*/

sub_0000039C {
*v0 = *a0; //lb  $v0, 0($a0)

if(v0 == 0) goto loc_000003BC;

v1 = 0;

loc_000003A8:
a0 = a0 + 1;

*v0 = *a0; //lb  $v0, 0($a0)

if(v0 != 0) goto loc_000003A8;

v1 = v1 + 1;

v0 = v1;

loc_000003BC:
return ra;

asm("nop");
}

/*---------------------------------------------------------*/

sub_000003C4 {
sp = sp - 16;
*sp = *s0;
*(sp + 8) = *ra;
*(sp + 4) = *s1;

s0 = a0;
*a0 = *a0; // lb $a0, 0($a0)
;
if(a0 == 0) goto loc_00000448;

s1 = 0;

loc_000003E4:
sub_000005E0();

asm("nop");

*v1 = *s0; // lb $v1, 0($s0)

if(v0 == v1) goto loc_00000438;

asm("nop");

loc_000003F8:
s1 = -1;
s0 = s0 + 1;

loc_00000400:
*a0 = *s0; // lb $a0, 0($s0)

if(a0 != 0) goto loc_000003E4;

asm("nop");

sub_000005E0();

a0 = 10;
v1 = 10;

if(v0 == v1) goto loc_0000045C;

loc_00000420:
v0 = -1;
*(sp + 8) = *ra;

loc_00000428:
*(sp + 4) = *s1;
*sp = *s0;

return ra;

sp = sp + 16;

loc_00000438:
if(s1 < 0) goto loc_000003F8;

s1 = s1 + 1;

loc_00000400();

s0 = s0 + 1;

loc_00000448:
sub_000005E0();

a0 = 10;
v1 = 10;

if(v0 != v1) goto loc_00000420;

s1 = 0;

loc_0000045C:
if(s1 < 0) goto loc_00000420;

v0 = s1 + 1;

loc_00000428();

*ra = *(sp + 8);
}

/*---------------------------------------------------------*/

sub_0000046C {
a3 = 0;

*v0 = *(a3 + 22028);
v1 = 0;
v1 = v1 + 22064;
a1 = v0 << 2; // SLL
a1 = a1 + v1;
v1 = v0 + 1;

if(v0 < 32)
  v0 = 1;

if(v0 == 0) goto loc_000004A0;

a2 = -1;
*a1 = *a0;
*(a3 + 22028) = *v1;
a2 = 0;

loc_000004A0:
return ra;
v0 = a2;
}

/*---------------------------------------------------------*/

sub_000004A8 {
/*  Mouvement de pile
sp = sp - 24;
*(sp + 12) = *s3;
*(sp + 16) = *ra;
*(sp + 8) = *s2;
*(sp + 4) = *s1;
*sp = *s0;
*/

v0 = 0;
*(v0 + 22028) = *s2;
v1 = s2 - 1;
v1 = s2 - 1;

if(v1 < 0) goto loc_00000500;

s3 = a0;
v0 = 0;
v1 = v1 << 2;
v0 = v0 + 22064;
s0 = v1 + v0;
s1 = 0;
*v0 = *s0;

loc_000004EC:
s1 = s1 + 1;

return v0;


s0 = s0 - 4;

if(s1 != s2) goto loc_000004EC; // + link

*v0 = *s0;

loc_00000500:
sub_00000578();

a0 = s3;

return ra;

asm("nop");

sp = sp - 16;
*(sp + 16) = *ra;
*(sp + 8) = *s2;
*(sp + 4) = *s1;
*sp = *s0;

v0 = 0;

*s2 = *(v0 + 22028);
v1 = s2 - 1;

if(v1 < 0) goto loc_00000560;

v0 = 0;

v1 = v1 << 2;
v0 = v0 + 22064;
s0 = v1 + v0;
s1 = 0;

*v0 = *s0;

loc_0000054C:
s1 = s1 + 1;

return v0; // link

s0 = s0 - 4;

if(s1 != s2) goto loc_0000054C;

*v0 = *s0;

loc_00000560:
*ra = *(sp + 12);
*s2 = *(sp + 8);
*s1 = *(sp + 4);
*s0 = *sp;

return ra;

sp = sp + 16;
}

/*---------------------------------------------------------*/

sub_00000578 {
sp = sp - 8;
*sp = *ra;

sub_0000060C();

asm("nop");

a0 = 0;

sp = sp - 8;

*sp = *ra;

sub_000003C4();

// Data ref 0x00003FC4 "Program aborted."

a0 = a0 + 16324;

sub_0000060C();

a0 = 1;
}

/*---------------------------------------------------------*/

sub_000005A4 {
sp = sp - 16;
*(sp + 8) = *ra;
v1 = a0;
*a0 = *zr; // 0 ??
v0 = a0 + a1;
a0 = 0;
v0 = v0 - 1;
a1 = sp;
a0 = a0 + 7380;
*(sp + 4) = *v0;

sub_0000085C();

*sp = *v1;
*ra = *(sp + 8);

return ra;

sp = sp + 16;
}

/*---------------------------------------------------------*/

sub_000005E0 {
sp = sp - 16;
*sp = *a0;
a1 = sp;
a0 = 1;
*(sp + 8) = *ra;

sceIoWrite();

a2 = 1;
*sp = *v0;
*(sp + 8) = *ra;

return ra;

sp = sp + 16;
}

/*---------------------------------------------------------*/

sub_0000060C {
v0 = 0;
sp = sp - 8;
v0 = v0 + 0;
*sp = *s0;
*(sp + 4) = *ra;

if(v0 == 0) goto loc_00000648;

s0 = a0;

sub_00000668();

asm("nop");

a0 = 1;

a1 = 0;

sceKernelSelfStopUnloadModule();

a2 = 0;

loc_00000640:
loc_00000640();

asm("nop");

loc_00000648:
if(a0 != 0) goto loc_00000658;

asm("nop");

sub_00000668();

asm("nop");

loc_00000658:
sceKernelExitThread();
a0 = s0;

loc_00000640();

asm("nop");
}

/*---------------------------------------------------------*/

sub_00000668 {
v0 = 0;
*v0 = *(v0 + 22048);

if(v0 <= 0) goto loc_00000680;

a0 = v0;

sceKernelFreePartitionMemory();

asm("nop");

loc_00000680:
return ra;

asm("nop");
}

Well, this is a little translation part, maybe we'll must to continue ... but we can starting to work. Remember few lines i distinguished, we gonna to look near these. First i translated all the part, with a lot of comments. So the end is near... xD
In module_start() we have sceKernelCreateThread() and sceKernelStartThread(), i think that this program uses a main thread.
Start to trace the programm, i start at module_start() and sub_00000000(). I'm happy because the part of the program which interested me seems to be the body of this program.
So I start to recreate the body of this program in C language (Hurra !)
Code:
sub_0000028C(void *a0, void *a1) {
int s1 = 0;

printf("Hello from the PRX");

while(i < a0)
{
  printf("Arg %d: %s\n", s1, a1);
  s1++;
}

sceKernelSleepThread();

return 0;

This part of code isn't a function (remember before), this is just a subroutine, so we can integrate it in the main()
Code:
#include <pspkernel.h>
#include <stdio.h> // for the function printf()

PSP_MODULE_INFO("TESTPRX", 0x1000, 1, 1);

/*
* main()
*/
int main(int argc, char **argv) // Template of a function main() with arguments
{
  int s1 = 0;

  printf("Hello from BTG");

  while(i < argc)
  {
        printf("Arg %d: %s\n", s1, argv[i]);
        s1++;
  }

  sceKernelSleepThread();

  return 0;
}

/*
* getModuleInfo()
*/
void* getModuleInfo(void)
{
  return (void *) &module_info;
}
And now, our code is reconstituted, this isn't the same, but it works like. Ouf !
Well, this tutorial is now finished... Thanks.

Enjoy
-BTG-
Any questions? Wink

BTG

Posts : 4
Join date : 21/02/2011

View user profile

Back to top Go down

Re: Reversing a program to pseudo c code

Post  M33 on Wed Apr 20, 2011 8:04 pm

nice tut.

M33
Admin

Posts : 17
Join date : 21/02/2011

View user profile http://m33user.netboarder.com

Back to top Go down

Re: Reversing a program to pseudo c code

Post  BTG on Sun May 01, 2011 3:10 pm

Thxs

BTG

Posts : 4
Join date : 21/02/2011

View user profile

Back to top Go down

Re: Reversing a program to pseudo c code

Post  Sponsored content


Sponsored content


Back to top Go down

View previous topic View next topic Back to top


 
Permissions in this forum:
You cannot reply to topics in this forum