Skip to content

Commit 2df3a0f

Browse files
committed
+Fermion-v15
1 parent 0a6fef1 commit 2df3a0f

File tree

15 files changed

+234
-59
lines changed

15 files changed

+234
-59
lines changed

CHANGELOG.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,12 @@
7474
* Build updated/tested for Electron v11
7575
* Updated language bindings
7676
* Compatibility changes for upcoming electron contextIsolation default behavior in v12
77-
* Compiled package support for OSX dropped, I need to boot an old laptop every time I make a release and it's PITA.
77+
* Compiled package support for OSX dropped, I need to boot an old laptop every time I make a release and it's PITA.
78+
79+
-= Fermion v1.5 =-
80+
81+
* Added device selection context menu, including remote socket support.
82+
* Added JS trap for ctrl/command-t to refresh the Frida script in the target. It is now practical to collapse side-bar and work on your code.
83+
* Added "GC" on the textarea. It was always a problem that high volume hooks could tank Fermion if the textarea grew too large. Fermion now limits the line count to 5000 and will delete old entries as new ones come in.
84+
* Changed color for the text area. I think eventually a full UI re-design will probably be in order (v2 maybe).
85+
* Added example: malloc

Examples/malloc.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//--------//
2+
// Malloc //
3+
//--------//
4+
5+
var pMalloc = Module.findExportByName(null, "malloc");
6+
7+
Interceptor.attach(pMalloc, {
8+
onEnter: function (args) {
9+
send("\n[+] Called malloc");
10+
send(" |_ Len : " + args[0]);
11+
this.mallocLen = args[0];
12+
},
13+
14+
onLeave: function (retval) {
15+
if (retval.toInt32() != 0) {
16+
send(" |_ Success : true");
17+
send(" |_ Dump : \n" + hexdump(retval, {length:parseInt(this.mallocLen)}));
18+
} else {
19+
send(" |_ Success : false");
20+
}
21+
}
22+
});

Fermion/assets/css/frida.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ textarea#FridaOut {
438438
font-family: monospace;
439439
font-size: 0.9em;
440440
line-height: 1.7em;
441-
background-color: #2f3542;
441+
background-color: #422f2f;
442442
}
443443

444444
.btn-level {

Fermion/assets/img/device.png

4.68 KB
Loading

Fermion/assets/img/version.png

-88 Bytes
Loading

Fermion/core.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,6 @@ app.on('activate', () => {
5656
}
5757
})
5858

59-
// In this file you can include the rest of your app's specific main process
60-
// code. You can also put them in separate files and require them here.
59+
// Add listener for device selector
60+
const ipc = require('electron').ipcMain;
61+
ipc.on('device-selector', (event, message) => bWin.webContents.send('device-selector', message));

