├── .github ├── logo_text.svg └── logo_visual.svg ├── .gitignore ├── LICENSE.md ├── README.md ├── examples ├── aot_modify_class_constructor_argument.js ├── aot_modify_class_function_argument.js ├── jit_modify_class_function_argument.js ├── read_class_static_bool_variable.js ├── read_class_static_int_variable.js ├── read_class_static_object_variable.js └── read_class_static_string_variable.js ├── fridax.js ├── libraries └── class_helper.js ├── package-lock.json ├── package.json ├── scripts └── .gitignore └── vendors └── frida-mono-api ├── LICENSE.md ├── README.md ├── index.js ├── mono-api-helper.js ├── mono-api.js └── mono-module.js /.github/logo_text.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 |

4 | FЯIDAX 5 |

6 |
7 | 8 |
9 | -------------------------------------------------------------------------------- /.github/logo_visual.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # General 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | 6 | # Icon must end with two \r 7 | Icon 8 | 9 | 10 | # Thumbnails 11 | ._* 12 | 13 | # Files that might appear in the root of a volume 14 | .DocumentRevisions-V100 15 | .fseventsd 16 | .Spotlight-V100 17 | .TemporaryItems 18 | .Trashes 19 | .VolumeIcon.icns 20 | .com.apple.timemachine.donotpresent 21 | 22 | # Directories potentially created on remote AFP share 23 | .AppleDB 24 | .AppleDesktop 25 | Network Trash Folder 26 | Temporary Items 27 | .apdisk 28 | 29 | # Logs 30 | logs 31 | *.log 32 | npm-debug.log* 33 | yarn-debug.log* 34 | yarn-error.log* 35 | lerna-debug.log* 36 | 37 | # Diagnostic reports (https://nodejs.org/api/report.html) 38 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 39 | 40 | # Runtime data 41 | pids 42 | *.pid 43 | *.seed 44 | *.pid.lock 45 | 46 | # Directory for instrumented libs generated by jscoverage/JSCover 47 | lib-cov 48 | 49 | # Coverage directory used by tools like istanbul 50 | coverage 51 | *.lcov 52 | 53 | # nyc test coverage 54 | .nyc_output 55 | 56 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 57 | .grunt 58 | 59 | # Bower dependency directory (https://bower.io/) 60 | bower_components 61 | 62 | # node-waf configuration 63 | .lock-wscript 64 | 65 | # Compiled binary addons (https://nodejs.org/api/addons.html) 66 | build/Release 67 | 68 | # Dependency directories 69 | node_modules/ 70 | jspm_packages/ 71 | 72 | # TypeScript v1 declaration files 73 | typings/ 74 | 75 | # TypeScript cache 76 | *.tsbuildinfo 77 | 78 | # Optional npm cache directory 79 | .npm 80 | 81 | # Optional eslint cache 82 | .eslintcache 83 | 84 | # Microbundle cache 85 | .rpt2_cache/ 86 | .rts2_cache_cjs/ 87 | .rts2_cache_es/ 88 | .rts2_cache_umd/ 89 | 90 | # Optional REPL history 91 | .node_repl_history 92 | 93 | # Output of 'npm pack' 94 | *.tgz 95 | 96 | # Yarn Integrity file 97 | .yarn-integrity 98 | 99 | # dotenv environment variables file 100 | .env 101 | .env.test 102 | 103 | # parcel-bundler cache (https://parceljs.org/) 104 | .cache 105 | 106 | # Next.js build output 107 | .next 108 | 109 | # Nuxt.js build / generate output 110 | .nuxt 111 | dist 112 | 113 | # Gatsby files 114 | .cache/ 115 | # Comment in the public line in if your project uses Gatsby and not Next.js 116 | # https://nextjs.org/blog/next-9-1#public-directory-support 117 | # public 118 | 119 | # vuepress build output 120 | .vuepress/dist 121 | 122 | # Serverless directories 123 | .serverless/ 124 | 125 | # FuseBox cache 126 | .fusebox/ 127 | 128 | # DynamoDB Local files 129 | .dynamodb/ 130 | 131 | # TernJS port file 132 | .tern-port 133 | 134 | # Stores VSCode versions used for testing VSCode extensions 135 | .vscode-test 136 | 137 | # Fridax specific 138 | .node-persist/ 139 | scripts_temp/ -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | =========== 3 | 4 | Copyright (c) 2020 Northwave B.V. (www.northwave-security.com) 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |
4 | Fridax is a Node package for dealing with Xamarin applications while using the Frida API. 5 |
6 | Goal 7 | • 8 | Installation 9 | • 10 | Usage 11 | • 12 | Examples 13 | • 14 | Issues 15 | • 16 | License 17 |
18 | Built with ❤ by the Northwave Red Team 19 |
20 |

