Skip to content

Commit

Permalink
Initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
CreepNT committed Jul 10, 2023
0 parents commit cb6c1e0
Show file tree
Hide file tree
Showing 64 changed files with 77,417 additions and 0 deletions.
23 changes: 23 additions & 0 deletions .github/ISSUE_TEMPLATE/executable-import-issue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
name: Executable import issue
about: Report a problem encountered while importing a PlayStation®Vita executable.
title: "[Import] "
labels: bug
assignees: ''

---

**Describe the bug**
Add any information you find may be relevant.

**Exception call stack**
If an exception happens, include the call stack here. The call stack will be displayed in either the `Details>>` extended panel (import failure) or in the `Additional Information` of the `Import Results Summary`. Include all the text in those panels here.
```
CALL STACK GOES HERE
```

**ELF source**
Please indicate the origin of the ELF file that causes this problem. If possible, include it along with the report. For system modules, indicate the exact firmware it was extracted from and in which path the module is located.

**Additional information**
Creation date of the extension (this can be found in `File>Install Extensions`): 20XX-XX-XX
35 changes: 35 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.gradle/*
.vscode/*
build/*

# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

.settings
.antProperties.xml
.project
.classpath
bin/help
bin/
dist/
32 changes: 32 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
The Clear BSD License

Copyright (c) 2023 CreepNT
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the disclaimer
below) provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
132 changes: 132 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@

# VitaLoader Redux
PlayStation®Vita ELF-PRX loader for Ghidra

## Features
Redux can be used in place of the ELF loader provided by Ghidra to load exectuables in ELF-PRX format targetting the PlayStation®Vita platform. **This loader does NOT support standard ELF executables - only use it for ELFs in PRX format.**

- Loads ELF files with SCE types (`ET_SCE_EXEC`, `ET_SCE_RELEXEC`, `ET_SCE_PSP2RELEXEC`) and standard types (`ET_REL`, `ET_EXEC`, `ET_CORE` ***in PRX format***)
- Locates and marks up all module entrypoints
- `module_start`
- `module_stop`
- `module_exit`
- `module_bootstart`
- `module_suspend`
- `module_proc_create`
- `module_proc_exit`
- `module_proc_kill`
- Locates, marks up and parses `NONAME` exports
- `SceModuleInfo`
- `SceProcessParam` and subfields
- `SceLibcParam` including Malloc Replacement
- Module thread parameters
- DTrace probes
- SDK version (displayed in `About Program` window)
- Locates and marks up all imports and exports
- Imports are separated based on the module from which they are imported
- Allows automatic renaming of symbols using NID databases

### New features
#### NID Analyzer
Naming of imports and exports using a NID database is no longer performed at import time. Use the new `NID Resolution` analyzer instead. Analysis can be performed multiple times with different databases.

The database used for analysis can be changed in the analyzer's settings in `Analysis > Auto Analyze '<program name>'`. The built-in databases are located in `%USERPROFILE%\.ghidra\<Ghidra version>\Extensions\VitaLoaderRedux\data\databases` and can be freely modified.
- `DefaultNIDDatabase.yaml` is used by default by the analyzer (`BuiltinDatabase`)
- `SecondaryNIDDatabase.yaml` can be selected by choosing `BuiltinSecondaryDatabase`
- An arbitrary database file can be used by choosing `ExternalDatabase`

To apply NIDs from multiple databases successively, disable the `Clear old names` setting.

#### Variable import relocation
Variable imports are now supported and handled properly ! This also applies to function-as-variable imports. A special memory block is created to "store" all imported variables. The relocations associated to them are applied

The varimport memory block can be customized at import time by clicking on the `Options...` button in the Import dialog.

Due to the way relocation is performed, certain code patterns will confuse the decompiler. For example, C code that should read as
```c
if (&sceWeaklyImportedFunction != NULL) {
sceWeaklyImportedFunction();
}
```
will transform info something similar to
```c
if (true) {
sceWeaklyImportedFunction();
}
```
i.e. the condition will always evaluate to 1.

The assembly will now however hold a reference to the function thunk. This can be used to understand what the correct disassembly is. **Users should always be wary of `if (true)` and `if (false)` tests as they usually hide a subtlety the decompiler is unable to recover.** Note that the affected code patterns are seen only in a few modules (e.g. `SceDisplay`) - this should not be an issue for most reverse engineering tasks.

#### Utility scripts
Can be found in the *Script Manager* under the `Vita` category.
- `MapRAMForNSKBL.py`
- Adds LPDDR2TOP in the memory map and merge it with NSKBL (`nskbl.bin`)
- Fixes missing references to `.bss` section and other stuff
- `AddHardwareDevices.py`
- Adds several hardware devices in the memory map
- Useful for reverse engineering of code running without MMU on (SKBL, NSKBL, CMeP binaries)

#### MeP-c5 support
- Original idea from [ghidra-mep](https://github.com/xyzz/ghidra-mep) by xyz
- **Written from scratch**
- *`ghidra-mep` used as reference (along with Ghidra "samples") for tricky points*
- Implements most of the MeP-c4 instruction set
- Coprocessor-modulo instructions are not implemented
- MeP-c5 instructions are not implemented (except `PREF`)
- The `CACHE` instruction is implemented
- **This fixes `halt_baddata()` in some CMeP binaries!**
- IVC2 coprocessor (i.e. Venezia core) is not implemented

## Installation
Download the [latest release](https://github.com/CreepNT/VitaLoaderRedux/releases/latest) for the Ghidra version you use.
Open Ghidra, select `File` > `Install Extensions...`, click on the green `+` and select the `.zip` you just downloaded.
Restart Ghidra, as asked by a dialog that should appear.

## Updating
Open Ghidra, select `File` > `Install Extensions...` and untick the checkbox next to `VitaLoaderRedux`.
Close Ghidra and follow the [install instructions](#Installation) again.

## Building
[Install Gradle](https://gradle.org/install/) then run `gradle` in a command prompt. Make sure to pass `-PGHIDRA_INSTALL_DIR=<path to Ghidra install>` if the environement variable `GHIDRA_INSTALL_DIR` isn't set.

**Building the extension for a version of Ghidra earlier than 10.3 is not supported.**

## Bug reports
Please report any error encountered with Redux in the [Issues Tracker](https://github.com/CreepNT/VitaLoaderRedux/issues).

Before submitting any bug report, update to the latest version of the extension. Make sure you are importing an ELF file **in PRX format** - regular ELF files are **not** supported.

If you are not able to load a file (`ARM ELF-PRX for PlayStation®Vita` is not displayed in the `Executable Type` list), ***please verify that your executable is not malformed***.

### Known bugs
None.

## Future plans
The following features might be implemented in Redux:
- Add missing structures (e.g. smaller `SceLibcParam`)
- Symbol parsing
- Object file support (`.o` files)
- Unwind tables parsing
- *if it might be useful for C++ binaries reversing, which I doubt*
- Full MeP-c5 implementation
- Venezia (MeP + IVC2) support

## Credits
- **“PlayStation” is a registered trademark or trademark of Sony Interactive Entertainment Inc.**
- astrelsky and all contributors - [GhidraOrbis](https://github.com/astrelsky/GhidraOrbis)
- xerpi and all contributors - [GhidraVitaLoader script](https://github.com/xerpi/GhidraVitaLoader)
- xyz - [ghidra-mep](https://github.com/xyzz/ghidra-mep)
- EsotericSoftware - [YamlBeans](https://github.com/EsotericSoftware/yamlbeans)
Special thanks for pre-release testing and various input:
- CelesteBlue
- GrapheneCt
- Macdu
- M Ibrahim
- Princess-of-Sleeping
- rem
- sarcastic_cat
- everyone else I forgot (sorry 😅)

## License
This repository is covered by the [Clear BSD License](/LICENSE), except the third-party libraries in the [lib/](/lib/) directory which are covered by the licenses listed in [lib/LICENSES](/lib/LICENSES).
62 changes: 62 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Builds a Ghidra Extension for a given Ghidra installation.
//
// An absolute path to the Ghidra installation directory must be supplied either by setting the
// GHIDRA_INSTALL_DIR environment variable or Gradle project property:
//
// > export GHIDRA_INSTALL_DIR=<Absolute path to Ghidra>
// > gradle
//
// or
//
// > gradle -PGHIDRA_INSTALL_DIR=<Absolute path to Ghidra>
//
// Gradle should be invoked from the directory of the project to build. Please see the
// application.gradle.version property in <GHIDRA_INSTALL_DIR>/Ghidra/application.properties
// for the correction version of Gradle to use for the Ghidra installation you specify.

//----------------------START "DO NOT MODIFY" SECTION------------------------------
def ghidraInstallDir

if (project.hasProperty("GHIDRA_INSTALL_DIR")) {
ghidraInstallDir = project.getProperty("GHIDRA_INSTALL_DIR")
} else if (System.env.GHIDRA_INSTALL_DIR) {
ghidraInstallDir = System.env.GHIDRA_INSTALL_DIR
}

if (ghidraInstallDir) {
apply from: new File(ghidraInstallDir).getCanonicalPath() + "/support/buildExtension.gradle"
}
else {
throw new GradleException("GHIDRA_INSTALL_DIR is not defined!")
}
//----------------------END "DO NOT MODIFY" SECTION-------------------------------

repositories {
// Declare dependency repositories here. This is not needed if dependencies are manually
// dropped into the lib/ directory.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html for more info.
// Ex: mavenCentral()
}

dependencies {
// Any external dependencies added here will automatically be copied to the lib/ directory when
// this extension is built.
}

// Exclude additional files from the built extension
// Ex: buildExtension.exclude '.idea/**'
1 change: 1 addition & 0 deletions data/ExtensionPoint.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ImportExportProperty
24 changes: 24 additions & 0 deletions data/VitaFunctionsThatDoNotReturn.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Vita functions which do not return
# Write the function's real name followed by the systematic name(s)
# (names should not start with '_' since these are stripped during checking)

stack_chk_fail
SceSysclibForDriver_B997493D
SceLibKernel_37691BF8
SceLibSsp_39AD080B

sceKernelExitProcessForUser
SceProcessmgr_C053DC6B

sceKernelStopped
SceDebugForKernel_F1F0C365

# panic_on_kernel_exception (used by Excpmgr)
SceDebugForKernel_082B8D6A
SceDebugForKernel_CCABDD98

sceKernelPanic
SceDebugForDriver_391B5B74

sceKernelPrintfPanic
SceDebugForDriver_00CCE39C
51 changes: 51 additions & 0 deletions data/buildLanguage.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>

<!--
+ Compile sleigh languages within this module.
+ Sleigh compiler options are read from the sleighArgs.txt file.
+ Eclipse: right-click on this file and choose menu item "Run As->Ant Build"
-->

<project name="privateBuildDeveloper" default="sleighCompile">

<property name="sleigh.compile.class" value="ghidra.pcodeCPort.slgh_compile.SleighCompile"/>

<!--Import optional ant properties. GhidraDev Eclipse plugin produces this so this file can find the Ghidra installation-->
<import file="../.antProperties.xml" optional="false" />

<target name="sleighCompile">

<!-- If language module is detached from installation, get Ghidra installation directory path from imported properties -->
<property name="framework.path" value="${ghidra.install.dir}/Ghidra/Framework"/>

<path id="sleigh.class.path">
<fileset dir="${framework.path}/SoftwareModeling/lib">
<include name="*.jar"/>
</fileset>
<fileset dir="${framework.path}/Generic/lib">
<include name="*.jar"/>
</fileset>
<fileset dir="${framework.path}/Utility/lib">
<include name="*.jar"/>
</fileset>
</path>

<available classname="${sleigh.compile.class}" classpathref="sleigh.class.path" property="sleigh.compile.exists"/>

<fail unless="sleigh.compile.exists" />

<java classname="${sleigh.compile.class}"
classpathref="sleigh.class.path"
fork="true"
failonerror="true">
<jvmarg value="-Xmx2048M"/>
<arg value="-t"/>
<arg value="-u"/>
<arg value="-n"/>
<arg value="-a"/>
<arg value="./languages"/>
</java>

</target>

</project>
Loading

0 comments on commit cb6c1e0

Please sign in to comment.