Sunday, May 26, 2024

Using Reflection in Go

Have you ever been writing Go and needed to quickly find all the possible methods or fields you can use with a particular function?

Go's built in "reflection" is a quick way to find out. A neat metaprogramming trick. For example, the following code, when used against a particular crypto library:

import ( 
	"reflect"
	"github.com/zmap/zcrypto/tls"
)
...

func GetJa3Hash(serverHello *tls.ServerHello) string {
    byteString := make([]byte, 0)
...

Next, we can iterate over the serverHello within our function call. I mostly use this for debugging. Essentially, reflection allows us to use a program to inspect its own source code on the fly. Consider the example below. We can iterate and print all of the fields, methods, and their corresponding types accessible from serverHello.

typ := reflect.TypeOf(*serverHello)

for i := 0; i < typ.NumField(); i++ {
	field := typ.Field(i)
	fmt.Printf("Field: %s, Type: %s\n", field.Name, field.Type)
}

for i := 0; i < typ.NumMethod(); i++ {
	method := typ.Method(i)
	fmt.Printf("Method: %s\n", method.Name)
}

And... wham. Now we have a quick list of fields we can access, along with their corresponding types. For example, SessionID or HeartbeatSupported, and so on.

Field: Version, Type: tls.TLSVersion
Field: Random, Type: []uint8
Field: SessionID, Type: []uint8
Field: CipherSuite, Type: tls.CipherSuite
Field: CompressionMethod, Type: uint8
Field: OcspStapling, Type: bool
Field: TicketSupported, Type: bool
Field: SecureRenegotiation, Type: bool
Field: HeartbeatSupported, Type: bool
Field: ExtendedRandom, Type: []uint8
Field: ExtendedMasterSecret, Type: bool
Field: SignedCertificateTimestamps, Type: []tls.ParsedAndRawSCT
Field: AlpnProtocol, Type: string

"The Laws of Reflection"

No comments:

Post a Comment

Using Python To Access archive.today, July 2025

It seems like a lot of the previous software wrappers to interact with archive.today (and archive.is, archive.ph, etc) via the command-line ...