🍌bananary analysis 🍌
Find a file
2026-01-25 15:17:12 +03:00
cheatengine feat(core): CheatEngine item container coprse loaders 2026-01-17 16:00:09 +03:00
ghidra chore(binana): update files 2024-07-13 17:42:21 -04:00
go feat(binana): add check command for profiles 2025-06-04 17:40:52 -04:00
ida fix(ida): fixed export crash on IDA 9.0 2024-11-25 23:28:52 -05:00
profile/3.3.5a-windows-386 feat(profile): new funcs 2026-01-25 15:17:12 +03:00
script feat(core): CheatEngine item container coprse loaders 2026-01-17 16:00:09 +03:00
.gitattributes tidy(profile): hide generated changes in git diff 2024-12-01 11:14:42 -05:00
.gitignore feat(binana): improve documentation, add a way to import information into IDA 2024-08-03 00:45:27 -04:00
go.mod feat(binana): add check command for profiles 2025-06-04 17:40:52 -04:00
go.sum feat(binana): add check command for profiles 2025-06-04 17:40:52 -04:00
Makefile feat(core): CheatEngine lua struct generator 2026-01-15 01:10:51 +03:00
README.md update README 2026-01-17 16:40:24 +03:00

binana

This repository hosts some work related to studying the original game binaries.

You can use the information here to get a headstart when working on the Whoa project.

Dependencies (optional)

This project can be utilized immediately using files we have already generated. However, if you wish to make modifications to the C header and symbol files, it may be necessary to refresh the generated files that are based on them.

You'll need:

  • Go >= 1.22
  • git
  • Make
  • Bash shell

You can regenerate everything to include your changes with:

make dependencies
make

Header files

To make looking at the binary easier, C header files to match the original executable's memory layout are provided. They aim to be lightweight and self-contained, so that many tools can make use of them.

Symbol files

Symbol files are text files that map addresses to functions and variables/data labels.

The format is based on the one used in the stock Ghidra script ImportSymbolsScript.py:

DataLabel 00DDAA77AA l 
FunctionName 00CC00DDEE f

To improve the call stack view in x64dbg, you should append an end field to every function, with the address where this function ends and another begins (i.e. after the last instruction of the function):

FunctionName 00CC00DDEE f end=00CC00DDFF

In this repo, script/compile-symbols is used to concatenate our organized symbol files into one big file (<game version>/symbol/main.sym).

To refresh the gigantic main.sym file after changing one of the source symbol files:

script/compile-symbols <game version>

Or just

make

Debugging files

The best way to know what a particular routine does is to use a debugger.

With our x64dbg files, you can easily navigate to various functions, read the call stack, play with variables, and explore data structures.

These files are autogenerated from the C header and symbol files, using our binana tool written in Go. You can install it like so:

make dependencies

To regenerate:

make

Ghidra

Importing C headers

To import the main header file into your Ghidra project,

  1. go to File 🡒 Parse C Source....
  2. Select clib.prf as your parse configuration, and clear all source files and input paths.
  3. Add the header profile/<game version>/include/main.h to the Source files to parse combo box.
  4. Add the path to profile/<game version>/include to the Include paths combo box.
  5. Add -DGHIDRA to a new line in Parse Options.
  6. press Parse to Program.

If all goes well, Data Type Manager will now contain the data structures from the headers.

Importing symbols

To import the symbol file into your Ghidra project,

  1. go to Window 🡒 Script Manager
  2. In the table view, lookup ImportSymbolsScript.py
  3. Run the script
  4. Enter the path to profile/<game version>/symbol/main.sym

IDA

Importing C headers

To import the main header file into your IDA database,

  1. Go to Options 🡒 Compiler
  2. Add IDA to the semicolon-separated Predefined macros list.
  3. Go to File 🡒 Load file 🡒 Parse C Header file
  4. Enter the path to profile/<game version>/include/main.h

Importing symbols

To use the IDC script,

  1. Go to File 🡒 Script file...
  2. Navigate to profile/<game version>/ida/import_all.idc
  3. Wait for everything to be reanalyzed

x64dbg

For ease of debugging, we provide x64dbg databases (generated by the Go tool from symbol maps), as well as x64dbg type information (generated by the same Go tool from the C headers).

Importing database

To load the database information into x64dbg:

  1. Open x96dbg.exe or x32dbg.exe directly
  2. Load your game binary
  3. Go to File 🡒 Database 🡒 Import database
  4. Navigate to profile/<game version>/x64dbg/game.dd32.

Importing types

To load the type information JSON file:

  1. Open the binary in x32dbg.exe
  2. in the console, type: LoadTypes <full path to local binana repository>\profile\<game version>\x32dbg\types.json

How to Inspect Object Fields in Cheat Engine

How to Build the Loading Scripts

make ce-lua

For Units

  • Select a target unit (it must be of type Unit).
  • Execute the script: Load_CGUnit.lua
    (Menu: Table -> Show Cheat Table Lua Script)

For Player (your character)

For Corpses

  • Execute the script: Load_CGCorpse.lua
  • Then hover your mouse cursor over the corpse.

For Items (items in the main 16-slot backpack)

For Containers (only for equipped bags)

How to generate a C struct

To generate a C struct, open the file youre interested in, remove the Cheat Engine loading code, and add this line at the end of the file (using CGCorpse as an example):

print(CGCorpse:toCStruct())

Then run:

lua Load_CGCorpse.lua

Generating dependent structs

If you also need dependent (referenced) structs, use:

print(CGCorpse:toCStructWithDeps())

Options for toCStruct and toCStructWithDeps

  • collapsePadding — if false, unk_ fields will be grouped into arrays (default: true)
  • flattenInheritance — if true, embedded fields and parent fields will be inlined into the struct (default: false)

Examples

print(CGCorpse:toCStructWithDeps({ flattenInheritance = true }))
print(CGCorpse:toCStructWithDeps({ collapsePadding = false, flattenInheritance = true }))