Build a debugger in 5 minutes (2/5)
Let’s tap into the internals of native processes with our own custom-made debugger.
Add process selection
We just hard-coded a process ID in our code, that’s not very practical. Let’s go ahead and fix it.
Add the following code just above the “Script” object:
ProcessListModel {
id: processModel
device: Frida.localSystem
}
That’s just a model, we also need a view. Let’s replace the “Button” object with a “TableView”:
TableView {
id: processes
height: parent.height
TableViewColumn {
role: "smallIcon"
width: 16
delegate: Image {
source: styleData.value
fillMode: Image.Pad
}
}
TableViewColumn { role: "pid"; title: "Pid"; width: 50 }
TableViewColumn { role: "name"; title: "Name"; width: 100 }
model: processModel
onActivated: {
Frida.localSystem.inject(script,
processModel.get(currentRow).pid);
}
}
So we set it up with three columns, each wired to the column names in our model. Now we’re ready to take it for a spin:
Our debugger is finally starting to look like something! We replaced the button with a real process list, and it’s only a matter of double-clicking to inject the script into the selected process.
Split out the script code
Before we go ahead and make the script code interesting, it’s clear we can’t keep that code inline in our qml. It’s just way too tedious to write a multi-line script that way, with all the escaping and concatenating it entails.
Open the “New” menu in Qt Creator, select the “General” category and pick “Text File”. Name it “agent.js” and proceed with default options. Let’s move our inline code into this new file and spice it up a tiny bit:
console.log("Hello from thread ID " +
Process.getCurrentThreadId());
Back in “geoshark.qml” replace the line
source: "console.log('Hello from Frida!');"
with
url: Qt.resolvedUrl("./agent.js")
And off we go:
That concludes the second minute of our five-minute tutorial.