Go Binaries (part 1)

We’re currently working on making Go binaries easier to understand using our ultra-fast Carbon disassembler. In the upcoming weeks we’ll be posting progress updates.

Let’s start with a basic hello world example.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
package main import "fmt" func main() { fmt.Println("Hello, World!") }
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

Without additional logic, functions name are not available.

We can see the referenced string, although it is not null-terminated, so that we don’t know its length.

The ‘main.main’ function is not treated as a function and even if we define it as such by pressing ‘P’, the decompiled result is hardly intelligible.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
void __stdcall sub_47D7B0(void)
{
uint32_t *puVar1;
int32_t in_FS_OFFSET;
undefined32 uStack8;
undefined32 uStack4;
while (puVar1 = (uint32_t *)(**(int32_t **)(in_FS_OFFSET + 0x14) + 8),
*(BADSPACEBASE **)0x10 < (undefined *)*puVar1 ||
(undefined *)*(BADSPACEBASE **)0x10 == (undefined *)*puVar1) {
uStack4 = 0x47D823;
sub_446900();
}
uStack8 = 0x491320;
uStack4 = 0x4BC178;
sub_478270(0x4BCEC0, *(undefined32 *)0x532A8C, &uStack8, 1, 1);
return;
}
void __stdcall sub_47D7B0(void) { uint32_t *puVar1; int32_t in_FS_OFFSET; undefined32 uStack8; undefined32 uStack4; while (puVar1 = (uint32_t *)(**(int32_t **)(in_FS_OFFSET + 0x14) + 8), *(BADSPACEBASE **)0x10 < (undefined *)*puVar1 || (undefined *)*(BADSPACEBASE **)0x10 == (undefined *)*puVar1) { uStack4 = 0x47D823; sub_446900(); } uStack8 = 0x491320; uStack4 = 0x4BC178; sub_478270(0x4BCEC0, *(undefined32 *)0x532A8C, &uStack8, 1, 1); return; }
void __stdcall sub_47D7B0(void)
{
    uint32_t *puVar1;
    int32_t in_FS_OFFSET;
    undefined32 uStack8;
    undefined32 uStack4;
    
    while (puVar1 = (uint32_t *)(**(int32_t **)(in_FS_OFFSET + 0x14) + 8),
          *(BADSPACEBASE **)0x10 < (undefined *)*puVar1 ||
          (undefined *)*(BADSPACEBASE **)0x10 == (undefined *)*puVar1) {
        uStack4 = 0x47D823;
        sub_446900();
    }
    uStack8 = 0x491320;
    uStack4 = 0x4BC178;
    sub_478270(0x4BCEC0, *(undefined32 *)0x532A8C, &uStack8, 1, 1);
    return;
}

So the first step is recognizing functions and retrieving their names.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
void __stdcall main.main(void)
{
uint32_t *puVar1;
int32_t in_FS_OFFSET;
undefined32 uStack8;
undefined *puStack4;
while (puVar1 = (uint32_t *)(**(int32_t **)(in_FS_OFFSET + 0x14) + 8),
*(BADSPACEBASE **)0x10 < (undefined *)*puVar1 ||
(undefined *)*(BADSPACEBASE **)0x10 == (undefined *)*puVar1) {
puStack4 = &main.main;
runtime.morestack_noctxt();
}
uStack8 = 0x491320;
puStack4 = (undefined *)0x4BC178;
fmt.Fprintln(0x4BCEC0, *(undefined32 *)0x532A8C, &uStack8, 1, 1);
return;
void __stdcall main.main(void) { uint32_t *puVar1; int32_t in_FS_OFFSET; undefined32 uStack8; undefined *puStack4; while (puVar1 = (uint32_t *)(**(int32_t **)(in_FS_OFFSET + 0x14) + 8), *(BADSPACEBASE **)0x10 < (undefined *)*puVar1 || (undefined *)*(BADSPACEBASE **)0x10 == (undefined *)*puVar1) { puStack4 = &main.main; runtime.morestack_noctxt(); } uStack8 = 0x491320; puStack4 = (undefined *)0x4BC178; fmt.Fprintln(0x4BCEC0, *(undefined32 *)0x532A8C, &uStack8, 1, 1); return;
void __stdcall main.main(void)
{
    uint32_t *puVar1;
    int32_t in_FS_OFFSET;
    undefined32 uStack8;
    undefined *puStack4;
    
    while (puVar1 = (uint32_t *)(**(int32_t **)(in_FS_OFFSET + 0x14) + 8),
          *(BADSPACEBASE **)0x10 < (undefined *)*puVar1 ||
          (undefined *)*(BADSPACEBASE **)0x10 == (undefined *)*puVar1) {
        puStack4 = &main.main;
        runtime.morestack_noctxt();
    }
    uStack8 = 0x491320;
    puStack4 = (undefined *)0x4BC178;
    fmt.Fprintln(0x4BCEC0, *(undefined32 *)0x532A8C, &uStack8, 1, 1);
    return;

While it's still not easy to read, we can grasp a bit more of its meaning.

To be continued...

Leave a Reply

Your email address will not be published. Required fields are marked *