diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5a5f80a --- /dev/null +++ b/.gitignore @@ -0,0 +1,32 @@ + +#Ignore thumbnails created by Windows +Thumbs.db +#Ignore files built by Visual Studio +*.obj +*.exe +*.pdb +*.user +*.aps +*.pch +*.vspscc +*_i.c +*_p.c +*.ncb +*.suo +*.tlb +*.tlh +*.bak +*.cache +*.ilk +*.log +[Bb]in +[Dd]ebug*/ +*.lib +*.sbr +obj/ +[Rr]elease*/ +_ReSharper*/ +[Tt]est[Rr]esult* +.vs/ +#Nuget packages folder +packages/ diff --git a/framework/Makefile b/Makefile similarity index 96% rename from framework/Makefile rename to Makefile index a20b49b..bd5e4b6 100644 --- a/framework/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ L_DIRS := -L. -Llib LIBS := # C++ Flags -CFLAGS := $(I_DIRS) -D_KERNEL -D_DEBUG -std=c11 -O2 -fno-builtin -nostartfiles -nodefaultlibs -nostdlib -nostdinc -fcheck-new -ffreestanding -fno-strict-aliasing -fno-exceptions -fno-asynchronous-unwind-tables -Wall -m64 -fPIC -Werror=implicit-function-declaration -Wno-unknown-pragmas +CFLAGS := $(I_DIRS) -D_KERNEL -D_DEBUG -std=c11 -O2 -fno-builtin -nostartfiles -nodefaultlibs -nostdlib -nostdinc -fcheck-new -ffreestanding -fno-strict-aliasing -fno-exceptions -fno-asynchronous-unwind-tables -Wall -m64 -fPIC -Werror -Wno-unknown-pragmas # Assembly flags SFLAGS := -nostartfiles -nodefaultlibs -nostdlib -fPIC diff --git a/framework/src/oni/utils/utils.s b/framework/src/oni/utils/utils.s deleted file mode 100644 index 8c8fe4c..0000000 --- a/framework/src/oni/utils/utils.s +++ /dev/null @@ -1,10 +0,0 @@ -.intel_syntax noprefix -.text -.global kernelRdmsr - -kernelRdmsr: - mov ecx, edi - rdmsr - shl rdx, 32 - or rax, rdx - ret diff --git a/framework/include/oni/config.h b/include/oni/config.h similarity index 65% rename from framework/include/oni/config.h rename to include/oni/config.h index e3cb1ad..89e806f 100644 --- a/framework/include/oni/config.h +++ b/include/oni/config.h @@ -3,8 +3,23 @@ // 64-bit ARM FreeBSD based device #define ONI_PLATFORM_AARCH64_BSD 1 +// 64-bit x64 FreeBSD orbis based device +#define ONI_PLATFORM_ORBIS_BSD 2 + +// 64-bit x64 FreeBSD 9 based device +#define ONI_PLATFORM_9_BSD 3 + // 32-bit ARM FreeBSD based device -#define ONI_PLATFORM_SAFE_BSD 2 +#define ONI_PLATFORM_SAFE_BSD 4 + +// 4.55 Orbis Firmware +#define ONI_PLATFORM_ORBIS_BSD_455 5 + +// 5.01 Orbis Firmware +#define ONI_PLATFORM_ORBIS_BSD_501 6 + +// 5.05 Orbis Firmware +#define ONI_PLATFORM_ORBIS_BSD_505 7 // Unknown device #define ONI_UNKNOWN_PLATFORM -1 @@ -16,7 +31,7 @@ // The current platform configured by oni #ifndef ONI_PLATFORM -#define ONI_PLATFORM ONI_PLATFORM_SAFE_BSD +#define ONI_PLATFORM ONI_PLATFORM_ORBIS_BSD_501 #endif // The maximum number of plugins for use with oni diff --git a/framework/include/oni/framework.h b/include/oni/framework.h similarity index 93% rename from framework/include/oni/framework.h rename to include/oni/framework.h index 4f88e83..4bf6920 100644 --- a/framework/include/oni/framework.h +++ b/include/oni/framework.h @@ -19,6 +19,9 @@ struct framework_t struct pluginmanager_t* pluginManager; }; +// Framework platform +extern struct framework_t* gFramework; + // Initialization parameters extern struct initparams_t* gInitParams; diff --git a/framework/include/oni/init/framework.h b/include/oni/init/framework.h similarity index 100% rename from framework/include/oni/init/framework.h rename to include/oni/init/framework.h diff --git a/framework/include/oni/init/initparams.h b/include/oni/init/initparams.h similarity index 100% rename from framework/include/oni/init/initparams.h rename to include/oni/init/initparams.h diff --git a/framework/include/oni/messaging/message.h b/include/oni/messaging/message.h similarity index 100% rename from framework/include/oni/messaging/message.h rename to include/oni/messaging/message.h diff --git a/framework/include/oni/messaging/messagecategory.h b/include/oni/messaging/messagecategory.h similarity index 100% rename from framework/include/oni/messaging/messagecategory.h rename to include/oni/messaging/messagecategory.h diff --git a/framework/include/oni/messaging/messagemanager.h b/include/oni/messaging/messagemanager.h similarity index 100% rename from framework/include/oni/messaging/messagemanager.h rename to include/oni/messaging/messagemanager.h diff --git a/framework/include/oni/plugins/plugin.h b/include/oni/plugins/plugin.h similarity index 59% rename from framework/include/oni/plugins/plugin.h rename to include/oni/plugins/plugin.h index f16a54a..9981323 100644 --- a/framework/include/oni/plugins/plugin.h +++ b/include/oni/plugins/plugin.h @@ -7,12 +7,12 @@ // Plugin description length #define PLUGIN_DESC_LEN 256 +struct plugin_t /* plugin_t Plugin structure that all plugins should "inherit" from */ -struct plugin_t { // Name of the plugin const char* name; @@ -21,8 +21,20 @@ struct plugin_t const char* description; // Plugin initialization prototype - int32_t(*plugin_init)(void* arg); + uint8_t(*plugin_load)(void* plugin); // Plugin close prototype - int32_t(*plugin_close)(); + uint8_t(*plugin_unload)(void* plugin); +}; + +struct plugininit_t +/* + plugininit_t + + This structure is used for passing "host" information to the plugins to use +*/ +{ + struct framework_t* framework; + struct logger_t* logger; + uint8_t* kernelBase; }; \ No newline at end of file diff --git a/framework/include/oni/plugins/pluginmanager.h b/include/oni/plugins/pluginmanager.h similarity index 100% rename from framework/include/oni/plugins/pluginmanager.h rename to include/oni/plugins/pluginmanager.h diff --git a/framework/include/oni/rpc/rpcconnection.h b/include/oni/rpc/rpcconnection.h similarity index 100% rename from framework/include/oni/rpc/rpcconnection.h rename to include/oni/rpc/rpcconnection.h diff --git a/framework/include/oni/rpc/rpcserver.h b/include/oni/rpc/rpcserver.h similarity index 100% rename from framework/include/oni/rpc/rpcserver.h rename to include/oni/rpc/rpcserver.h diff --git a/include/oni/utils/cpu.h b/include/oni/utils/cpu.h new file mode 100644 index 0000000..a6ddf2a --- /dev/null +++ b/include/oni/utils/cpu.h @@ -0,0 +1,4 @@ +#pragma once + +void cpu_enable_wp(); +void cpu_disable_wp(); diff --git a/include/oni/utils/dynlib.h b/include/oni/utils/dynlib.h new file mode 100644 index 0000000..54b6dcb --- /dev/null +++ b/include/oni/utils/dynlib.h @@ -0,0 +1,6 @@ +#pragma once +#include + +int64_t sys_dynlib_load_prx(char* prxPath); +int64_t sys_dynlib_unload_prx(int64_t prxID); +int64_t sys_dynlib_dlsym(int64_t moduleHandle, const char* functionName, void *destFuncOffset); \ No newline at end of file diff --git a/framework/include/oni/utils/kdlsym.h b/include/oni/utils/kdlsym.h similarity index 63% rename from framework/include/oni/utils/kdlsym.h rename to include/oni/utils/kdlsym.h index 91e38d3..1a5490e 100644 --- a/framework/include/oni/utils/kdlsym.h +++ b/include/oni/utils/kdlsym.h @@ -8,6 +8,14 @@ #if ONI_PLATFORM==ONI_UNKNOWN_PLATFORM #include "kdlsym/default.h" +#elif ONI_PLATFORM==ONI_PLATFORM_ORBIS_BSD +#include "kdlsym/orbis.h" +#elif ONI_PLATFORM==ONI_PLATFORM_ORBIS_BSD_455 +#include "kdlsym/orbis455.h" +#elif ONI_PLATFORM==ONI_PLATFORM_ORBIS_BSD_501 +#include "kdlsym/orbis501.h" +#elif ONI_PLATFORM==ONI_PLATFORM_ORBIS_BSD_505 +#include "kdlsym/orbis505.h" #elif ONI_PLATFORM==ONI_PLATFORM_SAFE_BSD #include "kdlsym/gunsafe2.h" #endif diff --git a/framework/include/oni/utils/kdlsym/default.h b/include/oni/utils/kdlsym/default.h similarity index 97% rename from framework/include/oni/utils/kdlsym/default.h rename to include/oni/utils/kdlsym/default.h index 3fb96ca..809c33a 100644 --- a/framework/include/oni/utils/kdlsym/default.h +++ b/include/oni/utils/kdlsym/default.h @@ -83,4 +83,6 @@ for the platforms that do enable kernel ASLR (Address Space Layout Randomization #define kdlsym_addr_mtx_init 0xDEADC0DE #define kdlsym_addr_sys_mlock 0xDEADC0DE #define kdlsym_addr_sys_kill 0xDEADC0DE +#define kdlsym_addr_sys_mkdir 0xDEADC0DE +#define kdlsym_addr_sys_rmdir 0xDEADC0DE #endif \ No newline at end of file diff --git a/include/oni/utils/kdlsym/orbis501.h b/include/oni/utils/kdlsym/orbis501.h new file mode 100644 index 0000000..fbd6c12 --- /dev/null +++ b/include/oni/utils/kdlsym/orbis501.h @@ -0,0 +1,89 @@ +#pragma once +#include + +#if ONI_PLATFORM==ONI_PLATFORM_ORBIS_BSD_501 +/* +These are the required functions in order for the Oni Framework to operate properly +These are all offsets into the base of the kernel. They expect all standard FreeBSD 9 prototypes + +The reason we do not hardcode offsets here, is due to the different platforms that are supported, and +for the platforms that do enable kernel ASLR (Address Space Layout Randomization?) +*/ + +#define kdlsym_addr_allproc 0x02382FF8 +#define kdlsym_addr_allproc_lock 0x02382F98 + +#define kdlsym_addr_critical_enter 0x0028E4D0 +#define kdlsym_addr_critical_exit 0x0028E4E0 + +#define kdlsym_addr_kernel_map 0x01AC60E0 +#define kdlsym_addr_kern_reboot 0x0010D280 +#define kdlsym_addr_kmem_alloc 0x000fcb70 +#define kdlsym_addr_kmem_free 0x000FCD40 +#define kdlsym_addr_kproc_create 0x00137CE0 + +#define kdlsym_addr_sys_mlockall 0x0013E1F0 +#define kdlsym_addr_sys_mlock 0x0013E140 + +#define kdlsym_addr_pfind 0x00403110 +#define kdlsym_addr_printf 0x00435c70 +#define kdlsym_addr_proc_rwmem 0x0030CDC0 +#define kdlsym_addr_pmap_activate 0x002EAC40 + +#define kdlsym_addr_vmspace_alloc 0x0019EA10 +#define kdlsym_addr_vmspace_free 0x0019ECB0 + +#define kdlsym_addr_snprintf 0x00435F80 + +#define kdlsym_addr_vsnprintf 0x00436020 + +#define kdlsym_addr__mtx_lock_flags 0x00401900 +#define kdlsym_addr__mtx_unlock_flags 0x00401BD0 + +#define kdlsym_addr__sx_slock 0x000F5B20 +#define kdlsym_addr__sx_sunlock 0x000F5E00 + +#define kdlsym_addr_vmspace_acquire_ref 0x0019EE80 +#define kdlsym_addr__vm_map_lock_read 0x0019F030 +#define kdlsym_addr__vm_map_unlock_read 0x0019F080 + +// TODO: Sort by alpha + +#define kdlsym_addr_sys_lseek 0x0033D620 +#define kdlsym_addr_sys_mmap 0x0013D120 +#define kdlsym_addr_sys_munmap 0x0013D890 +#define kdlsym_addr_utilUSleep 0x00658850 +#define kdlsym_addr_kthread_exit 0x00138530 +#define kdlsym_addr_kthread_add 0x00138250 +#define kdlsym_addr_sys_read 0x001529a0 +#define kdlsym_addr_sys_fstat 0x000C14B0 +#define kdlsym_addr_sys_close 0x000c0f30 +#define kdlsym_addr_sys_socket 0x00318b10 +#define kdlsym_addr_sys_write 0x00152eb0 + + +#define kdlsym_addr_sys_getdents 0x00340FC0 +#define kdlsym_addr_sys_bind 0x00319450 +#define kdlsym_addr_sys_listen 0x00319690 +#define kdlsym_addr_sys_accept 0x00319da0 +#define kdlsym_addr_sys_recvfrom 0x0031B090 +#define kdlsym_addr_sys_sendto 0x0031A940 +#define kdlsym_addr_sys_open 0x0033B5C0 +#define kdlsym_addr_memcpy 0x001ea420 +#define kdlsym_addr_memset 0x3201F0 +#define kdlsym_addr_sys_stat 0x0033DC10 + +#define kdlsym_addr_Xfast_syscall 0x000001C0 +#define kdlsym_addr_sys_dup2 0x000BF0D0 +#define kdlsym_addr_sys_shutdown 0x0031B2D0 +#define kdlsym_addr_sys_unlink 0x0033D000 +#define kdlsym_addr_sys_setuid 0x00054950 +#define kdlsym_addr_sys_ptrace 0x0030D250 +#define kdlsym_addr_sscanf 0x001757F0 +#define kdlsym_addr_mtx_init 0x004023B0 + +#define kdlsym_addr_sys_kill 0x000D1A50 + +#define kdlsym_addr_sys_mkdir 0x00340780 +#define kdlsym_addr_sys_rmdir 0x00340B00 +#endif diff --git a/include/oni/utils/kdlsym/orbis505.h b/include/oni/utils/kdlsym/orbis505.h new file mode 100644 index 0000000..367d0f2 --- /dev/null +++ b/include/oni/utils/kdlsym/orbis505.h @@ -0,0 +1,89 @@ +#pragma once + +#if ONI_PLATFORM==ONI_PLATFORM_ORBIS_BSD_505 +/* +These are the required functions in order for the Oni Framework to operate properly +These are all offsets into the base of the kernel. They expect all standard FreeBSD 9 prototypes + +The reason we do not hardcode offsets here, is due to the different platforms that are supported, and +for the platforms that do enable kernel ASLR (Address Space Layout Randomization?) +*/ +#define kdlsym_addr_allproc 0x2382ff8 +#define kdlsym_addr_allproc_lock 0x2382f98 + +#define kdlsym_addr_critical_enter 0x28e7a0 +#define kdlsym_addr_critical_exit 0x28e7b0 + +#define kdlsym_addr_kernel_map 0x1AC60E0 +#define kdlsym_addr_kern_reboot 0x0010D390 +#define kdlsym_addr_kmem_alloc 0xfcc80 +#define kdlsym_addr_kmem_free 0xfce50 +#define kdlsym_addr_kproc_create 0x137df0 + +#define kdlsym_addr_sys_mlock 0x0013E250 +#define kdlsym_addr_sys_mlockall 0x0013E300 + +#define kdlsym_addr_pfind 0x4034e0 +#define kdlsym_addr_printf 0x436040 +#define kdlsym_addr_proc_rwmem 0x30d150 +#define kdlsym_addr_pmap_activate 0x2eafd0 + +#define kdlsym_addr_vmspace_alloc 0x19eb20 +#define kdlsym_addr_vmspace_free 0x19edc0 + +#define kdlsym_addr_snprintf 0x436350 + +#define kdlsym_addr_vsnprintf 0x004363F0 + +#define kdlsym_addr__mtx_lock_flags 0x401cd0 +#define kdlsym_addr__mtx_unlock_flags 0x401fa0 + +#define kdlsym_addr__sx_slock 0xf5c30 +#define kdlsym_addr__sx_xlock 0xf5e10 +#define kdlsym_addr__sx_sunlock 0xf5f10 +#define kdlsym_addr__sx_xunlock 0xf5fd0 + +#define kdlsym_addr_vmspace_acquire_ref 0x19ef90 +#define kdlsym_addr__vm_map_lock_read 0x19f140 +#define kdlsym_addr__vm_map_unlock_read 0x19f190 + +// TODO: Sort by alpha + +#define kdlsym_addr_sys_lseek 0x0033D9F0 +#define kdlsym_addr_sys_mmap 0x0013D230 +#define kdlsym_addr_sys_munmap 0x0013D9A0 +#define kdlsym_addr_utilUSleep 0x00658C30 +#define kdlsym_addr_kthread_exit 0x138640 +#define kdlsym_addr_kthread_add 0x00138360 +#define kdlsym_addr_sys_read 0x00152AB0 +#define kdlsym_addr_sys_fstat 0x000C1430 +#define kdlsym_addr_sys_close 0x000C0EB0 +#define kdlsym_addr_sys_socket 0x00318EE0 +#define kdlsym_addr_sys_write 0x00152FC0 + + +#define kdlsym_addr_sys_getdents 0x00341390 +#define kdlsym_addr_sys_bind 0x00319820 +#define kdlsym_addr_sys_listen 0x00319A60 +#define kdlsym_addr_sys_accept 0x0031A170 +#define kdlsym_addr_sys_recvfrom 0x0031B460 +#define kdlsym_addr_sys_sendto 0x0031AD10 +#define kdlsym_addr_sys_open 0x0033B990 +#define kdlsym_addr_memcpy 0x1ea530 +#define kdlsym_addr_memset 0x003205C0 +#define kdlsym_addr_sys_stat 0x0033DFE0 + +#define kdlsym_addr_Xfast_syscall 0x1c0 +#define kdlsym_addr_sys_dup2 0x000BF050 +#define kdlsym_addr_sys_shutdown 0x0031B6A0 +#define kdlsym_addr_sys_unlink 0x0033D3D0 +#define kdlsym_addr_sys_setuid 0x00054950 +#define kdlsym_addr_sys_ptrace 0x0030D5E0 +#define kdlsym_addr_sscanf 0x00175900 +#define kdlsym_addr_mtx_init 0x00402780 +#define kdlsym_addr_sys_mlock 0x0013E250 +#define kdlsym_addr_sys_kill 0x000D19D0 +#define kdlsym_addr_sys_mkdir 0x00340B50 +#define kdlsym_addr_sys_rmdir 0x00340ED0 +#endif + diff --git a/framework/include/oni/utils/kernel.h b/include/oni/utils/kernel.h similarity index 100% rename from framework/include/oni/utils/kernel.h rename to include/oni/utils/kernel.h diff --git a/framework/include/oni/utils/lock.h b/include/oni/utils/lock.h similarity index 100% rename from framework/include/oni/utils/lock.h rename to include/oni/utils/lock.h diff --git a/framework/include/oni/utils/log/logger.h b/include/oni/utils/log/logger.h similarity index 96% rename from framework/include/oni/utils/log/logger.h rename to include/oni/utils/log/logger.h index dc523a2..ee13691 100644 --- a/framework/include/oni/utils/log/logger.h +++ b/include/oni/utils/log/logger.h @@ -36,7 +36,7 @@ struct logger_t char finalBuffer[Logger_MaxBuffer]; // Handle to log file on hdd - volatile volatile int logHandle; + volatile int logHandle; struct lock_t lock; diff --git a/framework/include/oni/utils/memory/allocator.h b/include/oni/utils/memory/allocator.h similarity index 100% rename from framework/include/oni/utils/memory/allocator.h rename to include/oni/utils/memory/allocator.h diff --git a/framework/include/oni/utils/memory/install.h b/include/oni/utils/memory/install.h similarity index 65% rename from framework/include/oni/utils/memory/install.h rename to include/oni/utils/memory/install.h index a80910a..0640e62 100644 --- a/framework/include/oni/utils/memory/install.h +++ b/include/oni/utils/memory/install.h @@ -1,4 +1,4 @@ #pragma once #include -uint8_t SelfElevateAndRun(uint8_t* userlandPayload, uint32_t userlandSize, void(*elevatedEntryPoint)(void* arguments)); \ No newline at end of file +uint8_t SelfElevateAndRun(uint8_t* userlandPayload, uint32_t userlandSize, void(*elevatedEntryPoint)(void* arguments)); diff --git a/include/oni/utils/patches.h b/include/oni/utils/patches.h new file mode 100644 index 0000000..5b94197 --- /dev/null +++ b/include/oni/utils/patches.h @@ -0,0 +1,6 @@ +#pragma once + +// +// This will install all of the pre-run patches needed for Mira to operate +// +extern void oni_installPrePatches(); \ No newline at end of file diff --git a/framework/include/oni/utils/sys_wrappers.h b/include/oni/utils/sys_wrappers.h similarity index 96% rename from framework/include/oni/utils/sys_wrappers.h rename to include/oni/utils/sys_wrappers.h index 66898db..d75f188 100644 --- a/framework/include/oni/utils/sys_wrappers.h +++ b/include/oni/utils/sys_wrappers.h @@ -33,6 +33,9 @@ extern int kkill(int pid, int signum); extern int kdup2(int oldd, int newd); extern int kshutdown(int s, int how); +extern int kmkdir(char* path, int mode); +extern int krmdir(char* path); + extern off_t klseek(int fd, off_t offset, int whence); extern caddr_t kmmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t pos); extern int kmunmap(void *addr, size_t len); diff --git a/include/oni/utils/syscall.h b/include/oni/utils/syscall.h new file mode 100644 index 0000000..2128c4c --- /dev/null +++ b/include/oni/utils/syscall.h @@ -0,0 +1,37 @@ +#pragma once +#include + +void* syscall1( + uint64_t number, + void* arg1 +); + +void* syscall2( + uint64_t number, + void* arg1, + void* arg2 +); + +void* syscall3( + uint64_t number, + void* arg1, + void* arg2, + void* arg3 +); + +void* syscall4( + uint64_t number, + void* arg1, + void* arg2, + void* arg3, + void* arg4 +); + +void* syscall5( + uint64_t number, + void* arg1, + void* arg2, + void* arg3, + void* arg4, + void* arg5 +); diff --git a/framework/include/oni/utils/types.h b/include/oni/utils/types.h similarity index 100% rename from framework/include/oni/utils/types.h rename to include/oni/utils/types.h diff --git a/link.x b/link.x new file mode 100644 index 0000000..d041fb9 --- /dev/null +++ b/link.x @@ -0,0 +1,64 @@ +OUTPUT_FORMAT("elf64-x86-64") +OUTPUT_ARCH(i386:x86-64) + +ENTRY(_start) + +PHDRS +{ + /* + * PF_X = 0x1 + * PF_W = 0x2 + * PF_R = 0x4 + */ + + ph_text PT_LOAD FLAGS (0x1 | 0x4); + ph_data PT_LOAD FLAGS (0x2 | 0x4); +} + +SECTIONS +{ + __payload_base = .; + + .text : + { + KEEP (*(.init)) + KEEP (*(.fini)) + + *(.text .text.*) + + . = ALIGN(4); + } : ph_text = 0x90909090 + + .rodata : + { + *(.rodata .rodata.*) + + . = ALIGN(4); + } + + . = ALIGN(0x4000); + + .data : + { + *(.data .data.*) + + . = ALIGN(0x10); + + __imports_start = .; + KEEP(*(.imports .imports.*)) + __imports_end = .; + + __patches_start = .; + KEEP(*(.patches .patches.*)) + QUAD(0); BYTE(0); BYTE(0); + __patches_end = .; + + __bss_start = .; + *(.bss .bss.*) *(COMMON) + __bss_end = .; + + . = . + 4; + . = ALIGN(4); + } : ph_data +} + diff --git a/oni-framework.vcxproj b/oni-framework.vcxproj new file mode 100644 index 0000000..90972b0 --- /dev/null +++ b/oni-framework.vcxproj @@ -0,0 +1,114 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {73d88a70-8f6f-49a7-b921-9db254527f92} + Linux + oni_framework + 15.0 + Linux + 1.0 + Generic + {2238F9CD-F817-4ECC-BD14-2524D2669B35} + + + + true + Makefile + ~/mira/Firmware/Dependencies + + + false + Makefile + ~/mira/Firmware/Dependencies + + + + + + + + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + Makefile;$(AdditionalSourcesToCopyMapping) + _KERNEL;_DEBUG + $(ProjectDir)include;$(SolutionDir)Firmware\Dependencies\freebsd-headers\include; + cd $(RemoteProjectDir);make create;make + cd $(RemoteProjectDir);make create;make clean;make + cd $(RemoteProjectDir);make create;make clean + $(RemoteRootDir)/$(ProjectName)/OniFramework.a + + + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + Makefile;$(AdditionalSourcesToCopyMapping) + _KERNEL + $(ProjectDir)include;$(SolutionDir)Firmware\Dependencies\freebsd-headers\include; + cd $(RemoteProjectDir);make create;make + cd $(RemoteProjectDir);make create;make clean;make + cd $(RemoteProjectDir);make create;make clean + $(RemoteRootDir)/$(ProjectName)/OniFramework.a + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pc/OniConnection.cs b/pc/OniConnection.cs deleted file mode 100644 index b0807dd..0000000 --- a/pc/OniConnection.cs +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Oni.OniConnection - * Created by: kiwidog (keybase.io/kiwidog) - * - * This is the class responsible for the basic communications - * I really need to refactor this, but at this point I don't care. - * - */ -using System; -using System.IO; -using System.Net.Sockets; -using System.Runtime.InteropServices; -using System.Text; - -namespace Oni -{ - /// - /// Categories, these MUST MATCH THE C IMPLEMENTATION - /// - public enum RPC_CATEGORY - { - /// - /// Nothing - /// - RPCCAT_NONE = 0, - - /// - /// System category - /// - RPCCAT_SYSTEM, - - /// - /// Logger category - /// - RPCCAT_LOG, - - /// - /// Debugger category - /// - RPCCAT_DBG, - - /// - /// File category - /// - RPCCAT_FILE, - - /// - /// Command category - /// - RPCCAT_CMD, - - /// - /// Category count - /// - RPCCAT_COUNT - }; - - /// - /// The bread and butter - /// - public class OniConnection - { - // Header magic, THIS MUST MATCH C IMPLEMENTATION - public const byte c_Magic = 0xCC; - - // Buffer size, THIS MUST MATCH C IMPLEMENTATION - public const int c_BufferSize = 0x4000; - - // IP address - protected readonly string m_Address; - - // Server port - protected readonly ushort m_Port; - - // Client - internal TcpClient m_Client; - - /// - /// Returns if the client is connected - /// - public bool Connected => m_Client?.Connected ?? false; - - /// - /// IP Address - /// - public string Address => m_Address; - - /// - /// Creates a new connection instance - /// - /// Ip address of the server - /// Port to connect to - public OniConnection(string p_IpAddress, ushort p_Port) - { - m_Address = p_IpAddress; - m_Port = p_Port; - } - - /// - /// Connect to a remote client - /// - /// True on success, false otherwise - public bool Connect() - { - try - { - m_Client = new TcpClient(m_Address, m_Port) - { - // Large file transfers will stall if this is set to low - SendTimeout = 1000 * 10, - ReceiveTimeout = 1000 * 10, - - // These must match the c implementation - SendBufferSize = c_BufferSize, - ReceiveBufferSize = c_BufferSize - }; - } - catch (Exception p_Exception) - { - Console.WriteLine(p_Exception); - return false; - } - - return m_Client.Connected; - } - - /// - /// Disconnects the client - /// - public void Disconnect() - { - try - { - m_Client.Close(); - } - catch (Exception p_Exception) - { - Console.WriteLine(p_Exception); - } - } - - /// - /// Serializes an object into a byte array - /// - /// Structure to serialize - /// Byte array of object - public byte[] SerializeObject(object p_Object) - { - var s_Size = Marshal.SizeOf(p_Object); - - var s_Data = new byte[s_Size]; - - var s_Ptr = Marshal.AllocHGlobal(s_Size); - - Marshal.StructureToPtr(p_Object, s_Ptr, true); - - Marshal.Copy(s_Ptr, s_Data, 0, s_Size); - - Marshal.FreeHGlobal(s_Ptr); - - return s_Data; - } - - /// - /// Deserializes a object to the specified structure - /// - /// Structure to deserialize - /// Incoming data to deserialize from - /// Object or null - public T DeserializeObject(byte[] p_Data) - { - var s_Size = Marshal.SizeOf(); - if (p_Data.Length < s_Size) - throw new InvalidDataException($"Data size is too small to deserialize {typeof(T).FullName}"); - - var s_Ptr = Marshal.AllocHGlobal(s_Size); - Marshal.Copy(p_Data, 0, s_Ptr, s_Size); - var s_Object = (T)Marshal.PtrToStructure(s_Ptr, typeof(T)); - Marshal.FreeHGlobal(s_Ptr); - - return s_Object; - } - - /// - /// Receive's an object from over the network, will not accept data afterwards - /// - /// Structure type to download - /// Object created - public T ReceiveObject() - { - var s_Size = Marshal.SizeOf(); - - byte[] s_Data; - using (var s_Reader = new BinaryReader(m_Client.GetStream(), Encoding.ASCII, true)) - s_Data = s_Reader.ReadBytes(s_Size); - - if (s_Data.Length < s_Size) - throw new InvalidDataException("incoming data length < required size"); - - var s_Object = DeserializeObject(s_Data); - - return s_Object; - } - - /// - /// Sends a structure to the server - /// - /// Type of structure - /// Structure to send - public void SendMessage(T p_Object) - { - var s_Data = SerializeObject(p_Object); - - using (var s_Writer = new BinaryWriter(m_Client.GetStream(), Encoding.ASCII, true)) - s_Writer.Write(s_Data); - } - - /// - /// Sends a message with the supplied header, and payload - /// - /// Header - /// Payload data - public void SendMessage(RpcMessageHeader p_Object, byte[] p_Payload) - { - var s_HeaderData = SerializeObject(p_Object); - - using (var s_Writer = new BinaryWriter(m_Client.GetStream(), Encoding.ASCII, true)) - { - s_Writer.Write(s_HeaderData); - s_Writer.Write(p_Payload); - } - } - - /// - /// Sends a message with a structure payload - /// - /// Type of payload - /// Header - /// Structure to send - public void SendMessage(RpcMessageHeader p_Header, T p_Payload) - { - var s_HeaderData = SerializeObject(p_Header); - var s_PayloadData = SerializeObject(p_Payload); - - using (var s_Writer = new BinaryWriter(m_Client.GetStream(), Encoding.ASCII, true)) - { - s_Writer.Write(s_HeaderData); - s_Writer.Write(s_PayloadData); - } - } - } -} diff --git a/pc/RpcMessageHeader.cs b/pc/RpcMessageHeader.cs deleted file mode 100644 index ce998bb..0000000 --- a/pc/RpcMessageHeader.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Oni -{ - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] - public struct RpcMessageHeader - { - /// - /// Magic byte, default: 0xCC - /// - public byte Magic; - - /// - /// Bool value representing if this current message is a Request or reply - /// - public byte Request; - - /// - /// The length of the payload, which comes after this header - /// - public ushort PayloadLength; - - /// - /// RPC Category - /// - public int Category; - - /// - /// Command CommandType - /// - public uint CommandType; - - /// - /// Error, if this is non-zero then do not read any payload - /// - public int Error; - } -} diff --git a/framework/src/oni/messaging/message.c b/src/oni/messaging/message.c similarity index 100% rename from framework/src/oni/messaging/message.c rename to src/oni/messaging/message.c diff --git a/framework/src/oni/messaging/messagecategory.c b/src/oni/messaging/messagecategory.c similarity index 100% rename from framework/src/oni/messaging/messagecategory.c rename to src/oni/messaging/messagecategory.c diff --git a/framework/src/oni/messaging/messagemanager.c b/src/oni/messaging/messagemanager.c similarity index 94% rename from framework/src/oni/messaging/messagemanager.c rename to src/oni/messaging/messagemanager.c index 22e3d61..669e5cc 100644 --- a/framework/src/oni/messaging/messagemanager.c +++ b/src/oni/messaging/messagemanager.c @@ -60,6 +60,8 @@ struct messagecategory_t* messagemanager_getCategory(struct messagemanager_t* ma if (!manager) return 0; + //WriteLog(LL_Debug, "[+] got dispatcher %p category: %d", manager, category); + if (category >= RPCCAT_COUNT) return 0; @@ -120,11 +122,12 @@ int32_t messagemanager_registerCallback(struct messagemanager_t* manager, uint32 return 0; // Install the listener to the category + //category->callbacks[callbackIndex] = callback; struct messagecategory_callback_t* categoryCallback = (struct messagecategory_callback_t*)kmalloc(sizeof(struct messagecategory_callback_t)); if (!categoryCallback) return 0; - categoryCallback->type = callbackType; // Set type + categoryCallback->type = callbackType; // TODO: Set type categoryCallback->callback = callback; category->callbacks[callbackIndex] = categoryCallback; @@ -156,12 +159,16 @@ void messagemanager_sendMessage(struct messagemanager_t* manager, struct allocat goto cleanup; } + //WriteLog(LL_Debug, "[+] sendMessage dispatcher: %p ref: %p message: %p", manager, msg, message); + if (message->header.category >= RPCCAT_COUNT) { WriteLog(LL_Error, "[-] invalid message category: %d max: %d", message->header.category, RPCCAT_COUNT); goto cleanup; } + //WriteLog(LL_Debug, "[+] getting dispatcher category"); + struct messagecategory_t* category = messagemanager_getCategory(manager, message->header.category); if (!category) { @@ -170,6 +177,7 @@ void messagemanager_sendMessage(struct messagemanager_t* manager, struct allocat } // Iterate through all of the callbacks + //WriteLog(LL_Debug, "[+] iterating callbacks"); for (uint32_t l_CallbackIndex = 0; l_CallbackIndex < RPCCATEGORY_MAX_CALLBACKS; ++l_CallbackIndex) { // Get the category callback structure diff --git a/framework/src/oni/plugins/pluginmanager.c b/src/oni/plugins/pluginmanager.c similarity index 88% rename from framework/src/oni/plugins/pluginmanager.c rename to src/oni/plugins/pluginmanager.c index cd86f9c..2531227 100644 --- a/framework/src/oni/plugins/pluginmanager.c +++ b/src/oni/plugins/pluginmanager.c @@ -62,7 +62,7 @@ int32_t pluginmanager_registerPlugin(struct pluginmanager_t* manager, struct plu if (!manager) { WriteLog(LL_Error, "no manager"); - return 0; + return false; } @@ -70,7 +70,7 @@ int32_t pluginmanager_registerPlugin(struct pluginmanager_t* manager, struct plu if (pluginIndex == -1) { WriteLog(LL_Error, "no free indices"); - return 0; + return false; } @@ -91,7 +91,7 @@ int32_t pluginmanager_registerPlugin(struct pluginmanager_t* manager, struct plu if (pluginExists) { WriteLog(LL_Error, "plugin exists"); - return 0; + return false; } // Assign our plugin @@ -100,11 +100,11 @@ int32_t pluginmanager_registerPlugin(struct pluginmanager_t* manager, struct plu // TODO: Make auto-loading configurable WriteLog(LL_Debug, "loading plugin: %s", plugin->name); - int32_t initResult = plugin->plugin_init(0); - if (!initResult) - return 0; + uint8_t pluginLoadResult = plugin->plugin_load(plugin); + if (!pluginLoadResult) + return false; - return 1; + return true; } int32_t pluginmanager_unregisterPlugin(struct pluginmanager_t* manager, struct plugin_t* plugin) @@ -113,12 +113,14 @@ int32_t pluginmanager_unregisterPlugin(struct pluginmanager_t* manager, struct p { if (manager->plugins[i] == plugin) { - pluginmanager_unregisterPlugin(manager, manager->plugins[i]); - return 1; + // Unload the plugin + plugin->plugin_unload(plugin); + manager->plugins[i] = NULL; + return true; } } - return 0; + return false; } void pluginmanager_shutdown(struct pluginmanager_t* manager) @@ -126,7 +128,7 @@ void pluginmanager_shutdown(struct pluginmanager_t* manager) spin_lock(&manager->lock); for (uint64_t i = 0; i < PLUGINMANAGER_MAX_PLUGINS; ++i) { - if (manager->plugins[i] == 0) + if (manager->plugins[i] == NULL) continue; pluginmanager_unregisterPlugin(manager, manager->plugins[i]); diff --git a/framework/src/oni/rpc/rpcconnection.c b/src/oni/rpc/rpcconnection.c similarity index 97% rename from framework/src/oni/rpc/rpcconnection.c rename to src/oni/rpc/rpcconnection.c index 17acc3a..1c29831 100644 --- a/framework/src/oni/rpc/rpcconnection.c +++ b/src/oni/rpc/rpcconnection.c @@ -8,7 +8,7 @@ #include #include -extern struct messagemanager_t* gMessageManager; +#include void rpcconnection_init(struct rpcconnection_t* connection) /* @@ -106,7 +106,6 @@ void rpcconnection_serverThread(void* data) } struct rpcconnection_t* connection = (struct rpcconnection_t*)data; - // Initialize all of the buffers WriteLog(LL_Debug, "rpcconnection_serverThread init buffers"); if (!rpcconnection_initializeBuffers(connection)) @@ -233,10 +232,10 @@ void rpcconnection_serverThread(void* data) } - WriteLog(LL_Debug, "dispatching message %p %p", gMessageManager, allocation); + WriteLog(LL_Debug, "dispatching message %p %p", gFramework->messageManager, allocation); // Now that we have the full message chunk, parse the category and the type and get it the fuck outa here - messagemanager_sendMessage(gMessageManager, allocation); + messagemanager_sendMessage(gFramework->messageManager, allocation); __dec(allocation); } diff --git a/framework/src/oni/rpc/rpcserver.c b/src/oni/rpc/rpcserver.c similarity index 99% rename from framework/src/oni/rpc/rpcserver.c rename to src/oni/rpc/rpcserver.c index 0727dfe..0db7acf 100644 --- a/framework/src/oni/rpc/rpcserver.c +++ b/src/oni/rpc/rpcserver.c @@ -29,7 +29,7 @@ void rpcserver_init(struct rpcserver_t* server, struct proc* process) WriteLog(LL_Debug, "zeroing connections"); for (uint32_t i = 0; i < ARRAYSIZE(server->connections); ++i) server->connections[i] = 0; - + server->thread = 0; server->isRunning = 0; @@ -126,7 +126,7 @@ int32_t rpcserver_startup(struct rpcserver_t* server, uint16_t port) } WriteLog(LL_Debug, "socket bound."); - + // Listen for clients if (klisten(server->socket, 3) == -1) { @@ -217,7 +217,7 @@ void rpcserver_serverThread(void* data) utilUSleep(100, RPC_SLEEP); // Create the new client thread which will handle dispatching - + int creationResult = kthread_add(rpcconnection_serverThread, clientConnection, server->process, (struct thread**)&clientConnection->thread, 0, 0, "oni_client"); if (creationResult != 0) { diff --git a/src/oni/utils/dynlib.c b/src/oni/utils/dynlib.c new file mode 100644 index 0000000..c80f1da --- /dev/null +++ b/src/oni/utils/dynlib.c @@ -0,0 +1,17 @@ +#include +#include + +int64_t sys_dynlib_load_prx(char* prxPath) +{ + return (int64_t)syscall1(594, prxPath); +} + +int64_t sys_dynlib_unload_prx(int64_t prxID) +{ + return (int64_t)syscall1(595, (void*)prxID); +} + +int64_t sys_dynlib_dlsym(int64_t moduleHandle, const char* functionName, void *destFuncOffset) +{ + return (int64_t)syscall3(591, (void*)moduleHandle, (void*)functionName, destFuncOffset); +} \ No newline at end of file diff --git a/framework/src/oni/utils/kdlsym.c b/src/oni/utils/kdlsym.c similarity index 100% rename from framework/src/oni/utils/kdlsym.c rename to src/oni/utils/kdlsym.c diff --git a/framework/src/oni/utils/lock.c b/src/oni/utils/lock.c similarity index 92% rename from framework/src/oni/utils/lock.c rename to src/oni/utils/lock.c index 4d801a5..a706162 100644 --- a/framework/src/oni/utils/lock.c +++ b/src/oni/utils/lock.c @@ -7,7 +7,7 @@ void spin_init(struct lock_t* lock) { void(*mtx_init)(struct mtx *m, const char *name, const char *type, int opts) = kdlsym(mtx_init); - mtx_init(&lock->mutex, NULL, NULL, 0); + mtx_init(&lock->mutex, "oni logger lock", NULL, 0); } void spin_lock(struct lock_t *lock) diff --git a/framework/src/oni/utils/log/logger.c b/src/oni/utils/log/logger.c similarity index 100% rename from framework/src/oni/utils/log/logger.c rename to src/oni/utils/log/logger.c diff --git a/framework/src/oni/utils/memory/allocator.c b/src/oni/utils/memory/allocator.c similarity index 100% rename from framework/src/oni/utils/memory/allocator.c rename to src/oni/utils/memory/allocator.c diff --git a/framework/src/oni/utils/memory/install.c b/src/oni/utils/memory/install.c similarity index 93% rename from framework/src/oni/utils/memory/install.c rename to src/oni/utils/memory/install.c index 261287a..fdbacf5 100644 --- a/framework/src/oni/utils/memory/install.c +++ b/src/oni/utils/memory/install.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -15,6 +16,10 @@ #include #include #include +#include + +#include +#include uint8_t* gUserBaseAddress = NULL; uint32_t gUserBaseSize = 0; @@ -22,6 +27,8 @@ void* gElevatedEntryPoint = NULL; void SelfElevateAndRunStage2(); + + uint8_t SelfElevateAndRun(uint8_t* userlandPayload, uint32_t userlandSize, void(*elevatedEntryPoint)(void* arguments)) { // Verify arguments @@ -34,7 +41,7 @@ uint8_t SelfElevateAndRun(uint8_t* userlandPayload, uint32_t userlandSize, void( gElevatedEntryPoint = elevatedEntryPoint; // TODO: kexec - //_kexec(SelfElevateAndRunStage2, NULL); + syscall1(11, SelfElevateAndRunStage2); return true; } @@ -52,6 +59,15 @@ void SelfElevateAndRunStage2() int(*kproc_create)(void(*func)(void*), void* arg, struct proc** newpp, int flags, int pages, const char* fmt, ...) = kdlsym(kproc_create); vm_map_t map = (vm_map_t)(*(uint64_t *)(kdlsym(kernel_map))); + // Apply patches + critical_enter(); + cpu_disable_wp(); + + oni_installPrePatches(); + + cpu_enable_wp(); + crtical_exit(); + // We currently are in kernel context, executing userland memory if (!gUserBaseAddress || !gUserBaseSize || !gElevatedEntryPoint) return; @@ -74,7 +90,6 @@ void SelfElevateAndRunStage2() return; printf("[+] Pre-faulting user memory %p %x\n", 0x926100000, 0x200000); - //mlock((void*)0x926100000, 0x200000); mlockall(1); printf("[+] Pre-faulting kernel memory %p %x\n", kernelPayload, gUserBaseSize); diff --git a/src/oni/utils/memory/syscall.s b/src/oni/utils/memory/syscall.s new file mode 100644 index 0000000..a29cdeb --- /dev/null +++ b/src/oni/utils/memory/syscall.s @@ -0,0 +1,49 @@ +.intel_syntax noprefix +.text + +.global syscall1, syscall2, syscall3, syscall4, syscall5 + +syscall: + mov rax,rdi + syscall + ret + +syscall1: + mov rax,rdi + mov rdi,rsi + syscall + ret + +syscall2: + mov rax,rdi + mov rdi,rsi + mov rsi,rdx + syscall + ret + +syscall3: + mov rax,rdi + mov rdi,rsi + mov rsi,rdx + mov rdx,rcx + syscall + ret + +syscall4: + mov rax,rdi + mov rdi,rsi + mov rsi,rdx + mov rdx,rcx + mov r10,r8 + syscall + ret + +syscall5: + mov rax,rdi + mov rdi,rsi + mov rsi,rdx + mov rdx,rcx + mov r10,r8 + mov r8,r9 + syscall + ret diff --git a/framework/src/oni/utils/sys_wrappers.c b/src/oni/utils/sys_wrappers.c similarity index 94% rename from framework/src/oni/utils/sys_wrappers.c rename to src/oni/utils/sys_wrappers.c index b9ac587..78a592e 100644 --- a/framework/src/oni/utils/sys_wrappers.c +++ b/src/oni/utils/sys_wrappers.c @@ -581,6 +581,51 @@ int kdup2(int oldd, int newd) return td->td_retval[0]; } +int kmkdir(char * path, int mode) +{ + int(*sys_mkdir)(struct thread *, struct mkdir_args *) = kdlsym(sys_mkdir); + + int error; + struct mkdir_args uap; + struct thread *td = curthread; + + // clear errors + td->td_retval[0] = 0; + + // call syscall + uap.path = path; + uap.mode = mode; + + error = sys_mkdir(td, &uap); + if (error) + return -error; + + // success + return td->td_retval[0]; +} + +int krmdir(char * path) +{ + int(*sys_rmdir)(struct thread *, struct rmdir_args *) = kdlsym(sys_rmdir); + + int error; + struct rmdir_args uap; + struct thread *td = curthread; + + // clear errors + td->td_retval[0] = 0; + + // call syscall + uap.path = path; + + error = sys_rmdir(td, &uap); + if (error) + return -error; + + // success + return td->td_retval[0]; +} + int kshutdown(int s, int how) { int(*sys_shutdown)(struct thread *, struct shutdown_args *) = kdlsym(sys_shutdown); diff --git a/src/oni/utils/utils.s b/src/oni/utils/utils.s new file mode 100644 index 0000000..7bfb051 --- /dev/null +++ b/src/oni/utils/utils.s @@ -0,0 +1,25 @@ +.intel_syntax noprefix +.text + +.global kernelRdmsr +.global cpu_enable_wp +.global cpu_disable_wp + +kernelRdmsr: + mov ecx, edi + rdmsr + shl rdx, 32 + or rax, rdx + ret + +cpu_enable_wp: + mov rax, cr0 + or rax, 0x10000 + mov cr0, rax + ret + +cpu_disable_wp: + mov rax, cr0 + and rax, ~0x10000 + mov cr0, rax + ret