-
Notifications
You must be signed in to change notification settings - Fork 0
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
0 parents
commit 73ca924
Showing
21 changed files
with
1,205 additions
and
0 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 |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# | ||
# https://help.github.com/articles/dealing-with-line-endings/ | ||
# | ||
# Linux start script should use lf | ||
/gradlew text eol=lf | ||
|
||
# These are Windows script files and should use crlf | ||
*.bat text eol=crlf | ||
|
||
# Binary files should be left untouched | ||
*.jar binary | ||
|
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 |
---|---|---|
@@ -0,0 +1,7 @@ | ||
.gradle | ||
libs | ||
build | ||
app/build | ||
config.json | ||
offsets.txt | ||
out.txt |
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 |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2024 n0thhhing | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
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 |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# IL2CPP AArch64 Offset Updater | ||
|
||
## Overview | ||
|
||
The Offset Updater is a tool designed to update | ||
offsets for IL2CPP binaries between updates on the AArch64 architecture. | ||
It utilizes Capstone for disassembly and provides a | ||
user-friendly way to manage offsets for dynamic library | ||
updates. The application is built in Kotlin and requires | ||
Java 21 to run. | ||
|
||
## Features | ||
|
||
- Reads offset configurations from a JSON file. | ||
- Supports pattern scanning in AArch64 binaries using the KMP algorithm. | ||
- Configurable verbosity for detailed output during processing. | ||
- Easy integration with existing projects via Gradle. | ||
|
||
## Requirements | ||
|
||
- **Java 21**: Ensure you have JDK 21 installed on your system. | ||
- **Kotlin**(only for building): The project is built using Kotlin, ensure you have the necessary dependencies set up in your build configuration. | ||
|
||
## Installation | ||
|
||
1. Clone the repository or download the project files. | ||
2. Navigate to the project directory. | ||
3. Open the terminal and run the following command to build the project: | ||
|
||
```bash | ||
./gradlew build # or ./gradlew jar to package | ||
``` | ||
|
||
## Configuration | ||
|
||
Before running the updater, create a `config.json` file in the project root directory. Here’s an example of the configuration: | ||
|
||
```json | ||
{ | ||
"sigLen": 64, | ||
"verbose": false, | ||
"offsetFile": "offsets.txt", | ||
"outputFile": "out.txt", | ||
"newLib": "new.so", | ||
"oldLib": "old.so" | ||
} | ||
``` | ||
|
||
- `sigLen`: Length of the signature for pattern matching. | ||
- `verbose`: Enables detailed logging if set to true. | ||
- `offsetFile`: The file containing the offsets to be updated. | ||
- `outputFile`: Where the new offsets should go | ||
- `newLib`: The new library file to scan. | ||
- `oldLib`: The old library file for reference. | ||
|
||
## Offset File Format | ||
Offset File Format | ||
The offsets.txt file must be formatted as follows: | ||
``` | ||
Copy code | ||
0xBEAF // comment | ||
0xF00D | ||
0x1234 | ||
// comment | ||
``` | ||
Each line can contain a hexadecimal offset prefixed with 0x. | ||
Comments can be added using // and will be ignored by the parser. | ||
Empty lines or lines with only comments will be skipped. | ||
|
||
## Usage | ||
|
||
1. Prepare the `offsets.txt` file containing the offsets to be updated, following the specified format. | ||
|
||
2. You can download the release JAR file from the [releases page](link-to-your-releases-page) and run the updater with the following command: | ||
|
||
```bash | ||
java -jar Updater-1.0.0.jar | ||
``` | ||
|
||
Alternatively, if you built the project yourself, run: | ||
|
||
```bash | ||
java -jar build/libs/Updater-1.0.0.jar | ||
``` | ||
|
||
3. The application will load the configuration, disassemble the old library, and search for patterns in the new library. | ||
|
||
## Output | ||
|
||
The application provides output regarding the status of the offset updates, like whether patterns were found a d the pattern itself. Verbose output can be enabled for detailed information. | ||
|
||
## License | ||
|
||
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more information. | ||
|
||
## Contributing | ||
|
||
Contributions are welcome! Please open issues for any bugs you find or feature requests you may have. | ||
|
||
## Acknowledgements | ||
|
||
- [Capstone](https://www.capstone-engine.org/) - A lightweight multi-platform, multi-architecture disassembly framework. | ||
- [Gson](https://github.com/google/gson) - A Java library to convert Java Objects into JSON and back. | ||
- [Kotlin](https://kotlinlang.org/) - A modern programming language that makes programming easier and more enjoyable. | ||
- [ktfmt-gradle](https://github.com/cortinico/ktfmt-gradle) A reliable kotlin formatter for gradle. |
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 |
---|---|---|
@@ -0,0 +1,62 @@ | ||
plugins { | ||
alias(libs.plugins.kotlin.jvm) | ||
alias(libs.plugins.ktfmt) | ||
application | ||
} | ||
|
||
repositories { | ||
google() | ||
mavenCentral() | ||
maven("https://jitpack.io") | ||
} | ||
|
||
dependencies { | ||
implementation(libs.guava) | ||
implementation(libs.capstone) | ||
implementation(libs.gson) | ||
implementation(libs.slf4j) | ||
} | ||
|
||
testing { | ||
suites { | ||
val test by getting(JvmTestSuite::class) { | ||
useKotlinTest("2.0.0") | ||
} | ||
} | ||
} | ||
|
||
java { | ||
toolchain { | ||
languageVersion = JavaLanguageVersion.of(21) | ||
} | ||
} | ||
|
||
application { | ||
mainClass = "org.updater.UpdaterKt" | ||
} | ||
|
||
ktfmt { | ||
kotlinLangStyle() | ||
} | ||
|
||
tasks.jar { | ||
manifest { | ||
attributes["Main-Class"] = application.mainClass.get() | ||
} | ||
|
||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE | ||
|
||
from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) }) | ||
|
||
archiveBaseName.set("Updater") | ||
archiveVersion.set("$version") | ||
} | ||
|
||
// Im not putting ktfmtFormat every time, wtf | ||
tasks.register("fmt") { | ||
dependsOn(tasks.ktfmtFormat) | ||
} | ||
|
||
tasks.named("build") { | ||
dependsOn(tasks.jar) | ||
} |
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 |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package org.updater | ||
|
||
import capstone.Capstone | ||
import capstone.api.Disassembler | ||
import capstone.api.DisassemblerFactory | ||
import com.google.gson.Gson | ||
import org.updater.utils.Color | ||
import org.updater.utils.FileHandler | ||
import org.updater.utils.KmpScanner | ||
import org.updater.utils.OffsetFileParser | ||
import org.updater.utils.getPattern | ||
|
||
private const val CONFIG_FILE = "config.json" | ||
|
||
var useVerbose = false | ||
|
||
data class Config( | ||
val sigLen: Int = 64, | ||
val verbose: Boolean = false, | ||
val offsetFile: String = "offsets.txt", | ||
val outputFile: String = "out.txt", | ||
val newLib: String = "new.so", | ||
val oldLib: String = "old.so", | ||
) | ||
|
||
data class OffsetResult(val offset: String, val pattern: String, val foundOffsets: List<String>) | ||
|
||
fun verbose(message: Any) { | ||
if (useVerbose) { | ||
println(message) | ||
} | ||
} | ||
|
||
fun main() { | ||
val startTime = System.currentTimeMillis() | ||
val config = loadConfig(CONFIG_FILE) | ||
|
||
useVerbose = config.verbose | ||
|
||
val offsets = OffsetFileParser.parse(config.offsetFile) | ||
val newLibBytes = FileHandler.readFileAsByteArr(config.newLib) | ||
val oldLibBytes = FileHandler.readFileAsByteArr(config.oldLib) | ||
|
||
var passCount = 0 | ||
var failCount = 0 | ||
|
||
val disassembler = | ||
DisassemblerFactory.createDisassembler(Capstone.CS_ARCH_ARM64, Capstone.CS_MODE_ARM).apply { | ||
setDetail(false) | ||
} | ||
|
||
FileHandler.writeFile(config.outputFile, "") | ||
|
||
offsets.forEach { offset -> | ||
val (result, found) = processOffset(disassembler, oldLibBytes, newLibBytes, offset, config) | ||
appendResultToFile(config.outputFile, result) | ||
if (found) passCount++ else failCount++ | ||
} | ||
|
||
printSummary(startTime, offsets.size, passCount, failCount) | ||
disassembler.close() | ||
} | ||
|
||
private fun loadConfig(filename: String): Config { | ||
return Gson().fromJson(FileHandler.readFileAsStr(filename), Config::class.java) | ||
} | ||
|
||
private fun processOffset( | ||
cs: Disassembler, | ||
oldBytes: ByteArray, | ||
newBytes: ByteArray, | ||
offset: Int, | ||
config: Config, | ||
): Pair<OffsetResult, Boolean> { | ||
val currentOffset = "0x${offset.toString(16)}" | ||
verbose(Color.green("Processing Offset: ${Color.blue(currentOffset)}")) | ||
|
||
val start = System.currentTimeMillis() | ||
val pattern = getPattern(cs, oldBytes, offset, config.sigLen) | ||
val occurrences = KmpScanner.scan(newBytes, pattern).map { "0x${it.toString(16)}" } | ||
val found = occurrences.isNotEmpty() | ||
verbose( | ||
if (occurrences.isNotEmpty()) Color.green("Pattern found at positions: ") + occurrences | ||
else Color.red("Pattern not found") | ||
) | ||
verbose( | ||
Color.green("Total processing time: ${Color.blue(System.currentTimeMillis() - start)}ms") | ||
) | ||
verbose("--------------------------------------") | ||
|
||
return Pair(OffsetResult(currentOffset, pattern, occurrences), found) | ||
} | ||
|
||
private fun appendResultToFile(filePath: String, result: OffsetResult) { | ||
val content = | ||
""" | ||
Offset: ${result.offset}: | ||
- Pattern: ${result.pattern} | ||
- Found offsets: ${if (result.foundOffsets.isNotEmpty()) result.foundOffsets.joinToString(", ") else "None"} | ||
""" | ||
.trimIndent() | ||
|
||
FileHandler.appendToFile(filePath, content) | ||
} | ||
|
||
private fun printSummary(startTime: Long, totalOffsets: Int, passCount: Int, failCount: Int) { | ||
val totalTime = System.currentTimeMillis() - startTime | ||
println(Color.green("Finished")) | ||
verbose(Color.green("\n$passCount patterns found")) | ||
verbose(Color.red("$failCount patterns not found")) | ||
verbose("$totalOffsets total (${Color.blue(totalTime)}ms)") | ||
} |
Oops, something went wrong.