mirror of
https://github.com/thunderbrewhq/binana.git
synced 2026-05-03 05:03:50 +00:00
feat(build): implement Clangd support && add lua symbols
This commit is contained in:
parent
6163593844
commit
e79ee08905
78 changed files with 399 additions and 5445 deletions
|
|
@ -18,12 +18,14 @@ var query_cmd = cobra.Command{
|
|||
|
||||
func init() {
|
||||
f := query_cmd.Flags()
|
||||
f.Bool("regex", false, "use regex to for matching token names")
|
||||
f.Uint32("min-build", 0, "the minimum build to return tokens for")
|
||||
f.Uint32("max-build", math.MaxUint32, "the maximum build to return tokens for")
|
||||
f.StringSlice("program", nil, "a list of programs to return tokens for")
|
||||
f.StringSlice("os", nil, "a list of kernel names to return tokens for (windows, darwin, linux)")
|
||||
f.StringSlice("arch", nil, "a list of CPU architectures to return tokens for (ppc, 386, amd64)")
|
||||
f.String("present", "normal", "control the way tokens are presented to console (normal, name-only)")
|
||||
f.Bool("quote", false, "quote strings before presenting")
|
||||
root.RootCmd.AddCommand(&query_cmd)
|
||||
}
|
||||
|
||||
|
|
@ -34,6 +36,10 @@ func run_query_cmd(cmd *cobra.Command, args []string) {
|
|||
err error
|
||||
presentation_mode string
|
||||
)
|
||||
params.RegEx, err = f.GetBool("regex")
|
||||
if err != nil {
|
||||
app.Fatal(err)
|
||||
}
|
||||
params.MinBuild, err = f.GetUint32("min-build")
|
||||
if err != nil {
|
||||
app.Fatal(err)
|
||||
|
|
@ -58,11 +64,17 @@ func run_query_cmd(cmd *cobra.Command, args []string) {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
params.Quote, err = f.GetBool("quote")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch presentation_mode {
|
||||
case "normal":
|
||||
params.Present = util.PresentQueryNormal
|
||||
case "name-only":
|
||||
params.Present = util.PresentQueryNameOnly
|
||||
case "sample-name":
|
||||
params.Present = util.PresentQuerySampleName
|
||||
default:
|
||||
cmd.Help()
|
||||
return
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"os"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
"github.com/parquet-go/parquet-go"
|
||||
"github.com/thunderbrewhq/binana/go/app"
|
||||
|
|
@ -17,11 +18,14 @@ type QueryPresentationMode uint8
|
|||
const (
|
||||
PresentQueryNormal QueryPresentationMode = iota
|
||||
PresentQueryNameOnly
|
||||
PresentQuerySampleName
|
||||
)
|
||||
|
||||
type QueryParams struct {
|
||||
//
|
||||
Present QueryPresentationMode
|
||||
// If true, presents the quoted version of the token name
|
||||
Quote bool
|
||||
// Match pattern for profile
|
||||
Profile string
|
||||
// Possible values for Program
|
||||
|
|
@ -35,6 +39,8 @@ type QueryParams struct {
|
|||
MaxBuild uint32
|
||||
// Regular expression for tokens (symbols/type information)
|
||||
Token string
|
||||
// If true, Token is a POSIX regular expression
|
||||
RegEx bool
|
||||
}
|
||||
|
||||
type token_query struct {
|
||||
|
|
@ -43,11 +49,47 @@ type token_query struct {
|
|||
token_regexp *regexp.Regexp
|
||||
}
|
||||
|
||||
func format_sample_name(sample db.Sample) (name string) {
|
||||
var ext string
|
||||
switch sample.MimeType {
|
||||
case "application/x-ms-pdb":
|
||||
ext = "pdb"
|
||||
case "application/vnd.microsoft.portable-executable":
|
||||
ext = "exe"
|
||||
case "application/x-executable":
|
||||
ext = "elf"
|
||||
case "application/x-mach-binary":
|
||||
ext = "macho"
|
||||
default:
|
||||
ext = "bin"
|
||||
}
|
||||
name = fmt.Sprintf("%s-%s-%d-%s-%s.%s", sample.Program, sample.Version, sample.Build, sample.OS, sample.Arch, ext)
|
||||
return
|
||||
}
|
||||
|
||||
func (token_query *token_query) present_token(token *db.Token) {
|
||||
sample, ok := token_query.sample_database[token.Source]
|
||||
if !ok {
|
||||
panic(token.Source)
|
||||
}
|
||||
name_wrap := func(s string) string {
|
||||
return s
|
||||
}
|
||||
if token_query.params.Quote {
|
||||
name_wrap = strconv.Quote
|
||||
}
|
||||
if token_query.params.Present == PresentQueryNameOnly {
|
||||
for _, name := range token.Names {
|
||||
if token_query.token_regexp.MatchString(name.Name) {
|
||||
fmt.Println(name.Name)
|
||||
fmt.Println(name_wrap(name.Name))
|
||||
}
|
||||
}
|
||||
return
|
||||
} else if token_query.params.Present == PresentQuerySampleName {
|
||||
sample_name := format_sample_name(sample)
|
||||
for _, name := range token.Names {
|
||||
if token_query.token_regexp.MatchString(name.Name) {
|
||||
fmt.Println(sample_name, name_wrap(name.Name))
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
@ -65,7 +107,7 @@ func (token_query *token_query) present_token(token *db.Token) {
|
|||
default:
|
||||
return
|
||||
}
|
||||
fmt.Printf("%s in sample: '%s' section: '%s'", kind_name, token.Source[:8], token.Section)
|
||||
fmt.Printf("%s in sample: ('%s', %s) section: '%s'", kind_name, token.Source[:8], format_sample_name(sample), token.Section)
|
||||
if token.Offset != "" {
|
||||
fmt.Printf(" at %s", token.Offset)
|
||||
}
|
||||
|
|
@ -88,7 +130,7 @@ func (token_query *token_query) present_token(token *db.Token) {
|
|||
panic(name.Kind)
|
||||
}
|
||||
|
||||
fmt.Printf("%s '%s'\n", name_kind_name, name.Name)
|
||||
fmt.Printf("%s: %s\n", name_kind_name, name_wrap(name.Name))
|
||||
}
|
||||
|
||||
fmt.Printf("--\n\n")
|
||||
|
|
@ -159,7 +201,11 @@ func (token_query *token_query) load_sample_database() (err error) {
|
|||
func Query(params *QueryParams) {
|
||||
var token_query token_query
|
||||
token_query.params = params
|
||||
token_query.token_regexp = regexp.MustCompilePOSIX(token_query.params.Token)
|
||||
if params.RegEx {
|
||||
token_query.token_regexp = regexp.MustCompilePOSIX(token_query.params.Token)
|
||||
} else {
|
||||
token_query.token_regexp = regexp.MustCompilePOSIX(regexp.QuoteMeta(params.Token))
|
||||
}
|
||||
|
||||
if err := token_query.load_sample_database(); err != nil {
|
||||
app.Fatal(err)
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ type Sample struct {
|
|||
// Possible sample types include:
|
||||
// * (Windows .exe) application/vnd.microsoft.portable-executable
|
||||
// * (Mach-O binary) application/x-mach-binary
|
||||
// * (Linux binary) application/x-elf
|
||||
// * (Linux binary) application/x-executable
|
||||
MimeType string `json:"mimetype" parquet:"mimetype,dict"`
|
||||
|
||||
// This is the code that signifies which program the sample is a build of.
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ func compile_ghidra_artifacts(profile *Profile, params *CompileArtifactsParams)
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = profile.Symbols.WriteTo(symbol_file)
|
||||
symbol_file.Close()
|
||||
return
|
||||
|
|
|
|||
|
|
@ -34,8 +34,12 @@ func parse_attributes(attribute_columns []string) (attributes map[string]string,
|
|||
}
|
||||
key, value_start, found := strings.Cut(attribute_column, "=")
|
||||
if !found {
|
||||
err = fmt.Errorf("extraneous column: '%s'", attribute_column)
|
||||
return
|
||||
// err = fmt.Errorf("extraneous column: '%s'", attribute_column)
|
||||
// return
|
||||
attributes[attribute_column] = ""
|
||||
current_key = ""
|
||||
current_value = ""
|
||||
continue
|
||||
}
|
||||
|
||||
current_key = key
|
||||
|
|
@ -146,6 +150,9 @@ func (symbol *Symbol) Parse(line string) (err error) {
|
|||
return
|
||||
}
|
||||
}
|
||||
if _, found := attributes["auto"]; found {
|
||||
symbol.Auto = true
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ type Symbol struct {
|
|||
// type=void*
|
||||
// The C syntax type of the data
|
||||
DataType string
|
||||
// auto
|
||||
// If present, this is an autoanalysis symbol and doesn't need to be imported
|
||||
Auto bool
|
||||
}
|
||||
|
||||
func (entry *Symbol) String() string {
|
||||
|
|
@ -66,6 +69,12 @@ func (entry *Symbol) WriteTo(w io.Writer) (n int64, err error) {
|
|||
}
|
||||
n += int64(b)
|
||||
}
|
||||
if entry.Auto {
|
||||
b, err = fmt.Fprint(w, " auto")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if entry.Comment != "" {
|
||||
b, err = fmt.Fprintf(w, " ; %s", entry.Comment)
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue