feat(build): implement Clangd support && add lua symbols

This commit is contained in:
phaneron 2026-04-01 17:36:35 -04:00
parent 6163593844
commit e79ee08905
78 changed files with 399 additions and 5445 deletions

View file

@ -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

View file

@ -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)

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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 {