CVE-2024-49534
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.
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
Acrobat Reader - https://acrobat.adobe.com/us/en/acrobat/pdf-reader.html
6.5 - CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N
CWE-125 - Out-of-bounds Read
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.
2024-09-10 - Vendor Disclosure
2024-12-10 - Vendor Patch Release
2024-12-11 - Public Release
Discovered by KPC of Cisco Talos.