Reverse Engineering Asked on July 16, 2021
First of here is the gdb remote protocol doc.
The idea of the below script is the following – you enter an actual command (one that will be send as a direct packet see packets) in the gdb window then when you continue the process my command will be executed instead of the IDA vCont;s:1
or vCont;c
. This so the IDA recognize the actual changes you have introduced by executing your command. Simply responding with “OK” after the qRcmd will not work for lets say stepping back because IDA wouldn’t ask for new register values.
I launch rr with rr replay -s 50505 -k
, I attach with IDA to localhost:23946. Here is my mitm code (in node.js):
const net=require("net")
const process = require('process');
net.createServer(server => {
const client = new net.Socket()
let lastcommand, response
client.connect(50505, "localhost")
/**
* @param {Buffer} string
*/
function createResponse(string)
{
string = string.slice(0, string.length - 1)
let checksum = 0
for(const a of string) checksum += a
checksum %= 256
return "$"+string.toString()+"#"+checksum.toString(0x10)
}
client.on("data", handler = data => {
let string = data.toString()
console.log(string),
server.write(string)
})
server.on("data", handlerserver = async data => {
let string = data.toString()
console.log(string)
let cmd
if((cmd = string.replace(/^$qRcmd,([a-f0-9]+)#/, (_, substring) => substring)) != string){
lastcommand = string = createResponse(Buffer.from(cmd, "hex"))
const innerresponse = createResponse(Buffer.from("OKn"))
console.log(innerresponse)
server.write(innerresponse)
response = lastcommand
return
}
else if(string.search(/^$vCont;c#a8/) != -1 || string.search(/^$vCont;s:1#23/) != -1) return console.log(response),
client.write(response)//, response = undefined
client.write(string)
})
}).listen(23946, "localhost")
Basically what’s not working is that when i enter bs
(step backwards one instruction packet) in the gdb monitor then press continue it’ll step backwards twice the first time and on the second it’ll run back to the beginning of the program.
It turned out IDA sends first sends vCont;c
and then vCont;s:1
for some weird reason in that particular instance. I fixed my mitm :
const net=require("net")
const process = require('process');
net.createServer(server => {
const client = new net.Socket()
let lastcommand, response, lastterm
client.connect(50505, "localhost")
/**
* @param {Buffer} string
*/
function createResponse(string)
{
string = string.slice(0, string.length - 1)
let checksum = 0
for(const a of string) checksum += a
checksum %= 256
return "$"+string.toString()+"#"+checksum.toString(0x10)
}
client.on("data", handler = data => {
let string = data.toString()
if(string.search(/^$Tdd/) != -1) lastterm = string
console.log(string),
server.write(string)
})
server.on("data", handlerserver = async data => {
let string = data.toString()
console.log(string)
let cmd
if((cmd = string.replace(/^$qRcmd,([a-f0-9]+)#/, (_, substring) => substring)) != string){
lastcommand = string = createResponse(Buffer.from(cmd, "hex"))
const innerresponse = createResponse(Buffer.from("OKn"))
console.log(innerresponse)
server.write(innerresponse)
response = lastcommand
return
}
else if(string.search(/^$vCont;c#a8/) != -1) return console.log(response),
client.write(response)//, response = undefined
else if(string.search(/^$vCont;s:1#23/) != -1) return console.log(lastterm), server.write(lastterm)
client.write(string)
})
}).listen(23946, "localhost")
I basically capture the last received signal and resend it the second time.
There is still a small issue when issuing a command when the program counter is on a break-point but that's small enough to ignore.
Answered by rec on July 16, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP