├── .gitignore
├── Frida.Exports
├── Frida.Exports.cpp
├── Frida.Exports.vcxproj
└── Frida.Exports.vcxproj.filters
├── Frida.NetStandard.sln
├── Frida.NetStandard
├── Device.cs
├── DeviceManager.cs
├── Frida.NetStandard.csproj
├── FridaProcess.cs
├── FridaSession.cs
├── GError.cs
├── Handle.cs
├── Ref.cs
├── Runtime.cs
├── Script.cs
├── ScriptWithRpc.cs
└── Utilities
│ └── InterfaceImplementer.cs
├── README.md
├── TestProgram
├── Program.cs
├── TestProgram.csproj
└── script.js
└── setup.ps1
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | #ignore thumbnails created by windows
3 | Thumbs.db
4 | #Ignore files build by Visual Studio
5 | *.obj
6 | *.exe
7 | *.pdb
8 | *.user
9 | *.aps
10 | *.pch
11 | *.vspscc
12 | *_i.c
13 | *_p.c
14 | *.ncb
15 | *.suo
16 | *.tlb
17 | *.tlh
18 | *.bak
19 | *.cache
20 | *.ilk
21 | *.log
22 | [Bb]in
23 | [Dd]ebug*/
24 | *.lib
25 | *.sbr
26 | obj/
27 | [Rr]elease*/
28 | _ReSharper*/
29 | [Tt]est[Rr]esult*
30 | .vs
31 | Frida.Exports/lib/
32 |
--------------------------------------------------------------------------------
/Frida.Exports/Frida.Exports.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lenacloud/frida-netstandard/89dd2167e947a028c07f5610381bc2af3136caa9/Frida.Exports/Frida.Exports.cpp
--------------------------------------------------------------------------------
/Frida.Exports/Frida.Exports.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | 15.0
23 | {44A9C4E0-9EE0-487E-A209-FBF78497027F}
24 | Win32Proj
25 | FridaExports
26 | 10.0.16299.0
27 |
28 |
29 |
30 | DynamicLibrary
31 | true
32 | v141
33 | Unicode
34 |
35 |
36 | DynamicLibrary
37 | false
38 | v141
39 | true
40 | Unicode
41 |
42 |
43 | DynamicLibrary
44 | true
45 | v141
46 | Unicode
47 |
48 |
49 | DynamicLibrary
50 | false
51 | v141
52 | true
53 | Unicode
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | true
75 | $(SolutionDir)$(PROCESSOR_ARCHITECTURE)\$(Configuration)\
76 |
77 |
78 | true
79 | $(SolutionDir)$(PROCESSOR_ARCHITECTURE)\$(Configuration)\
80 |
81 |
82 | false
83 |
84 |
85 | false
86 |
87 |
88 |
89 | NotUsing
90 | Level3
91 | Disabled
92 | true
93 | WIN32;_DEBUG;FRIDAEXPORTS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
94 | true
95 | lib/x86;%(AdditionalIncludeDirectories)
96 |
97 |
98 | Windows
99 | true
100 | frida-core.lib;%(AdditionalDependencies)
101 | lib/x86;%(AdditionalLibraryDirectories)
102 | $(OutDir)$(TargetName)$(TargetExt)
103 |
104 |
105 |
106 |
107 | NotUsing
108 | Level3
109 | Disabled
110 | true
111 | _DEBUG;FRIDAEXPORTS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
112 | true
113 | lib/x64;%(AdditionalIncludeDirectories)
114 |
115 |
116 | Windows
117 | true
118 | frida-core.lib;%(AdditionalDependencies)
119 | lib/x64
120 | $(OutDir)$(TargetName)$(TargetExt)
121 |
122 |
123 |
124 |
125 | Use
126 | Level3
127 | MaxSpeed
128 | true
129 | true
130 | true
131 | WIN32;NDEBUG;FRIDAEXPORTS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
132 | true
133 |
134 |
135 | Windows
136 | true
137 | true
138 | true
139 |
140 |
141 |
142 |
143 | Use
144 | Level3
145 | MaxSpeed
146 | true
147 | true
148 | true
149 | NDEBUG;FRIDAEXPORTS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
150 | true
151 |
152 |
153 | Windows
154 | true
155 | true
156 | true
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
--------------------------------------------------------------------------------
/Frida.Exports/Frida.Exports.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 |
--------------------------------------------------------------------------------
/Frida.NetStandard.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27428.2015
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Frida.Exports", "Frida.Exports\Frida.Exports.vcxproj", "{44A9C4E0-9EE0-487E-A209-FBF78497027F}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Frida.NetStandard", "Frida.NetStandard\Frida.NetStandard.csproj", "{CB9B5A82-92C6-4B35-A6ED-D063C6878FC9}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestProgram", "TestProgram\TestProgram.csproj", "{17503C7C-38BC-482D-8756-858CCFFC6DBF}"
11 | EndProject
12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1E514DD4-E232-4675-8B59-6BB89053D72C}"
13 | ProjectSection(SolutionItems) = preProject
14 | README.md = README.md
15 | setup.ps1 = setup.ps1
16 | EndProjectSection
17 | EndProject
18 | Global
19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
20 | Debug|Any CPU = Debug|Any CPU
21 | Debug|x64 = Debug|x64
22 | Debug|x86 = Debug|x86
23 | Release|Any CPU = Release|Any CPU
24 | Release|x64 = Release|x64
25 | Release|x86 = Release|x86
26 | EndGlobalSection
27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
28 | {44A9C4E0-9EE0-487E-A209-FBF78497027F}.Debug|Any CPU.ActiveCfg = Debug|Win32
29 | {44A9C4E0-9EE0-487E-A209-FBF78497027F}.Debug|x64.ActiveCfg = Debug|x64
30 | {44A9C4E0-9EE0-487E-A209-FBF78497027F}.Debug|x64.Build.0 = Debug|x64
31 | {44A9C4E0-9EE0-487E-A209-FBF78497027F}.Debug|x86.ActiveCfg = Debug|Win32
32 | {44A9C4E0-9EE0-487E-A209-FBF78497027F}.Debug|x86.Build.0 = Debug|Win32
33 | {44A9C4E0-9EE0-487E-A209-FBF78497027F}.Release|Any CPU.ActiveCfg = Release|Win32
34 | {44A9C4E0-9EE0-487E-A209-FBF78497027F}.Release|x64.ActiveCfg = Release|x64
35 | {44A9C4E0-9EE0-487E-A209-FBF78497027F}.Release|x64.Build.0 = Release|x64
36 | {44A9C4E0-9EE0-487E-A209-FBF78497027F}.Release|x86.ActiveCfg = Release|Win32
37 | {44A9C4E0-9EE0-487E-A209-FBF78497027F}.Release|x86.Build.0 = Release|Win32
38 | {CB9B5A82-92C6-4B35-A6ED-D063C6878FC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39 | {CB9B5A82-92C6-4B35-A6ED-D063C6878FC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
40 | {CB9B5A82-92C6-4B35-A6ED-D063C6878FC9}.Debug|x64.ActiveCfg = Debug|Any CPU
41 | {CB9B5A82-92C6-4B35-A6ED-D063C6878FC9}.Debug|x64.Build.0 = Debug|Any CPU
42 | {CB9B5A82-92C6-4B35-A6ED-D063C6878FC9}.Debug|x86.ActiveCfg = Debug|Any CPU
43 | {CB9B5A82-92C6-4B35-A6ED-D063C6878FC9}.Debug|x86.Build.0 = Debug|Any CPU
44 | {CB9B5A82-92C6-4B35-A6ED-D063C6878FC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
45 | {CB9B5A82-92C6-4B35-A6ED-D063C6878FC9}.Release|Any CPU.Build.0 = Release|Any CPU
46 | {CB9B5A82-92C6-4B35-A6ED-D063C6878FC9}.Release|x64.ActiveCfg = Release|Any CPU
47 | {CB9B5A82-92C6-4B35-A6ED-D063C6878FC9}.Release|x64.Build.0 = Release|Any CPU
48 | {CB9B5A82-92C6-4B35-A6ED-D063C6878FC9}.Release|x86.ActiveCfg = Release|Any CPU
49 | {CB9B5A82-92C6-4B35-A6ED-D063C6878FC9}.Release|x86.Build.0 = Release|Any CPU
50 | {17503C7C-38BC-482D-8756-858CCFFC6DBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
51 | {17503C7C-38BC-482D-8756-858CCFFC6DBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
52 | {17503C7C-38BC-482D-8756-858CCFFC6DBF}.Debug|x64.ActiveCfg = Debug|Any CPU
53 | {17503C7C-38BC-482D-8756-858CCFFC6DBF}.Debug|x64.Build.0 = Debug|Any CPU
54 | {17503C7C-38BC-482D-8756-858CCFFC6DBF}.Debug|x86.ActiveCfg = Debug|Any CPU
55 | {17503C7C-38BC-482D-8756-858CCFFC6DBF}.Debug|x86.Build.0 = Debug|Any CPU
56 | {17503C7C-38BC-482D-8756-858CCFFC6DBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
57 | {17503C7C-38BC-482D-8756-858CCFFC6DBF}.Release|Any CPU.Build.0 = Release|Any CPU
58 | {17503C7C-38BC-482D-8756-858CCFFC6DBF}.Release|x64.ActiveCfg = Release|Any CPU
59 | {17503C7C-38BC-482D-8756-858CCFFC6DBF}.Release|x64.Build.0 = Release|Any CPU
60 | {17503C7C-38BC-482D-8756-858CCFFC6DBF}.Release|x86.ActiveCfg = Release|Any CPU
61 | {17503C7C-38BC-482D-8756-858CCFFC6DBF}.Release|x86.Build.0 = Release|Any CPU
62 | EndGlobalSection
63 | GlobalSection(SolutionProperties) = preSolution
64 | HideSolutionNode = FALSE
65 | EndGlobalSection
66 | GlobalSection(ExtensibilityGlobals) = postSolution
67 | SolutionGuid = {90172FFC-B641-445A-B00F-2DDE6AADC762}
68 | EndGlobalSection
69 | EndGlobal
70 |
--------------------------------------------------------------------------------
/Frida.NetStandard/Device.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace Frida.NetStandard
6 | {
7 | public enum FridaDeviceType
8 | {
9 | Local = 0,
10 | Remote = 1,
11 | USB = 2,
12 | }
13 | public class Device
14 | {
15 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
16 | static extern IntPtr _frida_device_get_name(IntPtr device);
17 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
18 | static extern IntPtr _frida_device_get_id(IntPtr device);
19 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
20 | static extern bool _frida_device_is_lost(IntPtr device);
21 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
22 | static extern FridaDeviceType _frida_device_get_dtype(IntPtr device);
23 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
24 | static extern IntPtr _frida_device_enumerate_processes_sync(IntPtr self, out IntPtr error);
25 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
26 | static extern int _frida_process_list_size(IntPtr list);
27 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
28 | static extern IntPtr _frida_process_list_get(IntPtr list, Int32 index);
29 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
30 | static extern void _frida_device_resume_sync(IntPtr self, UInt32 pid, out IntPtr error);
31 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
32 | static extern IntPtr _frida_device_attach_sync(IntPtr self, UInt32 pid, out IntPtr error);
33 |
34 | Handle handle;
35 |
36 | public Device(Func builder)
37 | {
38 | handle = new Handle(builder);
39 | }
40 |
41 | public string Name => _frida_device_get_name(handle.Pointer).ReadStringAndFree();
42 | public string Id => _frida_device_get_id(handle.Pointer).ReadStringAndFree();
43 | public bool IsLost => _frida_device_is_lost(handle.Pointer);
44 | public FridaDeviceType Type => _frida_device_get_dtype(handle.Pointer);
45 | public byte[] Icon => throw new NotImplementedException();
46 | public List EnumerateProcesses()
47 | {
48 | IntPtr error;
49 | using (var devices = new Ref(_frida_device_enumerate_processes_sync(handle.Pointer, out error)))
50 | {
51 | GError.Throw(error);
52 | var len = _frida_process_list_size(devices.Pointer);
53 | var ret = new List();
54 | for (int i = 0; i < len; i++)
55 | {
56 | ret.Add(new FridaProcess(() => _frida_process_list_get(devices.Pointer, i)));
57 | }
58 | return ret;
59 | }
60 | }
61 |
62 | public uint Spawn()
63 | => throw new NotImplementedException();
64 |
65 |
66 | public void Resume(uint pid)
67 | {
68 | IntPtr error;
69 | _frida_device_resume_sync(handle.Pointer, pid, out error);
70 | GError.Throw(error);
71 | }
72 |
73 | public FridaSession Attach(uint pid)
74 | {
75 | return new FridaSession(() =>
76 | {
77 | IntPtr error;
78 | var session = _frida_device_attach_sync(handle.Pointer, pid, out error);
79 | GError.Throw(error);
80 | return session;
81 | });
82 | }
83 |
84 | public override string ToString()
85 | {
86 | return "Device " + handle.Pointer;
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/Frida.NetStandard/DeviceManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace Frida.NetStandard
6 | {
7 | public class DeviceManager
8 | {
9 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
10 | static extern IntPtr _frida_device_manager_new();
11 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
12 | static extern void _frida_device_manager_close_sync(IntPtr deviceManager);
13 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
14 | static extern IntPtr _frida_device_manager_enumerate_devices_sync(IntPtr deviceManager, out IntPtr error);
15 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
16 | static extern int _frida_device_list_size(IntPtr list);
17 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
18 | static extern IntPtr _frida_device_list_get(IntPtr list, Int32 index);
19 |
20 | Handle handle;
21 |
22 | public DeviceManager()
23 | {
24 | handle = new Handle(_frida_device_manager_new);
25 | }
26 |
27 | public List EnumerateDevices()
28 | {
29 |
30 | IntPtr error;
31 | using (var devices = new Ref(_frida_device_manager_enumerate_devices_sync(handle.Pointer, out error)))
32 | {
33 | GError.Throw(error);
34 | var len = _frida_device_list_size(devices.Pointer);
35 | var ret = new List();
36 | for (int i = 0; i < len; i++)
37 | {
38 | ret.Add(new Device(() => _frida_device_list_get(devices.Pointer, i)));
39 | }
40 | return ret;
41 | }
42 | }
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/Frida.NetStandard/Frida.NetStandard.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Frida.NetStandard/FridaProcess.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.InteropServices;
4 | using System.Text;
5 |
6 | namespace Frida.NetStandard
7 | {
8 | public class FridaProcess
9 | {
10 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
11 | static extern IntPtr _frida_device_get_name(IntPtr device);
12 |
13 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
14 | static extern uint _frida_process_get_pid(IntPtr device);
15 |
16 | Handle handle;
17 | public FridaProcess(Func builder)
18 | {
19 | handle = new Handle(builder);
20 | }
21 |
22 | public string Name => _frida_device_get_name(handle.Pointer).ReadStringAndFree();
23 | public uint Pid => _frida_process_get_pid(handle.Pointer);
24 |
25 | public byte[] SmallIcon => throw new NotImplementedException();
26 | public byte[] LargeIcon => throw new NotImplementedException();
27 |
28 | public override string ToString()
29 | => $"{Name} ({Pid})";
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/Frida.NetStandard/FridaSession.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.InteropServices;
4 | using System.Text;
5 |
6 | namespace Frida.NetStandard
7 | {
8 | public class FridaSession
9 | {
10 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
11 | static extern Int32 _frida_session_get_pid(IntPtr self);
12 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
13 | static extern void _frida_session_detach_sync(IntPtr self);
14 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
15 | static extern IntPtr _frida_session_create_script_sync(IntPtr self, string name, string source, out IntPtr error);
16 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
17 | static extern IntPtr _frida_session_enable_debugger_sync(IntPtr self, UInt16 port, out IntPtr error);
18 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
19 | static extern IntPtr _frida_session_disable_debugger_sync(IntPtr self, out IntPtr error);
20 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
21 | static extern IntPtr _frida_session_enable_jit_sync(IntPtr self, out IntPtr error);
22 |
23 | Handle handle;
24 | public FridaSession(Func builder)
25 | {
26 | handle = new Handle(builder);
27 | }
28 |
29 | public int Pid => _frida_session_get_pid(handle.Pointer);
30 | public void Dettach()
31 | => _frida_session_detach_sync(handle.Pointer);
32 |
33 | public ScriptWithRpc CreateScriptWithRpc(string source)
34 | => CreateScriptWithRpc(null, source);
35 |
36 | public ScriptWithRpc CreateScriptWithRpc(string name, string source)
37 | {
38 | return new ScriptWithRpc(() =>
39 | {
40 | IntPtr error;
41 | var script = _frida_session_create_script_sync(handle.Pointer, name, source, out error);
42 | GError.Throw(error);
43 | return script;
44 | });
45 | }
46 |
47 |
48 | public Script CreateScript(string source)
49 | => CreateScript(null, source);
50 | public Script CreateScript(string name, string source)
51 | {
52 | return new Script(() =>
53 | {
54 | IntPtr error;
55 | var script = _frida_session_create_script_sync(handle.Pointer, name, source, out error);
56 | GError.Throw(error);
57 | return script;
58 | });
59 | }
60 |
61 | public void EnableDebugger(UInt16 port = 0)
62 | {
63 | IntPtr error;
64 | _frida_session_enable_debugger_sync(handle.Pointer, port, out error);
65 | GError.Throw(error);
66 | }
67 |
68 | public void DisableDebugger()
69 | {
70 | IntPtr error;
71 | _frida_session_disable_debugger_sync(handle.Pointer, out error);
72 | GError.Throw(error);
73 | }
74 |
75 | public void EnableJit()
76 | {
77 | IntPtr error;
78 | _frida_session_enable_jit_sync(handle.Pointer, out error);
79 | GError.Throw(error);
80 | }
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/Frida.NetStandard/GError.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace Frida.NetStandard
5 | {
6 | [StructLayout(LayoutKind.Sequential)]
7 | struct GError
8 | {
9 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
10 | static extern void _frida_g_clear_error(ref IntPtr ptr);
11 |
12 | public Int32 GQuark;
13 | public Int32 Code;
14 | public string Message;
15 | public static void Throw(IntPtr ptr)
16 | {
17 | if (ptr == IntPtr.Zero)
18 | return;
19 | var err = (GError)Marshal.PtrToStructure(ptr, typeof(GError));
20 | _frida_g_clear_error(ref ptr);
21 | throw new InvalidOperationException(err.Message ?? "Unknown frida error");
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Frida.NetStandard/Handle.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace Frida.NetStandard
5 | {
6 | class Handle
7 | {
8 |
9 | public IntPtr Pointer { get; private set; }
10 |
11 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
12 | static extern void _frida_g_object_unref(IntPtr ptr);
13 |
14 | public Handle(Func handle)
15 | {
16 | try
17 | {
18 | Runtime.Ref();
19 | Pointer = handle();
20 | if (Pointer == IntPtr.Zero)
21 | Runtime.Unref();
22 | }
23 | catch
24 | {
25 | Runtime.Unref();
26 | throw;
27 | }
28 | }
29 |
30 | ~Handle()
31 | {
32 | if (Pointer == IntPtr.Zero)
33 | return;
34 | _frida_g_object_unref(Pointer);
35 | Runtime.Unref();
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Frida.NetStandard/Ref.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace Frida.NetStandard
5 | {
6 | class Ref : IDisposable
7 | {
8 | public IntPtr Pointer { get; private set; }
9 | bool disposed = false;
10 |
11 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
12 | static extern void _frida_g_object_unref(IntPtr ptr);
13 |
14 | public void Dispose()
15 | {
16 | if (disposed)
17 | return;
18 | disposed = true;
19 | if (Pointer != IntPtr.Zero)
20 | _frida_g_object_unref(Pointer);
21 | Runtime.Unref();
22 | }
23 |
24 | public Ref(IntPtr handle)
25 | {
26 | Pointer = handle;
27 | }
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/Frida.NetStandard/Runtime.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Threading;
4 |
5 | namespace Frida.NetStandard
6 | {
7 | static class Runtime
8 | {
9 | public const string LibName = "Frida.Exports.dll";
10 | static volatile int refs = 0;
11 |
12 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
13 | static extern void _frida_init();
14 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
15 | static extern void _frida_deinit();
16 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
17 | static extern void _frida_g_free(IntPtr ptr);
18 |
19 | public static void Ref()
20 | {
21 | if (Interlocked.Increment(ref refs) == 1)
22 | {
23 | Console.WriteLine("Initializing frida");
24 | _frida_init();
25 | }
26 | }
27 |
28 | public static void Unref()
29 | {
30 |
31 | if (Interlocked.Decrement(ref refs) <= 0)
32 | {
33 | Console.WriteLine("Deinitializing frida");
34 | _frida_deinit();
35 | }
36 | }
37 | public static string ReadStringAndFree(this IntPtr ptr)
38 | {
39 | var ret = Marshal.PtrToStringAuto(ptr);
40 | _frida_g_free(ptr);
41 | return ret;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Frida.NetStandard/Script.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using Newtonsoft.Json.Linq;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Runtime.InteropServices;
6 | using System.Text;
7 |
8 | namespace Frida.NetStandard
9 | {
10 | public class Script
11 | {
12 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
13 | static extern void _frida_script_load_sync(IntPtr device, out IntPtr error);
14 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
15 | static extern void _frida_script_unload_sync(IntPtr device, out IntPtr error);
16 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
17 | static extern void _frida_script_eternalize_sync(IntPtr device, out IntPtr error);
18 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
19 | static extern void _frida_script_post_sync(IntPtr device, string message, IntPtr data, UInt32 dataLength, out IntPtr error);
20 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
21 | static extern void _frida_script_connect_message_handler(IntPtr handle, IntPtr fnPointer);
22 | [DllImport(Runtime.LibName, CharSet = CharSet.Unicode)]
23 | static extern void _frida_script_disconnect_message_handler(IntPtr handle, IntPtr fnPointer);
24 |
25 | delegate void OnScriptMessageDelegate(IntPtr message, IntPtr data, UInt32 dataSize);
26 | Handle handle;
27 | IntPtr onMessageDelegate;
28 | GCHandle onMessageDelegateHandle;
29 |
30 | public Script(Func builder)
31 | {
32 | handle = new Handle(builder);
33 | OnScriptMessageDelegate del = OnScriptMessage;
34 | onMessageDelegateHandle = GCHandle.Alloc(del);
35 | onMessageDelegate = Marshal.GetFunctionPointerForDelegate(del);
36 | _frida_script_connect_message_handler(handle.Pointer, onMessageDelegate);
37 | }
38 |
39 | ~Script()
40 | {
41 | if (handle != null && onMessageDelegate != IntPtr.Zero)
42 | {
43 | _frida_script_disconnect_message_handler(handle.Pointer, onMessageDelegate);
44 | onMessageDelegateHandle.Free();
45 | }
46 | }
47 |
48 | // {"type":"log","level":"info","payload":"Script initialized"}
49 | public delegate void MessageDelegate(string type, JToken payload, byte[] data);
50 | public event MessageDelegate OnMessage;
51 | public delegate void ConsoleDelegate(string level, string data);
52 | public event ConsoleDelegate OnConsole;
53 |
54 |
55 |
56 | void OnScriptMessage(IntPtr messagePtr, IntPtr data, UInt32 dataSize)
57 | {
58 | try
59 | {
60 | var message = messagePtr.ReadStringAndFree();
61 | byte[] dataBytes = null;
62 | if (data != IntPtr.Zero)
63 | {
64 | dataBytes = new byte[dataSize];
65 | Marshal.Copy(data, dataBytes, 0, (int)dataSize);
66 | }
67 |
68 | var payload = JsonConvert.DeserializeObject(message);
69 | JToken type;
70 | if (!payload.TryGetValue("type", out type) || type.Type != JTokenType.String)
71 | return;
72 | ProcessMessage(type.Value(), payload, dataBytes);
73 |
74 | } catch (Exception ex)
75 | {
76 | OnConsole?.Invoke("error", "ERROR PROCESSING MESSAGE: " + ex.Message);
77 | }
78 | }
79 |
80 | class FridaLog
81 | {
82 | public string level { get; set; }
83 | public string payload { get; set; }
84 | }
85 | protected virtual void ProcessMessage(string type, JObject data, byte[] dataBytes)
86 | {
87 | switch (type)
88 | {
89 | case "log":
90 | var msg = data.ToObject();
91 | OnConsole?.Invoke(msg.level, msg.payload);
92 | break;
93 | default:
94 | JToken payload;
95 | data.TryGetValue("payload", out payload);
96 | OnMessage?.Invoke(type, payload, dataBytes);
97 | break;
98 | }
99 | }
100 |
101 | public void Load()
102 | {
103 | IntPtr error;
104 | _frida_script_load_sync(handle.Pointer, out error);
105 | GError.Throw(error);
106 | }
107 |
108 | public void Unload()
109 | {
110 | IntPtr error;
111 | _frida_script_unload_sync(handle.Pointer, out error);
112 | GError.Throw(error);
113 | }
114 |
115 | public void Eternalize()
116 | {
117 | IntPtr error;
118 | _frida_script_eternalize_sync(handle.Pointer, out error);
119 | GError.Throw(error);
120 | }
121 |
122 | public void Post(object payload, byte[] data = null)
123 | {
124 | IntPtr dataPtr = IntPtr.Zero;
125 | try
126 | {
127 | var message = JsonConvert.SerializeObject(payload);
128 | if (data != null)
129 | {
130 | dataPtr = Marshal.AllocHGlobal(data.Length);
131 | Marshal.Copy(data, 0, dataPtr, data.Length);
132 | }
133 | IntPtr error;
134 | _frida_script_post_sync(handle.Pointer, message, dataPtr, (uint)(data?.Length ?? 0), out error);
135 | GError.Throw(error);
136 | }
137 | finally
138 | {
139 | if (dataPtr != IntPtr.Zero)
140 | Marshal.FreeHGlobal(dataPtr);
141 | }
142 | }
143 | }
144 |
145 | }
146 |
--------------------------------------------------------------------------------
/Frida.NetStandard/ScriptWithRpc.cs:
--------------------------------------------------------------------------------
1 | using Frida.NetStandard.Utilities;
2 | using Newtonsoft.Json;
3 | using Newtonsoft.Json.Linq;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Reflection;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 |
11 | namespace Frida.NetStandard
12 | {
13 | public abstract class FridaRpcException : Exception
14 | {
15 | protected FridaRpcException(string message, Exception ex = null) : base(message, ex) { }
16 | }
17 | public class FridaRpcSerializationException : FridaRpcException
18 | {
19 | public FridaRpcSerializationException(Exception ex) : base(ex.Message, ex){ }
20 | }
21 |
22 | public class FridaRpcScriptException : FridaRpcException
23 | {
24 | public string ErrorName { get; private set; }
25 | public string JsErrorStack { get; private set; }
26 |
27 | public FridaRpcScriptException(string message, string errName, string errStack) : base(errStack ?? message)
28 | {
29 | this.ErrorName = errName;
30 | this.JsErrorStack = errStack;
31 | }
32 |
33 | public override string ToString()
34 | {
35 | return $"{Message} at \n {JsErrorStack}";
36 | }
37 | }
38 | public class ScriptWithRpc : Script, IInterfaceImplementation
39 | {
40 | public ScriptWithRpc(Func builder)
41 | : base(builder)
42 | {
43 | Rpc = InterfaceImplementer.Create(this);
44 | }
45 |
46 | public TRpc Rpc { get; }
47 |
48 | object IInterfaceImplementation.Call(MethodInfo method, object[] arguments)
49 | {
50 | return ((IInterfaceImplementation)this).CallAsync(method, arguments)
51 | .ConfigureAwait(false)
52 | .GetAwaiter()
53 | .GetResult();
54 | }
55 |
56 | class Operation
57 | {
58 | public TaskCompletionSource