forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Call Syscalls from plain binary ASM?

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
Hellcat



Joined: 24 Jan 2007
Posts: 84

PostPosted: Sat Jan 03, 2009 1:43 pm    Post subject: Call Syscalls from plain binary ASM? Reply with quote

I know I'm probably going to be stoned to death, but I'll take my chance and ask anyway....

Let's say I have a small block of raw ASM code, injected to somewhere in the PSPs RAM and jumped in to.

Is there a good and known way of calling syscalls (like sceIoOpen and stuff) from there?
Since I'm not having any imports and the like I can't think of a decent way of doing that (besides manually letting the code run through the whole RAM to find the libs I need and fetch the adresses of the calls).

Any hint to make it more easy? :)


Secondly, how do I get the compiler to just make a plain binary from some ASM source, w/o headers, footers or anything else....


Any help apreciated, thanks :)
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Sat Jan 03, 2009 2:17 pm    Post subject: Reply with quote

Firstly, you want to just use GAS, the gnu assembler. It's part of the normal toolchain. Look at gas tutorials for the x86, then substitute MIPS for x86. You'll find various .s and .S files in the PSP SDK source you can look at for examples of syntax. The difference is the .S files are run through the c preprocessor so that you can make defines and such just like with c, even though it's assembly.

For example, in a .s file you would define a constant like this:

Code:
MY_CONST EQU 3


In a .S file, you can still do that, or you can do:

Code:
#define MY_CONST 3


If you're mixing C and asm, the latter method might be easier as you can make one set of defines in a .h file and include it in both c and asm files.

Secondly, it's EXTREMELY easy to call PSP system functions from asm: just put the arguments in a0-a3 and t0-t3 (if more than four args), then do a jal to the function name. For example:

Code:
   li a0,1000
   jal sceKernelDelayThread
   nop


Don't forget about that delay slot! Of course, the above could be done like this:

Code:
   jal sceKernelDelayThread
   li a0,1000


Note that the above is calling USER level functions from user mode.
Back to top
View user's profile Send private message AIM Address
Hellcat



Joined: 24 Jan 2007
Posts: 84

PostPosted: Sat Jan 03, 2009 2:39 pm    Post subject: Reply with quote

Thanks :) That already helps alot!

What I don't get is, when I just do a "jal sceKernelDelayThread", where and how does it get the actual address of "sceKernelDelayThread" to jump to?

Anyway, this is enough to get started already, I think, thanks again! :)
Back to top
View user's profile Send private message
FreePlay



Joined: 04 Jan 2006
Posts: 71
Location: Schenectady, New York, USA

PostPosted: Sat Jan 03, 2009 3:06 pm    Post subject: Reply with quote

J.F.,

I think he's trying to go about using functions without requiring *any* external code.
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Sat Jan 03, 2009 5:07 pm    Post subject: Reply with quote

You mean building the code on the fly inside the app, like Dynamic Recompiling? Same statements still apply, he just has to "compile" the code himself, ORing the address of the function into the opcode for JAL and then storing that at the correct location in memory, then flushing the data cache and invalidating the code cache. That's quite a bit more complex, but still follows the same guidelines as far as the assembly language goes.

The function addresses for the SDK functions are done the way any function address is.

Code:
    code_buffer[curr_index] = JAL_OP | (((u32)&sceKernelDelayThread & 0x0FFFFFFC) >> 2);


Something like that. If you look at the sdk libraries, they're often nothing more than lots of stubs that call the actually library function. The stubs themselves change according to what mode the code is in vs what mode the lib function is.

The encoding of the instructions themselves are in the MIPS32 Architecture: Vol 2. You can find that just about anywhere online. Looking at an existing DR for the PSP might be helpful as well. For that, check out something like Daedalus.
Back to top
View user's profile Send private message AIM Address
Torch



Joined: 28 May 2008
Posts: 842

PostPosted: Sat Jan 03, 2009 9:05 pm    Post subject: Reply with quote

I don't understand how this works either.

Code:
   0x0000003C: 0xAE02123C '<...' - sw         $v0, 4668($s0)
   0x00000040: 0x3C0602BF '...<' - lui        $a2, 0x2BF
