Software Engineering at CoreTech
Hi, I’m Chris 👋. I head up our Software Engineering team at CoreTech. We’re responsible for creating bespoke and highly-assured, typically low-level, capabilities across a range of platforms.
We focus on writing “good” code. Whether that’s designing a new product from the ground up, or modernising and building on a legacy codebase, we pride ourselves on not just finding the quickest way to solve problems, but the best way.
It can be hard to talk about the work that we do due to client confidentiality. We’ll focus here on how we work instead, and the sorts of drivers that get us up in the morning.
By the way, if this sounds perfect for you, have you considered joining our team?
What’s “good”?
When I say we write “good” code, this is a catch-all term for making sure that:
Everything works as expected (no surprises!)
Environmental failure is handled safely
We have the confidence to make changes
It’s easy to understand and maintain
Among other things, we place huge emphasis on designing for the future, understanding that we may not always be the ones maintaining our products. Our worst nightmare is producing shelfware. These team goals help minimise the chances of that happening!
This can often mean that, as well as spending several months designing your dream solution, you’ll find yourself leaping between platforms and languages, and writing tools and patches, in order to make the end-to-end capability a reality.
Our expertise
We develop primarily in C
, C++
and Python
. We write low-level products that typically don’t involve any user interaction and interface directly with the underlying operating system. This could be on Linux, Windows, macOS, Android, iOS, or any number of more niche platforms.
Our products typically include some form of:
Networking and secure communications
Runtime data processing and manipulation
Encryption and hashing algorithms
Configuration and runtime patching
We’ll also often be found doing a bit of reverse engineering of our own products. When we do this, we’re trying to understand exactly what the compiler and linker have done to our source, and spot any potential space savings or identify undesirable artefacts.
Tooling and the attention-to-detail mindset
Delivering robust, leak-free, fail-safe products alone requires an almost impossible level of attention to detail and understanding of language intricacies. We don’t expect everyone to be heroes ready to vanquish every beast in the here-be-dragons depths of legacy code – and hey, even heroes have off days. That’s why we always work in small teams, and make best use of our tooling.
There’s no substitute for good tooling, and we work hard to add more tools to our arsenal year-on-year. We’ve put together the following as an example of the sorts of tools and techniques we rely on every day:
Each of these acts as an insurance policy. As each tool gives us greater confidence in the quality of the product being developed, we hope to:
Increase the likelihood that unsafe and inconsistent code is caught before it’s deployed
Reduce developer burden in review, freeing them up to focus on whether the solution meets the fundamental requirements
Formalise and automatically enforce standards, including auto-formatting and linting, thereby lifting the burden from individual developers
That being said, there’s no substitute for a good whiteboard and a round table. In our specialist domain, Stack Overflow rarely helps, and we rely heavily on knowledge-sharing within the team.
Is it for me?
As a team, we are completionists. We spend a good deal of our time trying to make it hard to write bad code, and identifying the many ways that you can do just that. As a mentality, it’s about building something that could, in theory, run indefinitely if required, free of leaks or undefined behaviours.
Take for example, the following short code snippet:
char buf[10];
FILE *fp = fopen("path", "rb");
size_t bytes_read = fread(buf, sizeof(char), sizeof(buf) - 1, fp);
Among other things we should be asking ourselves:
What is this trying to achieve? Is this the best way to do that?
What are the possible return values of
fopen
andfread
? What are the ways they can fail?Is this code vulnerable to exploitation? Does it rely on undefined behaviour?
Is this code platform agnostic or will it behave differently on different architectures?
Is the code memory performant? Could it introduce memory leaks?
Is this code safely re-entrant? Is it thread-safe?
These sorts of questions don’t just apply to compiled code, and we carry out similar processes of hardening and review on all of our products.
Hopefully that gives you an insight into the team and our ways of working! And if, having read this far, you’re still interested, let me know why!
Handy links
SEI CERT Coding Standards – excellent advice on common secure coding paradigms
CWE’s common software weaknesses – an overview of CWE’s common software vulnerabilities and bad practices such as TOCTOU bugs
devdocs.io - an aggregate documentation reference site for most languages
godbolt.org - a compiler explorer to understand how different compilers and flags handle your code
And some key books we keep on our office bookshelf: