Talos Vulnerability Report

TALOS-2024-2076

Adobe Acrobat Reader Font Program Function Definition Out-Of-Bounds Read Vulnerability

December 11, 2024
CVE Number

CVE-2024-49534

SUMMARY

An out-of-bounds read vulnerability exists in font handling code of Adobe Acrobat Reader 2024.002.21005. A font file with a specially crafted function definition in the font program embedded into a PDF can trigger an out of bounds memory read which can lead to disclosure of sensitive information and aid further exploitation. An attacker needs to trick the user into opening the malicious file to trigger this vulnerability.

CONFIRMED VULNERABLE VERSIONS

The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.

Adobe Acrobat Reader 2024.002.21005

PRODUCT URLS

Acrobat Reader - https://acrobat.adobe.com/us/en/acrobat/pdf-reader.html

CVSSv3 SCORE

6.5 - CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N

CWE

CWE-125 - Out-of-bounds Read

DETAILS

Adobe Acrobat Reader is one of the most popular and feature-rich PDF readers on the market. It has a large user base and is usually a default PDF reader on systems. It also integrates into web browsers as a plugin for rendering PDFs.

Adobe Acrobat supports parsing of embedded font files in the PDF. A supported font file starts with a table directory (TableDirectory ) followed by one or more table record (TableRecord) entries. The structure of TableDirectory is as follows:

Offset Size   Name
------ ----- --------------------------------------
0x00    0x04  sfntVersion (0x00010000 or 0x4F54544F  )
0x04    0x02  numTables
0x06    0x02  searchRange
0x08    0x02  entrySelector
0x0c    0x02  rangeShift

If the value of the sfntVersion field is 0x00010000 or 0x74727565, the font contains TrueType data. The CFF data will be present if the value of sfntVersion is 0x4F54544F (‘OTTO). The numTables field specifies the number of TableRecord entries present in the font file. The structure of a TableRecord entry is as follows:

Offset Size   Name
------ ----- ----------------------------------
0x00    0x04  tableTag
0x04    0x04  tableChecksum
0x08    0x04  tableOffset
0x0C    0x04  tableLength

tableTag is the name of TableRecord. The tableOffset field specifies the offset of the table from the beginning of the file. The tableLength indicates the length of the table. The structure of each TableRecord depends on the type table, which is defined by the tableTag.

A font file may contain instructions, which can be present in the fpgm, glyf, or prep tables. These instructions are applied during the rasterization process to ensure that the glyph preserves its characteristics and legibility when rendered at different sizes on various devices. In other words, these instructions control how a glyph outline is fitted for a particular size or device.

Instructions are interpreted by the TrueType interpreter, which executes them sequentially. Most instructions take their arguments from the interpreter stack and place their results back onto the stack. However, a small number of instructions are used to push data onto the interpreter stack.

Instructions in a font can be categorized into the font program, the control value program, and the glyph program. The font program is stored in the fpgm table, the control value program is stored in the prep table, and the glyph program is present in the glyf table.

The font program contains only function definitions and instruction definitions. The functions and instructions defined by the font program are used in the control value program or the glyph program.

An example of a simple font program containing only one function definition is as follows:

B0 00 2C 0D 5C 5A 2D 

The bytecode B0 (PUSHB) pushes 1 byte onto the interpreter stack. In this case, 00 will be pushed onto the interpreter stack, meaning a total of 2 bytes are consumed by the interpreter. The next bytecode is 2C (FDEF), which marks the beginning of a function definition and pops a number from the interpreter stack to uniquely identify this function. In this case, the interpreter stack has the value 0, so this function is marked as function 0. The function ends when the bytecode 2D (ENDF) is encountered.

This vulnerability occurs when a function definition contains an instruction with arbitrarily large data. In our case, the font program contains invalid function definitions, and the execution of the function by the control value program triggers this bug. This can be observed in the debugger (with PageHeap enabled):

0:000> p
Time Travel Position: 128CDD:604
eax=70f14954 ebx=53ac2ed0 ecx=a58ef9ae edx=40878dd4 esi=70f14a18 edi=00000000
eip=70c2f5c6 esp=006fb9ec ebp=006fbb64 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x39db6:
70c2f5c6 ffb5ecfeffff    push    dword ptr [ebp-114h] ss:002b:006fba50=0000054c ;<------------------ (1)
0:000> p
Time Travel Position: 128CDD:605
eax=70f14954 ebx=53ac2ed0 ecx=a58ef9ae edx=40878dd4 esi=70f14a18 edi=00000000
eip=70c2f5cc esp=006fb9e8 ebp=006fbb64 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x39dbc:
70c2f5cc 50              push    eax
0:000> p
malloc vuln buffer of size 0x54c
Time Travel Position: 128CDD:606
eax=70f14954 ebx=53ac2ed0 ecx=a58ef9ae edx=40878dd4 esi=70f14a18 edi=00000000
eip=70c2f5cd esp=006fb9e4 ebp=006fbb64 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x39dbd:
70c2f5cd 8b08            mov     ecx,dword ptr [eax]  ds:002b:70f14954=70ef1078
0:000> p
Time Travel Position: 128CDD:607
eax=70f14954 ebx=53ac2ed0 ecx=70ef1078 edx=40878dd4 esi=70f14a18 edi=00000000
eip=70c2f5cf esp=006fb9e4 ebp=006fbb64 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x39dbf:
70c2f5cf 8b31            mov     esi,dword ptr [ecx]  ds:002b:70ef1078=70be9860
0:000> p
Time Travel Position: 128CDD:608
eax=70f14954 ebx=53ac2ed0 ecx=70ef1078 edx=40878dd4 esi=70be9860 edi=00000000
eip=70c2f5d1 esp=006fb9e4 ebp=006fbb64 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x39dc1:
70c2f5d1 8bce            mov     ecx,esi
0:000> p
Time Travel Position: 128CDD:609
eax=70f14954 ebx=53ac2ed0 ecx=70be9860 edx=40878dd4 esi=70be9860 edi=00000000
eip=70c2f5d3 esp=006fb9e4 ebp=006fbb64 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x39dc3:
70c2f5d3 ff15ac26e370    call    dword ptr [CoolType!CTGetVersion+0x14fa3c (70e326ac)] ds:002b:70e326ac={ntdll!LdrpValidateUserCallTarget (77cf8e70)}
0:000> p
Time Travel Position: 128CDD:615
eax=0e17d30c ebx=53ac2ed0 ecx=70be9860 edx=00005000 esi=70be9860 edi=00000000
eip=70c2f5d9 esp=006fb9e4 ebp=006fbb64 iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200247
CoolType!CTCleanup+0x39dc9:
70c2f5d9 ffd6            call    esi {CoolType!CTInit+0x6210 (70be9860)}   ;<------------------ (2)
0:000> p
Time Travel Position: 128CE1:101C
eax=43320ab0 ebx=53ac2ed0 ecx=0000054c edx=00000000 esi=70be9860 edi=00000000
eip=70c2f5db esp=006fb9e4 ebp=006fbb64 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x39dcb:
70c2f5db 59              pop     ecx
0:000> dd eax                                                             ;<------------------ (3)
43320ab0  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
43320ac0  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
43320ad0  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
43320ae0  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
43320af0  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
43320b00  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0

