-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
87a09eb
commit fa182df
Showing
3 changed files
with
46 additions
and
154 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
[package] | ||
name = "skyline_rs_template" | ||
name = "nro_hook" | ||
version = "0.1.0" | ||
authors = ["jam1garner <[email protected]>"] | ||
edition = "2018" | ||
|
@@ -11,8 +11,10 @@ titleid = "01006A800016E000" | |
crate-type = ["cdylib"] | ||
|
||
[dependencies] | ||
skyline = { git = "https://github.com/ultimate-research/skyline-rs.git" } | ||
#skyline = { git = "https://github.com/ultimate-research/skyline-rs.git" } | ||
skyline = { path = "../../skyline-rs", features = ["nro_internal"] } | ||
skyline_smash = { git = "https://github.com/ultimate-research/skyline-smash.git" } | ||
parking_lot = { version = "0.10", features = ["nightly"] } | ||
|
||
[profile.dev] | ||
panic = "abort" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,110 +1,19 @@ | ||
# skyline-rs-template | ||
# NRO hook plugin | ||
|
||
A template for writing skyline plugins for modding switch games using Rust and skyline-rs. | ||
A plugin allowing for centralized hooking of NROs, allowing multiple plugins to all hook NRO load. | ||
|
||
[Documentation for skyline-rs](https://ultimate-research.github.io/skyline-rs-template/doc/skyline/index.html) | ||
## Install | ||
|
||
## Prerequisites | ||
**Note:** Requires [cargo-skyline](https://github.com/jam1garner/cargo-skyline) to be installed | ||
|
||
* [Rust](https://www.rust-lang.org/install.html) - make sure rustup, cargo, and rustc (preferrably nightly) are installed. | ||
* [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) | ||
To install, simply run: | ||
|
||
## Setup | ||
|
||
NOTE: for easier/newer setup, use [cargo skyline](https://github.com/jam1garner/cargo-skyline) | ||
|
||
1. Install linkle and my fork of Xargo: | ||
```sh | ||
# Install linkle | ||
cargo install --features=binaries --git https://github.com/MegatonHammer/linkle | ||
|
||
# Install Xargo | ||
cargo install --force --git https://github.com/jam1garner/xargo.git | ||
``` | ||
2. Make a folder for you to store all of your plugins | ||
``` | ||
mkdir plugins | ||
cd plugins | ||
``` | ||
3. Within your plugins folder, clone [rust-std-skyline-squashed](https://github.com/jam1garner/rust-std-skyline-squashed) | ||
```sh | ||
# Make sure you are inside of your plugins folder | ||
git clone https://github.com/jam1garner/rust-std-skyline-squashed | ||
``` | ||
Note: you only have to clone the `std` once to be shared between every plugin in the folder. | ||
|
||
## Creating and building a plugin | ||
|
||
1. From within the same folder as where you cloned `rust-std-skyline-squashed` clone this repo and rename it to match the | ||
name of your plugin. To clone and rename all at once, use: | ||
``` | ||
git clone https://github.com/jam1garner/skyline-rs-template [name of plugin] | ||
``` | ||
2. Make sure you're inside the folder for your plugin: | ||
```sh | ||
cd [name of plugin] | ||
cargo skyline install | ||
``` | ||
3. There's a few places you'll need to rename your plugin. First in `Cargo.toml` near the top, change | ||
``` | ||
name = "skyline-rs-template" | ||
``` | ||
To a name suitable for your plugin. Next, go into `src/lib.rs` and edit the following line: | ||
```rust | ||
#[skyline::main(name = "module_name_test")] | ||
``` | ||
to reflect what you want your module to be named on your console. | ||
|
||
4. Lastly, to compile your plugin use the following command in the root of the project (beside the `Cargo.toml` file): | ||
```sh | ||
cargo nro | ||
``` | ||
Your resulting plugin will be the `.nro` found in the folder | ||
``` | ||
[plugin name]/target/aarch64-skyline-switch | ||
Or, if your IP isn't configured yet, use | ||
``` | ||
To install (you must already have skyline installed on your switch), put the plugin on your SD at: | ||
``` | ||
sd:/atmosphere/contents/[title id]/romfs/skyline/plugins | ||
``` | ||
So, for example, smash plugins go in the following folder: | ||
``` | ||
sd:/atmosphere/contents/01006A800016E000/romfs/skyline/plugins | ||
``` | ||
|
||
## Troubleshooting | ||
|
||
**"Cannot be used on stable"** | ||
|
||
First, make sure you have a nightly installed: | ||
``` | ||
rustup install nightly | ||
``` | ||
Second, make sure it is your default channel: | ||
``` | ||
rustup default nightly | ||
``` | ||
--- | ||
``` | ||
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/bin/cargo-nro.rs:280:13 | ||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace | ||
``` | ||
|
||
Make sure you are *inside* the root of the plugin you created before running `cargo nro` | ||
|
||
Have a problem/solution that is missing here? Create an issue or a PR! | ||
|
||
## Updating | ||
|
||
For updating your dependencies such as skyline-rs: | ||
|
||
``` | ||
cargo update | ||
``` | ||
|
||
For updating your version of `rust-std-skyline-squashed`: | ||
|
||
``` | ||
# From inside your plugins folder | ||
rm -rf && git clone https://github.com/jam1garner/rust-std-skyline-squashed | ||
cargo skyline install --ip X.X.X.X | ||
``` | ||
Where `X.X.X.X` is your switch's IP address |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,67 +1,48 @@ | ||
#![feature(proc_macro_hygiene)] | ||
|
||
use skyline::{hook, install_hook}; | ||
use std::thread; | ||
use std::time::Duration; | ||
use skyline::nn::ro; | ||
use skyline::libc::{c_void, c_int, size_t}; | ||
use skyline::from_c_str; | ||
|
||
extern "C" fn test() -> u32 { | ||
2 | ||
} | ||
|
||
//#[hook(offset = 0x12345)] | ||
#[hook(replace = test)] | ||
fn test_replacement() -> u32 { | ||
|
||
let original_test = original!(); | ||
|
||
let val = original_test(); | ||
|
||
println!("[override] original value: {}", val); // 2 | ||
|
||
val + 1 | ||
} | ||
use parking_lot::Mutex; | ||
|
||
#[skyline::main(name = "skyline_rs_template")] | ||
pub fn main() { | ||
println!("Hello from Skyline Rust Plugin!"); | ||
|
||
install_hook!(test_replacement); | ||
use skyline::nro::NroInfo; | ||
|
||
let x = test(); | ||
type Callback = fn(&NroInfo); | ||
|
||
// Make a vector to hold the children which are spawned. | ||
let mut children = vec![]; | ||
static HOOKS: Mutex<Vec<Callback>> = Mutex::new(Vec::new()); | ||
|
||
let sleep_times = [0, 100, 500, 200, 5000, 100, 150, 0, 0, 300]; | ||
#[hook(replace = ro::LoadModule)] | ||
pub fn handle_load_module( | ||
out_module: *mut ro::Module, | ||
image: *const c_void, | ||
buffer: *mut c_void, | ||
buffer_size: size_t, | ||
flag: c_int | ||
) -> c_int { | ||
let ret = original!()(out_module, image, buffer, buffer_size, flag); | ||
|
||
for i in 0..10 { | ||
let sleep_time = sleep_times[i]; | ||
// Spin up another thread | ||
children.push(thread::spawn(move || { | ||
thread::sleep(Duration::from_millis(sleep_time)); | ||
println!("this is thread number {}", i); | ||
})); | ||
let name = unsafe { from_c_str(&(*out_module).Name as *const u8) }; | ||
println!("Test test test {}", name); | ||
let nro_info = NroInfo::new(&name, unsafe { &mut *out_module }); | ||
for hook in HOOKS.lock().iter() { | ||
hook(&nro_info) | ||
} | ||
|
||
for child in children { | ||
// Wait for the thread to finish. Returns a result. | ||
let _ = child.join(); | ||
} | ||
ret | ||
} | ||
|
||
println!("[main] test returned: {}", x); // 3 | ||
#[skyline::main(name = "nro_hook")] | ||
pub fn main() { | ||
println!("[NRO hook] Installing NRO hook..."); | ||
install_hook!(handle_load_module); | ||
println!("[NRO hook] NRO hook installed."); | ||
} | ||
|
||
println!("{}", std::fs::read_to_string("sd:/test.txt").unwrap()); | ||
for x in std::fs::read_dir("sd:/atmosphere").unwrap() { | ||
println!("{:?}", x.unwrap()); | ||
} | ||
#[no_mangle] | ||
pub extern "Rust" fn add_nro_load_hook(callback: Callback) { | ||
let mut hooks = HOOKS.lock(); | ||
|
||
// keep-alive thread | ||
thread::spawn(||{ | ||
loop { | ||
println!("Still alive?"); | ||
thread::sleep(Duration::from_secs(3)); | ||
println!("Still alive!"); | ||
thread::sleep(Duration::from_secs(1)); | ||
} | ||
}); | ||
hooks.push(callback); | ||
} |