Advertising (This ad goes away for registered users. You can Login or Register)

[Eloader] 5. Stub headers

Forum rules
Forum rule Nº 15 is strictly enforced in this subforum.
Post Reply
User avatar
m0skit0
Guru
Posts: 3817
Joined: Mon Sep 27, 2010 6:01 pm

[Eloader] 5. Stub headers

Post by m0skit0 » Mon Sep 27, 2010 2:41 pm

Originally posted by m0skit0 on advancedpsp.tk.

Ok, time to more serious things: resolving stubs. But for that we need to know first what a stub is and what structure it has.

Stubs are functions imported by an executable. We call a function "imported" when its implementation (the actual code) is not included in the executable itself, but in the OS. So the OS has to resolve these imports, that is, make those imported functions point to the right OS code (doing a jump or a syscall in our case here). As we saw before, ELF stubs are this way before being loaded:

Code: Select all

; Section .sceStub.text - Address 0x08C92974
   0x08C92974: 0x03E00008 '....' - jr         $ra
   0x08C92978: 0x00000000 '....' - nop       
   0x08C9297C: 0x03E00008 '....' - jr         $ra
   0x08C92980: 0x00000000 '....' - nop       
   0x08C92984: 0x03E00008 '....' - jr         $ra
   0x08C92988: 0x00000000 '....' - nop       
   0x08C9298C: 0x03E00008 '....' - jr         $ra
   0x08C92990: 0x00000000 '....' - nop       
   0x08C92994: 0x03E00008 '....' - jr         $ra
   0x08C92998: 0x00000000 '....' - nop       
   0x08C9299C: 0x03E00008 '....' - jr         $ra
   0x08C929A0: 0x00000000 '....' - nop       
   0x08C929A4: 0x03E00008 '....' - jr         $ra
   0x08C929A8: 0x00000000 '....' - nop       
   0x08C929AC: 0x03E00008 '....' - jr         $ra
   0x08C929B0: 0x00000000 '....' - nop       
   0x08C929B4: 0x03E00008 '....' - jr         $ra
   0x08C929B8: 0x00000000 '....' - nop       
   0x08C929BC: 0x03E00008 '....' - jr         $ra
   0x08C929C0: 0x00000000 '....' - nop       
   0x08C929C4: 0x03E00008 '....' - jr         $ra
   0x08C929C8: 0x00000000 '....' - nop       
   0x08C929CC: 0x03E00008 '....' - jr         $ra
   0x08C929D0: 0x00000000 '....' - nop
   ...
and so on... So we need to have those calls that do absolutley nothing getting replaced by proper jumps and syscalls, like:

Code: Select all

; Section .sceStub.text - Address 0x08C92974
   0x08C92974: 0x0A200020 ' . .' - j          loc_08800080
   0x08C92978: 0x00000000 '....' - nop       
   0x08C9297C: 0x0A20002B '+. .' - j          loc_088000AC
   0x08C92980: 0x00000000 '....' - nop       
   0x08C92984: 0x03E00008 '....' - jr         $ra
   0x08C92988: 0x00088A8C '....' - syscall    0x222A
   0x08C9298C: 0x03E00008 '....' - jr         $ra
   0x08C92990: 0x00088B8C '....' - syscall    0x222E
   0x08C92994: 0x03E00008 '....' - jr         $ra
   0x08C92998: 0x00088C8C '....' - syscall    0x2232
   0x08C9299C: 0x03E00008 '....' - jr         $ra
   0x08C929A0: 0x000882CC '....' - syscall    0x220B
   0x08C929A4: 0x03E00008 '....' - jr         $ra
   0x08C929A8: 0x000886CC '....' - syscall    0x221B
   0x08C929AC: 0x03E00008 '....' - jr         $ra
   0x08C929B0: 0x0008874C 'L...' - syscall    0x221D
   0x08C929B4: 0x03E00008 '....' - jr         $ra
   0x08C929B8: 0x00084D8C '.M..' - syscall    0x2136
   0x08C929BC: 0x03E00008 '....' - jr         $ra
   0x08C929C0: 0x00084E8C '.N..' - syscall    0x213A
   ...
Each pair is an imported function jump/call. So for example any call in the code that refers to sceKernelCpuSuspendIntr() is actually doing a JAL to the address 0x08C92974, which as you can see will jump to address 0x08800080, which is user mode memory, so no need for syscall. But the question is how do the OS knows what stubs references what function?

For this, there's an ELF section named .lib.stubs that has stub headers like this one:

Code: Select all

typedef struct
{
   u32 library_name_index;
   u16 import_flags;
   u16 library_version;
   u16 import_stubs;
   u16 stub_size;
   u32* nid_pointer;
   u32* jump_pointer;
} tStubEntry;
Each one of this stubs describes the imports for a given library. So we'll have a stub header for each library imported by the ELF. Let's see the meanings of the data important to us:

* library_name_index: this is an index in string table section that holds library name as a NULL terminated character string.
* stub_size: number of stubs to resolve for this library.
* nid_pointer: address of first NID of library in NIDs array.
* jump_pointer: address of first stub to be resolved in stubs array (like seen before ;))


What is a NID? A NID is a 32-bit universal identifier for FW functions. This way, FW recognizes what function we're talking about, just by an integer. For most functions this is first 32-bits of SHA-1 hash of function name, but some NIDs were just randomized by Sony back in 2.70 FW IIRC.

Now it's so simple: we just have to resolve all stubs indicated in each stub header. For each library (we don't even need to know the name, as NIDs are universal ;)), we have to resolve as many NIDs as indicated by stub_size, and for each NID, we have to resolve the correspondent stub. A simple approach in C pseudo-code would look like this:

Code: Select all

/* Resolves imports in ELF's program section already loaded in memory */
unsigned int resolve_imports(tStubEntry* pstub_entry, unsigned int stubs_size, tNIDResolver* nid_table)
{
   int i,j;
   u32* cur_nid;
   u32* cur_call;
   unsigned int resolving_count = 0;

   /* Browse ELF stub's headers */
   for(i=0; i<stubs_size; i+=sizeof(tStubEntry))
   {
      cur_nid = pstub_entry->nid_pointer;
      cur_call = pstub_entry->jump_pointer;
      
      /* For each stub header, browse all stubs */
      for(j=0; j<pstub_entry->stub_size; j++)
      {
         /* Resolve stub */
         resolve_call(cur_nid, cur_call);
         /* Next NID */
         cur_nid++;
         /* Next stub (8 bytes each) */
         cur_call += 2;
         /* Update count */
         resolving_count++;
      }

      /* Next stub */
      pstub_entry++;
   }
   
   return resolving_count;   
}
But the question is now obviously: how to resolve the ELF stubs? Well, you'll have to wait until next chapter ;)
Advertising
I wanna lots of mov al,0xb
Image
"just not into this RA stuffz"

tbg
Posts: 111
Joined: Mon Sep 27, 2010 4:35 pm

Re: [Eloader] 5. Stub headers

Post by tbg » Tue Sep 28, 2010 8:32 am

Translated into Spanish...
Advertising
TBG : Team Extraction member

Post Reply

Return to “Programming and Security”