At (2), the malloc function is called to create a vulnerable buffer named program_buffer. The size of the vulnerable buffer is 0x54c and it can be observed at (1). The content of the program_buffer is examined at (3). Note that the program_buffer will store the font program, the control value program, and metadata related to the program.

0:000> p
Time Travel Position: 128D12:189B
eax=43320cf4 ebx=40878c18 ecx=006fb870 edx=000000d1 esi=00000265 edi=540b8d98
eip=70bec596 esp=006fb844 ebp=006fb84c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
CoolType!CTInit+0x8f46:
70bec596 56              push    esi                                  ; ---------------------------> (4)
0:000> p
Time Travel Position: 128D12:189C
eax=43320cf4 ebx=40878c18 ecx=006fb870 edx=000000d1 esi=00000265 edi=540b8d98
eip=70bec597 esp=006fb840 ebp=006fb84c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
CoolType!CTInit+0x8f47:
70bec597 57              push    edi
0:000> p
Time Travel Position: 128D12:189D
eax=43320cf4 ebx=40878c18 ecx=006fb870 edx=000000d1 esi=00000265 edi=540b8d98
eip=70bec598 esp=006fb83c ebp=006fb84c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
CoolType!CTInit+0x8f48:
70bec598 50              push    eax                                 ; ---------------------------> (5)
0:000> dd eax
43320cf4  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
43320d04  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
43320d14  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
43320d24  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
43320d34  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
43320d44  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
43320d54  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
43320d64  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0

0:000> p
Time Travel Position: 128D12:189E
eax=43320cf4 ebx=40878c18 ecx=006fb870 edx=000000d1 esi=00000265 edi=540b8d98
eip=70bec599 esp=006fb838 ebp=006fb84c iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
CoolType!CTInit+0x8f49:
70bec599 e80afdffff      call    CoolType!CTInit+0x8c58 (70bec2a8)    ; ---------------------------> (6)
0:000> p
Time Travel Position: 128D12:1B19
eax=43320cf4 ebx=40878c18 ecx=00000000 edx=00000265 esi=00000265 edi=540b8d98
eip=70bec59e esp=006fb838 ebp=006fb84c iopl=0         nv up ei pl nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200203
CoolType!CTInit+0x8f4e:
70bec59e 83c40c          add     esp,0Ch
0:000> dd 43320cf4                                                      ; ---------------------------> (7)
43320cf4  b02c00b0 b04b1300 b058502a b059764a
43320d04  183f2300 582b06b0 b04b593d 7d58502a
43320d14  b0d42059 182e1301 2c01b02d ffffc939
43320d24  02b02d2b 58524b2c 21592345 2c03b02d
43320d34  b0201869 21585040 2d7640b0 b02c04b0
43320d44  21582b06 587a2123 59cd1bdd 58524b1b
43320d54  ed1bfd58 21231b59 592b05b0 597646b0
43320d64  cd1bdd58 18595959 2c05b02d 2d5a5c0d

At (6), memcpy function is called to copy the font program to the buffer. The content of the buffer are examined at (5) and (7) .

 0:000> 
Time Travel Position: 128D24:B45
eax=0e186c5c ebx=53ac2ed0 ecx=70c362e0 edx=10000000 esi=70c362e0 edi=43320b84
eip=70c362e3 esp=006fb798 ebp=006fb798 iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200247
CoolType!CTCleanup+0x40ad3:
70c362e3 8b4d08          mov     ecx,dword ptr [ebp+8] ss:002b:006fb7a0=43320cf4  <--------------------- (8)
0:000> db 43320cf4
43320cf4  b0 00 2c b0 00 13 4b b0-2a 50 58 b0 4a 76 59 b0  ..,...K.*PX.JvY.
43320d04  00 23 3f 18 b0 06 2b 58-3d 59 4b b0 2a 50 58 7d  .#?...+X=YK.*PX}
43320d14  59 20 d4 b0 01 13 2e 18-2d b0 01 2c 39 c9 ff ff  Y ......-..,9...
43320d24  2b 2d b0 02 2c 4b 52 58-45 23 59 21 2d b0 03 2c  +-..,KRXE#Y!-..,
43320d34  69 18 20 b0 40 50 58 21-b0 40 76 2d b0 04 2c b0  i. .@PX!.@v-..,.
43320d44  06 2b 58 21 23 21 7a 58-dd 1b cd 59 1b 4b 52 58  .+X!#!zX...Y.KRX
43320d54  58 fd 1b ed 59 1b 23 21-b0 05 2b 59 b0 46 76 59  X...Y.#!..+Y.FvY
43320d64  58 dd 1b cd 59 59 59 18-2d b0 05 2c 0d 5c 5a 2d  X...YYY.-..,.\Z-
0:000> p
Time Travel Position: 128D24:B46
eax=0e186c5c ebx=53ac2ed0 ecx=43320cf4 edx=10000000 esi=70c362e0 edi=43320b84
eip=70c362e6 esp=006fb798 ebp=006fb798 iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200247
CoolType!CTCleanup+0x40ad6:
70c362e6 56              push    esi
0:000> p
Time Travel Position: 128D24:B47
eax=0e186c5c ebx=53ac2ed0 ecx=43320cf4 edx=10000000 esi=70c362e0 edi=43320b84
eip=70c362e7 esp=006fb794 ebp=006fb798 iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200247
CoolType!CTCleanup+0x40ad7:
70c362e7 57              push    edi
0:000> p
Time Travel Position: 128D24:B48
eax=0e186c5c ebx=53ac2ed0 ecx=43320cf4 edx=10000000 esi=70c362e0 edi=43320b84
eip=70c362e8 esp=006fb790 ebp=006fb798 iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200247
CoolType!CTCleanup+0x40ad8:
70c362e8 8b7d0c          mov     edi,dword ptr [ebp+0Ch] ss:002b:006fb7a4=43320f59  ; <--------------------- (9)
0:000> p
Time Travel Position: 128D24:B49
eax=0e186c5c ebx=53ac2ed0 ecx=43320cf4 edx=10000000 esi=70c362e0 edi=43320f59
eip=70c362eb esp=006fb790 ebp=006fb798 iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200247
CoolType!CTCleanup+0x40adb:
70c362eb 893df8c8f070    mov     dword ptr [CoolType!CTGetVersion+0x229c88 (70f0c8f8)],edi ds:002b:70f0c8f8=00000000
0:000> p
Time Travel Position: 128D24:B4A
eax=0e186c5c ebx=53ac2ed0 ecx=43320cf4 edx=10000000 esi=70c362e0 edi=43320f59
eip=70c362f1 esp=006fb790 ebp=006fb798 iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200247
CoolType!CTCleanup+0x40ae1:
70c362f1 890dfcc8f070    mov     dword ptr [CoolType!CTGetVersion+0x229c8c (70f0c8fc)],ecx ds:002b:70f0c8fc=00000000
0:000> p
Time Travel Position: 128D24:B4B
eax=0e186c5c ebx=53ac2ed0 ecx=43320cf4 edx=10000000 esi=70c362e0 edi=43320f59
eip=70c362f7 esp=006fb790 ebp=006fb798 iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200247
CoolType!CTCleanup+0x40ae7:
70c362f7 eb47            jmp     CoolType!CTCleanup+0x40b30 (70c36340)
0:000> p
Time Travel Position: 128D24:B4C
eax=0e186c5c ebx=53ac2ed0 ecx=43320cf4 edx=10000000 esi=70c362e0 edi=43320f59
eip=70c36340 esp=006fb790 ebp=006fb798 iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200247
CoolType!CTCleanup+0x40b30:
70c36340 3bcf            cmp     ecx,edi                       ;     <------------------------- (10)
0:000> p
Time Travel Position: 128D24:B4D
eax=0e186c5c ebx=53ac2ed0 ecx=43320cf4 edx=10000000 esi=70c362e0 edi=43320f59
eip=70c36342 esp=006fb790 ebp=006fb798 iopl=0         nv up ei ng nz ac po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200293
CoolType!CTCleanup+0x40b32:
70c36342 72b5            jb      CoolType!CTCleanup+0x40ae9 (70c362f9)   [br=1]
0:000> p
Time Travel Position: 128D24:B4E
eax=0e186c5c ebx=53ac2ed0 ecx=43320cf4 edx=10000000 esi=70c362e0 edi=43320f59
eip=70c362f9 esp=006fb790 ebp=006fb798 iopl=0         nv up ei ng nz ac po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200293
CoolType!CTCleanup+0x40ae9:
70c362f9 8a11            mov     dl,byte ptr [ecx]          ds:002b:43320cf4=b0    ;     <------------------------- (11)
0:000> p
Time Travel Position: 128D24:B4F
eax=0e186c5c ebx=53ac2ed0 ecx=43320cf4 edx=100000b0 esi=70c362e0 edi=43320f59
eip=70c362fb esp=006fb790 ebp=006fb798 iopl=0         nv up ei ng nz ac po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200293
CoolType!CTCleanup+0x40aeb:
70c362fb 41              inc     ecx
0:000> p
Time Travel Position: 128D24:B50
eax=0e186c5c ebx=53ac2ed0 ecx=43320cf5 edx=100000b0 esi=70c362e0 edi=43320f59
eip=70c362fc esp=006fb790 ebp=006fb798 iopl=0         nv up ei pl nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200207
CoolType!CTCleanup+0x40aec:
70c362fc 832d04c9f07001  sub     dword ptr [CoolType!CTGetVersion+0x229c94 (70f0c904)],1 ds:002b:70f0c904=00989680
0:000> p
Time Travel Position: 128D24:B51
eax=0e186c5c ebx=53ac2ed0 ecx=43320cf5 edx=100000b0 esi=70c362e0 edi=43320f59
eip=70c36303 esp=006fb790 ebp=006fb798 iopl=0         nv up ei pl nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200212
CoolType!CTCleanup+0x40af3:
70c36303 0fb6f2          movzx   esi,dl
0:000> p
Time Travel Position: 128D24:B52
eax=0e186c5c ebx=53ac2ed0 ecx=43320cf5 edx=100000b0 esi=000000b0 edi=43320f59
eip=70c36306 esp=006fb790 ebp=006fb798 iopl=0         nv up ei pl nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200212
CoolType!CTCleanup+0x40af6:
70c36306 747b            je      CoolType!CTCleanup+0x40b73 (70c36383)   [br=0]
0:000> p
Time Travel Position: 128D24:B53
eax=0e186c5c ebx=53ac2ed0 ecx=43320cf5 edx=100000b0 esi=000000b0 edi=43320f59
eip=70c36308 esp=006fb790 ebp=006fb798 iopl=0         nv up ei pl nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200212
CoolType!CTCleanup+0x40af8:
70c36308 a1acc8f070      mov     eax,dword ptr [CoolType!CTGetVersion+0x229c3c (70f0c8ac)] ds:002b:70f0c8ac=43320b84
0:000> p
Time Travel Position: 128D24:B54
eax=43320b84 ebx=53ac2ed0 ecx=43320cf5 edx=100000b0 esi=000000b0 edi=43320f59
eip=70c3630d esp=006fb790 ebp=006fb798 iopl=0         nv up ei pl nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200212
CoolType!CTCleanup+0x40afd:
70c3630d 80b81901000001  cmp     byte ptr [eax+119h],1      ds:002b:43320c9d=01
0:000> p
Time Travel Position: 128D24:B55
eax=43320b84 ebx=53ac2ed0 ecx=43320cf5 edx=100000b0 esi=000000b0 edi=43320f59
eip=70c36314 esp=006fb790 ebp=006fb798 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
CoolType!CTCleanup+0x40b04:
70c36314 7513            jne     CoolType!CTCleanup+0x40b19 (70c36329)   [br=0]
0:000> p
Time Travel Position: 128D24:B56
eax=43320b84 ebx=53ac2ed0 ecx=43320cf5 edx=100000b0 esi=000000b0 edi=43320f59
eip=70c36316 esp=006fb790 ebp=006fb798 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
CoolType!CTCleanup+0x40b06:
70c36316 80fa2c          cmp     dl,2Ch
0:000> p
Time Travel Position: 128D24:B57
eax=43320b84 ebx=53ac2ed0 ecx=43320cf5 edx=100000b0 esi=000000b0 edi=43320f59
eip=70c36319 esp=006fb790 ebp=006fb798 iopl=0         nv up ei ng nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200296
CoolType!CTCleanup+0x40b09:
70c36319 740e            je      CoolType!CTCleanup+0x40b19 (70c36329)   [br=0]
0:000> p
Time Travel Position: 128D24:B58
eax=43320b84 ebx=53ac2ed0 ecx=43320cf5 edx=100000b0 esi=000000b0 edi=43320f59
eip=70c3631b esp=006fb790 ebp=006fb798 iopl=0         nv up ei ng nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200296
CoolType!CTCleanup+0x40b0b:
70c3631b 80fa89          cmp     dl,89h
0:000> p
Time Travel Position: 128D24:B59
eax=43320b84 ebx=53ac2ed0 ecx=43320cf5 edx=100000b0 esi=000000b0 edi=43320f59
eip=70c3631e esp=006fb790 ebp=006fb798 iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200216
CoolType!CTCleanup+0x40b0e:
70c3631e 7409            je      CoolType!CTCleanup+0x40b19 (70c36329)   [br=0]
0:000> p
Time Travel Position: 128D24:B5A
eax=43320b84 ebx=53ac2ed0 ecx=43320cf5 edx=100000b0 esi=000000b0 edi=43320f59
eip=70c36320 esp=006fb790 ebp=006fb798 iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200216
CoolType!CTCleanup+0x40b10:
70c36320 80beb851e47000  cmp     byte ptr CoolType!CTGetVersion+0x162548 (70e451b8)[esi],0 ds:002b:70e45268=01
0:000> p
Time Travel Position: 128D24:B5B
eax=43320b84 ebx=53ac2ed0 ecx=43320cf5 edx=100000b0 esi=000000b0 edi=43320f59
eip=70c36327 esp=006fb790 ebp=006fb798 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x40b17:
70c36327 744e            je      CoolType!CTCleanup+0x40b67 (70c36377)   [br=0]
0:000> p
Time Travel Position: 128D24:B5C
eax=43320b84 ebx=53ac2ed0 ecx=43320cf5 edx=100000b0 esi=000000b0 edi=43320f59
eip=70c36329 esp=006fb790 ebp=006fb798 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x40b19:
70c36329 56              push    esi
0:000> p
Time Travel Position: 128D24:B5D
eax=43320b84 ebx=53ac2ed0 ecx=43320cf5 edx=100000b0 esi=000000b0 edi=43320f59
eip=70c3632a esp=006fb78c ebp=006fb798 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x40b1a:
70c3632a 8b34b54805ef70  mov     esi,dword ptr CoolType!CTGetVersion+0x20d8d8 (70ef0548)[esi*4] ds:002b:70ef0808=70c39720  ;     <------------------------- (12)
0:000> p
Time Travel Position: 128D24:B5E
eax=43320b84 ebx=53ac2ed0 ecx=43320cf5 edx=100000b0 esi=70c39720 edi=43320f59
eip=70c36331 esp=006fb78c ebp=006fb798 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x40b21:
70c36331 51              push    ecx
0:000> p
Time Travel Position: 128D24:B5F
eax=43320b84 ebx=53ac2ed0 ecx=43320cf5 edx=100000b0 esi=70c39720 edi=43320f59
eip=70c36332 esp=006fb788 ebp=006fb798 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x40b22:
70c36332 8bce            mov     ecx,esi
0:000> p
Time Travel Position: 128D24:B60
eax=43320b84 ebx=53ac2ed0 ecx=70c39720 edx=100000b0 esi=70c39720 edi=43320f59
eip=70c36334 esp=006fb788 ebp=006fb798 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x40b24:
70c36334 ff15ac26e370    call    dword ptr [CoolType!CTGetVersion+0x14fa3c (70e326ac)] ds:002b:70e326ac={ntdll!LdrpValidateUserCallTarget (77cf8e70)}
0:000> p
Time Travel Position: 128D24:B6C
eax=0e1872e4 ebx=53ac2ed0 ecx=70c39720 edx=00140010 esi=70c39720 edi=43320f59
eip=70c3633a esp=006fb788 ebp=006fb798 iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200247
CoolType!CTCleanup+0x40b2a:
70c3633a ffd6            call    esi {CoolType!CTCleanup+0x43f10 (70c39720)} ;     <------------------------- (13)
0:000> p
Time Travel Position: 128D24:B8A
eax=43320cf6 ebx=53ac2ed0 ecx=00000264 edx=70f0f040 esi=70c39720 edi=43320f59
eip=70c3633c esp=006fb788 ebp=006fb798 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200206
CoolType!CTCleanup+0x40b2c:
70c3633c 59              pop     ecx

