Jump to content

[PC] Broken Sword 1 (Shadow of the Templars Director's Cut) - Font editing


Go to solution Solved by Rabatini,

Recommended Posts

  • Solution

Use Mummggtool,, you can find here in the graphics topic.

You can use this quickbms script into your .exe to parse it.

 

# Executable file parsing and extraction - PE/NE/LE/ROM/ELF/XBE (script 0.3.1)
# script for QuickBMS http://quickbms.aluigi.org

print "This script dumps all the sections of the PE file.\nUse -V to view the content of all the fields."

set SIGN_ELF binary "\x7fELF"

math ImageBase = 0
math NumberOfSections = 0
math DO_LAME_PARSE_RESOURCES = 0
callfunction PARSE_EXE 1

# you need: ImageBase, NumberOfSections
if NumberOfSections > 0
    # RVA example
    #math OFFSET = 0x1234
    #print "File Offset       %OFFSET|x%"
    #callfunction file2rva 1
    #print "Virtual Address   %OFFSET|x%"
    #callfunction rva2file 1
    #print "File Offset       %OFFSET|x%"
    #example

    if DO_LAME_PARSE_RESOURCES != 0
        getarray resource_address   10 2
        log MEMORY_FILE10 0 0
    endif

    # not necessary but it's ok to don't read over the space of the section
    #sortarray 0 1   # VirtualAddress
    sortarray 2 1   # PointerToRawData
    get EXE_SIZE asize

    math MAX = 0
    for x = 0 < NumberOfSections
        getarray VirtualAddress     0 x
        getarray VirtualSize        1 x
        getarray PointerToRawData   2 x
        getarray SizeOfRawData      3 x
        getarray Name               4 x

        string NAME p= "%08x_%08x_%08x_%s.dat" VirtualAddress PointerToRawData SizeOfRawData Name
        if PointerToRawData != 0
            math TMP = x
            math TMP + 1
            if TMP < NumberOfSections
                getarray NEXT_OFFSET 2 TMP
            else
                math NEXT_OFFSET = EXE_SIZE
            endif
            if PointerToRawData u>= EXE_SIZE
                math SizeOfRawData = 0
            endif
            math TMP = PointerToRawData
            math TMP + SizeOfRawData
            if TMP u> NEXT_OFFSET
                math SizeOfRawData = NEXT_OFFSET
                math SizeOfRawData - PointerToRawData
            endif

            if SizeOfRawData > 0
                log NAME PointerToRawData SizeOfRawData
            endif
        endif

        if DO_LAME_PARSE_RESOURCES != 0
            if VirtualAddress == resource_address
                log MEMORY_FILE10 PointerToRawData SizeOfRawData
            endif
        endif

        xmath TMP "PointerToRawData + SizeOfRawData"
        if TMP u> MAX
            math MAX = TMP
        endif
    next x

    get SIZE asize
    if MAX u< SIZE
        math SIZE - MAX
        string NAME p= "LASTDATA_%08x_%08x.dat" MAX SIZE
        log NAME MAX SIZE
    endif

    if DO_LAME_PARSE_RESOURCES != 0
        get SIZE asize MEMORY_FILE10
        if SIZE > 0
            callfunction LAME_PARSE_RESOURCES
        endif
    endif
endif



startfunction PARSE_EXE
    get memsize asize
    goto 0

    getdstring MAGIC2 2
    goto 0
    getdstring MAGIC4 4
    goto 0

    if MAGIC2 == "MZ"

        #typedef struct _IMAGE_DOS_HEADER {
        WORD e_magic;
        WORD e_cblp;
        WORD e_cp;
        WORD e_crlc;
        WORD e_cparhdr;
        WORD e_minalloc;
        WORD e_maxalloc;
        WORD e_ss;
        WORD e_sp;
        WORD e_csum;
        WORD e_ip;
        WORD e_cs;
        WORD e_lfarlc;
        WORD e_ovno;
        WORD e_res[4];
        WORD e_oemid;
        WORD e_oeminfo;
        WORD e_res2[10];
        LONG e_lfanew;

        if e_lfanew != 0
            goto e_lfanew
        endif

        savepos BASE_OFF
        #DWORD Signature;
        getdstring Signature 2

        if Signature == "LX"
            set Signature string "LE"
        elif Signature == "W3"
            set Signature string "LE"
        elif Signature == "W4"
            set Signature string "LE"
        endif

        if Signature == "PE"
            math DO_LAME_PARSE_RESOURCES = 1
            get SKIP short

            #typedef struct _IMAGE_FILE_HEADER {
            WORD Machine;
            WORD NumberOfSections;
            DWORD TimeDateStamp;
            DWORD PointerToSymbolTable;
            DWORD NumberOfSymbols;
            WORD SizeOfOptionalHeader;
            WORD Characteristics;

            #typedef struct _IMAGE_OPTIONAL_HEADER / IMAGE_OPTIONAL_HEADER32 {
            WORD Magic;
            if Magic == 0x10b

                # WORD			Magic;
                  BYTE			MajorLinkerVersion;
                  BYTE			MinorLinkerVersion;
                  DWORD 		SizeOfCode;
                  DWORD 		SizeOfInitializedData;
                  DWORD 		SizeOfUninitializedData;
                  DWORD 		AddressOfEntryPoint;
                  DWORD 		BaseOfCode;
                  DWORD 		BaseOfData;
                  DWORD 		ImageBase;
                  DWORD 		SectionAlignment;
                  DWORD 		FileAlignment;
                  WORD			MajorOperatingSystemVersion;
                  WORD			MinorOperatingSystemVersion;
                  WORD			MajorImageVersion;
                  WORD			MinorImageVersion;
                  WORD			MajorSubsystemVersion;
                  WORD			MinorSubsystemVersion;
                  DWORD 		Win32VersionValue;
                  DWORD 		SizeOfImage;
                  DWORD 		SizeOfHeaders;
                  DWORD 		CheckSum;
                  WORD			Subsystem;
                  WORD			DllCharacteristics;
                  DWORD 		SizeOfStackReserve;
                  DWORD 		SizeOfStackCommit;
                  DWORD 		SizeOfHeapReserve;
                  DWORD 		SizeOfHeapCommit;
                  DWORD 		LoaderFlags;
                  DWORD 		NumberOfRvaAndSizes;

            elif Magic == 0x20b

                # WORD			Magic;
                  BYTE			MajorLinkerVersion;
                  BYTE			MinorLinkerVersion;
                  DWORD 		SizeOfCode;
                  DWORD 		SizeOfInitializedData;
                  DWORD 		SizeOfUninitializedData;
                  DWORD 		AddressOfEntryPoint;
                  DWORD 		BaseOfCode;
                  ULONGLONG		ImageBase;
                  DWORD 		SectionAlignment;
                  DWORD 		FileAlignment;
                  WORD			MajorOperatingSystemVersion;
                  WORD			MinorOperatingSystemVersion;
                  WORD			MajorImageVersion;
                  WORD			MinorImageVersion;
                  WORD			MajorSubsystemVersion;
                  WORD			MinorSubsystemVersion;
                  DWORD 		Win32VersionValue;
                  DWORD 		SizeOfImage;
                  DWORD 		SizeOfHeaders;
                  DWORD 		CheckSum;
                  WORD			Subsystem;
                  WORD			DllCharacteristics;
                  ULONGLONG		SizeOfStackReserve;
                  ULONGLONG		SizeOfStackCommit;
                  ULONGLONG		SizeOfHeapReserve;
                  ULONGLONG		SizeOfHeapCommit;
                  DWORD 		LoaderFlags;
                  DWORD 		NumberOfRvaAndSizes;

            elif Magic == 0x107

                # WORD			Magic;
                  BYTE			MajorLinkerVersion;
                  BYTE			MinorLinkerVersion;
                  DWORD 		SizeOfCode;
                  DWORD 		SizeOfInitializedData;
                  DWORD 		SizeOfUninitializedData;
                  DWORD 		AddressOfEntryPoint;
                  DWORD 		BaseOfCode;
                  DWORD 		BaseOfData;
                  DWORD 		BaseOfBss;
                  DWORD 		GprMask;
                  DWORD 		CprMask[4];
                  DWORD 		GpValue;

            else

                print "Error: unsupported PE NT magic %Magic|x%"
                cleanexit

            endif

            math IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16
            for x = 0 < IMAGE_NUMBEROF_DIRECTORY_ENTRIES
                DWORD VirtualAddress;
                DWORD Size;
                putarray 10 x VirtualAddress
            next x

            for x = 0 < NumberOfSections
                BYTE Name[8];
                DWORD VirtualSize;
                DWORD VirtualAddress;
                DWORD SizeOfRawData;
                DWORD PointerToRawData;
                DWORD PointerToRelocations;
                DWORD PointerToLinenumbers;
                WORD NumberOfRelocations;
                WORD NumberOfLinenumbers;
                DWORD Characteristics;

                putarray 0 x VirtualAddress
                if VirtualSize == 0
                    math VirtualSize = SizeOfRawData
                endif
                putarray 1 x VirtualSize
                putarray 2 x PointerToRawData
                putarray 3 x SizeOfRawData
                putarray 4 x Name
            next x

        elif Signature == "NE"

            # nestruct.h of HTE http://hte.sourceforge.net
            #uint16   magic;                    // Magic number
            byte   ver;                      // Version number
            byte   rev;                      // Revision number
            uint16   enttab;                   // Offset of Entry Table
            uint16   cbenttab;                 // Number of bytes in Entry Table
            uint32  crc;                      // Checksum of whole file
            uint16   flags;                    // Flag uint16
            uint16   autodata;                 // Automatic data segment number
            uint16   heap;                     // Initial heap allocation
            uint16   stack;                    // Initial stack allocation
            uint32  csip;                     // Initial CS:IP setting
            uint32  sssp;                     // Initial SS:SP setting
            uint16   cseg;                     // Count of file segments
            uint16   cmod;                     // Entries in Module Reference Table
            uint16   cbnrestab;                // Size of non-resident name table
            uint16   segtab;                   // Offset of Segment Table
            uint16   rsrctab;                  // Offset of Resource Table
            uint16   restab;                   // Offset of resident name table
            uint16   modtab;                   // Offset of Module Reference Table
            uint16   imptab;                   // Offset of Imported Names Table
            uint32  nrestab;                  // Offset of Non-resident Names Table
            uint16   cmovent;                  // Count of movable entries
            uint16   align;                    // Segment alignment shift count
            uint16   cres;                     // Count of resource segments
            byte   os;                       // Target Operating system
            byte   flagsothers;              // Other .EXE flags
            uint16   pretthunks;               // offset to return thunks
            uint16   psegrefbytes;             // offset to segment ref. bytes
            uint16   swaparea;                 // Minimum code swap area size
            uint16   expver;                   // Expected Windows version number

            math TMP_OFF = BASE_OFF
            math TMP_OFF + segtab
            goto TMP_OFF
            for x = 0 < cseg
                uint16 offset;
                uint16 size;
                uint16 flags;
                uint16 minalloc;

                math offset << align
                log "segment/" offset size
            next x

            math TMP_OFF = BASE_OFF
            math TMP_OFF + rsrctab
            goto TMP_OFF
            get ALIGN_SHIFT short
            # TTYPEINFO
            for
                get TYPE short
                if TYPE == 0
                    break
                endif
                get COUNT short
                get RESERVED long
                string NAME p "%d/" TYPE
                for x = 0 < COUNT
                    get OFFSET short
                    get SIZE short
                    get FLAGS short
                    get ID short
                    get HANDLE short
                    get USAGE short
                    math OFFSET << ALIGN_SHIFT
                    math SIZE   << ALIGN_SHIFT
                    log NAME OFFSET SIZE
                next x
            next

        elif Signature == "LE"

              #WORD			e32_magic;
              BYTE			e32_border;
              BYTE			e32_worder;
              DWORD 		e32_level;
              WORD			e32_cpu;
              WORD			e32_os;
              DWORD 		e32_ver;
              DWORD 		e32_mflags;
              DWORD 		e32_mpages;
              DWORD 		e32_startobj;
              DWORD 		e32_eip;
              DWORD 		e32_stackobj;
              DWORD 		e32_esp;
              DWORD 		e32_pagesize;
              DWORD 		e32_lastpagesize;
              DWORD 		e32_fixupsize;
              DWORD 		e32_fixupsum;
              DWORD 		e32_ldrsize;
              DWORD 		e32_ldrsum;
              DWORD 		e32_objtab;
              DWORD 		e32_objcnt;
              DWORD 		e32_objmap;
              DWORD 		e32_itermap;
              DWORD 		e32_rsrctab;
              DWORD 		e32_rsrccnt;
              DWORD 		e32_restab;
              DWORD 		e32_enttab;
              DWORD 		e32_dirtab;
              DWORD 		e32_dircnt;
              DWORD 		e32_fpagetab;
              DWORD 		e32_frectab;
              DWORD 		e32_impmod;
              DWORD 		e32_impmodcnt;
              DWORD 		e32_impproc;
              DWORD 		e32_pagesum;
              DWORD 		e32_datapage;
              DWORD 		e32_preload;
              DWORD 		e32_nrestab;
              DWORD 		e32_cbnrestab;
              DWORD 		e32_nressum;
              DWORD 		e32_autodata;
              DWORD 		e32_debuginfo;
              DWORD 		e32_debuglen;
              DWORD 		e32_instpreload;
              DWORD 		e32_instdemand;
              DWORD 		e32_heapsize;
              BYTE			e32_res3[12];
              DWORD 		e32_winresoff;
              DWORD 		e32_winreslen;
              WORD			e32_devid;
              WORD			e32_ddkver;

            math ImageBase = 0
            math NumberOfSections = e32_objcnt
            math TMP = e32_datapage
            for x = 0 < NumberOfSections
                u32     vsize;
                u32     base_reloc_addr;
                u32     flags;
                u32     page_map_index;
                u32     page_map_count;
                u8      name[4];

                putarray 0 x base_reloc_addr
                putarray 1 x vsize
                putarray 2 x TMP
                putarray 3 x vsize
                putarray 4 x Name

                math vsize x e32_pagesize
                math TMP + vsize
            next x

        else

            print "Error: unsupported executable type %Signature%"
            cleanexit

        endif

    elif MAGIC4 == SIGN_ELF

        u8      e_ident[16];
        getvarchr TMP_4 e_ident 4
        getvarchr TMP_5 e_ident 5
        if TMP_5 == 2
            endian big
        endif
        if TMP_4 == 1

            #u8      e_ident[16];
            u16     e_type;
            u16     e_machine;
            u32     e_version;
            u32     e_entry;
            u32     e_phoff;
            u32     e_shoff;
            u32     e_flags;
            u16     e_ehsize;
            u16     e_phentsize;
            u16     e_phnum;
            u16     e_shentsize;
            u16     e_shnum;
            u16     e_shstrndx;

            math ImageBase = 0
            math NumberOfSections = e_shnum
            goto e_shoff
            for x = 0 < NumberOfSections
                u32     sh_name;
                u32     sh_type;
                u32     sh_flags;
                u32     sh_addr;     
                u32     sh_offset;
                u32     sh_size;
                u32     sh_link;
                u32     sh_info;
                u32     sh_addralign;
                u32     sh_entsize;

                putarray 0 x sh_addr
                putarray 1 x sh_size
                putarray 2 x sh_offset
                putarray 3 x sh_size
                putarray 4 x "" # Name, don't care at the moment
            next x

        elif TMP_4 == 2

            #u8      e_ident[16];
            u16     e_type;
            u16     e_machine;
            u32     e_version;
            u64     e_entry;
            u64     e_phoff;
            u64     e_shoff;
            u32     e_flags;
            u16     e_ehsize;
            u16     e_phentsize;
            u16     e_phnum;
            u16     e_shentsize;
            u16     e_shnum;
            u16     e_shstrndx;

            math ImageBase = 0
            math NumberOfSections = e_shnum
            goto e_shoff
            for x = 0 < NumberOfSections
                u32     sh_name;
                u32     sh_type;
                u64     sh_flags;
                u64     sh_addr;
                u64     sh_offset;
                u64     sh_size;
                u32     sh_link;
                u32     sh_info;
                u64     sh_addralign;
                u64     sh_entsize;

                putarray 0 x sh_addr
                putarray 1 x sh_size
                putarray 2 x sh_offset
                putarray 3 x sh_size
                putarray 4 x "" # Name, don't care at the moment
            next x

        else

            print "Error: unsupported ELF file"
            cleanexit

        endif

    elif MAGIC4 == "XBEH"

        u32     magic_id;
        u8      signature[256];
        u32     base_address;
        u32     size_of_headers;
        u32     size_of_image;
        u32     size_of_imageheader;
        u32     timedate;
        u32     certificate_address;
        u32     number_of_sections;
        u32     section_header_address;
        u32     initialisation_flags;
        u32     entry_point;
        u32     tls_address;
        u32     pe_stack_commit;
        u32     pe_heap_reserve;
        u32     pe_heap_commit;
        u32     pe_base_address;
        u32     pe_size_of_image;
        u32     pe_checksum;
        u32     pe_timedate;
        u32     debug_pathname_address;
        u32     debug_filename_address;
        u32     debug_unicode_filename_address;
        u32     kernel_image_thunk_address;
        u32     non_kernel_import_directory_address;
        u32     number_of_library_versions;
        u32     library_versions_address;
        u32     kernel_library_version_address;
        u32     xapi_library_version_address;
        u32     logo_bitmap_address;
        u32     logo_bitmap_size;

        math ImageBase = base_address
        math NumberOfSections = number_of_sections
        math section_header_address - ImageBase
        goto section_header_address
        for x = 0 < NumberOfSections
            u32     section_flags;
            u32     virtual_address;
            u32     virtual_size;
            u32     raw_address;
            u32     raw_size;
            u32     section_name_address;
            u32     section_name_ref_count;
            u32     head_shared_page_ref_count_address;
            u32     tail_shared_page_ref_count_address;
            u8      section_digest[20];

            putarray 0 x virtual_address
            putarray 1 x virtual_size
            putarray 2 x raw_address
            putarray 3 x raw_size
            putarray 4 x "" # Name, don't care at the moment
        next x

    elif MAGIC4 == "XEX2"

        endian big
        byte magic_id[4];
        uint32 flags;
        uint32 size;
        uint32 res;
        uint32 file_header_offset;
        uint32 number_of_sections;

        for x = 0 < number_of_sections
            get Value long
        next x

        goto file_header_offset
        uint32 hdr_size;
        uint32 image_size;
        uint8  key[256];
        uint32 unk1;
        uint32 image_flags;
        uint32 load_address;
        uint8  hash1[20];
        uint32 unk2;
        uint8  hash2[20];
        uint8  unk3[16];
        uint8  loader_key[16];
        uint32 unk4;
        uint8  hash3[20];
        uint32 region;
        uint32 media_mask;
        uint32 pages;

        # not supported and not useful

    else

        print "Error: unsupported executable"
        cleanexit

    endif
endfunction

startfunction file2rva
    math RET = -1
    math DIFF = -1
    for x = 0 < NumberOfSections
        getarray VirtualAddress 0 x
        getarray VirtualSize 1 x
        getarray PointerToRawData 2 x
        getarray SizeOfRawData 3 x

        set VirtualAddress long VirtualAddress
        set VirtualSize long VirtualSize
        set PointerToRawData long PointerToRawData
        set SizeOfRawData long SizeOfRawData

        if OFFSET u>= PointerToRawData
            math TMP = PointerToRawData
            math TMP + SizeOfRawData
            if OFFSET u< TMP
                math TMP = OFFSET
                math TMP - PointerToRawData
                if TMP u< diff
                    math diff = TMP
                    math RET = x
                endif
            endif
        endif
    next x
    math OFFSET + ImageBase
    if RET >= 0
        getarray VirtualAddress 0 RET
        getarray PointerToRawData 2 RET

        set VirtualAddress long VirtualAddress
        set PointerToRawData long PointerToRawData

        math OFFSET + VirtualAddress
        math OFFSET - PointerToRawData
    endif
endfunction

startfunction rva2file
    math OFFSET - ImageBase
    math RET = -1
    math DIFF = -1
    for x = 0 < NumberOfSections
        getarray VirtualAddress 0 x
        getarray VirtualSize 1 x
        getarray PointerToRawData 2 x
        getarray SizeOfRawData 3 x

        set VirtualAddress long VirtualAddress
        set VirtualSize long VirtualSize
        set PointerToRawData long PointerToRawData
        set SizeOfRawData long SizeOfRawData

        if OFFSET u>= VirtualAddress
            math TMP = VirtualAddress
            math TMP + VirtualSize
            if OFFSET u< TMP
                math TMP = OFFSET
                math TMP - VirtualAddress
                if TMP u< diff
                    math diff = TMP
                    math RET = x
                endif
            endif
        endif
    next x
    if RET >= 0
        getarray VirtualAddress 0 RET
        getarray PointerToRawData 2 RET

        set VirtualAddress long VirtualAddress
        set PointerToRawData long PointerToRawData

        math OFFSET + PointerToRawData
        math OFFSET - VirtualAddress
    endif
endfunction

startfunction LAME_PARSE_RESOURCES
    getdstring DUMMY 0xc MEMORY_FILE10
    get ENTRIES1 short MEMORY_FILE10
    get ENTRIES2 short MEMORY_FILE10
    xmath ENTRIES "ENTRIES1 + ENTRIES2"
    for i = 0 < ENTRIES
        get DUMMY long MEMORY_FILE10
        get OFFSET long MEMORY_FILE10
        savepos TMP MEMORY_FILE10
        if OFFSET & 0x80000000
            math OFFSET & 0x7fffffff
            goto OFFSET MEMORY_FILE10
            callfunction LAME_PARSE_RESOURCES
        else
            goto OFFSET MEMORY_FILE10
            get OFFSET long MEMORY_FILE10
            get SIZE long MEMORY_FILE10
            math OFFSET + ImageBase
            callfunction rva2file 1
            log "resources/" OFFSET SIZE
        endif
        goto TMP MEMORY_FILE10
    next i
endfunction

 

  • Thanks 2
Link to comment
Share on other sites

Posted (edited)

This is "out of range" for me! I tried this program (MummGGTool), but the settings don't tell me anything...

Thank you for the effort and the time you gave me!

Edit:
I didn't give up and tried to reach the same result as Rabatini. After some time I succeeded.
I couldn't find a way to directly export/import this font, but I did find a way to search for the font!
Thank you.

Snmekobrazovky2024-05-14001825.thumb.png.12c0f46f7d09d5d683a3419d69ae72bd.png

Edited by martin2306
Link to comment
Share on other sites

  • 2 weeks later...
On 5/8/2024 at 1:21 PM, martin2306 said:

This is "out of range" for me! I tried this program (MummGGTool), but the settings don't tell me anything...

Thank you for the effort and the time you gave me!

Edit:
I didn't give up and tried to reach the same result as Rabatini. After some time I succeeded.
I couldn't find a way to directly export/import this font, but I did find a way to search for the font!
Thank you.

Snmekobrazovky2024-05-14001825.thumb.png.12c0f46f7d09d5d683a3419d69ae72bd.png

Click with right button of mouse in muggtool and save as bmp or png, edit, and them click twice with left button of mouse to import.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...