In this episode of the Hack the Planet Podcast:

We talk with Zach of Zachtronics, creator of some of the best video games of all time, about his philosophy of game design, the story of the creation of Exapunks, and the correct pronunciation of Shenzhen I/O.

Zachtronics –

Manuals & Zines –

Be a guest on the show! We want your hacker rants! Give us a call on the Hacker Helpline: PSTN 206-486-NARC (6272) and leave a message, or send an audio email to

Original music produced by Symbol Crash. Warning: Some explicit language and adult themes.

Rocket Surgery with Arko

In this episode of the Hack the Planet Podcast:

We talk about making hardware that can survive in space with Arko, a robotics engineer and polymath hacker who has published open-source projects for high altitude balloons and autonomous vehicles, and revitalized the North American demo scene with his board for LayerOne. Other topics include growing up around the space program, the Nullspace hackerspace in LA, the ethics of self-driving cars, and what the amateur radio hobby called Summits on the Air has to do with avionics for spacecraft.

This episode could be a great introduction to designing avionics for spacecraft, for getting into the demoscene, or serve as an excuse to buy a bunch more radio equipment. If you are looking for as many as three new expensive hobbies, this is the episode for you.


Arko’s Project Site –
Github –

Arko @ UKHAS 2013 –
UKHAS HabHub –
NullSpace –

LayerOne Demoscene Board –
Northern Dragons (demo group) –
BBC MicroBot –

Summits on the Air –

Be a guest on the show! We want your hacker rants! Give us a call on the Hacker Helpline: PSTN 206-486-NARC (6272) and leave a message, or send an audio email to

Original music produced by Symbol Crash. Warning: Some explicit language and adult themes.

Securing Hardware with Joe Fitz

In this episode of the Hack the Planet Podcast:

Joe Fitzpatrick of is the best known hardware security trainer on the planet.  We talk to him about how he retargeted his hardware security training program to a remote audience and what he’s learned about designing hacker trainings over the years. We also discuss a new hardware hacking tool that Joe built for both training and real world use: the Tigard, available on Crowd Supply. Joe has also been prototyping a PCI Express multi-tool, the Epic Erebus, and we brainstormed some ways to get into trouble with one. As usual, we discuss his backstory and some additional projects including a drone-based taco delivery service.

Be a guest on the show! We want your hacker rants! Give us a call on the Hacker Helpline: PSTN 206-486-NARC (6272) and leave a message, or send an audio email to

Original music produced by Symbol Crash. Warning: Some explicit language and adult themes.



B-Sides PDX:

Interview with Malware Unicorn

In this episode of the Hack the Planet Podcast:

We dive into reverse engineering and malware development with Malware Unicorn, red teamer and author of some of the best the malware development training on the internet. We discuss why MacOS is an interesting environment for malware, tips for building your own reverse engineering lab, and future trainings in the works. We recorded this episode before the latest training was released, but you can find Malware Unicorn’s portable executable injection study on her website linked below.


Malware Unicorn Workshops –

Xori –

Writing Bad @$$ Malware for OS X –

lena151 Tutorials –

Flare-On Challenges –

Joe Sandbox –

Universal Loader –

Be a guest on the show! We want your hacker rants! Give us a call on the Hacker Helpline: PSTN 206-486-NARC (6272) and leave a message, or send an audio email to

Original music produced by Symbol Crash. Warning: Some explicit language and adult themes.


In this episode of the Hack the Planet Podcast:

Noid is the former head of DEF CON security, founder of the LayerOne conference and the Black Lodge Research hackerspace, gunsmith, and anti-zombie technology enthusiast. We talk about the early history and social dynamics of BBS’s, the formation and growth of DEF CON, how to run a security team for unruly hackers in the middle of the desert, and why you shouldn’t go to DEF CON this year.

We also go into the formation of DC groups and the split from 2600, the formation of Black Lodge Research, and Noid’s artisanal hobbies including cooking and classic gun collecting.

Despite the advice of our guest, Hack the Planet will be attending DEF CON 29 in-person! Give us a call or drop us an email if you want to be interviewed for the show or meet up at the event!

Be a guest on the show! We want your hacker rants! Give us a call on the Hacker Helpline: PSTN 206-486-NARC (6272) and leave a message, or send an audio email to

Original music produced by Symbol Crash. Warning: Some explicit language and adult themes.

Interview with Ilja van Sprundel

In this episode of the Hack the Planet Podcast:

We are joined by a master of C code audit, Ilja van Sprundel, Director of PenTest at IOActive and prolific public speaker. We ask him how he learned to be such a bad ass, including some epic stories from the past, and go over some of his recent areas of interest including IOMMU, bootloader, and kernel vulnerabilities.

Ilja’s Links:
An Offensive Approach to Teaching Information Security (Summer School):
Netric (archive):

Things not to do when using an IOMMU:
BSD kernel vulns:
Windows drivers:
X Security:
iOS Security:
Hacking Smart Phones:

Daniel Stone, Wayland and X:


Be a guest on the show! We want your hacker rants! Give us a call on the Hacker Helpline: PSTN 206-486-NARC (6272) and leave a message, or send an audio email to

Original music produced by Symbol Crash. Warning: Some explicit language and adult themes.

Interview with Eric Michaud

In this episode of the Hack the Planet Podcast:

We do an actual ingress episode, not like the game. We discuss all manner of physical entry techniques, from doors to cars to tamper evident containers, with Eric Michaud, co-founder of TOOOL US and CEO of RiftRecon.

Can you beat the drug test? Find out in this episode! We also discuss the evolution of the US hackerspace movement from its European roots and ponder the post-COVID future of hackerspaces.

Eric’s Links:
Gone in 60 Seconds:
Lemon Caper:
Security of Urine Drug Testing Paper:
Open in 30 Seconds (talk):
Open in 30 Seconds (book):

Be a guest on the show! We want your hacker rants! Give us a call on the Hacker Helpline: PSTN 206-486-NARC (6272) and leave a message, or send an audio email to

Original music produced by Symbol Crash. Warning: Some explicit language and adult themes.

The Universal Loader for Go

As promised in the previous post, Go Assembly on the arm64, I have been working on a very special project for the past couple months, and I’m very pleased to announce the Universal Loader!

This Golang library provides a consistent interface across all platforms for loading shared libraries from memory and without using CGO. When I say “all platforms”, I mean Linux, Windows, and OSX including the new M1 Apple chip.

Until someone tells me differently, I am claiming that this is the very first loader to work on the M1, Golang or not. I haven’t tried it myself yet, but it will likely also work on any POSIX system, like BSD variants, without changes. If you try this on a new platform, let me know!

Additionally, the Linux backend of the loader does not use memfd, and I believe this is the first Golang loader to do that as well. The Linux ramdisk implementation memfd is very easy to use, but it’s also relatively easy to detect.

Consistent Interface

On all platforms, this is a basic example of how to use Universal to load a shared library from memory and call an exported symbol inside it:

Just pass in your library as a byte array, call LoadLibrary on it and give it a name, then you can Call() any exported symbol in that library with whatever arguments you want.

All you have to do differently on a different platform is load the right type of library for your platform. On OSX, you would load myLibrary.dyld, on Linux, and on Windows myLibrary.DLL.

Check out the examples/ folder in the repo and the tests for more details.

Algorithms and References

The Linux and Windows implementations are very straight-forward and based on the same basic algorithms that have been widely used for years, and I used malisal’s excellent repo as a reference, with some minor changes.

For the OSX loader, I referred heavily to MalwareUnicorn’s wonderful training, but I did have to make a few updates. For one thing, dyld is not guaranteed to be the next image in memory after the base image.

Also have to give a heartful thank you to C-Sto and lesnuages, who contributed code to the Windows and OSX loaders, respectively.

Last but not least, this library makes heavy use of our own fork of the debug library, so this would not have been possible without contributions over the years from the whole Binject crew, and it’s a perfect example of the power of the tools we’ve made.

This isn’t the first tool to come out of our work in Binject, and it definitely will not be the last.

Once you get locked into a serious m*****e collection, the tendency is to push it as far as you can.

Go Assembly on the arm64

If you have ever looked at Go’s assembly language, you were likely confused into giving up. Against all odds, I recently managed to implement some Go assembly that lets you call a cdecl function in a native library directly from Go on the new M1 Apple chip platform, which is arm64/POSIX based. My joy at never having to look at Go assembly again was short-lived, however, as several of my friends asked me to write something up to explain what I had learned about Go assembly, thus forcing me to relive this traumatic experience in some detail. So here it is friends, I hope it helps.

Why would you use Go Assembly?

Go assembly lets you define a function that you can call from Go that can use all of the low-level assembly operators available on your platform. This means you can avoid using CGO entirely, and avoid having to set up the heinous external cross-compiling toolchains that CGO requires. Go itself can assemble Go assembly on every platform without installing external tools.

What is Go Assembly?

plan9 was a particular set of design principles applied to recreating Unix at Bell Labs in the 80’s. Golang is essentially the plan9 re-implementation of C++, and the Go assembler is based directly on the plan9 assembler (notice the common thread from plan9 to Golang is Rob Pike). Much like plan9 itself, Golang at first seems confusing, but over time you start to see the method behind the madness. Everything is consistent in a way that C++ isn’t, and removing inconsistencies lets you write better code faster, once you get used to it.

This is not true of the Go assembler, however. If there is some underlying pattern that makes everything consistently understandable, I haven’t seen it. It’s best to understand upfront that you are marching into the mouth of madness and stop trying to force things to make sense. Just relax and accept that the underlying design decisions are probably beyond our ability to comprehend.

Try to remember HOW this works and don’t worry about WHY it is this way. Trust me on this. Take some deep breaths, and here we go.

Go assembly does not have a one-to-one correspondence with native assembly

The most confusing part about Go assembly is that it looks like native assembly, but it isn’t.

It renames almost all the registers

For example, on arm64, the main registers that the Arm spec calls X0-X7 are referred to as R0-R7 in Go assembly. You will have to check the Go assembler documentation for every platform you work on to see what the registers have been renamed to.

It renames some of the operators entirely

For example, on arm64, the branch-to-register-with-link operator BLR is renamed to CALL, but BL is not renamed. This means that for every operator you want to use, you will have to check and make sure that the Go version of that operator for your platform is the same operator.

It changes the order of some arguments to operators from native assembly, but not all of them

It’s not even as simple as changing the order from right-to-left to left-to-right. For many operators, such as the ones that assign to pairs of registers, the order of the first two arguments is the same as native assembly, but the order of the rest of the arguments is reversed!

So not only will you have to check that the operator names haven’t changed, you’ll also have to check to see how the order of the operands is different in Go assembly.

Go assembly is not meant for you

This is very clearly a tool meant for use mainly by developers on the Go language runtime itself. There are tons of useful Go assembly libraries inside Go, but they’re all restricted to being called only from inside the Go runtime.

Even though it’s an abstraction over native assembly, Go assembly is different for every platform anyway

The Go assemblers for different platforms have some things in common, but they’re all different and will have different register and operator renaming rules. This means that you will have to write a different version of your Go assembly function for every target platform that you want it to run on!

Be very careful, because the same instructions (like MOVD or CALL) might have the same names in Go assembly from one platform to the other, but they might have very different behavior! Go assembly is really totally different variants of Go assembly for every platform.

The only documentation you really have to work with are two long pages that describe the naming of registers and operator arguments for arm64 and ppc64. You can text-search on these pages for the native assembly operators you’re familiar with and figure out which Go assembly operator corresponds to them. For every other platform, the only documentation is short notes on the main page.