The above code is related to the interpreter. It takes the start address and the end address of a buffer that contains instructions to be executed sequentially by the interpreter. In this case, the buffer contains the font program. At (10), a loop starts that checks whether the buffer has reached its end. If not, the loop continues. It reads the opcode of an instruction at (11) and uses the opcode as an index at (12) to get the address of a function that contains the actual implementation. The virtual function called at (13) executes the implementation related to the opcode.

In our case, function 0x14 in the font program is responsible for the crash. The parsing of the function definition can be observed below:

0:000> g
43320ef9  b0 14 2c b3 00 40 01 40                          ..,..@.@       ;<--------------------------------  (14)
Time Travel Position: 128D25:1159
eax=43320ef9 ebx=53ac2ed0 ecx=43320ef9 edx=43320ef9 esi=70c36850 edi=43320f59
eip=70c362f9 esp=006fb790 ebp=006fb798 iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200287
CoolType!CTCleanup+0x40ae9:
70c362f9 8a11            mov     dl,byte ptr [ecx]          ds:002b:43320ef9=b0
0:000> pc
Time Travel Position: 128D25:116B
eax=43320b84 ebx=53ac2ed0 ecx=70c39720 edx=43320eb0 esi=70c39720 edi=43320f59
eip=70c36334 esp=006fb788 ebp=006fb798 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x40b24:
70c36334 ff15ac26e370    call    dword ptr [CoolType!CTGetVersion+0x14fa3c (70e326ac)] ds:002b:70e326ac={ntdll!LdrpValidateUserCallTarget (77cf8e70)}
0:000> p
Time Travel Position: 128D25:1177
eax=0e1872e4 ebx=53ac2ed0 ecx=70c39720 edx=00140010 esi=70c39720 edi=43320f59
eip=70c3633a esp=006fb788 ebp=006fb798 iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200247
CoolType!CTCleanup+0x40b2a:
70c3633a ffd6            call    esi {CoolType!CTCleanup+0x43f10 (70c39720)}
0:000> p
Time Travel Position: 128D25:1195
eax=43320efb ebx=53ac2ed0 ecx=0000005f edx=70f0f040 esi=70c39720 edi=43320f59
eip=70c3633c esp=006fb788 ebp=006fb798 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200206
CoolType!CTCleanup+0x40b2c:
70c3633c 59              pop     ecx

