5 years ago, I said in one of my articles that I shall return, one day, with a method of hot patching functions inside live processes; So… I guess this is that day.

What we’ll try to achieve here is to replace, from outside, a function inside a running executable, without stopping/freezing the process (or crashing it…).

In my opinion, applying hot patches is quite a daunting task, if implemented from scratch, since:

  • it requires access to a different process’ memory (most operating systems are fans of process isolation)
  • has software compatibility constraints (Windows binaries vs Linux binaries)
  • has architecture compatibility constraints (32bit vs 64bit)
  • it implies working with machine code and brings certain issues to the table
  • it has only a didactic purpose - probably no one would actually use a ‘from-scratch’ method since there are tools that do this better

Considering these, I guess it is better to use something that was actually written for this task and not coding something manually. Therefore, we’ll be looking at a way to do this with Intel Pin. I stumbled upon this tool while working at a completely different project but it seems to be quite versatile. Basically, it is described as a Dynamic Binary Instrumentation Tool, however we’ll be using it to facilitate the procedure of writing code to another process’ memory.

Initial Preparations

Start by downloading Intel Pin and extract it somewhere in your workspace.

I’m doing this tutorial on Ubuntu x86_64, but I’m expecting the code to be highly similar on Windows or other operating systems.

Now, I imagine this turns out to be useful for endpoints that provide remote services to clients - i.e.: a server receives some sort of input and is expected to also return something. Let’s say that someone discovered that a  service is vulnerable to certain inputs - so it can be compromised by the first attacker who submits a specially crafted request. We’ll consider that taking the service down, compiling, deploying and launching a new instance is not a desirable solution so hot patching is wanted until a new version is ready. 

I’ll use the following dummy C program to illustrate the aforementioned model - to keep it simple, I’m reading inputs from stdin (instead of a tcp stream / network).