1

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("OK\n"))
            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.

1 Answer 1

1

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(/^\$T\d\d/) != -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("OK\n"))
            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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.