[...]
0:000> g
43320efb  2c b3 00 40 01 40 42 42                          ,..@.@BB             ;<--------------------------------  (15)
Time Travel Position: 128D25:119A
eax=43320efb ebx=53ac2ed0 ecx=43320efb edx=70f0f040 esi=70c39720 edi=43320f59
eip=70c362f9 esp=006fb790 ebp=006fb798 iopl=0         nv up ei ng nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200283
CoolType!CTCleanup+0x40ae9:
70c362f9 8a11            mov     dl,byte ptr [ecx]          ds:002b:43320efb=2c
0:000> pc
Time Travel Position: 128D25:11A8
eax=43320b84 ebx=53ac2ed0 ecx=70c36850 edx=70f0f02c esi=70c36850 edi=43320f59
eip=70c36334 esp=006fb788 ebp=006fb798 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
CoolType!CTCleanup+0x40b24:
70c36334 ff15ac26e370    call    dword ptr [CoolType!CTGetVersion+0x14fa3c (70e326ac)] ds:002b:70e326ac={ntdll!LdrpValidateUserCallTarget (77cf8e70)}
0:000> p
Time Travel Position: 128D25:11B4
eax=0e186d0a ebx=53ac2ed0 ecx=70c36850 edx=00000400 esi=70c36850 edi=43320f59
eip=70c3633a esp=006fb788 ebp=006fb798 iopl=0         nv up ei pl zr na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200247
CoolType!CTCleanup+0x40b2a:
70c3633a ffd6            call    esi {CoolType!CTCleanup+0x41040 (70c36850)}  ;<--------------------------------  (16)

At (14), the b0 (PUSHB) instruction pushes the next byte, 0x14, to the interpreter stack. This value indicates the function number. In the next iteration at (15), the opcode 0x2c (FDEF) is encountered, which defines function 0x14. The function responsible for handling the opcode 0x2c is called at (16) to define the font function 0x14.

0:000> p
Time Travel Position: 128D25:11D5
eax=00000001 ebx=43320ab8 ecx=70f0f040 edx=43320efc esi=43320b84 edi=00000014
eip=70c368c9 esp=006fb774 ebp=006fb780 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200297
CoolType!CTCleanup+0x410b9:
70c368c9 8bc8            mov     ecx,eax
0:000> p
Time Travel Position: 128D25:11D6
eax=00000001 ebx=43320ab8 ecx=00000001 edx=43320efc esi=43320b84 edi=00000014
eip=70c368cb esp=006fb774 ebp=006fb780 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200297
CoolType!CTCleanup+0x410bb:
70c368cb 668944fb06      mov     word ptr [ebx+edi*8+6],ax ds:002b:43320b5e=0002
0:000> p
Time Travel Position: 128D25:11D7
eax=00000001 ebx=43320ab8 ecx=00000001 edx=43320efc esi=43320b84 edi=00000014
eip=70c368d0 esp=006fb774 ebp=006fb780 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200297
CoolType!CTCleanup+0x410c0:
70c368d0 8bc2            mov     eax,edx
0:000> p
Time Travel Position: 128D25:11D8
eax=43320efc ebx=43320ab8 ecx=00000001 edx=43320efc esi=43320b84 edi=00000014
eip=70c368d2 esp=006fb774 ebp=006fb780 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200297
CoolType!CTCleanup+0x410c2:
70c368d2 2b84cea4000000  sub     eax,dword ptr [esi+ecx*8+0A4h] ds:002b:43320c30=43320cf4 ; <-------------- (17)
0:000> p
Time Travel Position: 128D25:11D9
eax=00000208 ebx=43320ab8 ecx=00000001 edx=43320efc esi=43320b84 edi=00000014
eip=70c368d9 esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x410c9:
70c368d9 8bf2            mov     esi,edx
0:000> p
Time Travel Position: 128D25:11DA
eax=00000208 ebx=43320ab8 ecx=00000001 edx=43320efc esi=43320efc edi=00000014
eip=70c368db esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x410cb:
70c368db 8904fb          mov     dword ptr [ebx+edi*8],eax ds:002b:43320b58=c0c0c0c0 ; <------------------- (18)
0:000> p
Time Travel Position: 128D25:11DB
eax=00000208 ebx=43320ab8 ecx=00000001 edx=43320efc esi=43320efc edi=00000014
eip=70c368de esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x410ce:
70c368de 8b0df8c8f070    mov     ecx,dword ptr [CoolType!CTGetVersion+0x229c88 (70f0c8f8)] ds:002b:70f0c8f8=43320f59

[...]
0:000> p
Time Travel Position: 128D25:11DE
eax=00000208 ebx=43320ab8 ecx=43320f59 edx=43320efc esi=43320efc edi=00000014
eip=70c368e8 esp=006fb774 ebp=006fb780 iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200287
CoolType!CTCleanup+0x410d8:
70c368e8 8a02            mov     al,byte ptr [edx]          ds:002b:43320efc=b3 ;<----------------------- (19)
0:000> p
Time Travel Position: 128D25:11DF
eax=000002b3 ebx=43320ab8 ecx=43320f59 edx=43320efc esi=43320efc edi=00000014
eip=70c368ea esp=006fb774 ebp=006fb780 iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200287
CoolType!CTCleanup+0x410da:
70c368ea 42              inc     edx

