Kenel mode / User Mode switch

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
apache37
Posts: 76
Joined: Fri Jun 04, 2004 3:13 pm

Kenel mode / User Mode switch

Post by apache37 »

Is there a way if I start my thread in user mode that I can change to kernel mode and vice versa? On the ps2 it was quite easy: DI(); ee_kmode_enter(); EI(); etc..

Thx!
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post by mrbrown »

Unless you put yourself in user mode by setting the appropiate bit in the cop0 status register, once you create a user mode thread you cannot flip back and forth between user and kernel mode.

If you are flipping back and forth, just use the code in the ee_kmode_enter() and ee_kmode_exit() macros.
apache37
Posts: 76
Joined: Fri Jun 04, 2004 3:13 pm

Post by apache37 »

Well if I start in kernel mode can I set the cop0 register and drop into user mode?
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post by mrbrown »

Yes, that's the first thing I said.
apache37
Posts: 76
Joined: Fri Jun 04, 2004 3:13 pm

Post by apache37 »

static inline int kmode_exit(void)
{
int status;

__asm__ volatile (
".set\tnoreorder\n\t" \
"mfc0\t%0, $12\n\t" \
"ori\t%0, 0x10\n\t" \
"mtc0\t%0, $12\n\t" \
"sync.p\n\t" : "=r" (status));

return status;
}

kmode_exit();
freezes the PSP.

Is it that I have the wrong registers?
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

Is this method still applicable in 2009? Or only on older firmware. I'm wondering if I can make user mode calls from my kernel thread if I do this.
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

The code as presented would never have worked on the PSP, it isn't quite as simple as that :)
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

Basically is there any way to redirect a user function call to a function thats in a kernel plugin?
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

So what you _actually_ want to do is get something in user mode to call a kernel function and not the other way around? That is what syscalls are for ;) In all serious you could export a function from your kernel module, find the syscall (that is up to you to work out :P) and replace the call to a syscall.
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

TyRaNiD wrote:So what you _actually_ want to do is get something in user mode to call a kernel function and not the other way around? That is what syscalls are for ;) In all serious you could export a function from your kernel module, find the syscall (that is up to you to work out :P) and replace the call to a syscall.
No I want to hook a pure user function call from my kernel module, without having to put the new function in user space. Or can I do something like replacing the user ordinary function call with a MAKE_SYSCALL ?? Will that work? I assume I will have to tamper with the surrounding code, set up registers etc, but I don't know MIPS.
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

From the stub list, it appears that the vblank functions are syscalls, but hooking them with syscall patch doesnt seem to work. I assume games use a statically linked version or something, so I wanted to hook that.
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

Stuff like sceDisplayWaitBlankStart are syscalls from what I recall, nothing more nothing less.
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

TyRaNiD wrote:Stuff like sceDisplayWaitBlankStart are syscalls from what I recall, nothing more nothing less.
Regarding my original question, is it possible?

I need to hook a user mode function, from my kernel module (an ordinary function, not a syscall). Can I replace the function call with a syscall?? How would I need to change any surrounding code if necessary?

I read something about the setddrmemoryprotection function that allows you to jump into a kernel function from a user thread, but I don't think any one got it to work. So I assume turning it into a syscall will work.
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

Well you could unlock kernel memory and jump into it, the issue comes if your code (or any kernel functions you call) uses absolute addresses for any variables etc. as while you will have unlocked the lower 4 megs of ram you still won't be able to access it through Kseg0 (i.e. addresses at 0x8xxxxxxx). If you are just patching the jal instruction then if you went the syscall route all you would need to do would be swap the jal and its delay branch around and then set the syscall as the second instruction.

e.g. if you have:

Code: Select all

jal someuserfunction
move $a0, $s0
You convert to:

Code: Select all

move $a0, $s0
syscall #num
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

I'll try converting it to a syscall. So I just have to make my module export a kernel-user function and when my module starts it will automatically make a syscall table entry for the function right.

How do I get the #num for my function? I understand that its not simply the address value in the syscall table....
User avatar
Coldbird
Posts: 97
Joined: Thu Feb 08, 2007 7:22 am

Post by Coldbird »

Sorry to bump a somewhat old topic but I've got the same question as Torch.
Someone know a way to figure out that num?
Been gone for some time. Now I'm back. Someone mind getting me up-2-date?
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

Its not easy on new firmware. The tables are randomized.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

The way some are found is to look at the old code when the NIDs were all computed from the name, then look for similar code in the new libs and see which random NID uses that code.
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

J.F. wrote:The way some are found is to look at the old code when the NIDs were all computed from the name, then look for similar code in the new libs and see which random NID uses that code.
?? But thats to find the NID. We want to find the syscall number for the function in the syscall table so that we can write a MIPS instruction "syscall num".

We already know the NID because we want to make a syscall to OUR OWN coded function in our kernel PRX. Apparently we need to find the syscall number that gets entered in the table when the PRX is loaded.

I'm a bit hazy on how the prx loader/syscall table and stuff works.
User avatar
Coldbird
Posts: 97
Joined: Thu Feb 08, 2007 7:22 am

Post by Coldbird »

Even if we didn't know our own NIDs... we could just compute them via SHA-1 from the functionnames... (which is what I do... I beg you - don't ask... xD)

Any idea where this numtable is located in memory? If we can just dump it it shouldn't be difficult to interpret it...

We would just have to disable interrupts for a few secs, dump it and reenable interrupts then.
Been gone for some time. Now I'm back. Someone mind getting me up-2-date?
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

The apihook functions from psplink already clearly show how to iterate through the syscall table and find function addresses.

That is what is used for patching one syscall to another for syscall hooks. The thing is you just give the addresses of the function you want to hook and the apihook functions replace it with the address of your hook function. The syscall number of the original function remains the same, only the address it jumps to is changed.

You'll have to figure out yourself and how to find the syscall number for your hook function address. (Because when you load your kernel PRX, its syscall exports will be entered in the table with their own syscall numbers.)
User avatar
Coldbird
Posts: 97
Joined: Thu Feb 08, 2007 7:22 am

Post by Coldbird »

Yeah but that table must be located somewhere afterall... I would need to know where.
Oh well... I will figure out a way I suppose. Got the sourcecode somewhere anyway.
Been gone for some time. Now I'm back. Someone mind getting me up-2-date?
Post Reply