Go assembly files typically make heavy use of build constraints as file suffixes, so that the right Go assembly file will be automatically included when you build for a particular platform. For a typical function, you’ll want to target amd64, arm64, and maybe 386, resulting in three different implementations in the files myfunc_amd64.s, myfunc_arm64.s, and myfunc_386.s. This also means that you will need to look at the Go assembler documentation for three different platforms, check the register and operator renaming and also how the arguments have been re-ordered.

Nice things about Go Assembly

This is a short list, but there are a few nice things about Go assembly over native assembly.

By default, it automatically aligns to 16 bytes, same as arm64 requires. You can easily change alignment at any point inside a function with the PCALIGN instruction, and it will automatically align the whole function correctly for you.

You don’t need to monkey with the stack as much, because it handles some of this for you.

Go assembly adds a bunch of strange rules that you don’t have to deal with in native assembly

To illustrate this, let’s look at a simple arm64 function in Go assembly that you can call from Go that simply calls a native function using the C calling convention (cdecl) with no arguments. The Go assembly function takes one argument, which is the address of the native function to call.

Function Definition

Line 1 is the function definition. The good news is that the function definitions are the same for all platforms in Go assembly. They start with the TEXT statement, which says this function should be mapped into the TEXT segment, which just means that it’s executable code and not data. So far so good.

Following that, however, is the function name, which begins with the bizarre centered dot character “·“. This character is a special symbol that tells the Go assembler that this function should be exposed to Go code. It’s possible to create assembly functions without this character, but they won’t be callable from Go. I have no idea how to type this character, I have been copy-pasting it from place to place since the first Go assembly file I ever saw.

After the centered dot is the function name and the (SB) part. This is not syntax similar to function parameters in Go, this is actually part of Go assembly’s weird addressing scheme which goes SYMBOLNAME+offset(relative to register), which you’ll see more of later. Function names are always declared relative to a special make-believe register called SB for “stack base”. Functions always start at the stack base with no offset, so they’re always fn(SB), no matter how many arguments they take.

Next on Line 1, we have “,4,”. That argument to a function declaration tells the Go assembler how to set up the frame for this function call. The value 4 here means NOSPLIT, which tells the Go assembler not to add a frame preamble that lets the frame be split. The other possible values for this are described in the Go assembly documentation here, but NOSPLIT should be fine unless your function gets very large.

Finally, on Line 1, we have this “$16-8” argument. The dollar sign is meaningless. The first number is the size of this function’s frame (16 bytes) and the second number is the size of the arguments to this function, which live in the caller’s frame (8 bytes, the length of the single 64-bit pointer argument to call0). If the function is set to NOSPLIT, these values are ignored. If the function is not set to NOSPLIT, they must be correct, so I try to set them correctly in case I turn NOSPLIT off at some point. The frame size appears to include the parameters from the caller’s frame as well as the return value from the current frame, so one way of thinking about this is that the frame extends from -8 (to include the argument passed to call0) forward 16 bytes (to include the return value from call0).

Now we’re finally off the first line and we get into the actual assembly!

Parameter and Return Naming

On the next line of assembly, we see that SYMBOLNAME+offset(relative to register) format again in a reference to another make-believe register FP (for “frame pointer”). The FP register points at the base of the current stack frame, and all references to the FP register are REQUIRED to have a symbol name associated with them or it’s a compile error. Those symbols correspond to the names of the arguments being passed in.

Go assembly is left-to-right, meaning that MOV instructions copy from the left to the right. The above line of assembly is copying the value found at 0 bytes from the base of the frame (FP), which is named “addr”, to the first arm64 register (R0).

As mentioned previously, the CALL operator in arm64 Go assembly maps to the BLR (branch-with-link-to-register) operator in native arm64 assembly. This calls the function whose address we passed in as an argument and copied to R0.

On the next line, we set up the return value. Since this is on arm64, we have to read the Parameter Passing part of the arm64 ABI to learn that function parameters are passed in on the R0-R8 registers and return values are passed back with the same registers. The first return value will come back on R0, just like the first argument was on R0. To copy this value to the last 8 bytes of our 16 byte frame, we again have to use the SYMBOLNAME+offset(relative to register) syntax. We assign it the name “ret” and copy it to an offset of +8 bytes relative to the frame pointer.

