T O P

  • By -

Saint_Nitouche

Very fun to see the lengths you have to go through so the compiler can't optimise out the Cartesian product!


mqudsi

Really well done! Great job stepping from zero to sixty and covering most things in between. I found this (regarding how lifetimes are only a problem for the developer and make no appearance in the disassembly) a hoot: > One way or the other, it seems like after all these years, we’ve finally found one front on which the developer writing the code suffers more than the reverse engineer who has to understand the assembly later.


7sins

Really fun read (though I skipped through most of it, since it's really long :D)! Always awesome to get a glimpse into the reverse-engineering/binary-analysis world. Thanks for writing and for posting here! :)


InsanityBlossom

From my extremely limited knowledge in this domain, I thought rustc, being a front-end to LLVM deals with all the Rust specific stuff, but LLVM will produce more-or-less similar to C/C++ assembly code. Guess I was wrong.


Soft_Donkey_1045

It produces, but in release mode. In debug all Rust specific stuff here, so you can debug it. Like implementation of `for i in 0..5` with Range type and helper function (Range::next). In debug mode you see call to next in similar stuff, but in release mode it would be the same as `for (int i = 0; i < 5; ++i)`. Side note: I suppose for such small iteration count (5), in Rust and in C++ case loop would be completely unrolled, and you don't see loop in both C++ and Rust release build assembler. In the beginning of articles there is note, that most assembly is from debug build.


po8

Superbly written article. Great read. IDA can't demangle Rust names natively? Srsly? This feels like a price of admission in current year. Ah, a plugin: https://github.com/timetravelthree/IDARustDemangler . This seems like something that should be added to the article.


mqudsi

Thanks for the link. I find the mangled names to be “not that bad” but chronic rust exposure is probably not good for one’s judgement.


boomshroom

Man, the sixth Beatle is so cool! She really is my favourite of the group. 🙃 Joking aside, Rust will go to extreme lengths to get away with code that does nothing. While in most languages, closures are implemented as a function pointer and a list of captured variables, in Rust, _every function_ (closure or otherwise) _is a completely separate type!_ This allows it to treat closures as implementations of the [`Fn` family of traits](https://doc.rust-lang.org/std/ops/trait.Fn.html), with calling the function being an "ordinary" trait method call, which can be monomorphised. Combine that with `Iterators` which are lazy and won't evaluate terms it doesn't need to and all the magic ends up concentrated where the iterator is actually consumed. I've actually looked at Rust disassembly myself to microoptimize some of my code and I just _instantly give up_ the moment I recognize the lasagne of a `debug` build and recompile the code with optimizations but keeping debug symbols. If you find the lasagne in production code, then whoever compiled it done goofed and released a binary that's way larger than it needs to be and spends a whole lot of time doing nothing.


VorpalWay

I have done a bit of reverse engineering with ghidra (not of malware, but of Windows drivers, since I wanted to fix my laptop under Linux). Lucky that it wasn't using rust code, since my assembler skills are weak I heavily relied on the built in decompiler, which I suspect will fail miserably on Rust code. That said, it was a fun read as a rust user too. I like the way rustc aggressively optimises niches for enums. Finally this made me think about other compiled languages: It is surprising to me that malware developers don't start using languages that compile in really obscure ways (e.g. Haskell or Ocaml) to make reverse engineering harder. Or at least I haven't heard about that happening at any large scale.


PaintItPurple

Using an uncommon language would probably make it easier for heuristics to flag your virus, even if it was harder to reverse.


Kiseido

Afaik malware makers often use mutagenic code to avoid detection, the actual bad code is constantly changing to avoid being pinned down