Recursive iterators in Rust
I've been looking for this blog post everywhere, but it doesn't exist, so I guess it's my turn to write about Some Fun with Rust.
The task at hand
Let's say you have a recursive,...
Rust generics vs Java generics
In my previous article, I said I needed to stop thinking of Rust generics as Java generics, because in Rust, generic types are erased.
Someone gently pointed out that they are also...
Rust modules vs files
A while back, I asked on Twitter what people found confusing in Rust, and one of the top topics was “how the module system maps to files”.
I remember struggling with...
Reading files the hard way - Part 1 (node.js, C, rust, strace)
Reading files the hard way: Part 1
Everybody knows how to use files. You just open up File Explorer, the Finder, or a File Manager, and bam - it's chock-full of files. There's folders and files as far as the eye can...
Reading files the hard way - Part 3 (ftrace, disk layouts, ext4)
Reading files the hard way: Part 3
So far, we've seen many ways to read a file from different programming languages, we've learned about syscalls, how to make those from assembly, then we've learned about memory...
Declarative memory management
It feels like an eternity since I've started using Rust, and yet I remember vividly what it felt like to bang my head against the borrow checker for the first few times.
Windows dynamic libraries, calling conventions, and transmute
Making our own ping: Part 2
So, how does
ping.exeactually send a ping? It seems unrealistic that
ping.exeitself implements all the protocols involved in sending a ping. So it must be calling some sort of...
FFI-safe types in Rust, newtypes and MaybeUninit
Making our own ping: Part 3
It's time to make
sup, our own take on
ping, use the Win32 APIs to send an ICMP echo. Earlier we discovered that Windows's
IcmpSendEcho2Ex. But for our purposes, the...
Designing and implementing a safer API on top of LoadLibrary
Making our own ping: Part 4
It's refactor time!
Our complete program is now about a hundred lines, counting blank lines (see the end of part 3 for a complete listing).
While this is pretty good for a...
A simple ping library, parsing strings into IPv4 address
Making our own ping: Part 5
We've just spent a lot of time abstracting over LoadLibrary, but we still have all the gory details of the Win32 ICMP API straight in our main.rs file! That won't do.
The builder pattern, and a macro that keeps FFI code DRY
Making our own ping: Part 6
Our ping API is simple, but it's also very limited:
pub fn ping(dest: ipv4::Addr) -> Result<(), String> // called as: ping(ipv4::Addr([8, 8, 8, 8])).unwrap();
Finding the default network interface through WMI
Making our own ping: Part 7
Let's set aside our
supproject for a while.
Don't get me wrong - it's a perfectly fine project, and, were we simply rewriting “ping” for Windows in Rust, we could...
Binding C APIs with variable-length structs and UTF-16
Making our own ping: Part 8
Okay, I lied.
I'm deciding - right this instant - that using wmic is cheating too. Oh, it was fair game when we were learning about Windows, but we're past that now.
Consuming Ethernet frames with the nom crate
Making our own ping: Part 9
Now that we've found the best way to find the “default network interface”… what can we do with that interface?
Well, listen for network traffic of course!
Rust 2020: Funding
Blog posts that praise Rust are many but funding is generally in short supply.
If even a small percentage of the money Rust saves companies was put back into the ecosystem it would...
Improving error handling - panics vs. proper errors
Making our own ping: Part 10
Before we move on to parsing more of our raw packets, I want to take some time to improve our error handling strategy.
ersatzcodebase contains a mix of
Parsing IPv4 packets, including numbers smaller than bytes
Making our own ping: Part 11
Hello and welcome to Part 11 of this series, wherein we finally use some of the code I prototyped way back when I was planning this series.
Where are we standing?
Let's review the...
Parsing and serializing ICMP packets with cookie-factory.
Making our own ping: Part 12
In the last part, we've finally parsed some IPv4 packets. We even found a way to filter only IPv4 packets that contain ICMP packets.
There's one thing we haven't done though, and...
Crafting ARP packets to find a remote host's MAC address
Making our own ping: Part 13
Alright. ALRIGHT. I know, we're all excited, but let's think about what we're doing again.
So we've managed to look at real network traffic and parse it completely. We've also...
Crafting ICMP-bearing IPv4 packets with the help of bitvec
Making our own ping: Part 14
So. Serializing IPv4 packets. Easy? Well, not exactly.
IPv4 was annoying to parse, because we had 3-bit integers, and 13-bit integers, and who knows what else. Serializing it is...
What's in a Linux executable?
Making our own executable packer: Part 1
Executables have been fascinating to me ever since I discovered, as a kid, that they were just files. If you renamed a
.exeto something else, you could open it in notepad! And if...
Running an executable without exec
Making our own executable packer: Part 2
In part 1, we've looked at three executables:
sample, an assembly program that prints “hi there” using the
entry_point, a C program that prints the...
Making our own executable packer: Part 3
In the last article, we found where code was hiding in our
samples/helloexecutable, by disassembling the whole file and then looking for syscalls.
Later on, we learned how to...
Making our own executable packer: Part 4
The last article, Position-independent code, was a mess. But who could blame us? We looked at the world, and found it to be a chaotic and seemingly nonsensical place. So, in order...
The simplest shared library
Making our own executable packer: Part 5
In our last article, we managed to load and execute a PIE (position-independent executable) compiled from the following code:
; in `elk/samples/hello.asm` global _start...
Loading multiple ELF objects
Making our own executable packer: Part 6
Up until now, we've been loading a single ELF file, and there wasn't much structure to how we did it: everyhing just kinda happened in
main, in no particular order.
But now that...
A half-hour to learn Rust
In order to increase fluency in a programming language, one has to read a lot of it. But how can you read a lot of it if you don't know what it means?
In this article, instead of...
Dynamic symbol resolution
Making our own executable packer: Part 7
Let's pick up where we left off: we had just taught
elkto load not only an executable, but also its dependencies, and then their dependencies as well.
We discovered that
Working with strings in Rust
There's a question that always comes up when people pick up the Rust programming language: why are there two string types? Why is there
GDB scripting and Indirect functions
Making our own executable packer: Part 9
In the last article, we cleaned up our dynamic linker a little. We even implemented the
But it's still pretty far away from running real-world applications....
Safer memory-mapped structures
Making our own executable packer: Part 10
Welcome back to the “Making our own executable packer” series, where digressions are our bread and butter.
Last time, we implemented indirect functions in a no-libc C...
More ELF relocations
Making our own executable packer: Part 11
In our last installment of “Making our own executable packer”, we did some code cleanups. We got rid of a bunch of
unsafecode, and found a way to represent...
A no_std Rust binary
Making our own executable packer: Part 12
In Part 11, we spent some time clarifying mechanisms we had previously glossed over: how variables and functions from other ELF objects were accessed at runtime.
We saw that doing...
Making our own executable packer: Part 13
Welcome back and thanks for joining us for the reads notes… the thirteenth installment of our series on ELF files, what they are, what they can do, what does the dynamic...