0:000> p
Time Travel Position: 128D25:11E0
eax=000002b3 ebx=43320ab8 ecx=43320f59 edx=43320efd esi=43320efc edi=00000014
eip=70c368eb esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200203
CoolType!CTCleanup+0x410db:
70c368eb 3c2d            cmp     al,2Dh                                     ;<--------------------- (20)
0:000> p
Time Travel Position: 128D25:11E1
eax=000002b3 ebx=43320ab8 ecx=43320f59 edx=43320efd esi=43320efc edi=00000014
eip=70c368ed esp=006fb774 ebp=006fb780 iopl=0         nv up ei ng nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200292
CoolType!CTCleanup+0x410dd:
70c368ed 7413            je      CoolType!CTCleanup+0x410f2 (70c36902)   [br=0]
0:000> p
Time Travel Position: 128D25:11E2
eax=000002b3 ebx=43320ab8 ecx=43320f59 edx=43320efd esi=43320efc edi=00000014
eip=70c368ef esp=006fb774 ebp=006fb780 iopl=0         nv up ei ng nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200292
CoolType!CTCleanup+0x410df:
70c368ef 52              push    edx
0:000> p
Time Travel Position: 128D25:11E3
eax=000002b3 ebx=43320ab8 ecx=43320f59 edx=43320efd esi=43320efc edi=00000014
eip=70c368f0 esp=006fb770 ebp=006fb780 iopl=0         nv up ei ng nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200292
CoolType!CTCleanup+0x410e0:
70c368f0 e866000000      call    CoolType!CTCleanup+0x4114b (70c3695b)   ;<---------------------  (21)
0:000> p
Time Travel Position: 128D25:11F3
eax=43320f01 ebx=43320ab8 ecx=00000004 edx=43320f01 esi=43320efc edi=00000014
eip=70c368f5 esp=006fb770 ebp=006fb780 iopl=0         nv up ei pl nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200212
CoolType!CTCleanup+0x410e5:
70c368f5 59              pop     ecx
0:000> db 43320f01
43320f01  42 42 01 4b b8 10 00 63-00 4b b8 10 00 59 20 8a  BB.K...c.K...Y .
43320f11  20 8a 55 58 20 8a 20 8a-52 58 23 62 20 b0 00 23   .UX . .RX#b ..#
43320f21  42 1c 45 41 b0 01 23 42-59 20 b0 40 52 58 b2 00  B.EA..#BY .@RX..

0:000> p
Time Travel Position: 128D25:11F4
eax=43320f01 ebx=43320ab8 ecx=43320efd edx=43320f01 esi=43320efc edi=00000014
eip=70c368f6 esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200212
CoolType!CTCleanup+0x410e6:
70c368f6 8b0df8c8f070    mov     ecx,dword ptr [CoolType!CTGetVersion+0x229c88 (70f0c8f8)] ds:002b:70f0c8f8=43320f59
0:000> p
Time Travel Position: 128D25:11F5
eax=43320f01 ebx=43320ab8 ecx=43320f59 edx=43320f01 esi=43320efc edi=00000014
eip=70c368fc esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200212
CoolType!CTCleanup+0x410ec:
70c368fc 8bd0            mov     edx,eax
0:000> p
Time Travel Position: 128D25:11F6
eax=43320f01 ebx=43320ab8 ecx=43320f59 edx=43320f01 esi=43320efc edi=00000014
eip=70c368fe esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200212
CoolType!CTCleanup+0x410ee:
70c368fe 3bd1            cmp     edx,ecx                            ;<---------------------  (22)
0:000> p
Time Travel Position: 128D25:11F7
eax=43320f01 ebx=43320ab8 ecx=43320f59 edx=43320f01 esi=43320efc edi=00000014
eip=70c36900 esp=006fb774 ebp=006fb780 iopl=0         nv up ei ng nz ac po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200293
CoolType!CTCleanup+0x410f0:
70c36900 72e6            jb      CoolType!CTCleanup+0x410d8 (70c368e8)   [br=1]
0:000> u
CoolType!CTCleanup+0x410ee:
70c368fe 3bd1            cmp     edx,ecx
70c36900 72e6            jb      CoolType!CTCleanup+0x410d8 (70c368e8)
70c36902 3bd1            cmp     edx,ecx
70c36904 7510            jne     CoolType!CTCleanup+0x41106 (70c36916)
70c36906 807aff2d        cmp     byte ptr [edx-1],2Dh
70c3690a 740a            je      CoolType!CTCleanup+0x41106 (70c36916)
70c3690c c705f4c8f07004110000 mov dword ptr [CoolType!CTGetVersion+0x229c84 (70f0c8f4)],1104h
70c36916 8bca            mov     ecx,edx   

[...]

  
0:000> g
43320f21  42 1c 45 41 b0 01 23 42-59 20 b0 40 52 58 b2 00  B.EA..#BY .@RX..
43320f31  20 00 43 63 42 b2 01 20-01 43 63 42 b0 20 63 b0   .CcB.. .CcB. c.
Time Travel Position: 128D25:1439
eax=43320f21 ebx=43320ab8 ecx=00000000 edx=43320f21 esi=43320efc edi=00000014
eip=70c368f5 esp=006fb770 ebp=006fb780 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
CoolType!CTCleanup+0x410e5:
70c368f5 59              pop     ecx
0:000> g
43320f22  1c 45 41 b0 01 23 42 59-20 b0 40 52 58 b2 00 20  .EA..#BY .@RX.. 
43320f32  00 43 63 42 b2 01 20 01-43 63 42 b0 20 63 b0 19  .CcB.. .CcB. c..
Time Travel Position: 128D25:144E
eax=43320f22 ebx=43320ab8 ecx=00000000 edx=43320f22 esi=43320efc edi=00000014
eip=70c368f5 esp=006fb770 ebp=006fb780 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
CoolType!CTCleanup+0x410e5:
70c368f5 59              pop     ecx
0:000> g
43320f23  45 41 b0 01 23 42 59 20-b0 40 52 58 b2 00 20 00  EA..#BY .@RX.. .
43320f33  43 63 42 b2 01 20 01 43-63 42 b0 20 63 b0 19 65  CcB.. .CcB. c..e
Time Travel Position: 128D25:1463
eax=43320f23 ebx=43320ab8 ecx=00000000 edx=43320f23 esi=43320efc edi=00000014
eip=70c368f5 esp=006fb770 ebp=006fb780 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
CoolType!CTCleanup+0x410e5:
70c368f5 59              pop     ecx
0:000> g
43320f24  41 b0 01 23 42 59 20 b0-40 52 58 b2 00 20 00 43  A..#BY .@RX.. .C
43320f34  63 42 b2 01 20 01 43 63-42 b0 20 63 b0 19 65 1c  cB.. .CcB. c..e.
Time Travel Position: 128D25:1478
eax=43320f24 ebx=43320ab8 ecx=00000000 edx=43320f24 esi=43320efc edi=00000014
eip=70c368f5 esp=006fb770 ebp=006fb780 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200246
CoolType!CTCleanup+0x410e5:
70c368f5 59              pop     ecx     
0:000> g
43321086  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????  ;<---------------------  (22)
43321096  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
Time Travel Position: 128D25:1499
eax=43321086 ebx=43320ab8 ecx=00000161 edx=43321086 esi=43320efc edi=00000014
eip=70c368f5 esp=006fb770 ebp=006fb780 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x410e5:
70c368f5 59              pop     ecx
 0:000> p
