feat(go): profiles are now configured by an info.json file

This commit is contained in:
phaneron 2024-11-27 01:55:46 -05:00
parent e591b8b17d
commit 9053d61b6b
13 changed files with 222 additions and 111 deletions

15
go/profile/generate.go Normal file
View file

@ -0,0 +1,15 @@
package profile
func (profile *Profile) Generate(compress_db bool) (err error) {
if err = profile.CreateIDAFiles(); err != nil {
return
}
if profile.Info.OS == "windows" {
if err = profile.CreateX64dbgFiles(compress_db); err != nil {
return
}
}
return
}

View file

@ -85,8 +85,19 @@ func (profile *Profile) generate_symbols_idc() (err error) {
b.P("static import_symbols() {")
b.T(1)
b.P("// Set/create names")
name_instances := make(map[string]int)
for _, symbol := range profile.SymbolTable.Entries {
quoted_name := strconv.Quote(symbol.Name)
name := symbol.Name
instances := name_instances[name]
name_instances[name] = instances + 1
if instances != 0 {
name = fmt.Sprintf("%s@%d", name, instances+1)
}
quoted_name := strconv.Quote(name)
address := fmt.Sprintf("0x%08X", symbol.StartAddress)
b.P("set_name(%s, %s);", address, quoted_name)
}
@ -133,11 +144,11 @@ func (profile *Profile) generate_symbols_idc() (err error) {
for _, function_symbol := range profile.SymbolTable.Entries {
if function_symbol.Kind == symfile.Function {
address := fmt.Sprintf("0x%08X", function_symbol.StartAddress)
b.P("set_func_start(%s, %s);", address, address)
if function_symbol.EndAddress != 0 {
end_address := fmt.Sprintf("0x%08X", function_symbol.EndAddress)
b.P("set_func_end(%s, %s);", address, end_address)
}
// b.P("set_func_start(%s, %s);", address, address)
// if function_symbol.EndAddress != 0 {
// end_address := fmt.Sprintf("0x%08X", function_symbol.EndAddress)
// b.P("set_func_end(%s, %s);", address, end_address)
// }
if function_symbol.Comment != "" {
b.P("set_func_cmt(%s, %s, 0);", address, strconv.Quote(function_symbol.Comment))
}

72
go/profile/info.go Normal file
View file

@ -0,0 +1,72 @@
package profile
import (
"encoding/json"
"fmt"
"os"
"slices"
"strconv"
)
var (
valid_os = []string{
"windows",
"darwin",
"linux",
}
valid_arch = []string{
"386",
"amd64",
"ppc",
}
)
type info_schema struct {
OS string `json:"os"`
Arch string `json:"arch"`
ModuleName string `json:"module_name"`
ModuleBase string `json:"module_base"`
}
type Info struct {
OS string
Arch string
ModuleName string
ModuleBase uint64
}
func read_info(filename string, info *Info) (err error) {
var b []byte
b, err = os.ReadFile(filename)
if err != nil {
return
}
var is info_schema
err = json.Unmarshal(b, &is)
if err != nil {
return
}
if !slices.Contains(valid_os, is.OS) {
err = fmt.Errorf("profile: invalid os '%s'", is.OS)
return
}
if !slices.Contains(valid_arch, is.Arch) {
err = fmt.Errorf("profile: invalid arch '%s'", is.Arch)
return
}
info.ModuleName = is.ModuleName
info.OS = is.OS
info.Arch = is.Arch
info.ModuleBase, err = strconv.ParseUint(is.ModuleBase, 16, 64)
if err != nil {
return
}
return
}

View file

@ -10,6 +10,7 @@ import (
)
type Profile struct {
Info Info
Directory string
SymbolTable *symfile.InMemoryTable
}
@ -29,6 +30,11 @@ func Open(profile_directory string) (profile *Profile, err error) {
fmt.Println("Opening profile", profile_directory)
profile = new(Profile)
if err = read_info(filepath.Join(profile_directory, "info.json"), &profile.Info); err != nil {
return
}
profile.Directory = profile_directory
path_to_symbols_file := filepath.Join(profile_directory, "symbol", "main.sym")

View file

@ -1,7 +1,7 @@
package profile
func (profile *Profile) CreateX64dbgFiles(module_name string, base_address uint64) (err error) {
if err = profile.generate_x64dbg_database(module_name, base_address); err != nil {
func (profile *Profile) CreateX64dbgFiles(compress_db bool) (err error) {
if err = profile.generate_x64dbg_database(compress_db); err != nil {
return
}

View file

@ -12,8 +12,14 @@ func hex_address(u uint64) string {
return fmt.Sprintf("0x%x", u)
}
func (profile *Profile) generate_x64dbg_database(module_name string, base_address uint64) (err error) {
func (profile *Profile) generate_x64dbg_database(compress bool) (err error) {
// Convert symbol table into x64dbg database
is_64bit := profile.Info.Arch == "amd64"
module_name := profile.Info.ModuleName
base_address := profile.Info.ModuleBase
var dd x64dbg.Database
for _, entry := range profile.SymbolTable.Entries {
@ -54,9 +60,14 @@ func (profile *Profile) generate_x64dbg_database(module_name string, base_addres
}
}
filename := "game.dd32"
if is_64bit {
filename = "game.dd64"
}
// save database
dd_path := filepath.Join(profile.Directory, "x32dbg", "game.dd32")
if err = x64dbg.SaveDatabase(dd_path, &dd); err != nil {
dd_path := filepath.Join(profile.Directory, "x64dbg", filename)
if err = x64dbg.SaveDatabase(dd_path, &dd, compress); err != nil {
return
}

View file

@ -101,7 +101,7 @@ loop:
func (profile *Profile) generate_x64dbg_types() (err error) {
// parse C headers
var cc_config cc.Config
cc_config.ABI, err = cc.NewABI("windows", "386")
cc_config.ABI, err = cc.NewABI("windows", profile.Info.Arch)
if err != nil {
panic(err)
}
@ -231,7 +231,7 @@ func (profile *Profile) generate_x64dbg_types() (err error) {
x64_types.Structs = append(x64_types.Structs, x64_struct)
}
types_file_path := filepath.Join(profile.Directory, "x32dbg", "types.json")
types_file_path := filepath.Join(profile.Directory, "x64dbg", "types.json")
err = x64dbg.SortTypes(&x64_types)
if err != nil {