XLA File Documentation


Summary

An XLA (Microsoft Excel 97-2003 Add-In) file is a small program that extends Excel, written in the VBA macro language and packaged as a hidden BIFF8 workbook inside the OLE2/Compound File Binary container. You do not open it like a document; you load it through File › Options › Add-ins › Manage: Excel Add-ins › Browse. Its MIME type is application/vnd.ms-excel. Because an XLA contains executable macro code, load a .xla only from a source you trust; the modern replacement is XLAM.

Technical details

FeatureValue
Full nameMicrosoft Excel 97-2003 Add-In
File extension.xla
MIME typeapplication/vnd.ms-excel
Format typeLegacy add-in: BIFF8 workbook in an OLE2/CFB container
DeveloperMicrosoft
IntroducedExcel 97 era (through Excel 2003)
Superseded by.xlam (Excel 2007+, ZIP/OPC package)
ContainerOLE2 / Compound File Binary (same as .xls, .doc)
Byte orderLittle-endian
Magic numberD0 CF 11 E0 A1 B1 1A E1
Contains codeYes — embedded VBA project (executable macros)
Workbook flagIsAddin = True; workbook hidden
Adds to ExcelCustom functions (UDFs), commands, toolbars/menus
Loaded viaAdd-in manager or Excel AddIns folder
Open standardNo (proprietary; format documented in [MS-XLS])
Security riskHigh — runs VBA on load (macro malware vector)
Related extensions.xlam, .xls, .xlsm, .xll
Specificationlearn.microsoft.com/openspecs/office_file_formats/ms-xls/
File signature (magic bytes)
D0 CF 11 E0 A1 B1 1A E1

Offset 0, 8 bytes. This is the OLE2 / Compound File Binary (CFB) header, the same signature that starts .xls, .doc, .ppt and other pre-2007 Office binaries. An XLA is a normal BIFF8 workbook flagged as an add-in and hidden, stored inside this compound-file container, so it shares the wrapper rather than having a unique magic of its own. The bytes are a deliberately non-ASCII pattern (0xD0CF11E0 loosely reads as “DOCFILE”). The modern .xlam add-in is a ZIP/OPC package instead, so it starts with 50 4B 03 04 (PK).

What is an XLA file?

XLA is the legacy add-in format for Microsoft Excel, used from the Excel 97 release through Excel 2003. An add-in is not a spreadsheet you read: it is a packaged set of VBA macros, and often custom worksheet functions, menu commands or toolbars, that extends Excel itself. Once loaded, its features become available across every workbook you open, whether that is a new function you can type into a cell or a button that automates a task. Microsoft replaced XLA with XLAM in Excel 2007, the same generational move that turned .xls into .xlsx/.xlsm.

Technically an XLA is an ordinary BIFF8 Excel workbook stored in the OLE2/Compound File Binary container, the same container behind .xls and .doc, but with one internal flag set: the workbook’s IsAddin property is True, which hides its sheets and turns it into a code host rather than a document. Its logic lives in an embedded VBA project. Everything below is about that container, where the code sits inside it, how Excel loads the add-in, and why a file whose whole purpose is to run code is a genuine security surface.

The OLE2/CFB container: a file system inside a file

The Compound File Binary format, also called OLE2 structured storage, is effectively a small hierarchical file system packed into one file. It begins with the 8-byte signature D0 CF 11 E0 A1 B1 1A E1 and divides the rest into fixed-size sectors (typically 512 bytes) chained together by allocation tables, much like FAT.

CFB layout (conceptual)
  header            512 bytes, magic D0 CF 11 E0 ...
  FAT / DIFAT       sector allocation chains
  directory         tree of "storages" (folders) and "streams" (files)
    Workbook        the BIFF8 records: sheets, names, add-in flag
    _VBA_PROJECT_   storage holding the compiled VBA
      dir, modules  the macro source and p-code
  mini-FAT + heap   small streams packed into the ministream

Inside this container, named streams play the role of files and storages the role of folders. The Workbook stream holds the BIFF8 record sequence that defines the (hidden) sheets, defined names and the add-in flag. A separate _VBA_PROJECT_ storage holds the macro code. Because the container is a general structured-storage format, the same D0 CF 11 E0 magic appears on .xls, .doc, .ppt and .msi: the file type is distinguished by the streams inside, not by the outer signature.

BIFF8 records and the add-in flag

The Workbook stream is a flat sequence of BIFF8 records, each a 2-byte record type, a 2-byte length, then the data. A workbook globals substream opens with a BOF record and carries the file’s structure: the sheet directory (BOUNDSHEET records), defined names (NAME records, which is how custom worksheet functions are exposed to formulas), and the workbook options. The single detail that makes this workbook an add-in rather than a document is a window/state flag that marks it hidden and its IsAddin property true, so Excel loads it into memory without showing its sheets. This is exactly why you can toggle a workbook between the two: setting ThisWorkbook.IsAddin = False in the VBA editor and saving as .xls turns an add-in back into an ordinary, visible workbook.

The VBA project: where the executable code lives

The code that gives an add-in its purpose sits in the _VBA_PROJECT_ storage. Inside it, a dir stream describes the project and one stream per module holds the macro. Each module stream contains two things: the compressed VBA source text and the compiled p-code for a specific Office/VBA version. Excel normally executes the p-code, falling back to recompiling the source only when the p-code version does not match. This split has a real consequence for auditing: tools that read only the source can miss code, and “VBA stomping” attacks deliberately leave malicious p-code while the visible source looks benign. Module code runs on defined triggers, most importantly Workbook_Open (also written as an Auto_Open macro), which fires the moment the add-in is loaded, before you do anything with Excel.

How Excel loads an XLA add-in

An XLA is not opened by double-clicking like a spreadsheet; it is registered with Excel’s add-in manager. The supported route is File › Options › Add-ins › Manage: Excel Add-ins › Go › Browse, after which the file is copied into the user’s AddIns folder and ticked to load. On every launch Excel reads the registered add-ins, opens each hidden workbook, and runs its startup code so the functions and commands are ready. An XLA still loads in current Microsoft 365 for backward compatibility, but an add-in written against an old Excel object model can fail on modern Excel because objects or methods it calls were changed or removed. Renaming .xla to .xlam only rewrites the container; VBA that depends on removed features still needs code changes. The clean upgrade is to open the XLA in Excel and Save As “Excel Add-In (*.xlam)”.

Security: an XLA is executable code

Unlike a passive spreadsheet, an XLA exists to run VBA, so loading one executes its macros in Excel with your user privileges. That places it in the same threat class as a macro-laden .xlsm or .xlam, and it is a well-established malware delivery vector. The concrete mechanics are worth understanding.

Attack path of a malicious add-in
  1. XLA registered / dropped into AddIns and enabled
  2. Excel opens the hidden workbook on startup
  3. Workbook_Open / Auto_Open fires automatically
  4. VBA calls Shell(), WScript, or Win32 APIs via Declare
  5. arbitrary code / download runs under the user account

Because the malicious action can be attached to Workbook_Open, no further user interaction is needed once the add-in is enabled. Modern Office defends against this in layers: files carrying the Mark of the Web (an NTFS Zone.Identifier stream added to internet downloads) have their macros blocked by default, and many organisations block add-in file types at the mail or web gateway entirely. The practical rules follow from the format: load an XLA only from a source you have verified, keep the Mark-of-the-Web macro block enabled rather than overriding it for an unsolicited file, and inspect an unfamiliar add-in in the VBA editor (Alt+F11) before enabling it — bearing in mind a locked or p-code-stomped project may hide its real behaviour from that view.

Extracting and migrating the code

Because the source lives as streams in the VBA project, you can audit or migrate an add-in without running it. In the VBA editor (Alt+F11), right-clicking a module and choosing Export File writes the macro source out as a .bas module or .cls class file, which is the normal way to move an add-in’s logic into a new project or review it in a diff. To recover the workbook data instead of the code, set ThisWorkbook.IsAddin = False, unhide the sheets, and save as .xls/.xlsx. Note that a project protected with a VBA password does not stop the code from running, only from being viewed in the editor; it is a display lock, not encryption, so it is not a security guarantee.

Frequently asked questions

What is the difference between XLA and XLAM?

Both are Excel add-ins. XLA is the legacy Excel 97-2003 format: a BIFF8 workbook in the OLE2/CFB container, starting with D0 CF 11 E0. XLAM is the Excel 2007+ format: a ZIP/OPC package that starts with 50 4B 03 04 (PK). XLA still loads in current Excel, but the supported upgrade is to open it and Save As .xlam.

Why won’t my XLA add-in work in Microsoft 365?

Add-ins written for old Excel versions can call objects or methods that later Excel changed or removed, so the VBA errors at runtime. Renaming to .xlam does not fix this because it only changes the container, not the code. The macro itself has to be revised for the current object model, and you should also confirm the file’s macros are not simply being blocked by Mark-of-the-Web security.

References