21 |
22 | 23 | ## Goal 24 | 25 | In the Northwave Red Team we conduct security penetration tests on, among other things, mobile applications. During almost every mobile application penetration test we want to modify the behaviour of the application in such a way that it bypasses certain checks (e.g. a PIN code check). 26 | 27 | Frida is a toolkit that allows us to do exactly that. It is a dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers. Using Frida you can, for example, inject and modify code of iOS and Android applications on runtime. However, if the application that is being pentested is a Xamarin application, it becomes more difficult to modify code on runtime, since Xamarin applications are basically wrappers that run a .NET binary. 28 | 29 | **Fridax to the rescue!** Fridax allows you to easily modify the .NET binary inside a Xamarin application on runtime. We've included some example scripts that e.g. modify constructor and function arguments. 30 | 31 | Happy hacking! 32 | 33 | ## Installation 34 | 35 | Clone this Git repository. 36 | 37 | ```bash 38 | git clone git@github.com:NorthwaveNL/fridax.git 39 | ``` 40 | 41 | Use the package manager [npm](https://www.npmjs.com/) to install the dependencies for Fridax. 42 | 43 | ```bash 44 | cd fridax 45 | npm install 46 | ``` 47 | 48 | ## Usage 49 | 50 | Please check the [known issues](#issues) before your start. 51 | 52 | 1. Connect your device (make sure it can be listed). 53 | - `frida-ls-devices` 54 | 2. Copy an example script to the scripts folder. 55 | - `cp examples/modify_class_function_argument.js scripts/modify_class_function_argument.js` 56 | 3. Adjust some of the config variables in the script (that you copied) to your needs. 57 | - Update `settingClassName`, `settingMethodName` and `settingMethodArgCount` 58 | 4. Start the application on your device and run your script! 59 | - `./fridax.js inject --scripts scripts/modify_class_function_argument.js` 60 | 61 | **All options** 62 | 63 | ```bash 64 | ./fridax.js 65 | 66 | Commands: 67 | ./fridax.js inject [scripts] Inject the given scripts list. 68 | 69 | Options: 70 | --version Show version number [boolean] 71 | -h, --help Show help [boolean] 72 | --device The address of the remote Frida device to connect to (or the string "usb") [default: "usb"] 73 | 74 | Examples: 75 | ./fridax.js inject --scripts scripts/modify_function_argument.js scripts/intercept_password.js scripts/sql_injection.js 76 | ``` 77 | 78 | ## Examples 79 | 80 | Example scripts can be found in `./examples`. Place an example script in the `./scripts` folder to try it out. Using the example scripts, all of the variables/functions in the example class below can be read/intercepted. 81 | 82 | ```csharp 83 | namespace CompanyName.ProjectName { 84 | 85 | class Settings { 86 | 87 | // Static int can be read 88 | public static readonly int secret1 = 1234; 89 | 90 | // Static bool can be read 91 | public static readonly bool secret2 = false; 92 | 93 | // Static object can be read 94 | public static readonly ObfuscatedString secret3 = ObfuscatedString("yGVhqI5yzbgYUnCP+ZukDw=="); 95 | 96 | // Static string can be read 97 | public static readonly string secret4 = "SecretValue"; 98 | 99 | // Constructor can be intercepted and arguments can be modified 100 | Settings(string a, string b, string c) { 101 | 102 | } 103 | 104 | // Function can be intercepted and argument can be modified 105 | GetElement(string id) { 106 | 107 | } 108 | 109 | } 110 | 111 | } 112 | ``` 113 | For example, to read the `public static readonly bool secret2` you can run the command below after copying `./examples/read_static_bool_from_class.js` to `./scripts/read_static_bool_from_class.js`. You also need to edit the `Company.ProjectName.Settings` class name and `secret2` variable name in that file to your needs. You can find out which names you need by using [dnSpy](https://github.com/0xd4d/dnSpy) on the Mono binary in the IPA/APK. 114 | 115 | ```bash 116 | ./fridax.js inject --scripts scripts/read_static_bool_from_class.js 117 | ``` 118 | 119 | ## Issues 120 | 121 | Issues or new features can be reported via the [GitHub issue tracker](https://github.com/NorthwaveNL/fridax/issues). Please make sure your issue or feature has not yet been reported by anyone else before submitting a new one. 122 | 123 | **Known issues** 124 | 125 | * Xamarin app needs to be running before you start this script (see [this issue](https://github.com/freehuntx/frida-mono-api/issues/4) for more information). 126 | * You get the error `Export not found: mono_aot_get_method`. This is due to your application being JIT-compiled. Please use the example scripts that are prefixed with `jit_` instead of `aot_` (AOT-compiled). See [issue #3](https://github.com/NorthwaveNL/fridax/issues/3) for more information. 127 | 128 | ## License 129 | 130 | Fridax is open-sourced software licensed under the [MIT license](https://github.com/NorthwaveNL/fridax/blob/develop/LICENSE.md). 131 | -------------------------------------------------------------------------------- /examples/aot_modify_class_constructor_argument.js: -------------------------------------------------------------------------------- 1 | import { MonoApiHelper, MonoApi } from '../vendors/frida-mono-api' 2 | import ClassHelper from '../libraries/class_helper' 3 | 4 | /* 5 | // For AOT-compiled applications only. 6 | // This example script can intercept the following method (constructor). 7 | // Furthermore it modifies the third argument (string c). 8 | 9 | namespace CompanyName.ProjectName.Views.Web.Html { 10 | 11 | class HtmlWebView { 12 | 13 | HtmlWebView(string a, string b, string c) { 14 | // This constructor will be intercepted. 15 | } 16 | 17 | } 18 | 19 | } 20 | */ 21 | 22 | // Intercept settings 23 | var settingClassName = "CompanyName.ProjectName.Views.Web.Html.HtmlWebView"; 24 | var settingMethodName = ".ctor"; 25 | var settingMethodArgCount = 3; 26 | 27 | // The root AppDomain is the initial domain created by the runtime when it is initialized. Programs execute on this AppDomain. 28 | const domain = MonoApi.mono_get_root_domain() 29 | 30 | // Get a reference to a certain class within the Xamarin application. 31 | var classInformation = ClassHelper.getClassByName(settingClassName); 32 | 33 | // Get the pointer to the ahead-of-time (AOT) compiled method 34 | let methodInformation = MonoApiHelper.ClassGetMethodFromName(classInformation, settingMethodName, settingMethodArgCount) 35 | 36 | // Allocate enough memory for MonoError initialization 37 | let monoErrorMemory = Memory.alloc(32) 38 | 39 | // Get the pointer to the method 40 | let nativeMethodPointer = MonoApi.mono_aot_get_method(domain, methodInformation, monoErrorMemory) 41 | 42 | // Attach interceptor and fish out the first method argument 43 | Interceptor.attach(nativeMethodPointer, { 44 | onEnter: function(args) { 45 | console.log("Entered " + settingMethodName + " with " + settingMethodArgCount + " argument(s)."); 46 | console.log("Value of `string c`: " + MonoApiHelper.StringToUtf8(args[3])); 47 | 48 | args[3] = MonoApiHelper.StringNew('This is the replaced value of `string c`.', domain); 49 | }, 50 | onLeave: function onLeave(log, retval, state) { 51 | console.log("Left " + settingMethodName + "."); 52 | } 53 | }) 54 | 55 | console.log(`'aot_modify_class_constructor_argument.js' attached and ready.`) 56 | -------------------------------------------------------------------------------- /examples/aot_modify_class_function_argument.js: -------------------------------------------------------------------------------- 1 | import { MonoApiHelper, MonoApi } from '../vendors/frida-mono-api' 2 | import ClassHelper from '../libraries/class_helper' 3 | 4 | /* 5 | // For AOT-compiled applications only. 6 | // This example script can intercept the following method (constructor). 7 | // Furthermore it modifies the first argument (string id). 8 | 9 | namespace CompanyName.ProjectName.Views.Web.Html { 10 | 11 | class HtmlWebView { 12 | 13 | GetElement(string id) { 14 | // This function will be intercepted. 15 | } 16 | 17 | } 18 | 19 | } 20 | */ 21 | 22 | // Intercept settings 23 | var settingClassName = "CompanyName.ProjectName.Views.Web.Html.HtmlWebView"; 24 | var settingMethodName = "GetElement"; 25 | var settingMethodArgCount = 1; 26 | 27 | // The root AppDomain is the initial domain created by the runtime when it is initialized. Programs execute on this AppDomain. 28 | const domain = MonoApi.mono_get_root_domain() 29 | 30 | // Get a reference to a certain class within the Xamarin application. 31 | var classInformation = ClassHelper.getClassByName(settingClassName); 32 | 33 | // Get the pointer to the ahead-of-time (AOT) compiled method 34 | let methodInformation = MonoApiHelper.ClassGetMethodFromName(classInformation, settingMethodName, settingMethodArgCount) 35 | 36 | // Allocate enough memory for MonoError initialization 37 | let monoErrorMemory = Memory.alloc(32) 38 | 39 | // Get the pointer to the method 40 | let nativeMethodPointer = MonoApi.mono_aot_get_method(domain, methodInformation, monoErrorMemory) 41 | 42 | // Attach interceptor and fish out the first method argument 43 | Interceptor.attach(nativeMethodPointer, { 44 | onEnter: function(args) { 45 | console.log("Entered " + settingMethodName + " with " + settingMethodArgCount + " argument(s)."); 46 | console.log("Value of `string id`: " + MonoApiHelper.StringToUtf8(args[1])); 47 | 48 | args[1] = MonoApiHelper.StringNew('This is the replaced value of `string id`.', domain); 49 | }, 50 | onLeave: function onLeave(log, retval, state) { 51 | console.log("Left " + settingMethodName + "."); 52 | } 53 | }) 54 | 55 | console.log(`'aot_modify_class_function_argument.js' attached and ready.`) 56 | -------------------------------------------------------------------------------- /examples/jit_modify_class_function_argument.js: -------------------------------------------------------------------------------- 1 | import { MonoApiHelper, MonoApi } from '../vendors/frida-mono-api' 2 | import ClassHelper from '../libraries/class_helper' 3 | 4 | /* 5 | // For JIT-compiled applications only. 6 | // This example script can intercept the following method (non-constructor). 7 | // Furthermore it modifies the first argument (string id). 8 | 9 | namespace CompanyName.ProjectName.Views.Web.Html { 10 | 11 | class HtmlWebView { 12 | 13 | GetElement(string id) { 14 | // This function will be intercepted. 15 | } 16 | 17 | } 18 | 19 | } 20 | */ 21 | 22 | // Intercept settings 23 | var settingClassName = "CompanyName.ProjectName.Views.Web.Html.HtmlWebView"; 24 | var settingMethodName = "GetElement"; 25 | var settingMethodArgCount = 1; 26 | 27 | // The root AppDomain is the initial domain created by the runtime when it is initialized. Programs execute on this AppDomain. 28 | const domain = MonoApi.mono_get_root_domain() 29 | 30 | // Get a reference to a certain class within the Xamarin application. 31 | var classInformation = ClassHelper.getClassByName(settingClassName); 32 | 33 | // Attach interceptor and fish out the first method argument 34 | MonoApiHelper.Intercept(classInformation, settingMethodName, { 35 | onEnter: function(args) { 36 | console.log("Entered " + settingMethodName + " with " + settingMethodArgCount + " argument(s)."); 37 | console.log("Value of `string id`: " + MonoApiHelper.StringToUtf8(args[1])); 38 | 39 | args[1] = MonoApiHelper.StringNew('This is the replaced value of `string id`.', domain); 40 | }, 41 | onLeave: function onLeave(log, retval, state) { 42 | console.log("Left " + settingMethodName + "."); 43 | } 44 | }) 45 | 46 | console.log(`'jit_modify_class_function_argument.js' attached and ready.`) 47 | -------------------------------------------------------------------------------- /examples/read_class_static_bool_variable.js: -------------------------------------------------------------------------------- 1 | import { MonoApiHelper, MonoApi } from '../vendors/frida-mono-api' 2 | import ClassHelper from '../libraries/class_helper' 3 | 4 | /* 5 | // This example script can read the static int variable `secret`. 6 | 7 | namespace CompanyName.ProjectName { 8 | 9 | class Settings { 10 | 11 | public static readonly bool secret = false; 12 | 13 | } 14 | 15 | } 16 | */ 17 | 18 | // Get a reference to ObfuscatedString password 19 | let settingsClass = ClassHelper.getClassByName("CompanyName.ProjectName.Settings") 20 | let secretField = MonoApiHelper.ClassGetFieldFromName(settingsClass, "secret") 21 | let secretValue = MonoApiHelper.FieldGetValueObject(secretField, settingsClass) 22 | 23 | // Unbox the Bool to the native int type and convert it to a boolean 24 | let unboxedSecretValue = MonoApiHelper.ObjectUnbox(secretValue) 25 | let boolSecretValue = unboxedSecretValue.readInt() === 1 26 | 27 | // Print result 28 | console.log('secret:', typeof(boolSecretValue), boolSecretValue) -------------------------------------------------------------------------------- /examples/read_class_static_int_variable.js: -------------------------------------------------------------------------------- 1 | import { MonoApiHelper, MonoApi } from '../vendors/frida-mono-api' 2 | import ClassHelper from '../libraries/class_helper' 3 | 4 | /* 5 | // This example script can read the static int variable `secret`. 6 | 7 | namespace CompanyName.ProjectName { 8 | 9 | class Settings { 10 | 11 | public static readonly int secret = 1234; 12 | 13 | } 14 | 15 | } 16 | */ 17 | 18 | // Get a reference to ObfuscatedString password 19 | let settingsClass = ClassHelper.getClassByName("CompanyName.ProjectName.Settings") 20 | let secretField = MonoApiHelper.ClassGetFieldFromName(settingsClass, "secret") 21 | let secretValue = MonoApiHelper.FieldGetValueObject(secretField, settingsClass) 22 | 23 | // Unbox the Int to the native int type 24 | let unboxedSecretValue = MonoApiHelper.ObjectUnbox(secretValue) 25 | 26 | // Print result 27 | console.log('secret:', typeof(unboxedSecretValue.readInt()), unboxedSecretValue.readInt()) -------------------------------------------------------------------------------- /examples/read_class_static_object_variable.js: -------------------------------------------------------------------------------- 1 | import { MonoApiHelper, MonoApi } from '../vendors/frida-mono-api' 2 | import ClassHelper from '../libraries/class_helper' 3 | 4 | /* 5 | // This example script can read the static ObfuscatedString variable `secret`. 6 | 7 | namespace CompanyName.ProjectName { 8 | 9 | class Settings { 10 | 11 | public static readonly ObfuscatedString secret; 12 | 13 | } 14 | 15 | } 16 | */ 17 | 18 | // Get a reference to ObfuscatedString secret 19 | let settingsClass = ClassHelper.getClassByName("CompanyName.ProjectName.Settings") 20 | let secretField = MonoApiHelper.ClassGetFieldFromName(settingsClass, "secret") 21 | let secretValue = MonoApiHelper.FieldGetValueObject(secretField, settingsClass) 22 | 23 | // Get a reference to the `ToString` function in the ObfuscatedString instance 24 | let obfuscatedStringClass = MonoApiHelper.ObjectGetClass(secretValue) 25 | let deobfuscateMethod = MonoApiHelper.ClassGetMethodFromName(obfuscatedStringClass, "ToString"); 26 | 27 | // Run `ToString` on the ObfuscatedString instance 28 | var resultData = MonoApiHelper.RuntimeInvoke(deobfuscateMethod, secretValue, NULL) 29 | 30 | // Convert value to an UTF8 string 31 | var result = MonoApiHelper.StringToUtf8(resultData) 32 | 33 | // Print result 34 | console.log('secret:', typeof(result), result) -------------------------------------------------------------------------------- /examples/read_class_static_string_variable.js: -------------------------------------------------------------------------------- 1 | import { MonoApiHelper, MonoApi } from '../vendors/frida-mono-api' 2 | import ClassHelper from '../libraries/class_helper' 3 | 4 | /* 5 | // This example script can read the static string variable `secret`. 6 | 7 | namespace CompanyName.ProjectName { 8 | 9 | class Settings { 10 | 11 | public static readonly string secret = "SecretValue"; 12 | 13 | } 14 | 15 | } 16 | */ 17 | 18 | // Get a reference to the secret string 19 | let settingsClass = ClassHelper.getClassByName("CompanyName.ProjectName.Settings") 20 | let secretField = MonoApiHelper.ClassGetFieldFromName(settingsClass, "secretString") 21 | let secretValue = MonoApiHelper.FieldGetValueObject(secretField, settingsClass) 22 | 23 | // Convert value to an UTF8 string 24 | var result = MonoApiHelper.StringToUtf8(secretValue) 25 | 26 | // Print result 27 | console.log('secret:', typeof(result), result) -------------------------------------------------------------------------------- /fridax.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * You should not change this file. 5 | * Please consult the `README.md` file for usage details. 6 | */ 7 | 8 | // Dependencies 9 | const fs = require(`fs`) 10 | const chalk = require(`chalk`) 11 | const inquirer = require(`inquirer`) 12 | const storage = require(`node-persist`) 13 | const frida = require(`frida`) 14 | const fridaInject = require(`frida-inject`) 15 | 16 | // Available arguments 17 | let argv = require(`yargs`) 18 | .scriptName(`./fridax.js`) 19 | .wrap(320) 20 | .help(`h`).alias(`h`, `help`) 21 | .option(`device`, { default: `usb`, description: `The address of the remote Frida device to connect to (or the string "usb")`}) 22 | .command(`inject [scripts]`, `Inject the given scripts list.`, (yargs) => { 23 | yargs 24 | .example(`$0 inject --scripts scripts/intercept_username.js scripts/intercept_password sql_injection.js`) 25 | .option(`scripts`, { 26 | alias: `s`, 27 | type: `array`, 28 | description: `A list of script names to run.` 29 | }) 30 | .demandOption(`scripts`) 31 | }, (argv) => {}) 32 | .demandCommand() 33 | .example(`$0 inject --scripts scripts/intercept_username.js scripts/intercept_password.js scripts/sql_injection.js`) 34 | .argv 35 | 36 | // The Fridax runtime 37 | async function main(options) { 38 | console.log(`[*] Awaiting storage initialization.`) 39 | await storage.init() 40 | 41 | let deviceManager = frida.getDeviceManager() 42 | let device = null; 43 | 44 | if (argv[`device`] !== `usb`) { 45 | console.log(`[*] Connecting to remote frida-server.`) 46 | device = await deviceManager.addRemoteDevice(argv[`device`]); 47 | } else { 48 | console.log(`[*] Awaiting USB device.`) 49 | device = await frida.getUsbDevice() 50 | } 51 | 52 | if (device == null) { 53 | return console.error(chalk.bold.red(`[!] Cannot find device.`)) 54 | } 55 | 56 | console.log(`[*] Up and running on ${device.name}.`) 57 | 58 | let application = await selectApplicationOnDevice(device) 59 | 60 | console.log(`[*] Happy hacking.`) 61 | 62 | let inject = await injectApplicationOnDevice(device, application) 63 | } 64 | 65 | // Give the user the option to choose an application 66 | async function selectApplicationOnDevice(device) { 67 | 68 | choices = [] 69 | applications = await device.enumerateApplications() 70 | 71 | selectedApplication = null 72 | selectedName = await storage.getItem(`selectedApplication`) 73 | 74 | for (i in applications) { 75 | choices.push({ 76 | name: applications[i][`name`], 77 | value: applications[i], 78 | }) 79 | 80 | if (applications[i][`name`] == selectedName) { 81 | selectedApplication = applications[i] 82 | } 83 | } 84 | 85 | let answers = await inquirer.prompt([ 86 | { 87 | type: `list`, 88 | name: `application`, 89 | message: `Which application do you want to inject?`, 90 | default: selectedApplication, 91 | choices: choices 92 | } 93 | ]) 94 | 95 | await storage.setItem(`selectedApplication`, answers.application.name) 96 | 97 | return answers.application; 98 | } 99 | 100 | // Inject the given scripts in the chosen application 101 | async function injectApplicationOnDevice(device, application) { 102 | let pid = application.pid ? application.pid : await device.spawn(application.identifier) 103 | 104 | var scripts = [`console.log('[*] Injected a test script (this runs from within the injected application)!')`] 105 | for (index in argv[`scripts`]) { 106 | var file = __dirname + `/${argv[`scripts`][index]}` 107 | if (fs.existsSync(file)) { 108 | scripts.push(file) 109 | } else { 110 | console.error(chalk.bold.red(`[!] File '${file}' does not exist.`)) 111 | } 112 | } 113 | 114 | return await fridaInject({ 115 | pid: pid, 116 | device: device, 117 | scripts: scripts, 118 | onAttach: session => console.log(`[*] Attached to application (session: ${session.pid}).`), 119 | onDetach: (session, reason) => console.log(`[*] Detached from application (session: ${session.pid}): ${reason}.`), 120 | onUnload: script => console.log(`[*] Script unloaded.`) 121 | }) 122 | } 123 | 124 | main() 125 | -------------------------------------------------------------------------------- /libraries/class_helper.js: -------------------------------------------------------------------------------- 1 | import { MonoApiHelper, MonoApi } from '../vendors/frida-mono-api' 2 | 3 | /** 4 | * Class containing helper functions for Mono classes 5 | */ 6 | export default class ClassHelper { 7 | 8 | /** 9 | * Retrieve a Mono class by the given name 10 | * 11 | * @param {string} The name of the class (e.g. `CompanyName.ProjectName.Views.Web.Html.HtmlWebView`) 12 | * @returns {object} The Mono class representing the given class name 13 | */ 14 | static getClassByName(class_name) { 15 | var result = null 16 | 17 | MonoApiHelper.AssemblyForeach(function(assembly) { 18 | var image = MonoApi.mono_assembly_get_image(assembly) 19 | var pointer = MonoApiHelper.ClassFromName(image, class_name) 20 | 21 | if (pointer != 0) { 22 | result = pointer 23 | } 24 | }) 25 | 26 | return result 27 | } 28 | 29 | /** 30 | * Retrieve the name of the given Mono class pointer 31 | * 32 | * @param {pointer} A pointer to a Mono class. 33 | * @returns {string} The name representing the class (e.g. `HtmlWebView`) 34 | */ 35 | static getNameByPointer(pointer) { 36 | return MonoApiHelper.ClassGetName(MonoApiHelper.ObjectGetClass(pointer)) 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fridax", 3 | "version": "1.0.0", 4 | "description": "Frida Xamarin Hooking", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/NorthwaveNL/fridax.git" 8 | }, 9 | "main": "hack.js", 10 | "dependencies": { 11 | "chalk": "^3.0.0", 12 | "console-stamp": "^0.2.9", 13 | "frida-ex-nativefunction": "^0.1.2", 14 | "frida-inject": "^0.4.1", 15 | "inquirer": "^7.1.0", 16 | "node-persist": "^3.0.5", 17 | "yargs": "^15.3.1" 18 | }, 19 | "devDependencies": {}, 20 | "author": "Tijme Gommers", 21 | "license": "MIT" 22 | } 23 | -------------------------------------------------------------------------------- /scripts/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything 2 | * 3 | 4 | # But not these files... 5 | !.gitignore -------------------------------------------------------------------------------- /vendors/frida-mono-api/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | =========== 3 | 4 | **Initial codebase** 5 | Copyright (c) 2018 freehuntx (https://github.com/freehuntx/frida-mono-api/) 6 | 7 | **Additions** 8 | Copyright (c) 2020 Northwave B.V. (www.northwave-security.com) 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | -------------------------------------------------------------------------------- /vendors/frida-mono-api/README.md: -------------------------------------------------------------------------------- 1 | ## Goal 2 | 3 | This is an adjusted version of freehuntx' [Frida Mono Api](https://github.com/freehuntx/frida-mono-api) library. The Frida Mono Api library is licensed under the [MIT License](https://github.com/NorthwaveNL/fridax/blob/master/vendors/frida-mono-api/LICENSE.md). 4 | -------------------------------------------------------------------------------- /vendors/frida-mono-api/index.js: -------------------------------------------------------------------------------- 1 | export { default as MonoApi } from './mono-api' 2 | export { default as MonoApiHelper } from './mono-api-helper' 3 | -------------------------------------------------------------------------------- /vendors/frida-mono-api/mono-api-helper.js: -------------------------------------------------------------------------------- 1 | import MonoApi from './mono-api' 2 | 3 | const rootDomain = MonoApi.mono_get_root_domain() 4 | 5 | const MonoApiHelper = { 6 | AssemblyForeach: cb => { 7 | return MonoApi.mono_assembly_foreach(MonoApi.mono_assembly_foreach.nativeCallback(cb), NULL) 8 | }, 9 | AssemblyLoadFromFull: (mono_image, filename, openStatusPtr, refonly) => { 10 | return MonoApi.mono_assembly_load_from_full(mono_image, Memory.allocUtf8String(filename), openStatusPtr, refonly) 11 | }, 12 | ClassEnumBasetype: MonoApi.mono_class_enum_basetype, 13 | ClassFromMonoType: MonoApi.mono_class_from_mono_type, 14 | ClassFromName: (mono_image, name) => { 15 | const resolved = resolveClassName(name) 16 | return MonoApi.mono_class_from_name(mono_image, Memory.allocUtf8String(resolved.namespace), Memory.allocUtf8String(resolved.className)) 17 | }, 18 | ClassGetFieldFromName: (mono_class, name) => { 19 | return MonoApi.mono_class_get_field_from_name(mono_class, Memory.allocUtf8String(name)) 20 | }, 21 | ClassGetFields: mono_class => { 22 | const fields = [] 23 | const iter = Memory.alloc(Process.pointerSize) 24 | let field 25 | 26 | while(!(field = MonoApi.mono_class_get_fields(mono_class, iter)).isNull()) { 27 | fields.push(field) 28 | } 29 | return fields 30 | }, 31 | ClassGetMethodFromName: (mono_class, name, argCnt = -1) => { 32 | return MonoApi.mono_class_get_method_from_name(mono_class, Memory.allocUtf8String(name), argCnt) 33 | }, 34 | ClassGetMethods: mono_class => { 35 | const methods = [] 36 | const iter = Memory.alloc(Process.pointerSize) 37 | let method 38 | 39 | while(!(method = MonoApi.mono_class_get_methods(mono_class, iter)).isNull()) { 40 | methods.push(method) 41 | } 42 | return methods 43 | }, 44 | ClassGetName: mono_class => { 45 | return Memory.readUtf8String(MonoApi.mono_class_get_name(mono_class)) 46 | }, 47 | ClassGetType: MonoApi.mono_class_get_type, 48 | ClassIsEnum: mono_class => MonoApi.mono_class_is_enum(mono_class) === 1, 49 | CompileMethod: MonoApi.mono_compile_method, 50 | DomainGet: MonoApi.mono_domain_get, 51 | FieldGetFlags: MonoApi.mono_field_get_flags, 52 | FieldGetName: mono_field => Memory.readUtf8String(MonoApi.mono_field_get_name(mono_field)), 53 | FieldGetValueObject: (mono_field, mono_object, domain = rootDomain) => { 54 | return MonoApi.mono_field_get_value_object(domain, mono_field, mono_object) 55 | }, 56 | GetBooleanClass: MonoApi.mono_get_boolean_class, 57 | GetInt32Class: MonoApi.mono_get_int32_class, 58 | GetSingleClass: MonoApi.mono_get_single_class, 59 | GetStringClass: MonoApi.mono_get_string_class, 60 | GetUInt32Class: MonoApi.mono_get_uint32_class, 61 | ImageLoaded: name => MonoApi.mono_image_loaded(Memory.allocUtf8String(name)), 62 | Intercept: hookManagedMethod, 63 | MethodGetFlags: (mono_method, iflags = 0) => MonoApi.mono_method_get_flags(mono_method, iflags), 64 | MethodGetName: mono_method => Memory.readUtf8String(MonoApi.mono_method_get_name(mono_method)), 65 | MethodSignature: MonoApi.mono_method_signature, 66 | ObjectGetClass: MonoApi.mono_object_get_class, 67 | ObjectGetVirtualMethod: MonoApi.mono_object_get_virtual_method, 68 | ObjectNew: (mono_class, domain = rootDomain) => MonoApi.mono_object_new(domain, mono_class), 69 | ObjectUnbox: mono_object => MonoApi.mono_object_unbox(mono_object), 70 | RuntimeInvoke: (mono_method, instance = NULL, args = NULL) => { 71 | const exception = NULL 72 | const result = MonoApi.mono_runtime_invoke(mono_method, instance, args, exception) 73 | 74 | if (!exception.isNull()) { 75 | throw new Error('Unknown exception happened.') 76 | } 77 | 78 | return result 79 | }, 80 | SignatureGetParamCount: MonoApi.mono_signature_get_param_count, SignatureGetParams: signature => { 81 | let params = [] 82 | let iter = Memory.alloc(Process.pointerSize) 83 | let type 84 | 85 | while(!(type = MonoApi.mono_signature_get_params(signature, iter)).isNull()) { 86 | params.push(type) 87 | } 88 | 89 | return params 90 | }, 91 | StringNew: (str, domain = rootDomain) => MonoApi.mono_string_new(domain, Memory.allocUtf8String(str)), 92 | StringToUtf8: mono_string => Memory.readUtf8String(MonoApi.mono_string_to_utf8(mono_string)), 93 | TypeGetClass: MonoApi.mono_type_get_class, 94 | TypeGetName: mono_type => Memory.readUtf8String(MonoApi.mono_type_get_name(mono_type)), 95 | TypeGetType: MonoApi.mono_type_get_type, 96 | TypeGetUnderlyingType: MonoApi.mono_type_get_underlying_type, 97 | ValueBox: (mono_class, valuePtr, domain = rootDomain) => MonoApi.mono_value_box(domain, mono_class, valuePtr) 98 | } 99 | 100 | function hookManagedMethod(klass, methodName, callbacks) { 101 | if (!callbacks) throw new Error('callbacks must be an object!'); 102 | if (!callbacks.onEnter && !callbacks.onLeave) throw new Error('At least one callback is required!'); 103 | 104 | let md = MonoApiHelper.ClassGetMethodFromName(klass, methodName); 105 | if (!md) throw new Error('Method not found!'); 106 | let impl = MonoApi.mono_compile_method(md) 107 | 108 | Interceptor.attach(impl, {...callbacks}); 109 | } 110 | 111 | function resolveClassName(className) { 112 | return { 113 | className: className.substring(className.lastIndexOf('.')+1), 114 | namespace: className.substring(0, className.lastIndexOf('.')) 115 | } 116 | } 117 | 118 | export default MonoApiHelper 119 | -------------------------------------------------------------------------------- /vendors/frida-mono-api/mono-api.js: -------------------------------------------------------------------------------- 1 | import ExNativeFunction from 'frida-ex-nativefunction' 2 | import monoModule from './mono-module' 3 | 4 | let MonoApi = { 5 | g_free: null, 6 | mono_add_internal_call: null, 7 | mono_alloc_special_static_data: null, 8 | mono_array_addr_with_size: ['pointer', ['pointer', 'int', 'uint32']], 9 | mono_array_class_get: null, 10 | mono_array_clone: null, 11 | mono_array_element_size: null, 12 | mono_array_length: ['uint32', ['pointer']], 13 | mono_array_new: null, 14 | mono_array_new_full: null, 15 | mono_array_new_specific: null, 16 | mono_assemblies_cleanup: null, 17 | mono_assemblies_init: null, 18 | mono_assembly_close: null, 19 | mono_assembly_fill_assembly_name: null, 20 | mono_assembly_foreach: ['int', ['pointer', 'pointer']], 21 | mono_assembly_get_assemblyref: null, 22 | mono_assembly_get_image: ['pointer', ['pointer']], 23 | mono_assembly_get_main: null, 24 | mono_assembly_get_object: null, 25 | mono_assembly_getrootdir: null, 26 | mono_assembly_invoke_load_hook: null, 27 | mono_assembly_invoke_search_hook: null, 28 | mono_assembly_load: null, 29 | mono_assembly_load_from: null, 30 | mono_assembly_load_from_full: ['pointer', ['pointer', 'pointer', 'pointer', 'uchar']], 31 | mono_assembly_load_full: null, 32 | mono_assembly_load_module: null, 33 | mono_assembly_load_reference: null, 34 | mono_assembly_load_references: null, 35 | mono_assembly_load_with_partial_name: ['pointer', ['pointer', 'pointer']], 36 | mono_assembly_loaded: null, 37 | mono_assembly_loaded_full: null, 38 | mono_assembly_name_parse: null, 39 | mono_assembly_names_equal: null, 40 | mono_assembly_open: null, 41 | mono_assembly_open_full: null, 42 | mono_assembly_set_main: null, 43 | mono_assembly_setrootdir: null, 44 | mono_aot_get_method: ['pointer', ['pointer', 'pointer', 'pointer']], 45 | mono_backtrace_from_context: null, 46 | mono_bitset_alloc_size: null, 47 | mono_bitset_clear: null, 48 | mono_bitset_clear_all: null, 49 | mono_bitset_clone: null, 50 | mono_bitset_copyto: null, 51 | mono_bitset_count: null, 52 | mono_bitset_equal: null, 53 | mono_bitset_find_first: null, 54 | mono_bitset_find_first_unset: null, 55 | mono_bitset_find_last: null, 56 | mono_bitset_find_start: null, 57 | mono_bitset_foreach: null, 58 | mono_bitset_free: null, 59 | mono_bitset_intersection: null, 60 | mono_bitset_intersection_2: null, 61 | mono_bitset_invert: null, 62 | mono_bitset_mem_new: null, 63 | mono_bitset_new: null, 64 | mono_bitset_set: null, 65 | mono_bitset_set_all: null, 66 | mono_bitset_size: null, 67 | mono_bitset_sub: null, 68 | mono_bitset_test: null, 69 | mono_bitset_test_bulk: null, 70 | mono_bitset_union: null, 71 | mono_bounded_array_class_get: null, 72 | mono_check_corlib_version: null, 73 | mono_class_array_element_size: null, 74 | mono_class_data_size: null, 75 | mono_class_describe_statics: null, 76 | mono_class_enum_basetype: ['pointer', ['pointer']], 77 | mono_class_from_generic_parameter: null, 78 | mono_class_from_mono_type: ['pointer', ['pointer']], 79 | mono_class_from_name: ['pointer', ['pointer', 'pointer', 'pointer']], 80 | mono_class_from_name_case: null, 81 | mono_class_from_typeref: null, 82 | mono_class_get: ['pointer', ['pointer', 'uint32']], 83 | mono_class_get_byref_type: null, 84 | mono_class_get_element_class: null, 85 | mono_class_get_event_token: null, 86 | mono_class_get_events: null, 87 | mono_class_get_field: null, 88 | mono_class_get_field_from_name: ['pointer', ['pointer', 'pointer']], 89 | mono_class_get_field_token: null, 90 | mono_class_get_fields: ['pointer', ['pointer', 'pointer']], 91 | mono_class_get_flags: null, 92 | mono_class_get_full: null, 93 | mono_class_get_image: null, 94 | mono_class_get_interfaces: null, 95 | mono_class_get_method_from_name: ['pointer', ['pointer', 'pointer', 'int']], 96 | mono_class_get_method_from_name_flags: null, 97 | mono_class_get_methods: ['pointer', ['pointer', 'pointer']], 98 | mono_class_get_name: ['pointer', ['pointer']], 99 | mono_class_get_namespace: ['pointer', ['pointer']], 100 | mono_class_get_nested_types: null, 101 | mono_class_get_nesting_type: null, 102 | mono_class_get_parent: ['pointer', ['pointer']], 103 | mono_class_get_properties: null, 104 | mono_class_get_property_from_name: ['pointer', ['pointer', 'pointer']], 105 | mono_class_get_property_token: null, 106 | mono_class_get_rank: null, 107 | mono_class_get_type: ['pointer', ['pointer']], 108 | mono_class_get_type_token: null, 109 | mono_class_get_userdata: null, 110 | mono_class_get_userdata_offset: null, 111 | mono_class_inflate_generic_method: null, 112 | mono_class_inflate_generic_method_full: null, 113 | mono_class_inflate_generic_type: null, 114 | mono_class_init: null, 115 | mono_class_instance_size: null, 116 | mono_class_is_assignable_from: null, 117 | mono_class_is_blittable: null, 118 | mono_class_is_enum: ['uchar', ['pointer']], 119 | mono_class_is_generic: null, 120 | mono_class_is_inflated: null, 121 | mono_class_is_subclass_of: null, 122 | mono_class_is_valuetype: null, 123 | mono_class_min_align: null, 124 | mono_class_name_from_token: null, 125 | mono_class_num_events: null, 126 | mono_class_num_fields: null, 127 | mono_class_num_methods: null, 128 | mono_class_num_properties: null, 129 | mono_class_set_userdata: null, 130 | mono_class_value_size: null, 131 | mono_class_vtable: null, 132 | mono_cli_rva_image_map: null, 133 | mono_code_manager_commit: null, 134 | mono_code_manager_destroy: null, 135 | mono_code_manager_foreach: null, 136 | mono_code_manager_invalidate: null, 137 | mono_code_manager_new: null, 138 | mono_code_manager_new_dynamic: null, 139 | mono_code_manager_reserve: null, 140 | mono_compile_method: ['pointer', ['pointer']], 141 | mono_config_for_assembly: null, 142 | mono_config_parse: null, 143 | mono_config_parse_memory: null, 144 | mono_config_string_for_assembly_file: null, 145 | mono_context_get: null, 146 | mono_context_init: null, 147 | mono_context_set: null, 148 | mono_counters_dump: null, 149 | mono_counters_enable: null, 150 | mono_counters_register: null, 151 | mono_custom_attrs_construct: null, 152 | mono_custom_attrs_free: null, 153 | mono_custom_attrs_from_assembly: null, 154 | mono_custom_attrs_from_class: null, 155 | mono_custom_attrs_from_event: null, 156 | mono_custom_attrs_from_field: null, 157 | mono_custom_attrs_from_index: null, 158 | mono_custom_attrs_from_method: null, 159 | mono_custom_attrs_from_param: null, 160 | mono_custom_attrs_from_property: null, 161 | mono_custom_attrs_get_attr: null, 162 | mono_custom_attrs_has_attr: null, 163 | mono_debug_add_method: null, 164 | mono_debug_cleanup: null, 165 | mono_debug_close_mono_symbol_file: null, 166 | mono_debug_domain_create: null, 167 | mono_debug_domain_unload: null, 168 | mono_debug_find_method: null, 169 | mono_debug_free_source_location: null, 170 | mono_debug_init: null, 171 | mono_debug_lookup_method: null, 172 | mono_debug_lookup_source_location: null, 173 | mono_debug_open_image_from_memory: null, 174 | mono_debug_open_mono_symbols: null, 175 | mono_debug_print_stack_frame: null, 176 | mono_debug_print_vars: null, 177 | mono_debug_symfile_lookup_location: null, 178 | mono_debug_symfile_lookup_method: null, 179 | mono_debug_using_mono_debugger: null, 180 | mono_debugger_breakpoint_callback: null, 181 | mono_debugger_check_runtime_version: null, 182 | mono_debugger_cleanup: null, 183 | mono_debugger_event: null, 184 | mono_debugger_handle_exception: null, 185 | mono_debugger_initialize: null, 186 | mono_debugger_insert_breakpoint: null, 187 | mono_debugger_insert_breakpoint_full: null, 188 | mono_debugger_lock: null, 189 | mono_debugger_method_has_breakpoint: null, 190 | mono_debugger_remove_breakpoint: null, 191 | mono_debugger_run_finally: null, 192 | mono_debugger_unlock: null, 193 | mono_declsec_flags_from_assembly: null, 194 | mono_declsec_flags_from_class: null, 195 | mono_declsec_flags_from_method: null, 196 | mono_declsec_get_assembly_action: null, 197 | mono_declsec_get_class_action: null, 198 | mono_declsec_get_demands: null, 199 | mono_declsec_get_inheritdemands_class: null, 200 | mono_declsec_get_inheritdemands_method: null, 201 | mono_declsec_get_linkdemands: null, 202 | mono_declsec_get_method_action: null, 203 | mono_digest_get_public_token: null, 204 | mono_disasm_code: null, 205 | mono_disasm_code_one: null, 206 | mono_dl_fallback_register: null, 207 | mono_dl_fallback_unregister: null, 208 | mono_dllmap_insert: null, 209 | mono_domain_add_class_static_data: null, 210 | mono_domain_assembly_open: null, 211 | mono_domain_create: null, 212 | mono_domain_create_appdomain: null, 213 | mono_domain_finalize: null, 214 | mono_domain_foreach: ['void', ['pointer', 'pointer']], 215 | mono_domain_free: null, 216 | mono_domain_get: ['pointer'], 217 | mono_domain_get_by_id: null, 218 | mono_domain_get_id: null, 219 | mono_domain_has_type_resolve: null, 220 | mono_domain_is_unloading: null, 221 | mono_domain_owns_vtable_slot: null, 222 | mono_domain_set: null, 223 | mono_domain_set_internal: null, 224 | mono_domain_try_type_resolve: null, 225 | mono_domain_unload: null, 226 | mono_environment_exitcode_get: null, 227 | mono_environment_exitcode_set: null, 228 | mono_escape_uri_string: null, 229 | mono_event_get_add_method: null, 230 | mono_event_get_flags: null, 231 | mono_event_get_name: null, 232 | mono_event_get_object: null, 233 | mono_event_get_parent: null, 234 | mono_event_get_raise_method: null, 235 | mono_event_get_remove_method: null, 236 | mono_exception_from_name: null, 237 | mono_exception_from_name_domain: null, 238 | mono_exception_from_name_msg: null, 239 | mono_exception_from_name_two_strings: null, 240 | mono_exception_from_token: null, 241 | mono_field_from_token: null, 242 | mono_field_get_data: null, 243 | mono_field_get_flags: ['uint', ['pointer']], 244 | mono_field_get_name: ['pointer', ['pointer']], 245 | mono_field_get_object: null, 246 | mono_field_get_offset: null, 247 | mono_field_get_parent: null, 248 | mono_field_get_type: ['pointer', ['pointer']], 249 | mono_field_get_value: ['void', ['pointer', 'pointer', 'pointer']], 250 | mono_field_get_value_object: ['pointer', ['pointer', 'pointer', 'pointer']], 251 | mono_field_set_value: ['void', ['pointer', 'pointer', 'pointer']], 252 | mono_field_static_get_value: null, 253 | mono_field_static_set_value: null, 254 | mono_file_map: null, 255 | mono_file_unmap: null, 256 | mono_free_method: null, 257 | mono_free_verify_list: null, 258 | mono_g_hash_table_destroy: null, 259 | mono_g_hash_table_foreach: null, 260 | mono_g_hash_table_foreach_remove: null, 261 | mono_g_hash_table_insert: null, 262 | mono_g_hash_table_lookup: null, 263 | mono_g_hash_table_lookup_extended: null, 264 | mono_g_hash_table_new: null, 265 | mono_g_hash_table_new_full: null, 266 | mono_g_hash_table_new_type: null, 267 | mono_g_hash_table_remove: null, 268 | mono_g_hash_table_replace: null, 269 | mono_g_hash_table_size: null, 270 | mono_gc_collect: null, 271 | mono_gc_collection_count: null, 272 | mono_gc_enable_events: null, 273 | mono_gc_get_generation: null, 274 | mono_gc_get_heap_size: null, 275 | mono_gc_get_used_size: null, 276 | mono_gc_is_finalizer_thread: null, 277 | mono_gc_max_generation: null, 278 | mono_gc_out_of_memory: null, 279 | mono_gc_wbarrier_arrayref_copy: null, 280 | mono_gc_wbarrier_generic_store: null, 281 | mono_gc_wbarrier_set_arrayref: null, 282 | mono_gc_wbarrier_set_field: null, 283 | mono_gc_wbarrier_value_copy: null, 284 | mono_gchandle_free: null, 285 | mono_gchandle_get_target: null, 286 | mono_gchandle_is_in_domain: null, 287 | mono_gchandle_new: null, 288 | mono_gchandle_new_weakref: null, 289 | mono_get_array_class: null, 290 | mono_get_boolean_class: ['pointer'], 291 | mono_get_byte_class: null, 292 | mono_get_char_class: null, 293 | mono_get_config_dir: null, 294 | mono_get_corlib: null, 295 | mono_get_dbnull_object: null, 296 | mono_get_delegate_invoke: null, 297 | mono_get_double_class: null, 298 | mono_get_enum_class: null, 299 | mono_get_exception_appdomain_unloaded: null, 300 | mono_get_exception_argument: null, 301 | mono_get_exception_argument_null: null, 302 | mono_get_exception_argument_out_of_range: null, 303 | mono_get_exception_arithmetic: null, 304 | mono_get_exception_array_type_mismatch: null, 305 | mono_get_exception_bad_image_format: null, 306 | mono_get_exception_bad_image_format2: null, 307 | mono_get_exception_cannot_unload_appdomain: null, 308 | mono_get_exception_class: null, 309 | mono_get_exception_divide_by_zero: null, 310 | mono_get_exception_execution_engine: null, 311 | mono_get_exception_file_not_found: null, 312 | mono_get_exception_file_not_found2: null, 313 | mono_get_exception_index_out_of_range: null, 314 | mono_get_exception_invalid_cast: null, 315 | mono_get_exception_invalid_operation: null, 316 | mono_get_exception_io: null, 317 | mono_get_exception_missing_field: null, 318 | mono_get_exception_missing_method: null, 319 | mono_get_exception_not_implemented: null, 320 | mono_get_exception_not_supported: null, 321 | mono_get_exception_null_reference: null, 322 | mono_get_exception_overflow: null, 323 | mono_get_exception_reflection_type_load: null, 324 | mono_get_exception_security: null, 325 | mono_get_exception_serialization: null, 326 | mono_get_exception_stack_overflow: null, 327 | mono_get_exception_synchronization_lock: null, 328 | mono_get_exception_thread_abort: null, 329 | mono_get_exception_thread_interrupted: null, 330 | mono_get_exception_thread_state: null, 331 | mono_get_exception_type_initialization: null, 332 | mono_get_exception_type_load: null, 333 | mono_get_inflated_method: null, 334 | mono_get_int16_class: null, 335 | mono_get_int32_class: ['pointer'], 336 | mono_get_int64_class: null, 337 | mono_get_intptr_class: null, 338 | mono_get_machine_config: null, 339 | mono_get_method: null, 340 | mono_get_method_constrained: null, 341 | mono_get_method_full: null, 342 | mono_get_object_class: null, 343 | mono_get_root_domain: ['pointer'], 344 | mono_get_sbyte_class: null, 345 | mono_get_single_class: ['pointer'], 346 | mono_get_special_static_data: null, 347 | mono_get_string_class: ['pointer'], 348 | mono_get_thread_class: null, 349 | mono_get_uint16_class: null, 350 | mono_get_uint32_class: ['pointer'], 351 | mono_get_uint64_class: null, 352 | mono_get_uintptr_class: null, 353 | mono_get_void_class: null, 354 | mono_guid_to_string: null, 355 | mono_image_add_to_name_cache: null, 356 | mono_image_addref: null, 357 | mono_image_close: null, 358 | mono_image_ensure_section: null, 359 | mono_image_ensure_section_idx: null, 360 | mono_image_get_assembly: null, 361 | mono_image_get_entry_point: null, 362 | mono_image_get_filename: null, 363 | mono_image_get_guid: null, 364 | mono_image_get_name: ['pointer', ['pointer']], 365 | mono_image_get_public_key: null, 366 | mono_image_get_resource: null, 367 | mono_image_get_strong_name: null, 368 | mono_image_get_table_info: ['pointer', ['pointer', 'int']], 369 | mono_image_get_table_rows: null, 370 | mono_image_has_authenticode_entry: null, 371 | mono_image_init: null, 372 | mono_image_init_name_cache: null, 373 | mono_image_is_dynamic: null, 374 | mono_image_load_file_for_image: null, 375 | mono_image_loaded: ['pointer', ['pointer']], 376 | mono_image_loaded_by_guid: null, 377 | mono_image_loaded_by_guid_full: null, 378 | mono_image_loaded_full: null, 379 | mono_image_lookup_resource: null, 380 | mono_image_open: null, 381 | mono_image_open_from_data: null, 382 | mono_image_open_from_data_full: null, 383 | mono_image_open_from_data_with_name: null, 384 | mono_image_open_full: null, 385 | mono_image_rva_map: null, 386 | mono_image_strerror: null, 387 | mono_image_strong_name_position: null, 388 | mono_image_verify_tables: null, 389 | mono_images_cleanup: null, 390 | mono_images_init: null, 391 | mono_init: null, 392 | mono_init_from_assembly: null, 393 | mono_init_version: null, 394 | mono_inst_name: null, 395 | mono_install_assembly_load_hook: null, 396 | mono_install_assembly_postload_refonly_search_hook: null, 397 | mono_install_assembly_postload_search_hook: null, 398 | mono_install_assembly_preload_hook: null, 399 | mono_install_assembly_refonly_preload_hook: null, 400 | mono_install_assembly_refonly_search_hook: null, 401 | mono_install_assembly_search_hook: null, 402 | mono_install_runtime_cleanup: null, 403 | mono_is_debugger_attached: null, 404 | mono_jit_cleanup: null, 405 | mono_jit_exec: null, 406 | mono_jit_info_get_code_size: null, 407 | mono_jit_info_get_code_start: null, 408 | mono_jit_info_get_method: null, 409 | mono_jit_info_table_find: null, 410 | mono_jit_init: null, 411 | mono_jit_init_version: null, 412 | mono_jit_parse_options: null, 413 | mono_jit_set_trace_options: null, 414 | mono_jit_thread_attach: null, 415 | mono_ldstr: null, 416 | mono_ldtoken: null, 417 | mono_load_remote_field: null, 418 | mono_load_remote_field_new: null, 419 | mono_loader_error_prepare_exception: null, 420 | mono_loader_get_last_error: null, 421 | mono_locks_dump: null, 422 | mono_lookup_internal_call: null, 423 | mono_lookup_pinvoke_call: null, 424 | mono_main: null, 425 | mono_marshal_string_to_utf16: null, 426 | mono_mb_free: null, 427 | mono_md5_final: null, 428 | mono_md5_get_digest: null, 429 | mono_md5_get_digest_from_file: null, 430 | mono_md5_init: null, 431 | mono_md5_update: null, 432 | mono_mempool_alloc: null, 433 | mono_mempool_alloc0: null, 434 | mono_mempool_contains_addr: null, 435 | mono_mempool_destroy: null, 436 | mono_mempool_empty: null, 437 | mono_mempool_get_allocated: null, 438 | mono_mempool_invalidate: null, 439 | mono_mempool_new: null, 440 | mono_mempool_stats: null, 441 | mono_mempool_strdup: null, 442 | mono_metadata_blob_heap: null, 443 | mono_metadata_cleanup: null, 444 | mono_metadata_compute_size: null, 445 | mono_metadata_custom_attrs_from_index: null, 446 | mono_metadata_declsec_from_index: null, 447 | mono_metadata_decode_blob_size: null, 448 | mono_metadata_decode_row: null, 449 | mono_metadata_decode_row_col: null, 450 | mono_metadata_decode_signed_value: null, 451 | mono_metadata_decode_table_row: null, 452 | mono_metadata_decode_table_row_col: null, 453 | mono_metadata_decode_value: null, 454 | mono_metadata_encode_value: null, 455 | mono_metadata_events_from_typedef: null, 456 | mono_metadata_field_info: null, 457 | mono_metadata_free_array: null, 458 | mono_metadata_free_marshal_spec: null, 459 | mono_metadata_free_method_signature: null, 460 | mono_metadata_free_mh: null, 461 | mono_metadata_free_type: null, 462 | mono_metadata_generic_class_is_valuetype: null, 463 | mono_metadata_get_constant_index: null, 464 | mono_metadata_get_generic_param_row: null, 465 | mono_metadata_get_marshal_info: null, 466 | mono_metadata_get_param_attrs: null, 467 | mono_metadata_guid_heap: null, 468 | mono_metadata_implmap_from_method: null, 469 | mono_metadata_init: null, 470 | mono_metadata_interfaces_from_typedef: null, 471 | mono_metadata_load_generic_param_constraints: null, 472 | mono_metadata_load_generic_params: null, 473 | mono_metadata_locate: null, 474 | mono_metadata_locate_token: null, 475 | mono_metadata_methods_from_event: null, 476 | mono_metadata_methods_from_property: null, 477 | mono_metadata_nested_in_typedef: null, 478 | mono_metadata_nesting_typedef: null, 479 | mono_metadata_packing_from_typedef: null, 480 | mono_metadata_parse_array: null, 481 | mono_metadata_parse_custom_mod: null, 482 | mono_metadata_parse_field_type: null, 483 | mono_metadata_parse_marshal_spec: null, 484 | mono_metadata_parse_method_signature: null, 485 | mono_metadata_parse_method_signature_full: null, 486 | mono_metadata_parse_mh: null, 487 | mono_metadata_parse_mh_full: null, 488 | mono_metadata_parse_param: null, 489 | mono_metadata_parse_signature: null, 490 | mono_metadata_parse_type: null, 491 | mono_metadata_parse_type_full: null, 492 | mono_metadata_parse_typedef_or_ref: null, 493 | mono_metadata_properties_from_typedef: null, 494 | mono_metadata_signature_alloc: null, 495 | mono_metadata_signature_dup: null, 496 | mono_metadata_signature_equal: null, 497 | mono_metadata_string_heap: null, 498 | mono_metadata_token_from_dor: null, 499 | mono_metadata_translate_token_index: null, 500 | mono_metadata_type_equal: null, 501 | mono_metadata_type_hash: null, 502 | mono_metadata_typedef_from_field: null, 503 | mono_metadata_typedef_from_method: null, 504 | mono_metadata_user_string: null, 505 | mono_method_body_get_object: null, 506 | mono_method_desc_free: null, 507 | mono_method_desc_from_method: null, 508 | mono_method_desc_full_match: null, 509 | mono_method_desc_match: null, 510 | mono_method_desc_new: null, 511 | mono_method_desc_search_in_class: null, 512 | mono_method_desc_search_in_image: null, 513 | mono_method_full_name: null, 514 | mono_method_get_class: null, 515 | mono_method_get_flags: ['uint', ['pointer', 'uint']], 516 | mono_method_get_header: ['pointer', ['pointer']], 517 | mono_method_get_index: null, 518 | mono_method_get_last_managed: null, 519 | mono_method_get_marshal_info: null, 520 | mono_method_get_name: ['pointer', ['pointer']], 521 | mono_method_get_object: null, 522 | mono_method_get_param_names: null, 523 | mono_method_get_param_token: null, 524 | mono_method_get_signature: null, 525 | mono_method_get_signature_full: null, 526 | mono_method_get_token: null, 527 | mono_method_has_marshal_info: null, 528 | mono_method_header_get_clauses: null, 529 | mono_method_header_get_code: null, 530 | mono_method_header_get_locals: null, 531 | mono_method_header_get_num_clauses: null, 532 | mono_method_signature: ['pointer', ['pointer']], 533 | mono_method_verify: null, 534 | mono_mlist_alloc: null, 535 | mono_mlist_append: null, 536 | mono_mlist_get_data: null, 537 | mono_mlist_last: null, 538 | mono_mlist_length: null, 539 | mono_mlist_next: null, 540 | mono_mlist_prepend: null, 541 | mono_mlist_remove_item: null, 542 | mono_mlist_set_data: null, 543 | mono_module_file_get_object: null, 544 | mono_module_get_object: null, 545 | mono_monitor_enter: null, 546 | mono_monitor_exit: null, 547 | mono_monitor_try_enter: null, 548 | mono_mprotect: null, 549 | mono_object_castclass_mbyref: null, 550 | mono_object_clone: null, 551 | mono_object_describe: null, 552 | mono_object_describe_fields: null, 553 | mono_object_get_class: ['pointer', ['pointer']], 554 | mono_object_get_domain: null, 555 | mono_object_get_size: null, 556 | mono_object_get_virtual_method: ['pointer', ['pointer', 'pointer']], 557 | mono_object_hash: null, 558 | mono_object_is_alive: null, 559 | mono_object_isinst: null, 560 | mono_object_isinst_mbyref: null, 561 | mono_object_new: ['pointer', ['pointer', 'pointer']], 562 | mono_object_new_alloc_specific: null, 563 | mono_object_new_fast: null, 564 | mono_object_new_from_token: null, 565 | mono_object_new_specific: null, 566 | mono_object_unbox: ['pointer', ['pointer']], 567 | mono_opcode_name: null, 568 | mono_opcode_value: null, 569 | mono_pagesize: null, 570 | mono_param_get_objects: null, 571 | mono_parse_default_optimizations: null, 572 | mono_path_canonicalize: null, 573 | mono_path_resolve_symlinks: null, 574 | mono_pe_file_open: null, 575 | mono_pmip: null, 576 | mono_poll: null, 577 | mono_print_method_from_ip: null, 578 | mono_print_thread_dump: null, 579 | mono_print_unhandled_exception: null, 580 | mono_profiler_coverage_get: null, 581 | mono_profiler_get_events: null, 582 | mono_profiler_install: null, 583 | mono_profiler_install_allocation: null, 584 | mono_profiler_install_appdomain: null, 585 | mono_profiler_install_assembly: null, 586 | mono_profiler_install_class: null, 587 | mono_profiler_install_coverage_filter: null, 588 | mono_profiler_install_enter_leave: null, 589 | mono_profiler_install_exception: null, 590 | mono_profiler_install_gc: null, 591 | mono_profiler_install_jit_compile: null, 592 | mono_profiler_install_jit_end: null, 593 | mono_profiler_install_module: null, 594 | mono_profiler_install_statistical: null, 595 | mono_profiler_install_thread: null, 596 | mono_profiler_install_transition: null, 597 | mono_profiler_load: null, 598 | mono_profiler_set_events: null, 599 | mono_property_get_flags: null, 600 | mono_property_get_get_method: ['pointer', ['pointer']], 601 | mono_property_get_name: null, 602 | mono_property_get_object: null, 603 | mono_property_get_parent: null, 604 | mono_property_get_set_method: ['pointer', ['pointer']], 605 | mono_property_get_value: ['pointer', ['pointer', 'pointer', 'pointer', 'pointer']], 606 | mono_property_set_value: ['int', ['pointer', 'pointer', 'pointer', 'pointer']], 607 | mono_ptr_class_get: null, 608 | mono_raise_exception: null, 609 | mono_reflection_get_custom_attrs: null, 610 | mono_reflection_get_custom_attrs_blob: null, 611 | mono_reflection_get_custom_attrs_by_type: null, 612 | mono_reflection_get_custom_attrs_data: null, 613 | mono_reflection_get_custom_attrs_info: null, 614 | mono_reflection_get_token: null, 615 | mono_reflection_get_type: null, 616 | mono_reflection_parse_type: null, 617 | mono_reflection_type_from_name: null, 618 | mono_reflection_type_get_handle: null, 619 | mono_register_bundled_assemblies: null, 620 | mono_register_config_for_assembly: null, 621 | mono_register_machine_config: null, 622 | mono_remote_class: null, 623 | mono_runtime_class_init: null, 624 | mono_runtime_cleanup: null, 625 | mono_runtime_delegate_invoke: null, 626 | mono_runtime_exec_main: null, 627 | mono_runtime_exec_managed_code: null, 628 | mono_runtime_get_main_args: null, 629 | mono_runtime_init: null, 630 | mono_runtime_invoke: ['pointer', ['pointer', 'pointer', 'pointer', 'pointer']], 631 | mono_runtime_invoke_array: null, 632 | mono_runtime_is_shutting_down: null, 633 | mono_runtime_object_init: null, 634 | mono_runtime_quit: null, 635 | mono_runtime_run_main: null, 636 | mono_runtime_set_shutting_down: null, 637 | mono_runtime_unhandled_exception_policy_get: null, 638 | mono_runtime_unhandled_exception_policy_set: null, 639 | mono_security_enable_core_clr: null, 640 | mono_security_set_core_clr_platform_callback: null, 641 | mono_security_set_mode: null, 642 | mono_set_assemblies_path: null, 643 | mono_set_break_policy: null, 644 | mono_set_commandline_arguments: null, 645 | mono_set_config_dir: null, 646 | mono_set_defaults: null, 647 | mono_set_dirs: null, 648 | mono_set_find_plugin_callback: null, 649 | mono_set_ignore_version_and_key_when_finding_assemblies_already_loaded: null, 650 | mono_set_rootdir: null, 651 | mono_set_signal_chaining: null, 652 | mono_sha1_final: null, 653 | mono_sha1_get_digest: null, 654 | mono_sha1_get_digest_from_file: null, 655 | mono_sha1_init: null, 656 | mono_sha1_update: null, 657 | mono_signature_explicit_this: null, 658 | mono_signature_get_call_conv: null, 659 | mono_signature_get_desc: null, 660 | mono_signature_get_param_count: ['uint32', ['pointer']], 661 | mono_signature_get_params: ['pointer', ['pointer', 'pointer']], 662 | mono_signature_get_return_type: null, 663 | mono_signature_hash: null, 664 | mono_signature_is_instance: null, 665 | mono_signature_vararg_start: null, 666 | mono_signbit_double: null, 667 | mono_signbit_float: null, 668 | mono_stack_walk: null, 669 | mono_stack_walk_no_il: null, 670 | mono_store_remote_field: null, 671 | mono_store_remote_field_new: null, 672 | mono_string_equal: null, 673 | mono_string_from_utf16: null, 674 | mono_string_hash: null, 675 | mono_string_intern: null, 676 | mono_string_is_interned: null, 677 | mono_string_new: ['pointer', ['pointer', 'pointer']], 678 | mono_string_new_len: null, 679 | mono_string_new_size: null, 680 | mono_string_new_utf16: null, 681 | mono_string_new_wrapper: null, 682 | mono_string_to_utf16: null, 683 | mono_string_to_utf8: ['pointer', ['pointer']], 684 | mono_stringify_assembly_name: null, 685 | mono_table_info_get_rows: ['int', ['pointer']], 686 | mono_thread_abort_all_other_threads: null, 687 | mono_thread_attach: ['pointer', ['pointer']], 688 | mono_thread_cleanup: null, 689 | mono_thread_create: null, 690 | mono_thread_current: null, 691 | mono_thread_detach: null, 692 | mono_thread_exit: null, 693 | mono_thread_force_interruption_checkpoint: null, 694 | mono_thread_get_abort_signal: null, 695 | mono_thread_get_main: null, 696 | mono_thread_has_appdomain_ref: null, 697 | mono_thread_init: null, 698 | mono_thread_interruption_checkpoint: null, 699 | mono_thread_interruption_request_flag: null, 700 | mono_thread_interruption_requested: null, 701 | mono_thread_manage: null, 702 | mono_thread_new_init: null, 703 | mono_thread_pool_cleanup: null, 704 | mono_thread_pop_appdomain_ref: null, 705 | mono_thread_push_appdomain_ref: null, 706 | mono_thread_request_interruption: null, 707 | mono_thread_set_main: null, 708 | mono_thread_stop: null, 709 | mono_thread_suspend_all_other_threads: null, 710 | mono_threads_abort_appdomain_threads: null, 711 | mono_threads_clear_cached_culture: null, 712 | mono_threads_get_default_stacksize: null, 713 | mono_threads_install_cleanup: null, 714 | mono_threads_request_thread_dump: null, 715 | mono_threads_set_default_stacksize: null, 716 | mono_threads_set_shutting_down: null, 717 | mono_trace: null, 718 | mono_trace_cleanup: null, 719 | mono_trace_is_traced: null, 720 | mono_trace_pop: null, 721 | mono_trace_push: null, 722 | mono_trace_set_level: null, 723 | mono_trace_set_level_string: null, 724 | mono_trace_set_mask: null, 725 | mono_trace_set_mask_string: null, 726 | mono_tracev: null, 727 | mono_type_create_from_typespec: null, 728 | mono_type_full_name: null, 729 | mono_type_generic_inst_is_valuetype: null, 730 | mono_type_get_array_type: null, 731 | mono_type_get_class: ['pointer', ['pointer']], 732 | mono_type_get_desc: null, 733 | mono_type_get_modifiers: null, 734 | mono_type_get_name: ['pointer', ['pointer']], 735 | mono_type_get_name_full: null, 736 | mono_type_get_object: null, 737 | mono_type_get_ptr_type: null, 738 | mono_type_get_signature: null, 739 | mono_type_get_type: ['int', ['pointer']], 740 | mono_type_get_underlying_type: ['pointer', ['pointer']], 741 | mono_type_is_byref: null, 742 | mono_type_is_reference: null, 743 | mono_type_size: null, 744 | mono_type_stack_size: null, 745 | mono_type_to_unmanaged: null, 746 | mono_unhandled_exception: null, 747 | mono_unicode_from_external: null, 748 | mono_unicode_to_external: null, 749 | mono_unity_class_is_abstract: null, 750 | mono_unity_class_is_interface: null, 751 | mono_unity_get_all_classes_with_name_case: null, 752 | mono_unity_liveness_allocate_struct: null, 753 | mono_unity_liveness_calculation_begin: null, 754 | mono_unity_liveness_calculation_end: null, 755 | mono_unity_liveness_calculation_from_root: null, 756 | mono_unity_liveness_calculation_from_root_managed: null, 757 | mono_unity_liveness_calculation_from_statics: null, 758 | mono_unity_liveness_calculation_from_statics_managed: null, 759 | mono_unity_liveness_finalize: null, 760 | mono_unity_liveness_free_struct: null, 761 | mono_unity_liveness_start_gc_world: null, 762 | mono_unity_liveness_stop_gc_world: null, 763 | mono_unity_seh_handler: null, 764 | mono_unity_set_embeddinghostname: null, 765 | mono_unity_set_unhandled_exception_handler: null, 766 | mono_unity_set_vprintf_func: null, 767 | mono_unity_socket_security_enabled_set: null, 768 | mono_unity_thread_fast_attach: null, 769 | mono_unity_thread_fast_detach: null, 770 | mono_upgrade_remote_class_wrapper: null, 771 | mono_utf8_from_external: null, 772 | mono_valloc: null, 773 | mono_value_box: ['pointer', ['pointer', 'pointer', 'pointer']], 774 | mono_value_copy: null, 775 | mono_value_copy_array: null, 776 | mono_value_describe_fields: null, 777 | mono_verifier_set_mode: null, 778 | mono_verify_corlib: null, 779 | mono_vfree: null, 780 | mono_vtable_get_static_field_data: null, 781 | mono_walk_stack: null, 782 | set_vprintf_func: null, 783 | unity_mono_close_output: null, 784 | unity_mono_install_memory_callbacks: null, 785 | unity_mono_method_is_generic: null, 786 | unity_mono_method_is_inflated: null, 787 | unity_mono_redirect_output: null, 788 | unity_mono_reflection_method_get_method: null 789 | } 790 | 791 | Object.keys(MonoApi).map(exportName => { 792 | if (MonoApi[exportName] === null) { 793 | MonoApi[exportName] = () => { throw new Error('Export signature missing: ' + exportName) } 794 | } else { 795 | const addr = Module.findExportByName(monoModule.name, exportName) 796 | MonoApi[exportName] = !addr 797 | ? () => { throw new Error('Export not found: ' + exportName) } 798 | : MonoApi[exportName] = new ExNativeFunction(addr, ...MonoApi[exportName]) 799 | } 800 | }) 801 | 802 | MonoApi.mono_thread_attach(MonoApi.mono_get_root_domain()) // Make sure we are attached to mono. 803 | MonoApi.module = monoModule; // Expose the module object. 804 | 805 | export default MonoApi 806 | -------------------------------------------------------------------------------- /vendors/frida-mono-api/mono-module.js: -------------------------------------------------------------------------------- 1 | const KNOWN_RUNTIMES = ['mono.dll', 'libmonosgen-2.0.so' ]; 2 | const KNOWN_EXPORTS = ['mono_thread_attach']; 3 | 4 | let monoModule = null; 5 | 6 | // Look for a known runtime module. 7 | for (let x in KNOWN_RUNTIMES) { 8 | let foundModule = Process.findModuleByName(x); 9 | if (foundModule) { 10 | monoModule = foundModule; 11 | break; 12 | } 13 | } 14 | 15 | // Look for a known mono export. 16 | if (!monoModule) { 17 | const monoThreadAttach = Module.findExportByName(null, 'mono_thread_attach') 18 | if (monoThreadAttach) monoModule = Process.findModuleByAddress(monoThreadAttach) 19 | } 20 | 21 | // Extended support to find the mono library by searching in module exports 22 | // This should fix issue #1 (https://github.com/NorthwaveNL/fridax/issues/1) 23 | if (!monoModule) { 24 | Process.enumerateModulesSync().forEach(function (singleModule) { 25 | Module.enumerateExportsSync(singleModule.name).forEach(function (singleExport) { 26 | if (singleExport.name.includes('mono_thread_attach')) { 27 | monoModule = Process.findModuleByName(singleModule.name) 28 | } 29 | }) 30 | }) 31 | } 32 | 33 | if (!monoModule) throw new Error('Can\'t find Mono runtime!') 34 | 35 | export default monoModule --------------------------------------------------------------------------------