Fermion/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "fermion",
3-
"version": "1.4.0",
3+
"version": "1.5.0",
44
"description": "Fermion is a stand-alone Frida electron tool.",
55
"main": "core.js",
66
"scripts": {

Fermion/src/device.html

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<html>
2+
3+
<head>
4+
<style>
5+
body {
6+
background-color: #ff4757 !important;
7+
-webkit-app-region:drag;
8+
}
9+
</style>
10+
<link rel="stylesheet" href="../assets/css/bootstrap.css">
11+
<link rel="stylesheet" href="../assets/css/frida.css">
12+
<script defer src="../assets/js/solid.js"></script>
13+
<script defer src="../assets/js/fontawesome.js"></script>
14+
</head>
15+
16+
<body>
17+
<div class="container-fluid">
18+
<div class="row"
19+
style="text-align:right;display:block;padding-right:5px;padding-top:5px">
20+
<a id="CloseDevice" href="#">
21+
<img src="../assets/img/x.png" height="10%" width="7%" style="-webkit-app-region: no-drag;">
22+
</a>
23+
<img src="../assets/img/device.png" height="18%" width="35%" style="-webkit-app-region:drag;float: left;display:block;padding-left:5px;">
24+
</div>
25+
<div class="form-check">
26+
<br /><br />
27+
<input class="form-check-input" type="radio" name="selectRadios" id="selectRadios1" value="option1" style="-webkit-app-region: no-drag;" checked>
28+
<label class="form-check-label" for="flexCheckChecked">Auto-Detect (Local / USB / Mobile)</label>
29+
<select type="deviceName" class="form-control" id="deviceName" style="-webkit-app-region: no-drag;">
30+
<option>local</option>
31+
</select><br />
32+
</div>
33+
<div class="form-check">
34+
<input class="form-check-input" type="radio" name="selectRadios" id="selectRadios2" value="option2" style="-webkit-app-region: no-drag;">
35+
<label class="form-check-label">Remote Socket</label>
36+
<div class="input-group mb-3" style="-webkit-app-region: no-drag;">
37+
<input type="text" class="form-control" placeholder="IP" aria-label="IP" style="width: 45%;" id="inputIP">
38+
<span class="input-group-text" style="-webkit-app-region: drag;">:</span>
39+
<input type="text" class="form-control" placeholder="Port" aria-label="Port" id="inputPort">
40+
</div>
41+
</div>
42+
43+
<button type="button" id="FridaUpdateDevice" class="btn btn-goon btn-sm btn-block btn-space" style="-webkit-app-region: no-drag; margin-top:30px;">Ok</button>
44+
</div>
45+
46+
<script type="text/javascript">
47+
const frida = require('frida');
48+
// Overwrite default node.js prop to get Jquery working
49+
window.$ = window.jQuery = require('jquery');
50+
51+
// Update dropdown
52+
async function updateDeviceList() {
53+
// Get dropdown array
54+
var dn = document.getElementById("deviceName");
55+
var currentDevice = dn.options[deviceName.selectedIndex].value;
56+
var dnArr = Array.from(dn.options).map(elem => elem.text);
57+
58+
// Get device array
59+
var dm = frida.getDeviceManager();
60+
var dev = await dm.enumerateDevices();
61+
var devArr = dev.map(elem => elem.id);
62+
63+
// Does the current device still exist?
64+
if (!devArr.includes(currentDevice)) {
65+
// Local is always a valid target
66+
dn.selectedIndex = 0;
67+
deviceId = 'local';
68+
}
69+
70+
// Remove stale entries from the dropdown
71+
dnArr.forEach(function(elem) {
72+
if (!devArr.includes(elem)) {
73+
$(`#deviceName option:contains("${elem}")`).remove()
74+
}
75+
})
76+
77+
// Add new entries to the dropdown
78+
devArr.forEach(function(elem) {
79+
if (!dnArr.includes(elem) && elem != "tcp" && elem != "socket") {
80+
$("#deviceName").append(new Option(elem))
81+
}
82+
})
83+
}
84+
85+
updateDeviceList();
86+
setInterval(function(){
87+
updateDeviceList();
88+
}, 5000);
89+
90+
// Update device and close dialog
91+
document.getElementById("FridaUpdateDevice").onclick = function () {
92+
// New device string
93+
var newDevice = null;
94+
95+
// Do action based on radio selector
96+
if (document.getElementById("selectRadios1").checked) {
97+
newDevice = document.getElementById("deviceName").value;
98+
} else {
99+
newDevice = "socket@" + document.getElementById("inputIP").value + ":" + document.getElementById("inputPort").value;
100+
}
101+
102+
const ipc = require('electron').ipcRenderer;
103+
ipc.send('device-selector', newDevice);
104+
105+
window.close();
106+
}
107+
108+
// Close dialog, make no changes to the device
109+
document.getElementById("CloseDevice").onclick = function () {
110+
window.close();
111+
}
112+
</script>
113+
</body>
114+
115+
</html>

Fermion/src/frida.html

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,13 @@
2929
<ul class="list-unstyled components">
3030
<div class="form-group mx-sm-3 mb-2">
3131
<label for="deviceName">Device</label>
32-
<select type="deviceName" class="form-control" id="deviceName">
33-
<option>local</option>
34-
</select>
35-
</div><br><br>
32+
<input type="deviceName" class="form-control" id="deviceName" value="local" style="background-color:lightgray; color:black;" disabled>
33+
</div>
34+
<ul class="list-unstyled CTAs">
35+
<li>
36+
<button type="button" id="setDevice" class="btn btn-goon btn-sm btn-block btn-space">Configure</button>
37+
</li>
38+
</ul><br>
3639
<div class="form-group mx-sm-3 mb-2">
3740
<label for="procID">Process ID</label>
3841
<input type="procID" class="form-control" id="procID" placeholder="ID">
@@ -211,7 +214,7 @@
211214
var editor = monaco.editor.create(document.getElementById('container'), {
212215
value: [
213216
'//-------------------------------------------//',
214-
'// Fermion v1.4 //',
217+
'// Fermion v1.5 //',
215218
'// ~b33f //',
216219
'//-------------------------------------------//',
217220
'',
@@ -224,9 +227,9 @@
224227
'// + I am trapping Ctrl-s / Ctrl-o in JS so you can save',
225228
'// and open files without clicking on the menu',
226229
'//',
227-
'// + The full Frida API is integrated in the editor',
228-
'// |-> monaco.languages.typescript.typescriptDefaults.addExtraLib(....)',
229-
'// |-> https://www.npmjs.com/package/@types/frida-gum',
230+
'// + I am trapping Ctrl-t in JS so you can reload the',
231+
'// current script in the attached target without',
232+
'// (un-collapsing &) clicking the sidebar',
230233
'',
231234
'// ~~ Frida ~~ //',
232235
'',
@@ -248,21 +251,17 @@
248251

249252
// Store the editor reff as a global var
250253
MonacoCodeEditor = editor;
251-
252-
// Update device list
253-
updateDeviceList();
254-
255-
// Configure interval to update device list
256-
setInterval(function(){
257-
updateDeviceList();
258-
}, 5000);
259254
});
260255
})();
261256

262257

263258
</script>
264259

265260
<script type="text/javascript">
261+
262+
// Print release firda version to textarea
263+
appendFridaLog("[+] Fermion v1.5 -> Frida v14.2.13");
264+
266265
$(document).ready(function () {
267266
$('#sidebarCollapse').on('click', function () {
268267
$('#sidebar').toggleClass('active');

Fermion/src/proc.html

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,14 @@
8787
deviceId = new URL(url).searchParams.get('deviceId');
8888

8989
// Retrieve device list
90-
async function getDeviceList() {
90+
async function getDeviceList(devInst) {
9191
var dm = await frida.getDeviceManager();
92+
// If the device is a remote socket we need to add it
93+
// manually
94+
if (devInst.startsWith("socket@")) {
95+
var sRemoteSocket = devInst.split('@')[1];
96+
dm.addRemoteDevice(sRemoteSocket);
97+
}
9298
var dev = await dm.enumerateDevices();
9399
return dev;
94100
}
@@ -106,7 +112,7 @@
106112
// Make sure the device list has updated
107113
if (atob(deviceId) != "local") {
108114
for (i = 0; i < 3; i++) {
109-
var dev = await getDeviceList();
115+
var dev = await getDeviceList(atob(deviceId));
110116
if (dev.length > 2) {
111117
break;
112118
}

0 commit comments

Comments
 (0)