Skip to content

Commit 192c6fe

Browse files
committed
Fixed #1. Find mono library dynamically if it is not 'mono.dll'.
1 parent 7d55375 commit 192c6fe

13 files changed

+997
-45
lines changed

examples/read_class_static_bool_variable.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import ClassHelper from '../libraries/class_helper'
1616
*/
1717

1818
// Get a reference to ObfuscatedString password
19-
let settingsClass = ClassHelper.getClassByName("CompanyName.ProjectName")
19+
let settingsClass = ClassHelper.getClassByName("CompanyName.ProjectName.Settings")
2020
let secretField = MonoApiHelper.ClassGetFieldFromName(settingsClass, "secret")
2121
let secretValue = MonoApiHelper.FieldGetValueObject(secretField, settingsClass)
2222

examples/read_class_static_int_variable.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import ClassHelper from '../libraries/class_helper'
1616
*/
1717

1818
// Get a reference to ObfuscatedString password
19-
let settingsClass = ClassHelper.getClassByName("CompanyName.ProjectName")
19+
let settingsClass = ClassHelper.getClassByName("CompanyName.ProjectName.Settings")
2020
let secretField = MonoApiHelper.ClassGetFieldFromName(settingsClass, "secret")
2121
let secretValue = MonoApiHelper.FieldGetValueObject(secretField, settingsClass)
2222

examples/read_class_static_object_variable.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import ClassHelper from '../libraries/class_helper'
1616
*/
1717

1818
// Get a reference to ObfuscatedString secret
19-
let settingsClass = ClassHelper.getClassByName("CompanyName.ProjectName")
19+
let settingsClass = ClassHelper.getClassByName("CompanyName.ProjectName.Settings")
2020
let secretField = MonoApiHelper.ClassGetFieldFromName(settingsClass, "secret")
2121
let secretValue = MonoApiHelper.FieldGetValueObject(secretField, settingsClass)
2222

examples/read_class_static_string_variable.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import ClassHelper from '../libraries/class_helper'
1616
*/
1717

1818
// Get a reference to the secret string
19-
let settingsClass = ClassHelper.getClassByName("CompanyName.ProjectName")
19+
let settingsClass = ClassHelper.getClassByName("CompanyName.ProjectName.Settings")
2020
let secretField = MonoApiHelper.ClassGetFieldFromName(settingsClass, "secretString")
2121
let secretValue = MonoApiHelper.FieldGetValueObject(secretField, settingsClass)
2222

fridax.js

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,7 @@ async function main(options) {
4242
device = await deviceManager.addRemoteDevice(argv[`device`]);
4343
} else {
4444
console.log(`[*] Awaiting USB device.`)
45-
let devices = await deviceManager.enumerateDevices()
46-
47-
devices.forEach(enumDevice => {
48-
if (enumDevice.type == `usb`) {
49-
device = enumDevice
50-
return
51-
}
52-
})
45+
device = await frida.getUsbDevice()
5346
}
5447

5548
if (device == null) {
@@ -59,9 +52,10 @@ async function main(options) {
5952
console.log(`[*] Up and running on ${device.name}.`)
6053

6154
let application = await selectApplicationOnDevice(device)
62-
let inject = await injectApplicationOnDevice(device, application)
63-
55+
6456
console.log(`[*] Happy hacking.`)
57+
58+
let inject = await injectApplicationOnDevice(device, application)
6559
}
6660

6761
// Give the user the option to choose an application

libraries/class_helper.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { MonoApiHelper, MonoApi } from 'frida-mono-api'
1+
import { MonoApiHelper, MonoApi } from '../vendors/frida-mono-api'
22

33
/**
44
* Class containing helper functions for Mono classes

package-lock.json

Lines changed: 27 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
"main": "hack.js",
1010
"dependencies": {
1111
"console-stamp": "^0.2.9",
12+
"frida-ex-nativefunction": "^0.1.2",
1213
"frida-inject": "^0.3.0",
13-
"frida-mono-api": "git+https://github.com/freehuntx/frida-mono-api.git",
1414
"inquirer": "^7.1.0",
1515
"node-persist": "^3.0.5",
1616
"yargs": "^15.3.1"

vendors/frida-mono-api/LICENSE.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
MIT License
2+
===========
3+
4+
Copyright (c) 2018 freehuntx (https://github.com/freehuntx/frida-mono-api/)
5+
Copyright (c) 2020 Northwave B.V. (www.northwave-security.com)
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
SOFTWARE.

vendors/frida-mono-api/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { default as MonoApi } from './mono-api'
2+
export { default as MonoApiHelper } from './mono-api-helper'
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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+
MethodGetFlags: (mono_method, iflags = 0) => MonoApi.mono_method_get_flags(mono_method, iflags),
63+
MethodGetName: mono_method => Memory.readUtf8String(MonoApi.mono_method_get_name(mono_method)),
64+
MethodSignature: MonoApi.mono_method_signature,
65+
ObjectGetClass: MonoApi.mono_object_get_class,
66+
ObjectGetVirtualMethod: MonoApi.mono_object_get_virtual_method,
67+
ObjectNew: (mono_class, domain = rootDomain) => MonoApi.mono_object_new(domain, mono_class),
68+
ObjectUnbox: mono_object => MonoApi.mono_object_unbox(mono_object),
69+
RuntimeInvoke: (mono_method, instance = NULL, args = NULL) => {
70+
const exception = NULL
71+
const result = MonoApi.mono_runtime_invoke(mono_method, instance, args, exception)
72+
73+
if (!exception.isNull()) {
74+
throw new Error('Unknown exception happened')
75+
}
76+
77+
return result
78+
},
79+
SignatureGetParamCount: MonoApi.mono_signature_get_param_count, SignatureGetParams: signature => {
80+
let params = []
81+
let iter = Memory.alloc(Process.pointerSize)
82+
let type
83+
84+
while(!(type = MonoApi.mono_signature_get_params(signature, iter)).isNull()) {
85+
params.push(type)
86+
}
87+
88+
return params
89+
},
90+
StringNew: (str, domain = rootDomain) => MonoApi.mono_string_new(domain, Memory.allocUtf8String(str)),
91+
StringToUtf8: mono_string => Memory.readUtf8String(MonoApi.mono_string_to_utf8(mono_string)),
92+
TypeGetClass: MonoApi.mono_type_get_class,
93+
TypeGetName: mono_type => Memory.readUtf8String(MonoApi.mono_type_get_name(mono_type)),
94+
TypeGetType: MonoApi.mono_type_get_type,
95+
TypeGetUnderlyingType: MonoApi.mono_type_get_underlying_type,
96+
ValueBox: (mono_class, valuePtr, domain = rootDomain) => MonoApi.mono_value_box(domain, mono_class, valuePtr)
97+
}
98+
99+
function resolveClassName(className) {
100+
return {
101+
className: className.substring(className.lastIndexOf('.')+1),
102+
namespace: className.substring(0, className.lastIndexOf('.'))
103+
}
104+
}
105+
106+
export default MonoApiHelper

0 commit comments

Comments
 (0)