2023-05-17 01:56:27 +00:00
|
|
|
# iwa-inspector
|
|
|
|
|
|
|
|
source for <https://sheetjs.com/tools/iwa-inspector>
|
|
|
|
|
|
|
|
`iwa-inspector` is a tool for inspecting iWork archives.
|
|
|
|
|
2023-07-26 00:12:12 +00:00
|
|
|
<https://oss.sheetjs.com/notes/iwa/> covers the high-level structure of files.
|
|
|
|
This inspector performs the top-level extraction of messages and parses using
|
|
|
|
extracted Protocol Buffer definitions.
|
|
|
|
|
2023-07-25 09:19:37 +00:00
|
|
|
## Usage
|
|
|
|
|
2023-07-26 00:12:12 +00:00
|
|
|
The sections are separated by a light gray horizontal line and a light gray
|
|
|
|
vertical line. Panels can be resized by click-dragging the line.
|
|
|
|
|
|
|
|
### Selecting a File
|
|
|
|
|
|
|
|
The file input element in the top-left corner of the page is limited to the IWA
|
|
|
|
file types: `.numbers`, `.key`, and `.pages`.
|
|
|
|
|
|
|
|
The site automatically fetches a sample file on load.
|
|
|
|
|
|
|
|
### Message Table
|
|
|
|
|
|
|
|
The message table is shown just below the header bar. The column headers are:
|
|
|
|
|
|
|
|
| name | description |
|
|
|
|
|:----------|:----------------------|
|
|
|
|
| `id` | Message ID |
|
|
|
|
| `type` | Numeric Message Type |
|
|
|
|
| `message` | Absolute Message Type |
|
|
|
|
| `path` | Location of Message |
|
|
|
|
|
|
|
|
The table can be sorted by clicking on the column headers.
|
|
|
|
|
|
|
|
### Searching for Messages
|
|
|
|
|
|
|
|
The search text box in the top-right corner of the page is a plaintext search
|
|
|
|
over the parsed messages. Searches will match field names, string values and
|
|
|
|
UUID fields of message type `.TSP.UUID`.
|
|
|
|
|
|
|
|
### Selecting a Message
|
2023-05-17 01:56:27 +00:00
|
|
|
|
2023-07-26 00:12:12 +00:00
|
|
|
When a row in the table is selected, the bottom-left panel will display the
|
|
|
|
Protocol Buffers definition for the message and the bottom-right panel will
|
|
|
|
display the parsed contents.
|
|
|
|
|
|
|
|
### Message Structure
|
|
|
|
|
|
|
|
The bottom-right panel shows the following information:
|
|
|
|
|
|
|
|
- "Message": parsed information following the message definition
|
|
|
|
- "Metadata": parsed information from the message metadata
|
|
|
|
- "Dependents": list of messages that list the current message as a dependency.
|
2023-05-17 01:56:27 +00:00
|
|
|
|
2023-07-25 09:19:37 +00:00
|
|
|
Clicking on a message name in the inspector will show the message definition in
|
|
|
|
the left pane. A "Return" link returns to the base message definition.
|
|
|
|
|
2023-05-17 01:56:27 +00:00
|
|
|
Clicking on a `.TSP.Reference` ID will jump to the referenced message.
|
|
|
|
|
2023-07-26 00:12:12 +00:00
|
|
|
### Exporting Data
|
|
|
|
|
2023-05-17 01:56:27 +00:00
|
|
|
Right-clicking a custom message type will show a context menu with options to
|
|
|
|
copy the raw byte representation (array of numbers) or parsed object (JSON).
|
|
|
|
|
|
|
|
## Development
|
|
|
|
|
2023-09-24 19:48:44 +00:00
|
|
|
### Website
|
|
|
|
|
2023-05-17 01:56:27 +00:00
|
|
|
`make dev` starts the dev server.
|
|
|
|
|
|
|
|
`make build` generates the static site.
|
|
|
|
|
2023-09-24 19:48:44 +00:00
|
|
|
`make init` installs dependencies.
|
|
|
|
|
|
|
|
### Protos and Messages
|
2023-07-25 09:19:37 +00:00
|
|
|
|
2023-09-24 19:48:44 +00:00
|
|
|
`make deps` requires a SIP-disabled Mac with Keynote + Numbers + Pages.
|
2023-05-17 01:56:27 +00:00
|
|
|
|
2024-09-21 00:16:46 +00:00
|
|
|
The last run was on 2024-09-20 against version 14.2 (7041.0.109)
|
|
|
|
|
|
|
|
<details><summary><b>Notes</b> (click to show)</summary>
|
|
|
|
|
|
|
|
14.2 deprecated message 0x847 (`.TSWP.UpdateDateTimeFieldCommandArchive`).
|
|
|
|
Curiously the message definition was retained in the protobuf definitions.
|
|
|
|
|
|
|
|
</details>
|
2023-09-24 06:05:06 +00:00
|
|
|
|
2023-09-24 19:48:44 +00:00
|
|
|
#### Software License Agreements
|
|
|
|
|
|
|
|
Before refreshing, each app must be launched once and the software license
|
|
|
|
agreements must be accepted.
|
|
|
|
|
2024-06-13 16:23:59 +00:00
|
|
|
In the 14.1 update, Keynote clearly states:
|
2023-09-24 19:48:44 +00:00
|
|
|
|
|
|
|
> By clicking Continue you agree to the terms of the Keynote Software License Agreement
|
|
|
|
|
|
|
|
Curiously, the Numbers "What's New in Numbers" popup does not have a similar
|
|
|
|
disclaimer. It is suspected that clicking "Continue" in Numbers and Pages serves
|
|
|
|
a similar purpose.
|
|
|
|
|
|
|
|
#### Disabling SIP
|
|
|
|
|
|
|
|
1) Enter Recovery mode:
|
|
|
|
|
|
|
|
On Intel Macs, shut down and restart while holding down Command+R keys.
|
|
|
|
|
|
|
|
On Apple Silicon Macs, shut down and restart while holding down the Touch ID.
|
|
|
|
It will display a message "Continue holding for startup options". Let go once
|
|
|
|
the message changes to "Loading startup options"
|
|
|
|
|
|
|
|
Select "Options" in the boot window and click the "Continue" button.
|
|
|
|
|
|
|
|
2) Open a terminal window (Utilities > Terminal) and run the following command:
|
|
|
|
|
|
|
|
```
|
|
|
|
csrutil disable
|
|
|
|
```
|
|
|
|
|
|
|
|
If there is no error, restart the machine.
|
|
|
|
|
|
|
|
**Apple Silicon Extra Steps**
|
|
|
|
|
|
|
|
If the command fails with a message like
|
|
|
|
|
|
|
|
```
|
|
|
|
csrutil: The OS environment does not allow changing security configuration options.
|
|
|
|
Ensure that the system was booted into Recovery OS via the standard user action.
|
|
|
|
```
|
|
|
|
|
|
|
|
3) Run the following command:
|
|
|
|
|
|
|
|
```
|
|
|
|
csrutil clear
|
|
|
|
```
|
|
|
|
|
|
|
|
4) Open the "Startup Security Utility" (in the Utilities menu)
|
|
|
|
|
|
|
|
5) Click "Security Policy..." and select "Permissive Security". Click "OK".
|
|
|
|
|
|
|
|
6) Reboot into recovery mode (explained in Step 1)
|
|
|
|
|
|
|
|
7) Open a terminal window (Utilities > Terminal) and run:
|
|
|
|
|
|
|
|
```
|
|
|
|
csrutil disable
|
|
|
|
```
|
|
|
|
|
|
|
|
**Remember to re-enable SIP after updating messages!**
|
2023-09-24 06:05:06 +00:00
|
|
|
|
|
|
|
#### Developer Tools error
|
|
|
|
|
|
|
|
Note: Runs may fail with an error like
|
|
|
|
|
|
|
|
```
|
|
|
|
error: Uncaught (in promise) "Could not find map!"
|
|
|
|
```
|
|
|
|
|
2023-09-24 19:48:44 +00:00
|
|
|
Running the command a second time typically shows a popup:
|
|
|
|
|
2023-12-15 03:13:56 +00:00
|
|
|
> Developer Tools Access needs to take control of another process for debugging to continue
|
2023-09-24 06:05:06 +00:00
|
|
|
|
2023-09-24 19:48:44 +00:00
|
|
|
It will ask for Touch ID or password. After authorization, the build should run.
|
2023-07-26 00:12:12 +00:00
|
|
|
|
|
|
|
## Protocol Buffer Details
|
|
|
|
|
|
|
|
Note that the `message` field is absolute. For example, `TSTArchives.proto`
|
|
|
|
specifies the `.TST.TileStorage` as follows:
|
|
|
|
|
|
|
|
```proto
|
|
|
|
package TST;
|
|
|
|
|
|
|
|
message TileStorage {
|
|
|
|
message Tile {
|
|
|
|
required uint32 tileid = 1;
|
|
|
|
required .TSP.Reference tile = 2;
|
|
|
|
}
|
|
|
|
repeated .TST.TileStorage.Tile tiles = 1;
|
|
|
|
optional uint32 tile_size = 2;
|
|
|
|
optional bool should_use_wide_rows = 3;
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
The protobuf extractor rewrites the message names using the absolute form:
|
|
|
|
|
|
|
|
```proto
|
|
|
|
message .TST.TileStorage {
|
|
|
|
message Tile {
|
|
|
|
required uint32 tileid = 1;
|
|
|
|
required .TSP.Reference tile = 2;
|
|
|
|
}
|
|
|
|
repeated .TST.TileStorage.Tile tiles = 1;
|
|
|
|
optional uint32 tile_size = 2;
|
|
|
|
optional bool should_use_wide_rows = 3;
|
|
|
|
}
|
|
|
|
```
|