1*a03ca8b9SKrzysztof Kosiński 2*a03ca8b9SKrzysztof Kosiński## Basic Definitions for Patching 3*a03ca8b9SKrzysztof Kosiński 4*a03ca8b9SKrzysztof Kosiński**Binary**: Executable image and data. Binaries may persist in an archive 5*a03ca8b9SKrzysztof Kosiński(e.g., chrome.7z), and need to be periodically updated. Formats for binaries 6*a03ca8b9SKrzysztof Kosińskiinclude {PE files EXE / DLL, ELF, DEX}. Architectures binaries include 7*a03ca8b9SKrzysztof Kosiński{x86, x64, ARM, AArch64, Dalvik}. A binary is also referred to as an executable 8*a03ca8b9SKrzysztof Kosińskior an image file. 9*a03ca8b9SKrzysztof Kosiński 10*a03ca8b9SKrzysztof Kosiński**Patching**: Sending a "new" file to clients who have an "old" file by 11*a03ca8b9SKrzysztof Kosińskicomputing and transmitting a "patch" that can be used to transform "old" into 12*a03ca8b9SKrzysztof Kosiński"new". Patches are compressed for transmission. A key performance metric is 13*a03ca8b9SKrzysztof Kosińskipatch size, which refers to the size of compressed patch file. For our 14*a03ca8b9SKrzysztof Kosińskiexperiments we use 7z. 15*a03ca8b9SKrzysztof Kosiński 16*a03ca8b9SKrzysztof Kosiński**Patch generation**: Computation of a "patch" from "old" and "new". This can be 17*a03ca8b9SKrzysztof Kosińskiexpensive (e.g., ~15-20 min for Chrome, using 1 GB of RAM), but since patch 18*a03ca8b9SKrzysztof Kosińskigeneration is a run-once step on the server-side when releasing "new" binaries, 19*a03ca8b9SKrzysztof Kosińskithe expense is not too critical. 20*a03ca8b9SKrzysztof Kosiński 21*a03ca8b9SKrzysztof Kosiński**Patch application**: Transformation from "old" binaries to "new", using a 22*a03ca8b9SKrzysztof Kosiński(downloaded) "patch". This is executed on client side on updates, so resource 23*a03ca8b9SKrzysztof Kosińskiconstraints (e.g., time, RAM, disk space) is more stringent. Also, fault- 24*a03ca8b9SKrzysztof Kosińskitolerance is important. This is usually achieved by an update system by having 25*a03ca8b9SKrzysztof Kosińskia fallback method of directly downloading "new" in case of patching failure. 26*a03ca8b9SKrzysztof Kosiński 27*a03ca8b9SKrzysztof Kosiński**Offset**: Position relative to the start of a file. 28*a03ca8b9SKrzysztof Kosiński 29*a03ca8b9SKrzysztof Kosiński**Local offset**: An offset relative to the start of a region of a file. 30*a03ca8b9SKrzysztof Kosiński 31*a03ca8b9SKrzysztof Kosiński**Element**: A region in a file with associated executable type, represented by 32*a03ca8b9SKrzysztof Kosińskithe tuple (exe_type, offset, length). Every Element in new file is associated 33*a03ca8b9SKrzysztof Kosińskiwith an Element in old file and patched independently. 34*a03ca8b9SKrzysztof Kosiński 35*a03ca8b9SKrzysztof Kosiński**Reference**: A directed connection between two offsets in a binary. For 36*a03ca8b9SKrzysztof Kosińskiexample, consider jump instructions in x86: 37*a03ca8b9SKrzysztof Kosiński 38*a03ca8b9SKrzysztof Kosiński 00401000: E9 3D 00 00 00 jmp 00401042 39*a03ca8b9SKrzysztof Kosiński 40*a03ca8b9SKrzysztof KosińskiHere, the 4 bytes `[3D 00 00 00]` starting at address `00401001` point to 41*a03ca8b9SKrzysztof Kosińskiaddress `00401042` in memory. This forms a reference from `offset(00401001)` 42*a03ca8b9SKrzysztof Kosiński(length 4) to `offset(00401042)`, where `offset(addr)` indicates the disk 43*a03ca8b9SKrzysztof Kosińskioffset corresponding to `addr`. A reference has a location, length (implicitly 44*a03ca8b9SKrzysztof Kosińskidetermined by reference type), body, and target. 45*a03ca8b9SKrzysztof Kosiński 46*a03ca8b9SKrzysztof Kosiński**Location**: The starting offset of bytes that store a reference. In the 47*a03ca8b9SKrzysztof Kosińskipreceding example, `offset(00401001)` is a location. Each location is the 48*a03ca8b9SKrzysztof Kosińskibeginning of a reference body. 49*a03ca8b9SKrzysztof Kosiński 50*a03ca8b9SKrzysztof Kosiński**Body**: The span of bytes that encodes reference data, i.e., 51*a03ca8b9SKrzysztof Kosiński[location, location + length) = 52*a03ca8b9SKrzysztof Kosiński[location, location + 1, ..., location + length - 1]. 53*a03ca8b9SKrzysztof KosińskiIn the preceding example, `length = 4`, so the reference body is 54*a03ca8b9SKrzysztof Kosiński`[00401001, 00401001 + 4) = [00401001, 00401002, 00401003, 00401004]`. 55*a03ca8b9SKrzysztof KosińskiAll reference bodies in an image must not overlap, and often regions boundaries 56*a03ca8b9SKrzysztof Kosińskiare required to not straddle a reference body. 57*a03ca8b9SKrzysztof Kosiński 58*a03ca8b9SKrzysztof Kosiński**Target**: The offset that's the destination of a reference. In the preceding 59*a03ca8b9SKrzysztof Kosińskiexample, `offset(00401042)` is the target. Different references can share common 60*a03ca8b9SKrzysztof Kosińskitargets. For example, in 61*a03ca8b9SKrzysztof Kosiński 62*a03ca8b9SKrzysztof Kosiński 00401000: E9 3D 00 00 00 jmp 00401042 63*a03ca8b9SKrzysztof Kosiński 00401005: EB 3B jmp 00401042 64*a03ca8b9SKrzysztof Kosiński 65*a03ca8b9SKrzysztof Kosińskiwe have two references with different locations and bodies, but same target 66*a03ca8b9SKrzysztof Kosińskiof `00401042`. 67*a03ca8b9SKrzysztof Kosiński 68*a03ca8b9SKrzysztof KosińskiBecause the bytes that encode a reference depend on its target, and potentially 69*a03ca8b9SKrzysztof Kosińskion its location, they are more likely to get modified from an old version of a 70*a03ca8b9SKrzysztof Kosińskibinary to a newer version. This is why "naive" patching does not do well on 71*a03ca8b9SKrzysztof Kosińskibinaries. 72*a03ca8b9SKrzysztof Kosiński 73*a03ca8b9SKrzysztof Kosiński**Target Key**: An alternative representation of a Target for a fixed pool, as its 74*a03ca8b9SKrzysztof Kosińskiindex in the sorted list of Target offsets. Keys are useful since: 75*a03ca8b9SKrzysztof Kosiński * Their numerical index are smaller than offsets, allowing more efficient 76*a03ca8b9SKrzysztof Kosiński storage of target correction data in patch. 77*a03ca8b9SKrzysztof Kosiński * They simplify association from Targets to Labels. 78*a03ca8b9SKrzysztof Kosiński 79*a03ca8b9SKrzysztof Kosiński**Disassembler**: Architecture specific data and operations, used to extract and 80*a03ca8b9SKrzysztof Kosińskicorrect references in a binary. 81*a03ca8b9SKrzysztof Kosiński 82*a03ca8b9SKrzysztof Kosiński**Type of reference**: The type of a reference determines the binary 83*a03ca8b9SKrzysztof Kosińskirepresentation used to encode its target. This affects how references are parsed 84*a03ca8b9SKrzysztof Kosińskiand written by a disassembler. There can be many types of references in the same 85*a03ca8b9SKrzysztof Kosińskibinary. 86*a03ca8b9SKrzysztof Kosiński 87*a03ca8b9SKrzysztof KosińskiA reference is represented by the tuple (disassembler, location, target, type). 88*a03ca8b9SKrzysztof KosińskiThis tuple contains sufficient information to write the reference in a binary. 89*a03ca8b9SKrzysztof Kosiński 90*a03ca8b9SKrzysztof Kosiński**Pool of targets**: Collection of targets that is assumed to have some semantic 91*a03ca8b9SKrzysztof Kosińskirelationship. Each reference type belong to exactly one reference pool. Targets 92*a03ca8b9SKrzysztof Kosińskifor references in the same pool are shared. 93*a03ca8b9SKrzysztof Kosiński 94*a03ca8b9SKrzysztof KosińskiFor example, the following describes two pools defined for Dalvik Executable 95*a03ca8b9SKrzysztof Kosińskiformat (DEX). Both pools spawn multiple types of references. 96*a03ca8b9SKrzysztof Kosiński 97*a03ca8b9SKrzysztof Kosiński1. Index in string table. 98*a03ca8b9SKrzysztof Kosiński - From bytecode to string index using 16 bits. 99*a03ca8b9SKrzysztof Kosiński - From bytecode to string index using 32 bits. 100*a03ca8b9SKrzysztof Kosiński - From field item to string index using 32 bits. 101*a03ca8b9SKrzysztof Kosiński2. Address in code. 102*a03ca8b9SKrzysztof Kosiński - Relative 16 bits pointer. 103*a03ca8b9SKrzysztof Kosiński - Relative 32 bits pointer. 104*a03ca8b9SKrzysztof Kosiński 105*a03ca8b9SKrzysztof KosińskiBoundaries between different pools can be ambiguous. Having all targets belong 106*a03ca8b9SKrzysztof Kosińskito the same pool can reduce redundancy, but will use more memory and might 107*a03ca8b9SKrzysztof Kosińskicause larger corrections to happen, so this is a trade-off that can be resolved 108*a03ca8b9SKrzysztof Kosińskiwith benchmarks. 109*a03ca8b9SKrzysztof Kosiński 110*a03ca8b9SKrzysztof Kosiński**Abs32 references**: References whose targets are adjusted by the OS during 111*a03ca8b9SKrzysztof Kosińskiprogram load. In an image, a **relocation table** typically provides locations 112*a03ca8b9SKrzysztof Kosińskiof abs32 references. At each abs32 location, the stored bytes then encode 113*a03ca8b9SKrzysztof Kosińskisemantic information about the target (e.g., as RVA). 114*a03ca8b9SKrzysztof Kosiński 115*a03ca8b9SKrzysztof Kosiński**Rel32 references**: References embedded within machine code, in which targets 116*a03ca8b9SKrzysztof Kosińskiare encoded as some delta relative to the reference's location. Typical examples 117*a03ca8b9SKrzysztof Kosińskiof rel32 references are branching instructions and instruction pointer-relative 118*a03ca8b9SKrzysztof Kosińskimemory access. 119*a03ca8b9SKrzysztof Kosiński 120*a03ca8b9SKrzysztof Kosiński**Equivalence**: A (src_offset, dst_offset, length) tuple describing a region of 121*a03ca8b9SKrzysztof Kosiński"old" binary, at an offset of |src_offset|, that is similar to a region of "new" 122*a03ca8b9SKrzysztof Kosińskibinary, at an offset of |dst_offset|. 123*a03ca8b9SKrzysztof Kosiński 124*a03ca8b9SKrzysztof Kosiński**Raw delta unit**: Describes a raw modification to apply on the new image, as a 125*a03ca8b9SKrzysztof Kosińskipair (copy_offset, diff), where copy_offset describes the position in new file 126*a03ca8b9SKrzysztof Kosińskias an offset in the data that was copied from the old file, and diff is the 127*a03ca8b9SKrzysztof Kosińskibytewise difference to apply. 128*a03ca8b9SKrzysztof Kosiński 129*a03ca8b9SKrzysztof Kosiński**Associated Targets**: A target in "old" binary is associated with a target in 130*a03ca8b9SKrzysztof Kosiński"new" binary if both targets: 131*a03ca8b9SKrzysztof Kosiński1. are part of similar regions from the same equivalence, and 132*a03ca8b9SKrzysztof Kosiński2. have the same local offset (relative to respective start regions), and 133*a03ca8b9SKrzysztof Kosiński3. are not part of any larger region from a different equivalence. 134*a03ca8b9SKrzysztof KosińskiNot all targets are necessarily associated with another target. 135*a03ca8b9SKrzysztof Kosiński 136*a03ca8b9SKrzysztof Kosiński**Target Affinity**: Level of confidence in the association between two targets. 137*a03ca8b9SKrzysztof KosińskiThe affinity between targets that are potentially associated is measured based 138*a03ca8b9SKrzysztof Kosińskion surrounding content, as well as reference type. 139*a03ca8b9SKrzysztof Kosiński 140*a03ca8b9SKrzysztof Kosiński**Label**: An integer assigned for each Target in "old" and "new" binary as part 141*a03ca8b9SKrzysztof Kosińskiof generating a patch, and used to alias targets when searching for similar 142*a03ca8b9SKrzysztof Kosińskiregions that will form equivalences. Labels are assigned such that 143*a03ca8b9SKrzysztof Kosińskiassociated targets in old and new binaries share the same Label. Unmatched 144*a03ca8b9SKrzysztof KosińskiTargets have a Label of 0. For example, given 145*a03ca8b9SKrzysztof Kosiński * "Old" targets = [0x1111, 0x3333, 0x5555, 0x7777], 146*a03ca8b9SKrzysztof Kosiński * "New" targets = [0x2222, 0x4444, 0x6666, 0x8888], 147*a03ca8b9SKrzysztof Kosińskito represent matchings 0x1111 <=> 0x6666, 0x3333 <=> 0x2222, we'd assign 148*a03ca8b9SKrzysztof Kosiński * Label 1 to 0x1111 (in "old") and 0x6666 (in "new"), 149*a03ca8b9SKrzysztof Kosiński * Label 2 to 0x3333 (in "old") and 0x2222 (in "new"). 150*a03ca8b9SKrzysztof Kosiński Represented as arrays indexed over Target Keys, we'd have: 151*a03ca8b9SKrzysztof Kosiński * "Old" labels = [1, 2, 0 ,0], 152*a03ca8b9SKrzysztof Kosiński * "New" labels = [2, 0, 1, 0]. 153*a03ca8b9SKrzysztof Kosiński 154*a03ca8b9SKrzysztof Kosiński**Encoded Image**: The result of projecting the content of an image to scalar 155*a03ca8b9SKrzysztof Kosińskivalues that describe content on a higher level of abstraction, masking away 156*a03ca8b9SKrzysztof Kosińskiundesirable noise in raw content. Notably, the projection encodes references 157*a03ca8b9SKrzysztof Kosińskibased on their associated label. 158*a03ca8b9SKrzysztof Kosiński 159*a03ca8b9SKrzysztof Kosiński## Interfaces 160*a03ca8b9SKrzysztof Kosiński 161*a03ca8b9SKrzysztof Kosińskizucchini_lib: Core Zucchini library that operate on buffers to generate and 162*a03ca8b9SKrzysztof Kosińskiapply patches. 163*a03ca8b9SKrzysztof Kosiński 164*a03ca8b9SKrzysztof Kosińskizucchini_io: Wrapper on zucchini_lib that handles file I/O, using memory-mapped 165*a03ca8b9SKrzysztof KosińskiI/O to interface with zucchini_lib. 166*a03ca8b9SKrzysztof Kosiński 167*a03ca8b9SKrzysztof Kosińskizucchini: Stand-alone executable that parses command-line arguments, and passes 168*a03ca8b9SKrzysztof Kosińskithe results to zucchini_io. Also implements various helper flows. 169*a03ca8b9SKrzysztof Kosiński 170*a03ca8b9SKrzysztof Kosiński## Zucchini Ensemble Patch Format 171*a03ca8b9SKrzysztof Kosiński 172*a03ca8b9SKrzysztof Kosiński### Types 173*a03ca8b9SKrzysztof Kosiński 174*a03ca8b9SKrzysztof Kosiński**int8**: 8-bit unsigned int. 175*a03ca8b9SKrzysztof Kosiński 176*a03ca8b9SKrzysztof Kosiński**uint32**: 32-bit unsigned int, little-endian. 177*a03ca8b9SKrzysztof Kosiński 178*a03ca8b9SKrzysztof Kosiński**int32**: 32-bit signed int, little-endian. 179*a03ca8b9SKrzysztof Kosiński 180*a03ca8b9SKrzysztof Kosiński**Varints**: This is a generic variable-length encoding for integer quantities 181*a03ca8b9SKrzysztof Kosińskithat strips away leading (most-significant) null bytes. 182*a03ca8b9SKrzysztof KosińskiThe Varints format is borrowed from protocol-buffers, see 183*a03ca8b9SKrzysztof Kosiński[documentation](https://developers.google.com/protocol-buffers/docs/encoding#varints) 184*a03ca8b9SKrzysztof Kosińskifor more info. 185*a03ca8b9SKrzysztof Kosiński 186*a03ca8b9SKrzysztof Kosiński**varuint32**: A uint32 encoded using Varints format. 187*a03ca8b9SKrzysztof Kosiński 188*a03ca8b9SKrzysztof Kosiński**varint32**: A int32 encoded using Varints format. 189*a03ca8b9SKrzysztof Kosiński 190*a03ca8b9SKrzysztof Kosiński### File Layout 191*a03ca8b9SKrzysztof Kosiński 192*a03ca8b9SKrzysztof KosińskiName | Format | Description 193*a03ca8b9SKrzysztof Kosiński--- | --- | --- 194*a03ca8b9SKrzysztof Kosińskiheader | PatchHeader | The header. 195*a03ca8b9SKrzysztof Kosińskielements_count | uint32 | Number of patch units. 196*a03ca8b9SKrzysztof Kosińskielements | PatchElement[elements_count] | List of all patch elements. 197*a03ca8b9SKrzysztof Kosiński 198*a03ca8b9SKrzysztof KosińskiPosition of elements in new file is ascending. 199*a03ca8b9SKrzysztof Kosiński 200*a03ca8b9SKrzysztof Kosiński### Structures 201*a03ca8b9SKrzysztof Kosiński 202*a03ca8b9SKrzysztof Kosiński**PatchHeader** 203*a03ca8b9SKrzysztof Kosiński 204*a03ca8b9SKrzysztof KosińskiName | Format | Description 205*a03ca8b9SKrzysztof Kosiński--- | --- | --- 206*a03ca8b9SKrzysztof Kosińskimagic | uint32 = kMagic | Magic value. 207*a03ca8b9SKrzysztof Kosińskimajor_version | uint16 | Major version number indicating breaking changes. 208*a03ca8b9SKrzysztof Kosińskiminor_version | uint16 | Minor version number indicating possibly breaking changes. 209*a03ca8b9SKrzysztof Kosińskiold_size | uint32 | Size of old file in bytes. 210*a03ca8b9SKrzysztof Kosińskiold_crc | uint32 | CRC32 of old file. 211*a03ca8b9SKrzysztof Kosińskinew_size | uint32 | Size of new file in bytes. 212*a03ca8b9SKrzysztof Kosińskinew_crc | uint32 | CRC32 of new file. 213*a03ca8b9SKrzysztof Kosiński 214*a03ca8b9SKrzysztof Kosiński**kMagic** == `'Z' | ('u' << 8) | ('c' << 16) | ('c' << 24)` 215*a03ca8b9SKrzysztof Kosiński 216*a03ca8b9SKrzysztof Kosiński**PatchElement** 217*a03ca8b9SKrzysztof KosińskiContains all the information required to produce a single element in new file. 218*a03ca8b9SKrzysztof Kosiński 219*a03ca8b9SKrzysztof KosińskiName | Format | Description 220*a03ca8b9SKrzysztof Kosiński--- | --- | --- 221*a03ca8b9SKrzysztof Kosińskiheader | PatchElementHeader | The header. 222*a03ca8b9SKrzysztof Kosińskiequivalences | EquivalenceList | List of equivalences. 223*a03ca8b9SKrzysztof Kosińskiraw_deltas | RawDeltaList | List of raw deltas. 224*a03ca8b9SKrzysztof Kosińskireference_deltas | ReferenceDeltaList | List of reference deltas. 225*a03ca8b9SKrzysztof Kosińskipool_count | uint32 | Number of pools. 226*a03ca8b9SKrzysztof Kosińskiextra_targets | ExtraTargetList[pool_count] | Lists of extra targets. 227*a03ca8b9SKrzysztof Kosiński 228*a03ca8b9SKrzysztof Kosiński**PatchElementHeader** 229*a03ca8b9SKrzysztof KosińskiDescribes a correspondence between an element in old and in new files. Some 230*a03ca8b9SKrzysztof Kosińskiredundancy arise from storing |new_offset|, but it is necessary to make 231*a03ca8b9SKrzysztof KosińskiPatchElement self contained. 232*a03ca8b9SKrzysztof Kosiński 233*a03ca8b9SKrzysztof KosińskiName | Format | Description 234*a03ca8b9SKrzysztof Kosiński--- | --- | --- 235*a03ca8b9SKrzysztof Kosińskiold_offset | uint32 | Starting offset of the element in old file. 236*a03ca8b9SKrzysztof Kosińskiold_length | uint32 | Length of the element in old file. 237*a03ca8b9SKrzysztof Kosińskinew_offset | uint32 | Starting offset of the element in new file. 238*a03ca8b9SKrzysztof Kosińskinew_length | uint32 | Length of the element in new file. 239*a03ca8b9SKrzysztof Kosińskiexe_type | uint32 | Executable type for this unit, see `enum ExecutableType`. 240*a03ca8b9SKrzysztof Kosińskiversion | uint16 | Version specific to the executable type for this unit. 241*a03ca8b9SKrzysztof Kosiński 242*a03ca8b9SKrzysztof Kosiński**EquivalenceList** 243*a03ca8b9SKrzysztof KosińskiEncodes a list of equivalences, where dst offsets (in new image) are ascending. 244*a03ca8b9SKrzysztof Kosiński 245*a03ca8b9SKrzysztof KosińskiName | Format | Description 246*a03ca8b9SKrzysztof Kosiński--- | --- | --- 247*a03ca8b9SKrzysztof Kosińskisrc_skip | Buffer<varint32> | Src offset for each equivalence, delta encoded. 248*a03ca8b9SKrzysztof Kosińskidst_skip | Buffer<varuint32> | Dst offset for each equivalence, delta encoded. 249*a03ca8b9SKrzysztof Kosińskicopy_count | Buffer<varuint32> | Length for each equivalence. 250*a03ca8b9SKrzysztof Kosiński 251*a03ca8b9SKrzysztof Kosiński**RawDeltaList** 252*a03ca8b9SKrzysztof KosińskiEncodes a list of raw delta units, with ascending copy offsets. 253*a03ca8b9SKrzysztof Kosiński 254*a03ca8b9SKrzysztof KosińskiName | Format | Description 255*a03ca8b9SKrzysztof Kosiński--- | --- | --- 256*a03ca8b9SKrzysztof Kosińskiraw_delta_skip | Buffer<varuint32> | Copy offset for each delta unit, delta encoded and biased by -1. 257*a03ca8b9SKrzysztof Kosińskiraw_delta_diff | Buffer<int8> | Bytewise difference for each delta unit. 258*a03ca8b9SKrzysztof Kosiński 259*a03ca8b9SKrzysztof Kosiński**ReferenceDeltaList** 260*a03ca8b9SKrzysztof KosińskiEncodes a list of reference deltas, in the order they appear in the new 261*a03ca8b9SKrzysztof Kosińskiimage file. A reference delta is a signed integer representing a jump through a 262*a03ca8b9SKrzysztof Kosińskilist of targets. 263*a03ca8b9SKrzysztof Kosiński 264*a03ca8b9SKrzysztof KosińskiName | Format | Description 265*a03ca8b9SKrzysztof Kosiński--- | --- | --- 266*a03ca8b9SKrzysztof Kosińskireference_delta | Buffer<varuint32> | Vector of reference deltas. 267*a03ca8b9SKrzysztof Kosiński 268*a03ca8b9SKrzysztof Kosiński**ExtraTargetList** 269*a03ca8b9SKrzysztof KosińskiEncodes a list of additional targets in the new image file, in ascending 270*a03ca8b9SKrzysztof Kosińskiorder. 271*a03ca8b9SKrzysztof Kosiński 272*a03ca8b9SKrzysztof KosińskiName | Format | Description 273*a03ca8b9SKrzysztof Kosiński--- | --- | --- 274*a03ca8b9SKrzysztof Kosińskipool_tag | uint8_t | Unique identifier for this pool of targets. 275*a03ca8b9SKrzysztof Kosińskiextra_targets | Buffer<varuint32> | Additional targets, delta encoded and biased by -1. 276*a03ca8b9SKrzysztof Kosiński 277*a03ca8b9SKrzysztof Kosiński**Buffer<T>** 278*a03ca8b9SKrzysztof KosińskiA generic vector of data. 279*a03ca8b9SKrzysztof Kosiński 280*a03ca8b9SKrzysztof KosińskiName | Format | Description 281*a03ca8b9SKrzysztof Kosiński--- | --- | --- 282*a03ca8b9SKrzysztof Kosińskisize |uint32 | Size of content in bytes. 283*a03ca8b9SKrzysztof Kosińskicontent |T[] | List of integers. 284*a03ca8b9SKrzysztof Kosiński 285*a03ca8b9SKrzysztof Kosiński# Format Changelog 286*a03ca8b9SKrzysztof KosińskiAll breaking changes to zucchini patch format will be documented in this 287*a03ca8b9SKrzysztof Kosińskisection. 288*a03ca8b9SKrzysztof Kosiński 289*a03ca8b9SKrzysztof KosińskiThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). 290*a03ca8b9SKrzysztof Kosiński 291*a03ca8b9SKrzysztof Kosiński## [Unreleased] 292*a03ca8b9SKrzysztof Kosiński 293*a03ca8b9SKrzysztof Kosiński## [1.0] - 2021-10-27 294*a03ca8b9SKrzysztof Kosiński### Added 295*a03ca8b9SKrzysztof KosińskiMajor/Minor version is encoded in PatchHeader 296*a03ca8b9SKrzysztof KosińskiDisassembler version associated with an element version is encoded in PatchElementHeader. 297