; Data ref 0x000010F0 "SystemControl"
   0x00000044: 0x262410F0 '..$&' - addiu      $a0, $s1, 4336
; Data ref 0x00001100 "SystemCtrlForKernel"
   0x00000048: 0x26451100 '..E&' - addiu      $a1, $s2, 4352
   0x0000004C: 0x0C0003AA '....' - jal        SystemCtrlForKernel_159AF5CC


The instruction 0x0C0003AA just jumps to a hardcoded address right?? Assuming thats how it is, how do you know that the function will always be at that address ?? I'm a noob at MIPS..

(Ironically the above is code to find another function :P)
Back to top
View user's profile Send private message
Bubbletune



Joined: 03 Jan 2009
Posts: 28

PostPosted: Sat Jan 03, 2009 9:32 pm    Post subject: Reply with quote

I use this trick a lot when I want a small snippet of code to reside in user memory (I don't know if that's what you want to do but it's a great example so I'll just use that here :P), I just allocate a user heap and copy some pure assembly code in there, then hook a function in user memory with it. :) Anyways, you'll need to do some dynamic linking on the buffer, both jumps, syscalls, imports and accessing of global memory.

Instead of seperately compiling it as a binary, I usually use MIPS opcode macros in C code, such as these. Copy the entire bit from [--- NEW FILE: mips-codegen.h ---] till [--- NEW FILE: test.c ---] (the end of the mips-codegen.h file) in a seperate header file and save it. Note that the 'j' instruction is called mips_jump, and the 'jal' instruction is called mips_jumpl in that header file, but you're free to change it.

Include it in your code and you can use it like this:
Code:
   /* declare the buffer to hold it (normally alloc in user mem) */
   unsigned int code[2];
   
   /* and a pointer towards it as the macros will change it */
   unsigned int *p = code;

   /* li $a0, 1000000 */
   mips_addiu(p, mips_a0, mips_zero, 1000000);
   
   /* syscall [syscall of DelayThread] */
   mips_syscall(p, sceKernelQuerySystemCall(sctrlHENFindFunction("sceThreadManager", "ThreadManForUser", 0xCEADEB47)));

Our 'code' buffer now contains the instructions to execute sceKernelDelayThread(1000000), and you can jump in to it, or place a hook towards it. Note that instructions like 'li' are actually pseudo-instructions, and what they really do is 'addiu' with the source register set to zero.

@Torch ELF (and PRX) files contain a relocation table with all addresses that require relocation (because they start at zero), which the ELF loader will apply when loading the module. However, talking about the jump, what you mentioned is the opcode, you should search the function name in that assembly and you'll find the stub of that function, which looks like a simple 'jr $ra, nop' in the assembly. However, again, the ELF loader replaces these useless instructions with a jump towards the function exported in the other module, so theoretically you're taking two jumps before you reach the actual function.

:)
Back to top
View user's profile Send private message
ne0h



Joined: 21 Feb 2008
Posts: 386

PostPosted: Sat Jan 03, 2009 9:40 pm    Post subject: Reply with quote

Quote:
ELF (and PRX) files contain a relocation table with all addresses that require relocation (because they start at zero), which the ELF loader will apply when loading the module.

uuu, finally I know what's the relocation table, thanks
_________________
Get Xplora!
Back to top
View user's profile Send private message
Torch



Joined: 28 May 2008
Posts: 842

PostPosted: Sat Jan 03, 2009 9:59 pm    Post subject: Reply with quote

But when you need to write code, such as code which an exploit jumps into, how would external calls be resolved then? In such cases you would need to manually find the functions right?
Back to top
View user's profile Send private message
Hellcat



Joined: 24 Jan 2007
Posts: 84

PostPosted: Sat Jan 03, 2009 10:21 pm    Post subject: Reply with quote

Torch wrote:
But when you need to write code, such as code which an exploit jumps into, how would external calls be resolved then? In such cases you would need to manually find the functions right?

THAT exactely is my situation in this case!

The MIPS itself isn't the problem, finding the function tables is.
When the injected code is loaded and jumped in to, there's no background process that resolves stubs and such, I'm in the empty void, left alone.

