When your app is being used by real customers, the ideal situation is that updating your application does not require your customers to manually download a new binary.
I’ll be showing a proof-of-concept in Go that fixes this. Text and code written by me but Claude AI helped me with section names and some typos.
Common Binary Update Challenges
There are some common problems related to updating a binary:
I come from a gym background where you lift stuff and put it back down. The weights do not strangle you or make you feel like an idiot by defending your lifts. You can very easily form a bubble where you think you’re unstoppable because you can always have your way and decide what you’re going to do. For example, when you lift weights, you can always lift a certain amount of weight that you know you can lift. Even if you try a 1 RM max, you can use a spotter or a rack that spots you.
Life has been very hectic. I’ve been juggling school, work and hobbies at the same time. There are many projects I’d like to work on but there is not enough time.
I’ve been very ambitious about this one project for a while now. This blog post is related to the project. Namely, how I’m going to implement mTLS authentication for the backend endpoints.
The backend will be running on my home server and the endpoints will be private and used by a handful of selected people.
Automating static analysis with the Binary Ninja API
Explanation
Static binary analysis can be a daunting task. It is time-consuming and hard. You should automate most of this hard work if possible.
The Binary Ninja API from my experience is the best tool for the job. This is because the whole binary analysis tool was developed with the API in mind.
Binary Ninja provides an API in Python, Rust, and C++. I believe Binary Ninja itself is built with the native C++ API. This means that in theory, everything you can do in the UI should be possible to do in some sort of API provided by Binary Ninja.
Casey Muratori told me to simulate conditional jumps and loops in this assignment.
They’re the same thing.
About this blog post
This blog post is a bit different since I’ve already completed this assignment. The reason for this is that I was being lazy while doing this, but now I decided I want to blog about this one too.
I spent tons of time debugging this, and I’m now going to provide the solution to this one but know that it took some debugging hours from me, and it wasn’t easy.
In the Performance-Aware Programming course by Casey Muratori, he gave a homework assignment (listing_0046) where you have to simulate the ADD/SUB/CMP instructions.
In the previous blog posts, I handled the immediate move instruction and register to register moves. This was easy because the MOV instruction does not modify the FLAGS register.
The instructions handled in this blog post require us to modify the zero flag (ZF) and sign flag (SF) bits from the FLAGS register.
In the previous blog post, I implemented the logic for immediate-to-register moves. However, I later realised that while the immediate-to-register move works correctly, the register-to-register move does not.
That is clearly false. It seems like the state doesn’t persist? I have no idea why this is happening. I’ll jump into CLion and investigate.
The question is, why is this code incorrect?
let reg = get_register_state(®_register, ®isters);
let rm = get_register_state(&rm_register, ®isters);
if reg_is_dest {
update_register_value(reg.register, rm.updated_value, &mut registers, instruction, memory_mode, mnemonic);
} else {
let rm = get_register_state(&rm_register, ®isters);
// in this branch we can just update the value with the immediate.
update_register_value(rm.register, reg.updated_value, &mut registers, instruction, memory_mode, mnemonic);
}
The branch jumps into the update_register_value function, but it seems that this function does not correctly update the values. This is evident because once we exit the scope of the code snippet, the value does not persist.
In this post I’m going to go through my thought process implementing the brains for my intel 8086 decoder. Currently, I’ve implemented the decoding of the bits of the compiled executable. Next I have to simulate the logic of executing for example mov ax, 50.
I’m writing this post as I go to better give people my thought process. In this blog post I’m going to be implementing the logic for an immediate to register mov instruction.