Time Travel Position: 128D25:149A
eax=43321086 ebx=43320ab8 ecx=43320f25 edx=43321086 esi=43320efc edi=00000014
eip=70c368f6 esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x410e6:
70c368f6 8b0df8c8f070    mov     ecx,dword ptr [CoolType!CTGetVersion+0x229c88 (70f0c8f8)] ds:002b:70f0c8f8=43320f59
0:000> p
Time Travel Position: 128D25:149B
eax=43321086 ebx=43320ab8 ecx=43320f59 edx=43321086 esi=43320efc edi=00000014
eip=70c368fc esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x410ec:
70c368fc 8bd0            mov     edx,eax
0:000> p
Time Travel Position: 128D25:149C
eax=43321086 ebx=43320ab8 ecx=43320f59 edx=43321086 esi=43320efc edi=00000014
eip=70c368fe esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x410ee:
70c368fe 3bd1            cmp     edx,ecx                                         ;<---------------------  (23)
0:000> p
Time Travel Position: 128D25:149D
eax=43321086 ebx=43320ab8 ecx=43320f59 edx=43321086 esi=43320efc edi=00000014
eip=70c36900 esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200216
CoolType!CTCleanup+0x410f0:
70c36900 72e6            jb      CoolType!CTCleanup+0x410d8 (70c368e8)   [br=0]
0:000> p
Time Travel Position: 128D25:149E
eax=43321086 ebx=43320ab8 ecx=43320f59 edx=43321086 esi=43320efc edi=00000014
eip=70c36902 esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200216
CoolType!CTCleanup+0x410f2:
70c36902 3bd1            cmp     edx,ecx
0:000> p
Time Travel Position: 128D25:149F
eax=43321086 ebx=43320ab8 ecx=43320f59 edx=43321086 esi=43320efc edi=00000014
eip=70c36904 esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200216
CoolType!CTCleanup+0x410f4:
70c36904 7510            jne     CoolType!CTCleanup+0x41106 (70c36916)   [br=1]
0:000> p
Time Travel Position: 128D25:14A0
eax=43321086 ebx=43320ab8 ecx=43320f59 edx=43321086 esi=43320efc edi=00000014
eip=70c36916 esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200216
CoolType!CTCleanup+0x41106:
70c36916 8bca            mov     ecx,edx
0:000> p
Time Travel Position: 128D25:14A1
eax=43321086 ebx=43320ab8 ecx=43321086 edx=43321086 esi=43320efc edi=00000014
eip=70c36918 esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200216
CoolType!CTCleanup+0x41108:
70c36918 8bc2            mov     eax,edx
0:000> p
Time Travel Position: 128D25:14A2
eax=43321086 ebx=43320ab8 ecx=43321086 edx=43321086 esi=43320efc edi=00000014
eip=70c3691a esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200216
CoolType!CTCleanup+0x4110a:
70c3691a 2bce            sub     ecx,esi                                         ;<---------------------  (24)
0:000> dd ecx
43321086  ???????? ???????? ???????? ????????
43321096  ???????? ???????? ???????? ????????
433210a6  ???????? ???????? ???????? ????????
433210b6  ???????? ???????? ???????? ????????
433210c6  ???????? ???????? ???????? ????????
433210d6  ???????? ???????? ???????? ????????
433210e6  ???????? ???????? ???????? ????????
433210f6  ???????? ???????? ???????? ????????
0:000> p
Time Travel Position: 128D25:14A3
eax=43321086 ebx=43320ab8 ecx=0000018a edx=43321086 esi=43320efc edi=00000014
eip=70c3691c esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200212
CoolType!CTCleanup+0x4110c:
70c3691c 49              dec     ecx
0:000> p
Time Travel Position: 128D25:14A4
eax=43321086 ebx=43320ab8 ecx=00000189 edx=43321086 esi=43320efc edi=00000014
eip=70c3691d esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x4110d:
70c3691d 66894cfb04      mov     word ptr [ebx+edi*8+4],cx ds:002b:43320b5c=c0c0  ;<---------------------  (25)
0:000> p
Time Travel Position: 128D25:14A5
eax=43321086 ebx=43320ab8 ecx=00000189 edx=43321086 esi=43320efc edi=00000014
eip=70c36922 esp=006fb774 ebp=006fb780 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200202
CoolType!CTCleanup+0x41112:
70c36922 5b              pop     ebx

At (17), the offset of function 0x14 is calculated from the beginning of the font program. At (18), this offset is stored in a buffer using the font function number as an index. Later, a loop starts at (19) to find the end of the font function. It reads an opcode and checks whether it is the 0x2D (ENDF) opcode. If not, a function is called at (21) to decode the instruction. Note that instruction lengths are variable. The function at (21) will decode the instruction and return a pointer to the next instruction in the buffer. At (22), the buffer containing the next instruction is compared with the end of the font program. If the next instruction is within the font program, the loop will continue.

