mirror of
https://github.com/thunderbrewhq/binana.git
synced 2026-03-23 06:00:15 +00:00
This commit is contained in:
parent
ac268a16c8
commit
2c2815ab0b
22 changed files with 2122 additions and 2 deletions
174
go/stringrecovery/stringrecovery.go
Normal file
174
go/stringrecovery/stringrecovery.go
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
package stringrecovery
|
||||
|
||||
import (
|
||||
"debug/macho"
|
||||
"debug/pe"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
charset_english = ` !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}~` + "`"
|
||||
lookup_table_english [256]bool
|
||||
)
|
||||
|
||||
type (
|
||||
Callback func(segment_name string, address uint64, token string)
|
||||
)
|
||||
|
||||
func init() {
|
||||
for _, c := range charset_english {
|
||||
lookup_table_english[c] = true
|
||||
}
|
||||
}
|
||||
|
||||
func recover_section(try_align bool, word_size uint64, minimum_length int, section_name string, virtual_address uint64, section_reader io.ReaderAt, callback Callback) (err error) {
|
||||
var (
|
||||
offset int64
|
||||
)
|
||||
|
||||
var (
|
||||
current_token strings.Builder
|
||||
current_token_offset int64
|
||||
)
|
||||
|
||||
for {
|
||||
var b [1]byte
|
||||
if _, err = section_reader.ReadAt(b[:], offset); err != nil {
|
||||
if err == io.EOF {
|
||||
err = nil
|
||||
break
|
||||
}
|
||||
}
|
||||
if b[0] == 0 {
|
||||
// if current_token != "", this is a 0-terminator
|
||||
// emit the token
|
||||
if current_token.Len() > 0 {
|
||||
if current_token.Len() < minimum_length {
|
||||
current_token.Reset()
|
||||
offset++
|
||||
continue
|
||||
}
|
||||
|
||||
align_offset := 0
|
||||
|
||||
if try_align {
|
||||
for i := uint64(current_token_offset); (i % word_size) != 0; i++ {
|
||||
current_token_offset++
|
||||
align_offset++
|
||||
}
|
||||
}
|
||||
|
||||
current_token_string := current_token.String()
|
||||
current_token_string = current_token_string[align_offset:]
|
||||
|
||||
callback(section_name, virtual_address+uint64(current_token_offset), current_token_string)
|
||||
current_token.Reset()
|
||||
}
|
||||
offset++
|
||||
continue
|
||||
}
|
||||
if lookup_table_english[b[0]] {
|
||||
if current_token.Len() == 0 {
|
||||
current_token_offset = offset
|
||||
}
|
||||
current_token.WriteByte(b[0])
|
||||
} else {
|
||||
// discard everything leaing up to this
|
||||
current_token.Reset()
|
||||
}
|
||||
offset++
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func recover_file_macho(word_size uint64, file *os.File, callback Callback) (err error) {
|
||||
var (
|
||||
macho_file *macho.File
|
||||
)
|
||||
macho_file, err = macho.NewFile(file)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, section := range macho_file.Sections {
|
||||
fmt.Fprintln(os.Stderr, "recovering", section.Name)
|
||||
switch section.Name {
|
||||
case "__cstring":
|
||||
if err = recover_section(false, word_size, 1, section.Name, section.Addr, section, callback); err != nil {
|
||||
return
|
||||
}
|
||||
case "__const":
|
||||
if err = recover_section(false, word_size, 4, section.Name, section.Addr, section, callback); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func recover_file_pe(file *os.File, callback Callback) (err error) {
|
||||
var (
|
||||
pe_file *pe.File
|
||||
)
|
||||
pe_file, err = pe.NewFile(file)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
image_base := uint64(0x400000)
|
||||
var word_size uint64
|
||||
|
||||
switch h := pe_file.OptionalHeader.(type) {
|
||||
case *pe.OptionalHeader32:
|
||||
word_size = 4
|
||||
image_base = uint64(h.ImageBase)
|
||||
case *pe.OptionalHeader64:
|
||||
word_size = 8
|
||||
image_base = h.ImageBase
|
||||
}
|
||||
|
||||
for _, section := range pe_file.Sections {
|
||||
fmt.Fprintln(os.Stderr, "recovering", section.Name)
|
||||
switch section.Name {
|
||||
case ".data":
|
||||
if err = recover_section(true, word_size, 4, section.Name, image_base+uint64(section.VirtualAddress), section, callback); err != nil {
|
||||
return
|
||||
}
|
||||
case ".rdata":
|
||||
if err = recover_section(true, word_size, 4, section.Name, image_base+uint64(section.VirtualAddress), section, callback); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func RecoverFile(filename string, callback Callback) (err error) {
|
||||
var file *os.File
|
||||
file, err = os.Open(filename)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var magic [4]byte
|
||||
if _, err = file.ReadAt(magic[:], 0); err != nil {
|
||||
return
|
||||
}
|
||||
magic_number := binary.LittleEndian.Uint32(magic[:])
|
||||
if magic[0] == 'M' && magic[1] == 'Z' {
|
||||
err = recover_file_pe(file, callback)
|
||||
} else if magic_number == 0xfeedface {
|
||||
err = recover_file_macho(4, file, callback)
|
||||
} else if magic_number == 0xfeedfacf {
|
||||
err = recover_file_macho(8, file, callback)
|
||||
} else if magic_number == 0xcefaedfe {
|
||||
err = recover_file_macho(4, file, callback)
|
||||
} else {
|
||||
err = errors.New("unknown file magic: " + filename)
|
||||
}
|
||||
return
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue