mirror of
https://github.com/thunderbrewhq/binana.git
synced 2025-12-12 01:42:29 +00:00
feat(go): attributes can now be quoted, symbols can now optionally include a data type (type=void*)
This commit is contained in:
parent
407d29a263
commit
de5bdadc78
4 changed files with 91 additions and 12 deletions
|
|
@ -12,6 +12,7 @@ You can use the information here to get a headstart when working on the [Whoa pr
|
||||||
* [Importing symbols](#importing-symbols)
|
* [Importing symbols](#importing-symbols)
|
||||||
- [IDA](#ida)
|
- [IDA](#ida)
|
||||||
* [Importing C headers](#importing-c-headers-1)
|
* [Importing C headers](#importing-c-headers-1)
|
||||||
|
* [Importing symbols](#importing-symbols-1)
|
||||||
- [x64dbg](#x64dbg)
|
- [x64dbg](#x64dbg)
|
||||||
* [Importing database](#importing-database)
|
* [Importing database](#importing-database)
|
||||||
* [Importing types](#importing-types)
|
* [Importing types](#importing-types)
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,15 @@ func (profile *Profile) generate_symbols_idc() (err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fmt.Fprintf(output_file, " // Apply data types\n")
|
||||||
|
|
||||||
|
for _, symbol := range profile.SymbolTable.Entries {
|
||||||
|
if symbol.DataType != "" {
|
||||||
|
quoted_data_type := strconv.Quote(symbol.DataType)
|
||||||
|
address := fmt.Sprintf("0x%08X", symbol.StartAddress)
|
||||||
|
fmt.Fprintf(output_file, " apply_type(%s, %s);\n", address, quoted_data_type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Fprintf(output_file, "}\n")
|
fmt.Fprintf(output_file, "}\n")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,68 @@ func (l *loader) read_line() (line string, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parse_attributes(attribute_columns []string) (attributes map[string]string, err error) {
|
||||||
|
attributes = make(map[string]string)
|
||||||
|
var (
|
||||||
|
scanning_quoted_string bool
|
||||||
|
current_key string
|
||||||
|
current_value string
|
||||||
|
)
|
||||||
|
for _, attribute_column := range attribute_columns {
|
||||||
|
if scanning_quoted_string {
|
||||||
|
current_value += " "
|
||||||
|
current_value += attribute_column
|
||||||
|
|
||||||
|
if strings.HasSuffix(attribute_column, `"`) {
|
||||||
|
scanning_quoted_string = false
|
||||||
|
attributes[current_key], err = strconv.Unquote(current_value)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
current_key = ""
|
||||||
|
current_value = ""
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
key, value_start, found := strings.Cut(attribute_column, "=")
|
||||||
|
if !found {
|
||||||
|
err = fmt.Errorf("extraneous column: '%s'", attribute_column)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
current_key = key
|
||||||
|
|
||||||
|
if strings.HasPrefix(value_start, `"`) {
|
||||||
|
current_value = value_start
|
||||||
|
if strings.HasSuffix(value_start, `"`) {
|
||||||
|
attributes[current_key], err = strconv.Unquote(value_start)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
scanning_quoted_string = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// unquoted, we can succeed immediately
|
||||||
|
attributes[current_key] = value_start
|
||||||
|
current_value = ""
|
||||||
|
current_key = ""
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if scanning_quoted_string {
|
||||||
|
err = fmt.Errorf("line ends in the middle of a quoted attribute --> \"%s", current_value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (l *loader) parse_line(line string) (err error) {
|
func (l *loader) parse_line(line string) (err error) {
|
||||||
// trim extraneous whitespace
|
// trim extraneous whitespace
|
||||||
line = strings.Trim(line, " \t")
|
line = strings.Trim(line, " \t")
|
||||||
|
|
@ -89,18 +151,22 @@ func (l *loader) parse_line(line string) (err error) {
|
||||||
|
|
||||||
// build attributes
|
// build attributes
|
||||||
if num_semantic_columns > 3 {
|
if num_semantic_columns > 3 {
|
||||||
for _, column := range columns[3:] {
|
extra_columns := columns[3:num_semantic_columns]
|
||||||
key, value, found := strings.Cut(column, "=")
|
|
||||||
if found {
|
var attributes map[string]string
|
||||||
switch key {
|
attributes, err = parse_attributes(extra_columns)
|
||||||
case "end":
|
if err != nil {
|
||||||
entry.EndAddress, err = strconv.ParseUint(value, 16, 64)
|
return fmt.Errorf("symfile: (*loader).parse_line: line %d: error parsing attribute: '%s'", l.line_number, err)
|
||||||
if err != nil {
|
}
|
||||||
return
|
|
||||||
}
|
if data_type, found := attributes["type"]; found {
|
||||||
default:
|
entry.DataType = data_type
|
||||||
return fmt.Errorf("symfile: (*loader).parse_line: line %d: unknown attribute '%s'", l.line_number, key)
|
}
|
||||||
}
|
|
||||||
|
if end_address, found := attributes["end"]; found {
|
||||||
|
entry.EndAddress, err = strconv.ParseUint(end_address, 16, 64)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,9 @@ type Entry struct {
|
||||||
// Attributes
|
// Attributes
|
||||||
// end=AABBCCEEDD
|
// end=AABBCCEEDD
|
||||||
EndAddress uint64
|
EndAddress uint64
|
||||||
|
// type=void*
|
||||||
|
// The C syntax type of the data
|
||||||
|
DataType string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Table interface {
|
type Table interface {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue