Gui-Yom / hlbc

Hashlink bytecode disassembler, analyzer, decompiler and assembler.
https://gui-yom.github.io/hlbc/
MIT License
55 stars 9 forks source link

.hdll decompilation doesn't work #3

Closed Vanello1908 closed 8 months ago

Vanello1908 commented 8 months ago

I want to decompile dead cells source code, but when I write .\hlbc.exe '.\Dead Cells\discord.hdll', I get Error: Invalid magic bytes (expected [72, 76, 66], found [77, 90, 144]). The same with ui.hdll Error: Invalid magic bytes (expected [72, 76, 66], found [77, 90, 144])

Gui-Yom commented 8 months ago

hlbc is not for decompiling native code contained in .hdll files. You should launch hlbc-gui and then load hlboot.dat or whatever the bytecode file is named.

N3rdL0rd commented 3 months ago

hlboot.dat isn't included as a separate file in Dead Cells... but it is embedded in the main executable. Here's a small Python script I wrote to extract it:

import warnings
import os

MAGIC_HEADER = b"\x48\x4C\x42" # "HLB" for hashlink bytecode
END_PADDING = b"\x58\x50\x41\x44\x44\x49\x4e\x47\x50\x41\x44\x44\x49\x4e\x47\x58" # "XPADDINGPADDINGX"

# region Configuration
OUTPUT = "boot.dat"       # Output filename
OUTPUT_IN_GAMEDIR = False # Save output in the original game dir?
###### CHANGEME #####
EXE_PATH = "D:\SteamLibrary\steamapps\common\Dead Cells\deadcells.exe"
GAME_PATH = "D:\SteamLibrary\steamapps\common\Dead Cells"
# endregion

def extract_bytecode():
    with open(EXE_PATH, "rb") as f:
        exe_data = f.read()
    hlb_start = exe_data.find(MAGIC_HEADER)
    if hlb_start == -1:
        raise ValueError("Hashlink bytecode not found in executable.")
    hlb_data = exe_data[hlb_start:]
    hlb_end = hlb_data.find(END_PADDING)
    if hlb_end == -1:
        warnings.warn("End padding not found in hashlink bytecode.")
        hlb_end = len(hlb_data)
    hlb_data = hlb_data[:hlb_end]
    return hlb_data

if __name__ == "__main__":
    hlb_data = extract_bytecode()
    with open(OUTPUT, "wb") as f:
        f.write(hlb_data)
    if OUTPUT_IN_GAMEDIR:
        with open(os.path.join(GAME_PATH, OUTPUT), "wb") as f:
            f.write(hlb_data)
    print("Hashlink bytecode extracted and saved to \"{}\".".format(OUTPUT))

.hdll files can be partially decompiled with IDA or Ghidra just like any other .dll, but the PDB files are only included with alpha releases, which you can opt-in to from Steam.

Gui-Yom commented 3 months ago

I figure it would not be that difficult to make hlbc load bytecode hidden inside another file. I'll implement that scan for HLB.