So, for doing anything usefull I'd need to find a way to call some syscalls by finding the addresses to JAL to.
Can't be that hard, previous things (like the 2.00->1.50 downgrader or eLoader) did it, I think.

I'll take a closer look at the old downgrader, I think....
Back to top
View user's profile Send private message
Bubbletune



Joined: 03 Jan 2009
Posts: 28

PostPosted: Sat Jan 03, 2009 10:32 pm    Post subject: Reply with quote

Hellcat wrote:
Torch wrote:
But when you need to write code, such as code which an exploit jumps into, how would external calls be resolved then? In such cases you would need to manually find the functions right?

THAT exactely is my situation in this case!

The MIPS itself isn't the problem, finding the function tables is.
When the injected code is loaded and jumped in to, there's no background process that resolves stubs and such, I'm in the empty void, left alone.

So, for doing anything usefull I'd need to find a way to call some syscalls by finding the addresses to JAL to.
Can't be that hard, previous things (like the 2.00->1.50 downgrader or eLoader) did it, I think.

I'll take a closer look at the old downgrader, I think....


I've wondered that for ages, due to the fact HEN source codes were never released (just the samples). I think they search the stubs of the game being exploited, which should be at the same address in most cases as far as I know.
Edit: Suspicion confirmed, reversed a bit of 3.50 HEN and it turns out it simply jumps right in to the imports of Lumines with hardcoded addresses :)
Back to top
View user's profile Send private message
Torch



Joined: 28 May 2008
Posts: 842

PostPosted: Sun Jan 04, 2009 5:28 am    Post subject: Reply with quote

Bubbletune wrote:

I've wondered that for ages, due to the fact HEN source codes were never released (just the samples). I think they search the stubs of the game being exploited, which should be at the same address in most cases as far as I know.
Edit: Suspicion confirmed, reversed a bit of 3.50 HEN and it turns out it simply jumps right in to the imports of Lumines with hardcoded addresses :)


The advantages of everyone's hardware and probably path of execution being 100% identical....

Also probably why the exploits required to try multiple times. Due to all environmental conditions being identical for everyone, the address are bound to turn out to be the same once in a while, even if there is a dynamic element involved.
Back to top
View user's profile Send private message
Bubbletune



Joined: 03 Jan 2009
Posts: 28

PostPosted: Sun Jan 04, 2009 6:24 am    Post subject: Reply with quote

Torch wrote:
The advantages of everyone's hardware and probably path of execution being 100% identical....

Also probably why the exploits required to try multiple times. Due to all environmental conditions being identical for everyone, the address are bound to turn out to be the same once in a while, even if there is a dynamic element involved.


In the case of game exploits this is less likely, as the game will be exactly the same for everyone when using the same savedata. In the VSH however, there is so, so, so many stuff being done by lots of modules, it's just a matter of luck to have the correct address.
Back to top
View user's profile Send private message
Torch



Joined: 28 May 2008
Posts: 842

PostPosted: Sun Jan 04, 2009 6:26 am    Post subject: Reply with quote

Bubbletune wrote:

In the case of game exploits this is less likely, as the game will be exactly the same for everyone when using the same savedata. In the VSH however, there is so, so, so many stuff being done by lots of modules, it's just a matter of luck to have the correct address.


But in the VSH we also have SO MANY useful stubs to jump into :D :D :D
Back to top
View user's profile Send private message
ne0h



Joined: 21 Feb 2008
Posts: 386

PostPosted: Tue Jan 06, 2009 2:17 am    Post subject: Reply with quote

Hellcat,
do you know how to get functions address only of the functions imported by the game?
_________________
Get Xplora!
Back to top
View user's profile Send private message
Hellcat



Joined: 24 Jan 2007
Posts: 84

PostPosted: Tue Jan 06, 2009 12:08 pm    Post subject: Reply with quote

You can use PRXTool to do disasm of the main binary executable of the game, it will give you the stub adresses for everything the game imports.

You can the use those to call the functions the game imports.

That's what has been done for the Sparta-SDK by Freeplay and MaTiAz.
Back to top
View user's profile Send private message
ne0h



