CVE-2025-27931
An out-of-bounds read vulnerability exists in the EMF functionality of PDF-XChange Editor version 10.5.2.395. By using a specially crafted EMF file, an attacker could exploit this vulnerability to perform an out-of-bounds read, potentially leading to the disclosure of sensitive information.
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
PDF-XChange Co. Ltd PDF-XChange Editor 10.5.2.395
PDF-XChange Editor - https://www.pdf-xchange.com/product/pdf-xchange-editor
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
PDF-XChange Editor is a powerful and feature-rich PDF viewer and editor. It offers a wide range of tools to view, create, edit, annotate, sign, and convert PDF files. It’s a popular alternative to heavier PDF applications like Adobe Acrobat.
PDF-XChange Editor supports the conversion of EMF files into PDFs. This vulnerability is related to the processing of EMF files during conversion.
An EMF (Enhanced Metafile Format) file stores images in a device-independent form. It begins with a header (EMR_HEADER
) that contains information about the structure and contents of the metafile. The structure of the EMR_HEADER
is as follows:
Offset Size Name
------ ---- --------------------------------------
0x00 0x04 recordType (0x00000001 )
0x04 0x04 recordSize
0x08 0x10 bounds
0x18 0x10 frame
0x28 0x04 recordSignature (0x464D4520)
0x2C 0x04 version
0x30 0x04 sizeInBytes
0x34 0x04 numOfRecords
0x38 0x02 Handles
0x3A 0x02 Reserved
Please note that the structure of EMR_HEADER
shown is not complete; it only includes the relevant fields.
For the EMR_HEADER
record, the recordType
must be 0x00000001
. The recordSize
indicates the total size of the header record in bytes. The recordSignature
field defines the record signature, which must have the value 0x464D4520
(FME
). The sizeInBytes
field specifies the size of the metafile in bytes. The numOfRecords
indicates the total number of records present in the metafile, including the EMR_HEADER
.
This vulnerability is associated with the record type EMR_POLYDRAW16
.
The EMR_POLYDRAW16
represents a set of line segments and Bezier curves. The structure of the EMR_POLYDRAW16
is as follows:
Offset Size Name
----- ---------- --------------------------------------
0x00 0x04 recordType (0x0000005C )
0x04 0x04 recordSize
0x08 0x10 bounds
0x18 0x04 cpts (N)
0x1C N*4 aPoints
0x1C+N*4 N abTypes
For the EMR_POLYDRAW16
record, the recordType
value must be 0x0000005C
. The cpts
value indicates the number of elements present in both aPoints
and abTypes
. aPoints
is an array of PointS
objects, while abTypes
is an array of bytes that specifies the types of points.This specify how a point is to be used in drawing cell. Its value can be point
enumeration as shown below:
typdef enum {
PT_CLOSEFIGURE = 0x01,
PT_LINETO = 0x02,
PT_BEZIERTO = 0x04,
PT_MOVETO = 0x06
} Point;
This vulnerability occurs while processing the abTypes
field when it contains the PT_BEZIERTO
point type. It can be observed during debugging with pageheap enabled:
0:006> p
Breakpoint 4 hit
Time Travel Position: 4C7339:177
rax=0000000000000042 rbx=000001c7f8b10fe0 rcx=0000000000000080
rdx=00007ffc600051c9 rsi=000001c79b51ff80 rdi=0000000000000004
rip=00007ffc600051c9 rsp=0000004f938fcb10 rbp=0000004f938fcc10
r8=000001c79b520000 r9=00007ffc5d6f0000 r10=000001c79b51ffec
r11=0000000000000014 r12=000000000000005c r13=000001c79b51f9e0
r14=0000004f938fd0d0 r15=0000000000000000
iopl=0 nv up ei pl nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
PDFXEditCore_x64!PXV_GetInstance+0x1b429b9:
00007ffc`600051c9 8b7e18 mov edi,dword ptr [rsi+18h] ds:000001c7`9b51ff98=00000014 ;<-------- (1)
0:006>db rsi L84 ;<-------- (2)
000001c7`9b51ff80 5c 00 00 00 80 00 00 00-5e 00 00 00 ca 07 00 00 \.......^.......
000001c7`9b51ff90 50 01 00 00 68 08 00 00-14 00 00 00 64 00 d0 07 P...h.......d...
000001c7`9b51ffa0 96 00 d2 07 c6 00 f3 07-b3 00 2a 08 79 00 2a 08 ..........*.y.*.
000001c7`9b51ffb0 66 00 f3 07 96 00 d2 07-ec 00 62 08 ec 00 62 08 f.........b...b.
000001c7`9b51ffc0 d2 07 ec 00 62 08 ec 00-62 08 aa 00 5a 08 dc 00 ....b...b...Z...
000001c7`9b51ffd0 12 08 eb 00 fc 07 e4 00-08 08 fa 00 ee 07 10 01 ................
000001c7`9b51ffe0 08 08 09 01 fc 07 18 01-12 08 4a 01 5a 08 08 01 ..........J.Z...
000001c7`9b51fff0 62 08 fa 00 34 08 06 02-02 02 02 02 02 06 04 04 b...4...........
000001c7`9b520000 ?? ?? ?? ?? ????
[...]
0:006> p
Time Travel Position: 4C7339:17D
rax=0000000000000042 rbx=0000000000000014 rcx=0000000000000080
rdx=00007ffc600051c9 rsi=000001c79b51ff9c rdi=0000000000000014
rip=00007ffc600051de rsp=0000004f938fcb10 rbp=0000004f938fcc10
r8=000001c79b520000 r9=00007ffc5d6f0000 r10=000001c79b51ffec
r11=0000000000000014 r12=000000000000005c r13=000001c79b51ffd0
r14=0000004f938fd0d0 r15=0000000000000000
iopl=0 nv up ei pl nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
PDFXEditCore_x64!PXV_GetInstance+0x1b429ce:
00007ffc`600051de 488d0cfd00000000 lea rcx,[rdi*8] ;<------------------------- (3)
0:006> p
Time Travel Position: 4C7339:17E
rax=0000000000000042 rbx=0000000000000014 rcx=00000000000000a0
rdx=00007ffc600051c9 rsi=000001c79b51ff9c rdi=0000000000000014
rip=00007ffc600051e6 rsp=0000004f938fcb10 rbp=0000004f938fcc10
r8=000001c79b520000 r9=00007ffc5d6f0000 r10=000001c79b51ffec
r11=0000000000000014 r12=000000000000005c r13=000001c79b51ffd0
r14=0000004f938fd0d0 r15=0000000000000000
iopl=0 nv up ei pl nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
PDFXEditCore_x64!PXV_GetInstance+0x1b429d6:
00007ffc`600051e6 e815b947fe call PDFXEditCore_x64!DllUnregisterServer+0xce0 (00007ffc`5e480b00) ;<------------------------- (4)
0:006> p
Time Travel Position: 4C7343:1A
rax=000001c79b9c0500 rbx=0000000000000014 rcx=00000000ffffffff
rdx=0000000000000008 rsi=000001c79b51ff9c rdi=0000000000000014
rip=00007ffc600051eb rsp=0000004f938fcb10 rbp=0000004f938fcc10
r8=0000000000000500 r9=0000000000000000 r10=0000000000000030
r11=0000000000000014 r12=000000000000005c r13=000001c79b51ffd0
r14=0000004f938fd0d0 r15=0000000000000000
iopl=0 nv up ei pl nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
PDFXEditCore_x64!PXV_GetInstance+0x1b429db:
00007ffc`600051eb 4c8be0 mov r12,rax
0:006> db rax ;<------------------------- (5)
000001c7`9b9c0500 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000001c7`9b9c0510 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000001c7`9b9c0520 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000001c7`9b9c0530 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000001c7`9b9c0540 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000001c7`9b9c0550 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000001c7`9b9c0560 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000001c7`9b9c0570 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0:006> pc
Time Travel Position: 4C7343:C5
rax=000000000000014a rbx=0000000000000000 rcx=0000004f938fd0d0
rdx=000001c79b9c0500 rsi=000001c79b51ffec rdi=0000000000000014
rip=00007ffc60005227 rsp=0000004f938fcb10 rbp=0000004f938fcc10
r8=0000000000000014 r9=000001c79b51ffec r10=0000000000000030
r11=0000000000000014 r12=000001c79b9c0500 r13=000001c79b51ffd0
r14=0000004f938fd0d0 r15=0000000000000000
iopl=0 nv up ei pl zr na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
PDFXEditCore_x64!PXV_GetInstance+0x1b42a17:
00007ffc`60005227 e8c4060000 call PDFXEditCore_x64!PXV_GetInstance+0x1b430e0 (00007ffc`600058f0) ;<------------------------- (6)
0:006> p
crash in this function, r15 contain vuln buffer, rbp is end of index, rsi is index
Time Travel Position: 4C7348:1596
rax=000001c79b9c05b0 rbx=0000000000000000 rcx=000000000000222e
rdx=0000000000005730 rsi=000001c79b51ffec rdi=0000000000000014
rip=00007ffc6000590d rsp=0000004f938fcaa0 rbp=0000000000000014
r8=0000000000000006 r9=0000000000000017 r10=0000000000000001
r11=0000000046ae5fff r12=000001c79b9c05b0 r13=0000004f938fd0d0
r14=0000004f938fd0d0 r15=000001c79b51ffec
iopl=0 nv up ei pl nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
PDFXEditCore_x64!PXV_GetInstance+0x1b430fd:
00007ffc`6000590d 4885c0 test rax,rax
0:006> db 000001c7`9b9c0500 ;<---------------------------------- (7)
000001c7`9b9c0500 64 00 00 00 d0 07 00 00-96 00 00 00 d2 07 00 00 d...............
000001c7`9b9c0510 c6 00 00 00 f3 07 00 00-b3 00 00 00 2a 08 00 00 ............*...
000001c7`9b9c0520 79 00 00 00 2a 08 00 00-66 00 00 00 f3 07 00 00 y...*...f.......
000001c7`9b9c0530 96 00 00 00 d2 07 00 00-ec 00 00 00 62 08 00 00 ............b...
000001c7`9b9c0540 ec 00 00 00 62 08 00 00-d2 07 00 00 ec 00 00 00 ....b...........
000001c7`9b9c0550 62 08 00 00 ec 00 00 00-62 08 00 00 aa 00 00 00 b.......b.......
000001c7`9b9c0560 5a 08 00 00 dc 00 00 00-12 08 00 00 eb 00 00 00 Z...............
000001c7`9b9c0570 fc 07 00 00 e4 00 00 00-08 08 00 00 fa 00 00 00 ................
At (1)
, the value of cpts
is read. The content of the EMR_POLYDRAW16
record is examined at (2)
. Next, at (3)
, the size of a buffer is calculated using cpts
. The method invoked at (4)
calls malloc
to allocate the aPoints
buffer. At (6)
, a method is called to read and write aPoints
to the buffer. Finally, at (7)
, the buffer is examined to display the content of the aPoints
field.
0:006> p
Time Travel Position: 4C7348:15A1
rax=000001c79b9c05b0 rbx=000001c79b9c05b0 rcx=000000000000222e
rdx=0000000000005730 rsi=0000000000000000 rdi=0000000000000014
rip=00007ffc60005940 rsp=0000004f938fcaa0 rbp=0000000000000014
r8=0000000000000006 r9=0000000000000017 r10=0000000000000001
r11=0000000046ae5fff r12=000001c79b9c05b0 r13=0000004f938fd0d0
r14=0000004f938fd0d0 r15=000001c79b51ffec
iopl=0 nv up ei pl nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
PDFXEditCore_x64!PXV_GetInstance+0x1b43130:
00007ffc`60005940 420fb60c3e movzx ecx,byte ptr [rsi+r15] ds:000001c7`9b51ffec=5a ;<---------------------------------- (8)
0:006> u rip L32
PDFXEditCore_x64!PXV_GetInstance+0x1b43130:
00007ffc`60005940 420fb60c3e movzx ecx,byte ptr [rsi+r15]
00007ffc`60005945 83e902 sub ecx,2
00007ffc`60005948 746b je PDFXEditCore_x64!PXV_GetInstance+0x1b431a5 (00007ffc`600059b5)
00007ffc`6000594a 83e901 sub ecx,1
00007ffc`6000594d 7466 je PDFXEditCore_x64!PXV_GetInstance+0x1b431a5 (00007ffc`600059b5)
00007ffc`6000594f 83e901 sub ecx,1
00007ffc`60005952 7422 je PDFXEditCore_x64!PXV_GetInstance+0x1b43166 (00007ffc`60005976)
00007ffc`60005954 83e901 sub ecx,1
00007ffc`60005957 741d je PDFXEditCore_x64!PXV_GetInstance+0x1b43166 (00007ffc`60005976)
00007ffc`60005959 bf01000000 mov edi,1 ;<----------------------- (9)
00007ffc`6000595e 3bcf cmp ecx,edi
00007ffc`60005960 756a jne PDFXEditCore_x64!PXV_GetInstance+0x1b431bc (00007ffc`600059cc)
00007ffc`60005962 f30f105304 movss xmm2,dword ptr [rbx+4]
00007ffc`60005967 498d4d10 lea rcx,[r13+10h]
00007ffc`6000596b f30f100b movss xmm1,dword ptr [rbx]
00007ffc`6000596f e8bc04ffff call PDFXEditCore_x64!PXV_GetInstance+0x1b33620 (00007ffc`5fff5e30)
00007ffc`60005974 eb56 jmp PDFXEditCore_x64!PXV_GetInstance+0x1b431bc (00007ffc`600059cc)
00007ffc`60005976 f30f104314 movss xmm0,dword ptr [rbx+14h]
00007ffc`6000597b 498d4d10 lea rcx,[r13+10h]
00007ffc`6000597f f30f104b10 movss xmm1,dword ptr [rbx+10h]
00007ffc`60005984 bf03000000 mov edi,3 ;<----------------------- (10)
00007ffc`60005989 f30f105b08 movss xmm3,dword ptr [rbx+8]
00007ffc`6000598e f30f105304 movss xmm2,dword ptr [rbx+4]
00007ffc`60005993 f30f11442430 movss dword ptr [rsp+30h],xmm0
00007ffc`60005999 f30f10430c movss xmm0,dword ptr [rbx+0Ch]
00007ffc`6000599e f30f114c2428 movss dword ptr [rsp+28h],xmm1
00007ffc`600059a4 f30f100b movss xmm1,dword ptr [rbx]
00007ffc`600059a8 f30f11442420 movss dword ptr [rsp+20h],xmm0
00007ffc`600059ae e83df3feff call PDFXEditCore_x64!PXV_GetInstance+0x1b324e0 (00007ffc`5fff4cf0)
00007ffc`600059b3 eb17 jmp PDFXEditCore_x64!PXV_GetInstance+0x1b431bc (00007ffc`600059cc)
00007ffc`600059b5 f30f105304 movss xmm2,dword ptr [rbx+4]
00007ffc`600059ba 498d4d10 lea rcx,[r13+10h]
00007ffc`600059be f30f100b movss xmm1,dword ptr [rbx]
00007ffc`600059c2 bf01000000 mov edi,1 ;<----------------------- (11)
00007ffc`600059c7 e8d403ffff call PDFXEditCore_x64!PXV_GetInstance+0x1b33590 (00007ffc`5fff5da0)
00007ffc`600059cc 8bc7 mov eax,edi
00007ffc`600059ce 03f7 add esi,edi ;<----------------------- (12)
00007ffc`600059d0 488d1cc3 lea rbx,[rbx+rax*8]
00007ffc`600059d4 8d46ff lea eax,[rsi-1] ;<----------------------- (13)
00007ffc`600059d7 42f6043801 test byte ptr [rax+r15],1 ;<----------------------- (14)
00007ffc`600059dc 740e je PDFXEditCore_x64!PXV_GetInstance+0x1b431dc (00007ffc`600059ec)
00007ffc`600059de 498b4510 mov rax,qword ptr [r13+10h]
00007ffc`600059e2 498d4d10 lea rcx,[r13+10h]
00007ffc`600059e6 ff90c8000000 call qword ptr [rax+0C8h]
00007ffc`600059ec 3bf5 cmp esi,ebp ;<----------------------- (15)
00007ffc`600059ee 0f824cffffff jb PDFXEditCore_x64!PXV_GetInstance+0x1b43130 (00007ffc`60005940) ;<----------------------- (16)
00007ffc`600059f4 4c8b742440 mov r14,qword ptr [rsp+40h]
00007ffc`600059f9 488bbc2480000000 mov rdi,qword ptr [rsp+80h]
00007ffc`60005a01 8d45ff lea eax,[rbp-1]
00007ffc`60005a04 498bcc mov rcx,r12
A loop begins at (8)
and ends at (16)
. At (8)
, it reads abTypes
. Based on abTypes
, the register value edi
is set. The default value is 0x01
, but it is set to 0x03
when the value of the abTypes
element is 0x05
or 0x04
, indicating the point type is PT_BEZIERTO
. At (12)
, edi
is added to the index. Later, at (14)
, this index is used to access abTypes
, but there is no check performed to ensure whether the index is within bounds. This can lead to an out-of-bounds read vulnerability, which we can observed at the time of crash:
0:006> g
(1438.1e8c): 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: 4C7357:0
rax=0000000000000014 rbx=000001c79b9c0658 rcx=48d23a57be070000
rdx=0000004f938fc9c0 rsi=0000000000000015 rdi=0000000000000003
rip=00007ffc600059d7 rsp=0000004f938fcaa0 rbp=0000000000000014
r8=0000000000000018 r9=0000000000000006 r10=00007ffc5d6f0000
r11=0000000046ae5fff r12=000001c79b9c05b0 r13=0000004f938fd0d0
r14=0000004f938fd0d0 r15=000001c79b51ffec
iopl=0 nv up ei pl nz na pe nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
PDFXEditCore_x64!PXV_GetInstance+0x1b431c7:
00007ffc`600059d7 42f6043801 test byte ptr [rax+r15],1 ds:000001c7`9b520000=??
0:006> dd rax+r15
000001c7`9b520000 ???????? ???????? ???????? ????????
000001c7`9b520010 ???????? ???????? ???????? ????????
000001c7`9b520020 ???????? ???????? ???????? ????????
000001c7`9b520030 ???????? ???????? ???????? ????????
000001c7`9b520040 ???????? ???????? ???????? ????????
000001c7`9b520050 ???????? ???????? ???????? ????????
000001c7`9b520060 ???????? ???????? ???????? ????????
000001c7`9b520070 ???????? ???????? ???????? ????????
0:006> u
PDFXEditCore_x64!PXV_GetInstance+0x1b431c7:
00007ffc`600059d7 42f6043801 test byte ptr [rax+r15],1
00007ffc`600059dc 740e je PDFXEditCore_x64!PXV_GetInstance+0x1b431dc (00007ffc`600059ec)
00007ffc`600059de 498b4510 mov rax,qword ptr [r13+10h]
00007ffc`600059e2 498d4d10 lea rcx,[r13+10h]
00007ffc`600059e6 ff90c8000000 call qword ptr [rax+0C8h]
00007ffc`600059ec 3bf5 cmp esi,ebp
00007ffc`600059ee 0f824cffffff jb PDFXEditCore_x64!PXV_GetInstance+0x1b43130 (00007ffc`60005940)
00007ffc`600059f4 4c8b742440 mov r14,qword ptr [rsp+40h]
0:006> kb
# RetAddr : Args to Child : Call Site
00 00007ffc`6000522c : 00000000`00000000 000001c7`9b51ffec 00000000`00000014 00001f68`00000423 : PDFXEditCore_x64!PXV_GetInstance+0x1b431c7
01 00007ffc`9c0aed9f : 00000000`000005a0 000001c7`f8a40d20 000001c7`f8a40d20 000001c7`f8a40d20 : PDFXEditCore_x64!PXV_GetInstance+0x1b42a1c
02 00007ffc`9c25d432 : 00000000`00000246 0000004f`938fcfa1 00007ffc`9c221284 00007ffc`9c0c883f : gdi32full!bInternalPlayEMF+0x2564f
03 00007ffc`60001486 : 00000000`00000014 0000004f`938fcfa1 000001c7`9b9e0100 0000004f`938fd0d0 : GDI32!EnumEnhMetaFileStub+0x52
04 00007ffc`5e8a6624 : 0000004f`938fd100 000001c7`eeb6f360 000001c7`fa41e6d0 000001c7`e922eeb0 : PDFXEditCore_x64!PXV_GetInstance+0x1b3ec76
05 00007ffc`5e8bcac0 : 000001c7`9b9400b0 000001c7`ee9bc7b0 00000000`00000000 000001c7`9b9400b0 : PDFXEditCore_x64!PXV_GetInstance+0x3e3e14
06 00007ffc`5e5c1375 : 0000004f`00001193 000001c7`fa507260 000001c7`fa507260 00000000`00000000 : PDFXEditCore_x64!PXV_GetInstance+0x3fa2b0
07 00007ffc`5e68ffb3 : 000001c7`ff9069f0 000001c7`f1970170 00000000`00000000 000001c7`f1970170 : PDFXEditCore_x64!PXV_GetInstance+0xfeb65
08 00007ffc`5f5de983 : 000001c7`ee9bc8d0 00000000`ffffffff 000001c7`f1970170 000001c7`ff87f8b0 : PDFXEditCore_x64!PXV_GetInstance+0x1cd7a3
09 00007ffc`5f52dfa7 : 00000000`ffffffff 00000000`00000314 000001c7`ef087fd0 00000000`00000000 : PDFXEditCore_x64!PXV_GetInstance+0x111c173
0a 00007ffc`9e097374 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : PDFXEditCore_x64!PXV_GetInstance+0x106b797
0b 00007ffc`9e27cc91 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x14
0c 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21
Exploiting this vulnerability allows for the reading of arbitrary memory within the process, potentially disclosing sensitive information.
2025-04-22 - Initial Vendor Contact
2025-05-07 - Vendor Disclosure
2025-07-22 - Vendor Patch Release
2025-08-05 - Public Release
Discovered by KPC of Cisco Talos.