The final line is a RET instruction, which returns from the function.

Passing an Argument with CALL

Well, we’ve made it this far, let’s take a look at the call1 function, which takes two arguments from Go (the pointer to call and a single argument to pass to that function).

This is very similar to call0. Please notice that we’ve increased the frame size and size of arguments for call1 by 8 bytes each, because we’re taking one more argument from Go, which will be passed to the internal function.

Now we’re going to use R0 for the first argument to pass to the internal function, and R1 to hold the address of the internal function. So on the first line, we copy the first argument from Go (named “addr”) from the base of the frame pointer to R1. On the next line, we copy the second argument from Go (named “arg1”) from an offset of +8 from the frame pointer to R0. Then we CALL the function at the address in R1, which will use the argument we set up in R0 as its first argument. Then we copy the return result from that CALL from R0 to a value named “ret” at an offset of +16 from the frame pointer and return.

If that made sense to you, I regret to inform you that you have already gone mad. My condolences, but now you can join my support group.

Other Notes

symbolname+8(SP) is referring to a different register than 8(SP)!

Similar to the make-believe registers FP and SB, there is another make-believe Go assembly register SP for “stack pointer”. While this is a real register on some platforms, on arm64, it is emulated. What’s worse is that there is another register on arm64 called SP which is not the stack pointer.

To resolve this conflict, Go assembly does something truly confusing. When the SYMBOLNAME+offset(SP) syntax is used (required when referencing the stack pointer as well, where the names are for local variables), Go assembly interprets this as meaning the “stack pointer” SP register and not the native arm64 register named SP. However, if you use just the offset(SP) syntax, it will refer to the native arm64 register instead.

GodBolt for arm64

Using this link, you can load GodBolt in arm64 mode, where you can code in C and immediately see the arm64 native assembly that the compiler generates.

Then you can go and search for each operator from the native assembly in the Go docs for the arm64 assembler and check if they have been renamed and how the operator order has changed.

In this way, it is possible to slowly convert native assembly to Go assembly. However, you will also have to remove the alignment code that the native compiler generates, because Go assembly will do this for you. You also have to replace the native assembly that references stack values with named references to the FP and SP pointers, for function arguments and local variables respectively. It’s probably best to use this method of conversion only for certain parts of native functions and to manually write the parts that reference FP and SP.


Go assembly was an attempt to make a slightly more universal style of assembly back before the invention of the modern generation of platform-independent intermediate representations like LLVM-IR. I would guess that its existence as an integral part of Go’s implementation is a throwback to Go’s plan9 origins, rather than a Good Thing.

I hope that sharing my suffering and the small bit of knowledge I’ve gained will help you in getting through whatever it was that brought you to this page in the first place… and I’m quite impressed with your tolerance for utter madness if you’ve made it this far.

Stay tuned to this channel, my next post will be what I actually made with Go assembler, and it’s a doozy! Here’s a hint, it’s the Go arm64 assembly implementations of call0 up to call6.

“I find this type of hackery distasteful.” – Rob Pike, referring to my crew

Interview with egyp7

In this episode of the Hack the Planet Podcast:

We talk red-teaming and CCDC with egyp7, volunteer for the National CCDC Red Team.

We go over war stories from CCDC Nationals, the early days of Metasploit and browser autopwn, as well as what’s been working well on professional red team engagements in the cloud era, advice on building wordlists, fun shell one-liners, and favorite offensive tools and exploits.


egyp7’s links:

WebLogic CVE-2019-2725:
Sliver C2:
Linux Exploit Suggester:
hasherazade’s PE Bear:

Be a guest on the show! We want your hacker rants! Give us a call on the Hacker Helpline: PSTN 206-486-NARC (6272) and leave a message, or send an audio email to

Original music produced by Symbol Crash. Warning: Some explicit language and adult themes.