taiHEN  1.0
CFW framework for PS Vita
taihen-user.c
1 /* taihen-user.c -- user exports for taiHEN
2  *
3  * Copyright (C) 2016 Yifan Lu
4  *
5  * This software may be modified and distributed under the terms
6  * of the MIT license. See the LICENSE file for details.
7  */
8 #include <psp2kern/types.h>
9 #include <psp2kern/sblacmgr.h>
10 #include <psp2kern/kernel/cpu.h>
11 #include <psp2kern/kernel/modulemgr.h>
12 #include <psp2kern/kernel/sysmem.h>
13 #include <psp2kern/kernel/threadmgr.h>
14 #include <psp2/kernel/error.h>
15 #include "error.h"
16 #include "hen.h"
17 #include "module.h"
18 #include "patches.h"
19 #include "taihen_internal.h"
20 
22 #define MAX_NAME_LEN 256
23 
25 #define MAX_ARGS_SIZE 256
26 
45  tai_hook_args_t kargs;
46  uint32_t func_nid;
47  const void *hook_func;
48  uint32_t state;
49  char k_module[MAX_NAME_LEN];
50  int main_mod;
51  tai_hook_ref_t k_ref;
52  SceUID kid, ret;
53  SceUID pid;
54 
55  ENTER_SYSCALL(state);
56  kargs.size = 0;
57  sceKernelMemcpyUserToKernel(&kargs, (uintptr_t)args, sizeof(kargs));
58  if (kargs.size == sizeof(kargs)) {
59  pid = sceKernelGetProcessId();
60  main_mod = (kargs.module == TAI_MAIN_MODULE);
61  if (main_mod || sceKernelStrncpyUserToKernel(k_module, (uintptr_t)kargs.module, MAX_NAME_LEN) < MAX_NAME_LEN) {
62  kid = taiHookFunctionExportForKernel(pid, &k_ref, main_mod ? kargs.module : k_module, kargs.library_nid, kargs.func_nid, kargs.hook_func);
63  if (kid >= 0) {
64  sceKernelMemcpyKernelToUser((uintptr_t)p_hook, &k_ref, sizeof(*p_hook));
65  ret = sceKernelCreateUserUid(pid, kid);
66  LOG("kernel uid: %x, user uid: %x", kid, ret);
67  } else {
68  ret = kid;
69  }
70  } else {
71  ret = TAI_ERROR_USER_MEMORY;
72  }
73  } else {
74  LOG("invalid args size: %x", kargs.size);
75  ret = TAI_ERROR_USER_MEMORY;
76  }
77  EXIT_SYSCALL(state);
78  return ret;
79 }
80 
106  tai_hook_args_t kargs;
107  uint32_t state;
108  char k_module[MAX_NAME_LEN];
109  int main_mod;
110  tai_hook_ref_t k_ref;
111  SceUID kid, ret;
112  SceUID pid;
113 
114  ENTER_SYSCALL(state);
115  sceKernelMemcpyUserToKernel(&kargs, (uintptr_t)args, sizeof(kargs));
116  if (kargs.size == sizeof(kargs)) {
117  pid = sceKernelGetProcessId();
118  main_mod = (kargs.module == TAI_MAIN_MODULE);
119  if (main_mod || sceKernelStrncpyUserToKernel(k_module, (uintptr_t)kargs.module, MAX_NAME_LEN) < MAX_NAME_LEN) {
120  kid = taiHookFunctionImportForKernel(pid, &k_ref, main_mod ? kargs.module : k_module, kargs.library_nid, kargs.func_nid, kargs.hook_func);
121  if (kid >= 0) {
122  sceKernelMemcpyKernelToUser((uintptr_t)p_hook, &k_ref, sizeof(*p_hook));
123  ret = sceKernelCreateUserUid(pid, kid);
124  LOG("kernel uid: %x, user uid: %x", kid, ret);
125  } else {
126  ret = kid;
127  }
128  } else {
129  ret = TAI_ERROR_USER_MEMORY;
130  }
131  } else {
132  LOG("invalid args size: %x", kargs.size);
133  ret = TAI_ERROR_USER_MEMORY;
134  }
135  EXIT_SYSCALL(state);
136  return ret;
137 }
138 
156  tai_offset_args_t kargs;
157  uint32_t state;
158  tai_hook_ref_t k_ref;
159  SceUID ret;
160  SceUID pid;
161  SceUID kid;
162 
163  ENTER_SYSCALL(state);
164  kargs.size = 0;
165  sceKernelMemcpyUserToKernel(&kargs, (uintptr_t)args, sizeof(kargs));
166  if (kargs.size == sizeof(kargs)) {
167  pid = sceKernelGetProcessId();
168  kid = sceKernelKernelUidForUserUid(pid, kargs.modid);
169  if (kid >= 0) {
170  ret = taiHookFunctionOffsetForKernel(pid, &k_ref, kid, kargs.segidx, kargs.offset, kargs.thumb, kargs.source);
171  if (ret >= 0) {
172  sceKernelMemcpyKernelToUser((uintptr_t)p_hook, &k_ref, sizeof(*p_hook));
173  ret = sceKernelCreateUserUid(pid, ret);
174  LOG("user uid: %x", ret);
175  }
176  } else {
177  LOG("Error getting kernel uid for %x: %x", kargs.modid, kid);
178  ret = kid;
179  }
180  } else {
181  LOG("invalid args size: %x", kargs.size);
182  ret = TAI_ERROR_USER_MEMORY;
183  }
184  EXIT_SYSCALL(state);
185  return ret;
186 }
187 
209 int taiGetModuleInfo(const char *module, tai_module_info_t *info) {
210  int main_mod;
211  char k_module[MAX_NAME_LEN];
212  uint32_t state;
213  SceUID pid;
214  tai_module_info_t k_info;
215  int ret;
216 
217  ENTER_SYSCALL(state);
218  pid = sceKernelGetProcessId();
219  main_mod = (module == TAI_MAIN_MODULE);
220  if (main_mod || sceKernelStrncpyUserToKernel(k_module, (uintptr_t)module, MAX_NAME_LEN) < MAX_NAME_LEN) {
221  sceKernelMemcpyUserToKernel(&k_info, (uintptr_t)info, sizeof(size_t));
222  if (k_info.size == sizeof(k_info)) {
223  ret = taiGetModuleInfoForKernel(pid, main_mod ? module : k_module, &k_info);
224  sceKernelMemcpyKernelToUser((uintptr_t)info, &k_info, k_info.size);
225  } else {
226  ret = TAI_ERROR_USER_MEMORY;
227  }
228  } else {
229  ret = TAI_ERROR_USER_MEMORY;
230  }
231  EXIT_SYSCALL(state);
232  return ret;
233 }
234 
246 int taiHookRelease(SceUID tai_uid, tai_hook_ref_t hook) {
247  uint32_t state;
248  SceUID pid, kid;
249  int ret;
250 
251  ENTER_SYSCALL(state);
252  pid = sceKernelGetProcessId();
253  kid = sceKernelKernelUidForUserUid(pid, tai_uid);
254  if (kid >= 0) {
255  ret = taiHookReleaseForKernel(kid, hook);
256  sceKernelDeleteUserUid(pid, tai_uid);
257  } else {
258  ret = kid;
259  }
260  EXIT_SYSCALL(state);
261  return ret;
262 }
263 
276 SceUID taiInjectAbs(void *dest, const void *src, size_t size) {
277  uint32_t state;
278  tai_hook_ref_t k_ref;
279  SceUID ret;
280  SceUID pid;
281 
282  ENTER_SYSCALL(state);
283  pid = sceKernelGetProcessId();
284  ret = taiInjectAbsForKernel(pid, dest, src, size);
285  if (ret >= 0) {
286  ret = sceKernelCreateUserUid(pid, ret);
287  LOG("user uid: %x", ret);
288  }
289  EXIT_SYSCALL(state);
290  return ret;
291 }
292 
305  tai_offset_args_t kargs;
306  uint32_t state;
307  tai_hook_ref_t k_ref;
308  SceUID ret;
309  SceUID pid;
310 
311  ENTER_SYSCALL(state);
312  kargs.size = 0;
313  sceKernelMemcpyUserToKernel(&kargs, (uintptr_t)args, sizeof(kargs));
314  if (kargs.size == sizeof(kargs)) {
315  pid = sceKernelGetProcessId();
316  ret = sceKernelKernelUidForUserUid(pid, kargs.modid);
317  if (ret >= 0) {
318  kargs.modid = ret;
319  ret = taiInjectDataForKernel(pid, kargs.modid, kargs.segidx, kargs.offset, kargs.source, kargs.source_size);
320  if (ret >= 0) {
321  ret = sceKernelCreateUserUid(pid, ret);
322  LOG("user uid: %x", ret);
323  }
324  } else {
325  LOG("Error getting kernel uid for %x: %x", kargs.modid, ret);
326  }
327  } else {
328  LOG("invalid args size: %x", kargs.size);
329  ret = TAI_ERROR_USER_MEMORY;
330  }
331  EXIT_SYSCALL(state);
332  return ret;
333 }
334 
344 int taiInjectRelease(SceUID tai_uid) {
345  uint32_t state;
346  SceUID pid, kid;
347  int ret;
348 
349  ENTER_SYSCALL(state);
350  pid = sceKernelGetProcessId();
351  kid = sceKernelKernelUidForUserUid(pid, tai_uid);
352  if (kid >= 0) {
353  ret = taiInjectReleaseForKernel(kid);
354  sceKernelDeleteUserUid(pid, tai_uid);
355  } else {
356  ret = kid;
357  }
358  EXIT_SYSCALL(state);
359  return ret;
360 }
361 
373 SceUID taiLoadKernelModule(const char *path, int flags, void *opt) {
374  uint32_t state;
375  char k_path[MAX_NAME_LEN];
376  SceUID pid;
377  int ret;
378 
379  ENTER_SYSCALL(state);
380  pid = sceKernelGetProcessId();
381  if (sceSblACMgrIsShell(0)) {
382  if (opt == NULL) {
383  if (sceKernelStrncpyUserToKernel(k_path, (uintptr_t)path, MAX_NAME_LEN) < MAX_NAME_LEN) {
384  ret = sceKernelLoadModuleForDriver(k_path, flags, NULL);
385  LOG("loaded %s: %x", k_path, ret);
386  if (ret >= 0) {
387  ret = sceKernelCreateUserUid(pid, ret);
388  LOG("user uid: %x", ret);
389  }
390  } else {
391  ret = TAI_ERROR_USER_MEMORY;
392  }
393  } else {
394  ret = TAI_ERROR_INVALID_ARGS;
395  }
396  } else {
397  ret = TAI_ERROR_NOT_ALLOWED;
398  }
399  EXIT_SYSCALL(state);
400  return ret;
401 }
402 
416 int taiStartKernelModuleForUser(SceUID modid, tai_module_args_t *args, void *opt, int *res) {
417  tai_module_args_t kargs;
418  char buf[MAX_ARGS_SIZE];
419  uint32_t state;
420  int ret;
421  int k_res;
422  SceUID pid;
423 
424  ENTER_SYSCALL(state);
425  pid = sceKernelGetProcessId();
426  if (sceSblACMgrIsShell(0)) {
427  kargs.size = 0;
428  sceKernelMemcpyUserToKernel(&kargs, (uintptr_t)args, sizeof(kargs));
429  if (kargs.size == sizeof(kargs)) {
430  if (kargs.args <= MAX_ARGS_SIZE && opt == NULL) {
431  ret = sceKernelKernelUidForUserUid(pid, modid);
432  if (ret >= 0) {
433  modid = ret;
434  ret = sceKernelMemcpyUserToKernel(buf, (uintptr_t)kargs.argp, kargs.args);
435  if (ret >= 0) {
436  k_res = 0;
437  ret = sceKernelStartModuleForDriver(modid, kargs.args, buf, kargs.flags, NULL, &k_res);
438  if (res) {
439  sceKernelMemcpyKernelToUser((uintptr_t)res, &k_res, sizeof(*res));
440  }
441  }
442  } else {
443  LOG("Error getting kernel uid for %x: %x", modid, ret);
444  }
445  } else {
446  LOG("invalid args size: %x", kargs.size);
447  ret = TAI_ERROR_USER_MEMORY;
448  }
449  } else {
450  ret = TAI_ERROR_INVALID_ARGS;
451  }
452  } else {
453  ret = TAI_ERROR_NOT_ALLOWED;
454  }
455  EXIT_SYSCALL(state);
456  return ret;
457 }
458 
469 SceUID taiLoadStartKernelModuleForUser(const char *path, tai_module_args_t *args) {
470  tai_module_args_t kargs;
471  char buf[MAX_ARGS_SIZE];
472  char k_path[MAX_NAME_LEN];
473  uint32_t state;
474  SceUID modid;
475  int ret;
476  SceUID pid;
477 
478  ENTER_SYSCALL(state);
479  pid = sceKernelGetProcessId();
480  if (sceSblACMgrIsShell(0)) {
481  kargs.size = 0;
482  sceKernelMemcpyUserToKernel(&kargs, (uintptr_t)args, sizeof(kargs));
483  if (kargs.size == sizeof(kargs)) {
484  if (kargs.args <= MAX_ARGS_SIZE) {
485  ret = sceKernelMemcpyUserToKernel(buf, (uintptr_t)kargs.argp, kargs.args);
486  if (ret >= 0) {
487  if (sceKernelStrncpyUserToKernel(k_path, (uintptr_t)path, MAX_NAME_LEN) < MAX_NAME_LEN) {
488  ret = sceKernelLoadStartModuleForDriver(k_path, kargs.args, buf, kargs.flags, NULL, NULL);
489  LOG("loaded %s: %x", k_path, ret);
490  if (ret >= 0) {
491  ret = sceKernelCreateUserUid(pid, ret);
492  LOG("user uid: %x", ret);
493  }
494  } else {
495  ret = TAI_ERROR_USER_MEMORY;
496  }
497  }
498  } else {
499  ret = TAI_ERROR_INVALID_ARGS;
500  }
501  } else {
502  LOG("invalid args size: %x", kargs.size);
503  ret = TAI_ERROR_USER_MEMORY;
504  }
505  } else {
506  ret = TAI_ERROR_NOT_ALLOWED;
507  }
508  EXIT_SYSCALL(state);
509  return ret;
510 }
511 
522 SceUID taiLoadStartModuleForPidForUser(const char *path, tai_module_args_t *args) {
523  tai_module_args_t kargs;
524  char buf[MAX_ARGS_SIZE];
525  char k_path[MAX_NAME_LEN];
526  uint32_t state;
527  SceUID modid;
528  int ret;
529 
530 
531  ENTER_SYSCALL(state);
532  if (sceSblACMgrIsShell(0)) {
533  kargs.size = 0;
534  sceKernelMemcpyUserToKernel(&kargs, (uintptr_t)args, sizeof(kargs));
535  if (kargs.size == sizeof(kargs)) {
536  if (kargs.args <= MAX_ARGS_SIZE) {
537  ret = sceKernelMemcpyUserToKernel(buf, (uintptr_t)kargs.argp, kargs.args);
538  if (ret >= 0) {
539  if (sceKernelStrncpyUserToKernel(k_path, (uintptr_t)path, MAX_NAME_LEN) < MAX_NAME_LEN) {
540  ret = sceKernelLoadStartModuleForPid(kargs.pid, k_path, kargs.args, buf, kargs.flags, NULL, NULL);
541  LOG("loaded %s: %x", k_path, ret);
542  if (ret >= 0) {
543  ret = sceKernelCreateUserUid(kargs.pid, ret);
544  LOG("user uid: %x", ret);
545  }
546  } else {
547  ret = TAI_ERROR_USER_MEMORY;
548  }
549  }
550  } else {
551  ret = TAI_ERROR_INVALID_ARGS;
552  }
553  } else {
554  LOG("invalid args size: %x", kargs.size);
555  ret = TAI_ERROR_USER_MEMORY;
556  }
557  } else {
558  ret = TAI_ERROR_NOT_ALLOWED;
559  }
560  EXIT_SYSCALL(state);
561  return ret;
562 }
563 
576 int taiStopKernelModuleForUser(SceUID modid, tai_module_args_t *args, void *opt, int *res) {
577  tai_module_args_t kargs;
578  char buf[MAX_ARGS_SIZE];
579  uint32_t state;
580  int ret;
581  int k_res;
582  SceUID pid;
583  SceUID kid;
584 
585  ENTER_SYSCALL(state);
586  pid = sceKernelGetProcessId();
587  if (sceSblACMgrIsShell(0)) {
588  kargs.size = 0;
589  sceKernelMemcpyUserToKernel(&kargs, (uintptr_t)args, sizeof(kargs));
590  if (kargs.size == sizeof(kargs)) {
591  if (kargs.args <= MAX_ARGS_SIZE && opt == NULL) {
592  kid = sceKernelKernelUidForUserUid(pid, modid);
593  if (kid >= 0) {
594  ret = sceKernelMemcpyUserToKernel(buf, (uintptr_t)kargs.argp, kargs.args);
595  if (ret >= 0) {
596  k_res = 0;
597  ret = sceKernelStopModuleForDriver(kid, kargs.args, buf, kargs.flags, NULL, &k_res);
598  if (res) {
599  sceKernelMemcpyKernelToUser((uintptr_t)res, &k_res, sizeof(*res));
600  }
601  if (ret >= 0) {
602  sceKernelDeleteUserUid(pid, modid);
603  }
604  }
605  } else {
606  LOG("Error getting kernel uid for %x: %x", modid, kid);
607  ret = kid;
608  }
609  } else {
610  ret = TAI_ERROR_INVALID_ARGS;
611  }
612  } else {
613  LOG("invalid args size: %x", kargs.size);
614  ret = TAI_ERROR_USER_MEMORY;
615  }
616  } else {
617  ret = TAI_ERROR_NOT_ALLOWED;
618  }
619  EXIT_SYSCALL(state);
620  return ret;
621 }
622 
633 int taiUnloadKernelModule(SceUID modid, int flags, void *opt) {
634  uint32_t state;
635  SceUID pid;
636  SceUID kid;
637  int ret;
638 
639  ENTER_SYSCALL(state);
640  pid = sceKernelGetProcessId();
641  if (sceSblACMgrIsShell(0)) {
642  if (opt == NULL) {
643  kid = sceKernelKernelUidForUserUid(pid, modid);
644  if (kid >= 0) {
645  ret = sceKernelUnloadModuleForDriver(kid, flags, NULL);
646  if (ret >= 0) {
647  sceKernelDeleteUserUid(pid, modid);
648  }
649  } else {
650  LOG("Error getting kernel uid for %x: %x", modid, kid);
651  ret = kid;
652  }
653  } else {
654  ret = TAI_ERROR_INVALID_ARGS;
655  }
656  } else {
657  ret = TAI_ERROR_NOT_ALLOWED;
658  }
659  EXIT_SYSCALL(state);
660  return ret;
661 }
662 
675 int taiStopUnloadKernelModuleForUser(SceUID modid, tai_module_args_t *args, void *opt, int *res) {
676  tai_module_args_t kargs;
677  char buf[MAX_ARGS_SIZE];
678  uint32_t state;
679  int ret;
680  int k_res;
681  SceUID pid;
682  SceUID kid;
683 
684  ENTER_SYSCALL(state);
685  pid = sceKernelGetProcessId();
686  if (sceSblACMgrIsShell(0)) {
687  kargs.size = 0;
688  sceKernelMemcpyUserToKernel(&kargs, (uintptr_t)args, sizeof(kargs));
689  if (kargs.size == sizeof(kargs)) {
690  if (kargs.args <= MAX_ARGS_SIZE && opt == NULL) {
691  kid = sceKernelKernelUidForUserUid(pid, modid);
692  if (kid >= 0) {
693  ret = sceKernelMemcpyUserToKernel(buf, (uintptr_t)kargs.argp, kargs.args);
694  if (ret >= 0) {
695  k_res = 0;
696  ret = sceKernelStopUnloadModuleForDriver(kid, kargs.args, buf, kargs.flags, NULL, &k_res);
697  if (res) {
698  sceKernelMemcpyKernelToUser((uintptr_t)res, &k_res, sizeof(*res));
699  }
700  if (ret >= 0) {
701  sceKernelDeleteUserUid(pid, modid);
702  }
703  }
704  } else {
705  LOG("Error getting kernel uid for %x: %x", modid, kid);
706  ret = kid;
707  }
708  } else {
709  ret = TAI_ERROR_INVALID_ARGS;
710  }
711  } else {
712  LOG("invalid args size: %x", kargs.size);
713  ret = TAI_ERROR_USER_MEMORY;
714  }
715  } else {
716  ret = TAI_ERROR_NOT_ALLOWED;
717  }
718  EXIT_SYSCALL(state);
719  return ret;
720 }
721 
734 int taiStopModuleForPidForUser(SceUID modid, tai_module_args_t *args, void *opt, int *res) {
735  tai_module_args_t kargs;
736  char buf[MAX_ARGS_SIZE];
737  uint32_t state;
738  int ret;
739  int k_res;
740  SceUID kid;
741 
742  ENTER_SYSCALL(state);
743  if (sceSblACMgrIsShell(0)) {
744  kargs.size = 0;
745  sceKernelMemcpyUserToKernel(&kargs, (uintptr_t)args, sizeof(kargs));
746  if (kargs.size == sizeof(kargs)) {
747  if (kargs.args <= MAX_ARGS_SIZE && opt == NULL) {
748  kid = sceKernelKernelUidForUserUid(kargs.pid, modid);
749  if (kid >= 0) {
750  ret = sceKernelMemcpyUserToKernel(buf, (uintptr_t)kargs.argp, kargs.args);
751  if (ret >= 0) {
752  k_res = 0;
753  ret = sceKernelStopModuleForPid(kargs.pid, kid, kargs.args, buf, kargs.flags, NULL, &k_res);
754  if (res) {
755  sceKernelMemcpyKernelToUser((uintptr_t)res, &k_res, sizeof(*res));
756  }
757  if (ret >= 0) {
758  sceKernelDeleteUserUid(kargs.pid, modid);
759  }
760  }
761  } else {
762  LOG("Error getting kernel uid for %x: %x", modid, kid);
763  ret = kid;
764  }
765  } else {
766  ret = TAI_ERROR_INVALID_ARGS;
767  }
768  } else {
769  LOG("invalid args size: %x", kargs.size);
770  ret = TAI_ERROR_USER_MEMORY;
771  }
772  } else {
773  ret = TAI_ERROR_NOT_ALLOWED;
774  }
775  EXIT_SYSCALL(state);
776  return ret;
777 }
778 
789 int taiUnloadModuleForPid(SceUID pid, SceUID modid, int flags, void *opt) {
790  uint32_t state;
791  SceUID kid;
792  int ret;
793 
794  ENTER_SYSCALL(state);
795  if (sceSblACMgrIsShell(0)) {
796  if (opt == NULL) {
797  kid = sceKernelKernelUidForUserUid(pid, modid);
798  if (kid >= 0) {
799  ret = sceKernelUnloadModuleForPid(pid, kid, flags, NULL);
800  if (ret >= 0) {
801  sceKernelDeleteUserUid(pid, modid);
802  }
803  } else {
804  LOG("Error getting kernel uid for %x: %x", modid, kid);
805  ret = kid;
806  }
807  } else {
808  ret = TAI_ERROR_INVALID_ARGS;
809  }
810  } else {
811  ret = TAI_ERROR_NOT_ALLOWED;
812  }
813  EXIT_SYSCALL(state);
814  return ret;
815 }
816 
829 int taiStopUnloadModuleForPidForUser(SceUID modid, tai_module_args_t *args, void *opt, int *res) {
830  tai_module_args_t kargs;
831  char buf[MAX_ARGS_SIZE];
832  uint32_t state;
833  int ret;
834  int k_res;
835  SceUID kid;
836 
837  ENTER_SYSCALL(state);
838  if (sceSblACMgrIsShell(0)) {
839  kargs.size = 0;
840  sceKernelMemcpyUserToKernel(&kargs, (uintptr_t)args, sizeof(kargs));
841  if (kargs.size == sizeof(kargs)) {
842  if (kargs.args <= MAX_ARGS_SIZE && opt == NULL) {
843  kid = sceKernelKernelUidForUserUid(kargs.pid, modid);
844  if (kid >= 0) {
845  ret = sceKernelMemcpyUserToKernel(buf, (uintptr_t)kargs.argp, kargs.args);
846  if (ret >= 0) {
847  k_res = 0;
848  ret = sceKernelStopUnloadModuleForPid(kargs.pid, kid, kargs.args, buf, kargs.flags, NULL, &k_res);
849  if (res) {
850  sceKernelMemcpyKernelToUser((uintptr_t)res, &k_res, sizeof(*res));
851  }
852  if (ret >= 0) {
853  sceKernelDeleteUserUid(kargs.pid, modid);
854  }
855  }
856  } else {
857  LOG("Error getting kernel uid for %x: %x", modid, kid);
858  ret = kid;
859  }
860  } else {
861  ret = TAI_ERROR_INVALID_ARGS;
862  }
863  } else {
864  LOG("invalid args size: %x", kargs.size);
865  ret = TAI_ERROR_USER_MEMORY;
866  }
867  } else {
868  ret = TAI_ERROR_NOT_ALLOWED;
869  }
870  EXIT_SYSCALL(state);
871  return ret;
872 }
873 
884 int taiMemcpyUserToKernel(void *kernel_dst, const void *user_src, size_t len) {
885  uint32_t state;
886  int ret;
887 
888  ENTER_SYSCALL(state);
889  if (sceSblACMgrIsShell(0)) {
890  ret = 0;
891  } else {
892  ret = TAI_ERROR_NOT_ALLOWED;
893  }
894  EXIT_SYSCALL(state);
895  if (ret == 0) {
896  return sceKernelMemcpyUserToKernel(kernel_dst, (uintptr_t)user_src, len);
897  } else {
898  return ret;
899  }
900 }
901 
916 int taiMemcpyKernelToUser(void *user_dst, const void *kernel_src, size_t len) {
917  uint32_t state;
918  int ret;
919 
920  ENTER_SYSCALL(state);
921  if (sceSblACMgrIsShell(0)) {
922  ret = 0;
923  } else {
924  ret = TAI_ERROR_NOT_ALLOWED;
925  }
926  EXIT_SYSCALL(state);
927  if (ret == 0) {
928  return sceKernelMemcpyKernelToUser((uintptr_t)user_dst, kernel_src, len);
929  } else {
930  return ret;
931  }
932 }
933 
940 int taiReloadConfig(void) {
941  uint32_t state;
942  int ret;
943 
944  ENTER_SYSCALL(state);
945  if (sceSblACMgrIsShell(0)) {
946  ret = hen_load_config();
947  } else {
948  ret = TAI_ERROR_NOT_ALLOWED;
949  }
950  EXIT_SYSCALL(state);
951  return ret;
952 }
SceUID taiLoadStartModuleForPidForUser(const char *path, tai_module_args_t *args)
Loads and starts a user module for another process.
Definition: taihen-user.c:522
int taiMemcpyKernelToUser(void *user_dst, const void *kernel_src, size_t len)
Copies data from kernel to user.
Definition: taihen-user.c:916
SceUID taiHookFunctionExportForKernel(SceUID pid, tai_hook_ref_t *p_hook, const char *module, uint32_t library_nid, uint32_t func_nid, const void *hook_func)
Add a hook to a module function export.
Definition: taihen.c:72
int taiHookReleaseForKernel(SceUID tai_uid, tai_hook_ref_t hook)
Release a hook.
Definition: taihen.c:204
Extended module information.
Definition: taihen.h:53
int taiMemcpyUserToKernel(void *kernel_dst, const void *user_src, size_t len)
Copies data from user to kernel.
Definition: taihen-user.c:884
uintptr_t tai_hook_ref_t
Hook information.
Definition: taihen.h:215
SceUID taiHookFunctionImportForKernel(SceUID pid, tai_hook_ref_t *p_hook, const char *module, uint32_t import_library_nid, uint32_t import_func_nid, const void *hook_func)
Add a hook to a module function import.
Definition: taihen.c:115
SceUID taiHookFunctionExportForUser(tai_hook_ref_t *p_hook, tai_hook_args_t *args)
Add a hook to a module function export for the calling process.
Definition: taihen-user.c:44
int taiStopKernelModuleForUser(SceUID modid, tai_module_args_t *args, void *opt, int *res)
Stops a kernel module.
Definition: taihen-user.c:576
SceUID taiHookFunctionOffsetForKernel(SceUID pid, tai_hook_ref_t *p_hook, SceUID modid, int segidx, uint32_t offset, int thumb, const void *hook_func)
Add a hook to a module manually with an offset.
Definition: taihen.c:159
int taiInjectReleaseForKernel(SceUID tai_uid)
Release an injection.
Definition: taihen.c:255
SceUID taiInjectDataForUser(tai_offset_args_t *args)
Inject data into the current process bypassing MMU flags given an offset.
Definition: taihen-user.c:304
SceUID taiHookFunctionImportForUser(tai_hook_ref_t *p_hook, tai_hook_args_t *args)
Add a hook to a module function import for the calling process.
Definition: taihen-user.c:105
int taiHookRelease(SceUID tai_uid, tai_hook_ref_t hook)
Release a hook for the calling process.
Definition: taihen-user.c:246
int taiGetModuleInfo(const char *module, tai_module_info_t *info)
Gets information on a currently loaded module.
Definition: taihen-user.c:209
int taiStartKernelModuleForUser(SceUID modid, tai_module_args_t *args, void *opt, int *res)
Starts a kernel module.
Definition: taihen-user.c:416
int taiUnloadModuleForPid(SceUID pid, SceUID modid, int flags, void *opt)
Unloads a user module for a process directly.
Definition: taihen-user.c:789
int hen_load_config(void)
Load tai config file.
Definition: hen.c:392
#define TAI_MAIN_MODULE
Definition: taihen.h:43
int taiInjectRelease(SceUID tai_uid)
Release an injection for the calling process.
Definition: taihen-user.c:344
SceUID taiInjectAbsForKernel(SceUID pid, void *dest, const void *src, size_t size)
Injects data into a process bypassing MMU flags.
Definition: taihen.c:219
Pass offset arguments to kernel.
Definition: taihen.h:78
Pass module arguments to kernel.
Definition: taihen.h:91
SceUID taiLoadKernelModule(const char *path, int flags, void *opt)
Loads a kernel module.
Definition: taihen-user.c:373
SceUID taiInjectAbs(void *dest, const void *src, size_t size)
Injects data into the current process bypassing MMU flags.
Definition: taihen-user.c:276
SceUID taiInjectDataForKernel(SceUID pid, SceUID modid, int segidx, uint32_t offset, const void *data, size_t size)
Inject data into a process bypassing MMU flags given an offset.
Definition: taihen.c:236
Pass hook arguments to kernel.
Definition: taihen.h:67
int taiUnloadKernelModule(SceUID modid, int flags, void *opt)
Unloads a kernel module directly.
Definition: taihen-user.c:633
int taiStopModuleForPidForUser(SceUID modid, tai_module_args_t *args, void *opt, int *res)
Stops a user module for another process.
Definition: taihen-user.c:734
int taiGetModuleInfoForKernel(SceUID pid, const char *module, tai_module_info_t *info)
Gets information on a currently loaded module.
Definition: taihen.c:191
size_t size
Structure size, set to sizeof(tai_module_info_t)
Definition: taihen.h:54
SceUID taiLoadStartKernelModuleForUser(const char *path, tai_module_args_t *args)
Loads and starts a kernel module.
Definition: taihen-user.c:469
int taiStopUnloadModuleForPidForUser(SceUID modid, tai_module_args_t *args, void *opt, int *res)
Stops and unloads a user module for a process.
Definition: taihen-user.c:829
SceUID taiHookFunctionOffsetForUser(tai_hook_ref_t *p_hook, tai_offset_args_t *args)
Add a hook to a module manually with an offset for the calling process.
Definition: taihen-user.c:155
int taiStopUnloadKernelModuleForUser(SceUID modid, tai_module_args_t *args, void *opt, int *res)
Stops and unloads a kernel module.
Definition: taihen-user.c:675