Reinvent the Wheel
54 comments
·May 24, 2025boricj
nssnsjsjsjs
I'll bite! What wheel is this?
boricj
This wheel: https://github.com/boricj/ghidra-delinker-extension
It's a Ghidra extension that can export relocatable object files from any program selection. In other words, it reverses the work done by a linker.
I originally built this as part of a video game decompilation project, having rejected the matching decompilation process used by the community at large. I still needed a way to divide and conquer the problem, which is how I got the funny idea of dividing programs. That allows a particular style of decompilation project I call Ship of Theseus: reimplementing chunks of a program one piece at a time and letting the linker stitch everything back together at every step, until you've replaced all the original binary code with reimplemented source code.
It's an exquisitely deep and complex topic, chock-full of ABI tidbits and toolchains shenanigans. There's next to no literature on this and it's antithetical to anything one might learn in CS 101. The technique itself is as powerful as it is esoteric, but I like to think that any reverse-engineer can leverage it with my tooling.
In particular, resynthesizing relocations algorithmically is one of those problems subject to the Pareto principle, where getting 80% of them right is reasonably easy but whittling down the last 20% is punishingly hard. Since I refuse to manually annotate them, I've had to relentlessly improve my analyzers until they get every last corner case right. It's by far the most challenging and exacting software engineering problem I've ever tackled, one that suffers no hacks or shortcuts.
Once I got it working, I then proceeded in the name of science to commit countless crimes against computer science with it (some of those achievements are documented on my blog). Cross-delinking in particular, that is delinking an artifact to a different platform that it originates from, is particularly mind-bending ; I've had some successes with it, but I sadly currently lack the tooling to bring this to its logical conclusion: Mad Max, but with program bits instead of car parts.
Ironically, most of my users are using it for matching decompilation projects: they delink object files from an artifact, then typically launch objdiff and try to create a source file that, when compiled, generates an object file that is equivalent to the one they ripped out of the artifact. I did not expect that to happen at all since I've built this tool to specifically not do this, but I guess when everything's a nail, people will manage to wield anything as a hammer.
weaksauce
got to imagine it is this https://github.com/boricj/ghidra-delinker-extension
Archelaos
Probably what he links to on his profile page.
begueradj
One of the most important reasons to reinvent the wheel which is is not mentioned by the author is to avoid adding complexity through unnecessary dependencies.
underdeserver
100% this, and I'll add that libraries become popular because they solve an issue in many different scenarios.
That menas that almost by definition, if a library is popular, it contains huge amounts of code that just isn't relevant to your use case.
The tradeoff should be whether you can code your version quickly (assuming it's not a crypto library, never roll your own crypto), because if you can, you'll be more familiar with it and carry a smaller dependency.
jfengel
Unfortunately, if you depend on any libraries, there's a decent chance one of them depends on some support library. Possibly for just one function. And then your build tool downloads the entire Internet.
thfuran
That depends a lot on your language / build system. The easier it is to add a dependency, the more likely that is to be how they work, broadly speaking.
rjsw
A ruby application that I will soon need to use downloads 227 packages.
zzo38computer
I also agree to avoid adding complexity through unnecessary dependencies.
> if a library is popular, it contains huge amounts of code that just isn't relevant to your use case.
It is true that many libraries do contain such code, whether or not they have dependencies. For example, SQLite does not have any dependencies but does have code that is not necessarily relevant to your use. However, some programs (including SQLite) have conditional compilation; that sometimes helps, but in many cases it is not suitable, since it is still the same program and conditional compilation does not change it into an entirely different one which is more suitable for your use.
Also, I find often that programs include some features that I do not want and exclude many others, and existing programs may be difficult to change to do it. So that might be another reason to write my own, too.
bitwize
"Never roll your own crypto" usually means "never devise your own crypto algorithms". Implementing an established algorithm yourself is OK provided you can prove your implementation works correctly. And... well, as Heartbleed showed, that's hard even with established crypto libraries.
kortilla
That’s true for frameworks but not good libraries.
anyonecancode
Less "reinventing" the wheel and more "uncovering the wheel."
megadragon9
Thanks for this inspiring essay, I couldn’t agree more that “reinventing for insight” is one of the best ways to learn. I had a similar experience couple months ago when I built an entire PyTorch-style machine learning library [1] from scratch, using nothing but Python and NumPy. I started with a tiny autograd engine, then gradually created layer modules, optimizers, data loaders etc... I simply wanted to learn machine learning from first principles. Along the way I attempted to reproduce classical convnets [2] all the way to a toy GPT-2 [3] using the library I built. It definitely helped me understand how machine learning worked underneath the hood without all the fancy abstractions that PyTorch/TensorFlow provides. Kinda like reinventing the car using the wheel I reinvented :)
[1] https://github.com/workofart/ml-by-hand
[2] https://github.com/workofart/ml-by-hand/blob/main/examples/c...
[3] https://github.com/workofart/ml-by-hand/blob/main/examples/g...
Waterluvian
90% of the time it’s wrong to “reinvent the wheel.” If you chose this option dogmatically, you’d be making the right choice 90% of the time. But this also represents a below average outcome as a one-sided die would roll this choice right 90% of the time, too.
Your job as the decision-making engineer is to develop the expertise to be able to make the right choice more than 95% of the time.
almosthere
People that work at Radial, Michelin, Good Year, etc... probably are sick of hearing it.
wcfrobert
Reinventing the wheel is the best way to learn. But imo that's really the only context where you should.
I love my rabbit holes, but at work, it's often not viable to explore them given deadlines and other constraints. If you want your wheel to be used in production though, it better be a good wheel, better than the existing products.
epolanski
99% of the people that reinvent wheels at work don't know how the wheel they don't like is even made and why it has the compromises it has.
mullingitover
If you're working in a startup I hope you'll completely ignore this advice, unless the particular wheel you're reinventing is core to the product/service your startup makes. If it's not, you're likely just setting your runway on fire and crashing the plane before takeoff.
bawis
I guess it's more like an advice for personal wheels, not professional ones.
epolanski
You still want to build a startup with people that know how to build wheels, and thus have done it professionally, in oss or personal projects.
awinter-py
engage rationally with build vs buy decisions
accept that there are compatibility boundaries such that it is sometimes quicker to create a new X than locate it on the market, or that X is too expensive and it's time to pursue vertical integration
but teams who can't do build vs buy properly are kind of doomed, sentenced to endless cycles of Not Invented Here syndrome which block other work.
if you're in a meeting and someone says 'we can't launch our website until we develop a platform-native way to host websites' you're in the wrong part of the curve
Ekaros
Go ahead build your own wheel. But often it is better just to use one already made.
There is lot of complexity that mature wheels have taken into account or have had to solve and you are likely miss lot of it. Not that building your own does not help you to understand it.
Still, I wouldn't replace wheels on my car with ones I made myself from scratch... Just like I wouldn't replace reasonable complex library.
imiric
Precisely.
While sometimes reinventing the wheel is a useful exercise, as TFA lays out, this is often a symptom of a larger Not Invented Here mentality. This is generally a harmful tendency in some organizations that leads to derailing project deadlines, and misdirecting resources towards building and maintaining software that is not core to the company's mission.
So in most cases the advice to not reinvent the wheel is more helpful. Deciding to ignore it, especially within a corporate environment, should be backed by very good reasons.
turtleyacht
> Reinvent for insight. Reuse for impact.
When Primeagen was once interviewed, he built out a whole Java architecture; the interviewer asked him, "Have you heard of grep?" And that started a journey.
If it were to happen to me, feels like a full circle to go from glue and dependencies to pointers and data structures. A welcome reverie.
semiinfinitely
People advise not to "reinvent the wheel" because doing so imbues you with the ability to create new things yourself- increasing your agency and power thereby relatively decreasing theirs. Also it often comes at some expense to them if they have some claim to your time eg boss/coworker.
isaacremuant
I love how you selfishly think about your agency as if there was no team involved dealing with your "snowflake creation".
When I give this advice it usually means I don't think the output is better than the existing thing and the dependency cost is better paid in the form of integration.I probably don't think you'll really maintain your creation or think about others using it when you do.
As long as we are throwing shitty incentives around.
But on a more neutral note, it's a tradeoff with many moving parts. Different choices for different scenarios.
zero-sharp
So you ignored the context surrounding this piece of advice?
Yea, reinventing the wheel is a great way to learn. You're not going to hear an educator tell you to not reinvent the wheel.
tehnub
Yep, not reinventing the wheel is advice you should consider in a business context, not when you’re programming for fun, although I’m sure there are hordes of people giving this advice outside of the business context and perhaps that’s what OP is responding to.
I've reinvented my own wheel in a particular niche. I didn't set out to do that, but I rejected the existing state of the art as fundamentally misguided. Then, I attempted to divide-and-conquer my particular problem, something that is conventionally considered impossible.
Against all odds, I not only succeeded (mostly thanks to ignorance and stubbornness), but my wheel turns out to be unbelievably good at what it does. Possibly even world-class. After further experimentation, it also enables feats that can only be described as pure heresy with troubling ease. Time passes and some people from that niche start picking up my wheel. They all hold it wrong at the beginning because it's so alien, but once they get the hang of it they never go back.
I get bug reports and feature requests from all over the world for the oddest of use-cases and workflows. I have deep, in-depth technical discussions with brilliant people I would've never met otherwise. I've witnessed achievements done by others with my wheel beyond my wildest dreams. I discover things that keep me awake at night. I get kicks out of melting down the brains of my uninitiated coworkers and colleagues explaining what my wheel does and what I can do with it.
Don't be afraid to reinvent the wheel. You never know what crazy, wild path it might roll you down to.