Week 12

Reversing Modern Languages

Or: where reverse engineering is going

Industry Standards

Where things are going

Challenges

  • New language abstractions
  • Standard library
  • Compiler generated code
  • Symbol mangling
  • Runtime

Some things to look for when reversing a new language

Standard Library

  • We're used to the C standard library (memcpy, printf, fopen, malloc, etc)
  • Most modern languages include a much larger standard library
    • May create lots of dead code for us to sift through
    • May be able to automatically signature the libs

Symbol Mangling

  • Even if symbols are included, the compiler might encode (mangle) included function names
    • Different signatures for overloaded functions
    • Reduce the character set
Name MS C++ SunPro C++
void h(int) ?h@@YAXH@Z __1cBh6Fi_v_

__ZN9Something6Inside6Deeper10deepMethodENSt3__16vectorINS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS7_IS9_EEEE

GoLang Introduction

Langauge constructs

Basic Syntax

  • package main: Defines the package name.
  • import "fmt": Imports the fmt package for I/O functions.
  • func main(): The main function where execution begins.
package main

import "fmt"

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

Here’s a simple Go program

Variables

  • var: Declares a variable
  • := will assign a variable with type inference
  • const: Variables can be constant
package main

import "fmt"

func main() {
    // Declare a variable
    var name string = "Alice"
    fmt.Println(name)

    // Type inference
    age := 30
    fmt.Println(age)

    // Constants
    const PI = 3.14
    fmt.Println(PI)
}

Go is statically typed, so variables have a fixed type

Control Flow

  • If-else statements
  • Switch statements
  • Looping for
package main

import "fmt"

func main() {
    age := 18
    if age >= 18 {
        fmt.Println("Adult")
    } else {
        fmt.Println("Minor")
    }
}

func main() {
    day := "Monday"
    switch day {
    case "Monday":
        fmt.Println("Start of the week")
    case "Friday":
        fmt.Println("Almost weekend")
    default:
        fmt.Println("Midweek")
    }
}

func main() {
    for i := 0; i < 5; i++ {
        fmt.Println(i)
    }
}

Go supports if-else, switch, and looping with for

Structs and Methods

  • Struct declaration
  • Method declaration
  • Comparing methods and functions
  • Struct instantiation
package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func (p Person) Greet() {
    fmt.Printf("Hello, my name is %s\n", p.Name)
}

func add(a int, b int) int {
    return a + b
}

func main() {
    p := Person{Name: "Alice", Age: 30}
    p.Greet()
}

Go supports structs and methods

Concurrency

  • Dispatch function on a separate thread
  • Communicate with go routines using channels
  • Write a message to the channel
  • Read a message from the channel
package main

import (
    "fmt"
    "time"
)

// This function sends a message to a channel after a delay.
func sendMessage(ch chan string) {
    time.Sleep(2 * time.Second) // Simulate some work with a 2-second delay
    ch <- "Hello from the goroutine!" // Send a message to the channel
}

func main() {
    // Create a channel of type string
    messageChannel := make(chan string)

    // Start the sendMessage function as a goroutine
    go sendMessage(messageChannel)

    // Wait for the message from the goroutine
    fmt.Println("Waiting for the message...")

    // Receive the message from the channel
    message := <-messageChannel // This line will block until the message is received
    fmt.Println("Received:", message)
}

For easy concurrency, go supports go routines and channels

GoLang Runtime

Case Study

What is the go runtime?

Set of libraries that support programs written in go

  • Memory management and garbage collection
  • Thread scheduler
  • Passing messages between channels
  • Standard libraries
  • Error handling

GoLang Binary

Runtime

Your Code

Go runtime is statically linked (unlike Java)

Strategies for analyzing large binaries

  • Find known symbols (if not stripped)
  • Find cross references for known
    • Strings
    • Imports (might only be used by the runtime)
  • Use dynamic analysis to narrow static analysis
    • Use strace/ltrace to see how system calls and libraries are used
    • Use GDB to quickly find important symbols
      • Get a backtrace

https://cloud.google.com/blog/topics/threat-intelligence/golang-internals-symbol-recovery/

Routines and Channels

https://cloud.google.com/blog/topics/threat-intelligence/golang-internals-symbol-recovery/

Error Handling

Reconstructing Program Semantics from Go Binaries

Lab 1

Go Example 1

Lab 2

Go Example 2

HW

Codebreaker 1-2

Week 12

By Chase Kanipe