Joined: 21 Feb 2008
Posts: 386

PostPosted: Tue Jan 06, 2009 8:57 pm    Post subject: Reply with quote

Ok, good...
Now, we have some sceKernelLoad\Start* functions, I've see that some modules in the UMD are not compressed with ~SCE or ~PSP signature, only plain ELF, can I load another module with my own imports?
I know that prabably is not possible but why?
_________________
Get Xplora!
Back to top
View user's profile Send private message
Torch



Joined: 28 May 2008
Posts: 842

PostPosted: Tue Jan 06, 2009 8:59 pm    Post subject: Reply with quote

ne0h wrote:
Ok, good...
Now, we have some sceKernelLoad\Start* functions, I've see that some modules in the UMD are not compressed with ~SCE or ~PSP signature, only plain ELF, can I load another module with my own imports?
I know that prabably is not possible but why?


No, you can't do anything like that until there is a working HEN core. The Sony checks will still be present to decrypt the module etc.

You can only jump stuff already in memory.
Back to top
View user's profile Send private message
ne0h



Joined: 21 Feb 2008
Posts: 386

PostPosted: Tue Jan 06, 2009 9:24 pm    Post subject: Reply with quote

Yes but, some files like mpeg.prx are not encrypted, how is it loaded?
Have this ELFs the Sony signature or something else? or are simple ELF files?
EDIT:
I've that only the user mode prx's is unencrypted, why?
There's no signcheck on user modules???
_________________
Get Xplora!
Back to top
View user's profile Send private message
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Sun Jan 11, 2009 11:23 pm    Post subject: Reply with quote

To answer the original question : there's an opcode, syscall 0xnnnn, which will directly invoke a syscall.

The tricky part is figuring out what the syscall ID that you want is. In the early days, syscall tables were static, varying only depending on the firmware and mode (VSH, game, etc.) in use.

But later firmwares (from around 2.50) started messing with that to make it harder to do exploits. Suffice to say, the most reliable way to find the syscall ID for a given function now is to find it imported by another module in your current environment, and read the syscall opcode from that module's import table.

But if you can find it already imported, then as has been said elsewhere, you might as well just jump into the jump table in the import data.

If you want to mess with this stuff further, you'll need to look into how the ELF import tables are laid out (they're just done according to the ELF standards). Using that knowledge you can search through RAM for stuff that looks like a module import table, and retrieve the info you need.

You can PM me for further details if you want to take it further, I'm in the process of revisiting all this stuff for the gripshift exploit.
_________________
Got a v2.0-v2.80 firmware PSP? Download the eLoader here to run homebrew on it!
The PSP Homebrew Database needs you!
Back to top
View user's profile Send private message
m0skit0



Joined: 02 Jun 2009
Posts: 226

PostPosted: Sat Jul 18, 2009 2:22 am    Post subject: Reply with quote

Awesome post!!! (sorry I had to say it)
_________________
The Incredible Bill Gates wrote:
The obvious mathematical breakthrough would be development of an easy way to factor large prime numbers.
Back to top
View user's profile Send private message
kralyk



Joined: 06 Apr 2008
Posts: 114
Location: Czech Republic, central EU

PostPosted: Sat Jul 18, 2009 3:04 am    Post subject: Reply with quote

how about using mips sceKernelQuerySystemCall(desired_function)?

Whats the difference between jumping to a syscall directly and using sceKernelQuerySystemCall?
_________________
...sorry for my english...
Back to top
View user's profile Send private message
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Sat Jul 18, 2009 3:20 am    Post subject: Reply with quote

sKQuerySystemCall returns the syscall ID, IIRC.

That's the easy way to find the syscall ID if you happen to have access to kernel mode and have the function address / syscall ID for sKQuerySystemCall in hand.

But if you're working at a very low level in raw assembly and don't have access to niceties such as getting the loader to fix up your import table for you, then sKQuerySystemCall may just be a distant dream.
_________________
Got a v2.0-v2.80 firmware PSP? Download the eLoader here to run homebrew on it!
The PSP Homebrew Database needs you!
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group