In our case, function 0x14 contains an arbitrarily large malformed instruction. When the function at (21) is called, it returns a pointer that points outside the font program buffer, which can be observed at (22). Consequently, the comparison at (23) becomes false, but the program does not bail out because it incorrectly assumes that the function definition will always be within the font program.

Later, the size of the function is calculated at (0x24). Here, the size of the function is determined to be 0x18a after removing the FDEF and ENDF opcodes, but the actual size of the function is 0x4f. For reference, the following bytes show only the vulnerable function definition.

B0 14   
2C 
B3 00 40 01 40 42 42 01 4B B8 10 00 63 00 4B B8 
10 00 59 20 8A 20 8A 55 58 20 8A 20 8A 52 58 23 
62 20 B0 00 23 42 1C 45 41 B0 01 23 42 59 20 B0 
40 52 58 B2 00 20 00 43 63 42 B2 01 20 01 43 63 
42 B0 20 63 B0 19 65 1C 21 59 1B 21 21 59 
2D 

The invalid instruction is 41 B0 01 .... The opcode 0x41 (NPUSHW) pushes 0xb0 words to the interpreter register. Note that the function definition itself doesn’t contain 0xb0 * 2 bytes, so when the function is called by the control value program, the execution of the function by the interpreter will lead to an out-of-bounds read. This can be observed at the time of the crash:

0:000> g
(ae8.1ef4): Access violation - code c0000005 (first/second chance not available)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
Time Travel Position: 128D32:0
eax=43321028 ebx=43320f59 ecx=43321028 edx=43320b84 esi=70c58990 edi=43321085
eip=70c362f9 esp=006fb760 ebp=006fb768 iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00200287
CoolType!CTCleanup+0x40ae9:
70c362f9 8a11            mov     dl,byte ptr [ecx]          ds:002b:43321028=??
0:000> dd ecx
43321028  ???????? ???????? ???????? ????????
43321038  ???????? ???????? ???????? ????????
43321048  ???????? ???????? ???????? ????????
43321058  ???????? ???????? ???????? ????????
43321068  ???????? ???????? ???????? ????????
43321078  ???????? ???????? ???????? ????????
43321088  ???????? ???????? ???????? ????????
43321098  ???????? ???????? ???????? ????????
0:000> u
CoolType!CTCleanup+0x40ae9:
70c362f9 8a11            mov     dl,byte ptr [ecx]
70c362fb 41              inc     ecx
70c362fc 832d04c9f07001  sub     dword ptr [CoolType!CTGetVersion+0x229c94 (70f0c904)],1
70c36303 0fb6f2          movzx   esi,dl
70c36306 747b            je      CoolType!CTCleanup+0x40b73 (70c36383)
70c36308 a1acc8f070      mov     eax,dword ptr [CoolType!CTGetVersion+0x229c3c (70f0c8ac)]
70c3630d 80b81901000001  cmp     byte ptr [eax+119h],1
70c36314 7513            jne     CoolType!CTCleanup+0x40b19 (70c36329)
0:000> kb
 # ChildEBP RetAddr      Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00 006fb768 70c3a11d     43320efc 43321085 43320f87 CoolType!CTCleanup+0x40ae9
01 006fb784 70c3633c     43320f87 0000002b 43320b84 CoolType!CTCleanup+0x4490d
02 006fb79c 70c3629e     43320f59 43320f87 43320c0c CoolType!CTCleanup+0x40b2c
03 006fb828 70c38962     43320f88 70f0d550 43320f59 CoolType!CTCleanup+0x40a8e
04 006fb858 70c373f9     43320f88 70f0d550 43320b84 CoolType!CTCleanup+0x43152
05 006fb8a4 70c371be     40878c18 40878d88 40878d48 CoolType!CTCleanup+0x41be9
06 006fb900 70c37077     006fba50 006fb980 00000001 CoolType!CTCleanup+0x419ae
07 006fb91c 70c33097     006fba50 006fb980 53ac2ed0 CoolType!CTCleanup+0x41867
08 006fbaa4 70c32922     53ac2ed0 70f14a18 006fbc90 CoolType!CTCleanup+0x3d887
09 006fbcd0 70c2b49b     006fc790 006fbd5c 00000000 CoolType!CTCleanup+0x3d112
0a 006fc7dc 70c2928a     00000000 00000000 00000000 CoolType!CTCleanup+0x35c8b
0b 006fc8b0 70c27d7d     4e4beda8 00000032 006fc984 CoolType!CTCleanup+0x33a7a
0c 006fd210 70c27418     4fde68fc 006fd244 a5e12cc2 CoolType!CTCleanup+0x3256d
0d 006fd56c 70c2733c     4fde68fc 4fde68e4 a5e12c06 CoolType!CTCleanup+0x31c08
0e 006fd5a8 70f803a1     53d36d28 4fde68fc 4fde68e4 CoolType!CTCleanup+0x31b2c
0f 006fd5bc 70f7553e     4fde68e4 70f74fd0 53cde954 AGM!AGMTerminate+0xa2f1
10 006fd5d0 70f70087     53cde960 713f0a50 00000001 AGM!AGMInitialize+0x1bd7e
11 006fd5f4 70f7f198     006fd620 006fd63c 006fd65c AGM!AGMInitialize+0x168c7
12 006fd608 70f7f1c4     00000001 e8a4fa6a 00000000 AGM!AGMTerminate+0x90e8
13 006fd6c0 70f7e711     006fd6e8 77cb5f2e 3f800000 AGM!AGMTerminate+0x9114
14 006fd71c 70f7e88d     4fde6820 006fd7e4 2e8f2428 AGM!AGMTerminate+0x8661
15 006fd788 70f7d529     006fd89c 4fde6820 006fd7e4 AGM!AGMTerminate+0x87dd
16 006fd8a4 698ee78a     006fd914 53d36df8 1b68afe0 AGM!AGMTerminate+0x7479
17 00000000 00000000     00000000 00000000 00000000 AcroRd32!DllCanUnloadNow+0x1c5dba

Using this vulnerability, it is possible to read arbitrary memory of the process. Because of complex interactions between PDF reader and font subcomponents, especially in the presence of a JavaScript engine, it is possible that sensitive contents of arbitrary memory could be disclosed, which could aid in further exploitation and exploit mitigation bypass.

TIMELINE

2024-09-10 - Vendor Disclosure
2024-12-10 - Vendor Patch Release
2024-12-11 - Public Release

Credit

Discovered by KPC of Cisco Talos.