ESET researchers examined CVE‑2025‑50165, a severe Home windows vulnerability described to grant distant code execution by merely opening a specifically crafted JPG file – probably the most broadly used picture codecs. The flaw, discovered and documented by Zscaler ThreatLabz, piqued our curiosity, as Microsoft assessed its severity as essential however deemed its exploitability as much less possible. Our root trigger evaluation allowed us to pinpoint the precise location of the defective code and reproduce the crash. We imagine that the exploitation state of affairs is more durable than it seems to be.
Key factors of this blogpost:
- ESET researchers provide a deep dive evaluation of the CVE‑2025‑50165 vulnerability, illustrated with pseudocode snippets.
- We offer our methodology to breed the crash utilizing a easy 12-bit or 16-bit JPG picture, and an examination of the preliminary launched patch.
- CVE-2025-50165 is a flaw within the encoding and compressing means of a JPG picture, not in its decoding.
- Our conclusion explores and reassesses the exploitability and the assault state of affairs of this flaw.
Overview
On November 20th, 2025, Zscaler ThreatLabz revealed an article documenting the invention of CVE‑2025‑50165, a high-impact distant code execution vulnerability current in WindowsCodecs.dll. This library is Home windows’ principal interface library answerable for dealing with commonest picture file codecs, reminiscent of JPG, PNG, GIF, BMP, and many others. Zscaler’s findings, in addition to the description offered by Microsoft, reveal that the flaw stems from the dereference of an uninitialized operate pointer in WindowsCodecs.dll, which is a part of the Home windows Imaging Part. The previous managed to trace down the dereference situation contained in the jpeg_finish_compress operate, which occurs to be referred to as when a JPG picture stream is compressed and (re-)encoded. In terms of image-handling vulnerabilities, one would first consider parsing and decoding bugs that occur as quickly because the picture is rendered. So this fairly particular susceptible code path left us with some questions we needed to reply:
- What are the precise situations to take the susceptible code path resulting in the dereference of the uninitialized operate pointer?
- When is jpeg_finish_compress referred to as?
- Why is the operate pointer not initialized?
Given how frequent JPG pictures are on the net, we needed solutions, so we began by investigating the code that brought about the crash.
Crash website
In line with the CVE‑2025‑50165 entry description, WindowsCodecs.dll variations from 10.0.26100.0 and earlier than 10.0.26100.4946 are affected. We analyzed the susceptible model 10.0.26100.4768 (SHA-1: 5887D96565749067564BABCD3DC5D107AB6666BD), after which carried out a binary comparability with the primary patched model 10.0.26100.4946 (SHA-1: 4EC1DC0431432BC318E78C520387911EC44F84FC). After downloading the corresponding symbols, we appeared on the crashing operate, jpeg_finish_compress. In line with a model string current in WindowsCodecs.dll – libjpeg-turbo model 3.0.2 (construct 20250529) – the DLL depends on a fairly previous implementation of the libjpeg-turbo library (launched on January 24th, 2024) to deal with JPG pictures. The publicly obtainable repository allowed us to map a lot of the related binary code and constructions to their supply code equivalents. For example, the compiled model of jpeg_finish_compress is similar to its supply code equal obtainable right here, as proven in Determine 1.

Primarily based on Zscaler’s findings, the crash occurs at jpeg_finish_compress+0xCC, which corresponds to line 48 in Determine 1, when dereferencing a operate pointer positioned at offset 0x10 of an unknown construction (pub). In line with libjpeg-turbo source code, this corresponds to a operate pointer named compress_data_12. So as to attain this particular path, the data_precision member of jpeg_compress_struct must be set to 12. This corresponds to the bit depth, or in different phrases the variety of bits used to explain colours. Primarily, WindowsCodecs.dll crashes when it tries to encode a 12‑bit precision JPG picture.
Patch diffing and root trigger evaluation
Utilizing Diaphora, a binary diffing software, we carried out a diff between the susceptible model 10.0.26100.4768 and the patched model 10.0.26100.4946, as proven in Determine 2.

Surprisingly, the crashing operate jpeg_finish_compress talked about within the article will not be current. Nevertheless, two encoding-related features have been modified: rawtransencode_master_selection and jinit_c_rawtranscode_coef_controller_turbo. The diff between the susceptible and patched variations of rawtransencode_master_selection is proven in Determine 3.

The one related distinction appears to be that the operate jinit_c_rawtranscode_coef_controller_turbo, which was beforehand inlined within the physique of the operate rawtransencode_master_selection, is now separated. Trying on the patched model of the jinit_c_rawtranscode_coef_controller_turbo operate reveals that the beforehand uninitialized construction member compress_data_12 is now set to level to a operate named rawtranscode_compress_output_16, as proven in Determine 4.

Be aware that the sphere compress_data_16, which was additionally not initialized within the susceptible model, can also be set to level to rawtranscode_compress_output_16 within the patched model. This operate is just a stub operate that calls rawtranscode_compress_output, which can point out that there’s no particular code to deal with both 12-bit or 16-bit precision JPG pictures.
Reproducing the crash
As talked about in Zscaler’s article, one can compile the code snippet proposed by Microsoft (https://study.microsoft.com/en-us/home windows/win32/wic/-wic-codec-jpegmetadataencoding#jpeg-re-encode-example-code) to decode and re-encode a JPG picture.
As soon as this program is compiled, the crash could be reproduced by offering both a 12-bit or a 16-bit JPG file. Going by the samples from the libjpeg-turbo repository, a 12-bit precision pattern picture is obtainable for obtain at https://github.com/libjpeg-turbo/libjpeg-turbo/blob/principal/testimages/testorig12.jpg. Feeding this picture to the re-encoding instance software resulted in a crash at the very same location talked about in Zscaler’s article. Determine 5 reveals the context of the crash throughout a debugging session.

The repeated hex worth 0xBAADF00D pointed to by the reminiscence deal with is a magic worth utilized by the C runtime (CRT) heap when a program calls HeapAlloc to allocate reminiscence. It marks the reminiscence as uninitialized (see https://www.nobugs.org/developer/win32/debug_crt_heap.html).
As indicated beforehand, each analyzed variations of WindowsCodecs.dll seem to have the ability to deal with 16-bit precision JPG pictures. However when testing such pictures, the re-encoding software crashes when dereferencing the compress_data_16 operate pointer, as noticed in Determine 6.

Having reproduced the crash, we questioned whether or not this particular vulnerability was additionally current within the supply code of the libjpeg-turbo library.
Exploring the supply code
Going by the commits of libjpeg-turbo revealed that related points have been resolved on December 18th, 2024, with commit e0e18de, introducing model 3.1.1. Primarily, the commit makes certain that constructions are zero-initialized and that an error is raised if a pointer is NULL. It seems that each one the zero-initializations and checks launched by this commit are absent within the susceptible and patched variations of WindowsCodecs.dll.
The patch message additionally hints at different potential susceptible code paths and, extra importantly, that crashes can also occur within the decompression course of when manipulating a JPG picture, as highlighted by the diff of file jdapistd.c, illustrated in Determine 7.

Because the commit description clearly specifies, a calling software would crash (because of the dereference of an uninitialized operate pointer) solely if it erroneously adjustments the data_precision area after calling the jpeg_start_compress or jpeg_start_decompress routines. This creates a fairly particular and certain unrealistic state of affairs the place an software utilizing WindowsCodecs.dll would alter the state of inside constructions. Whereas such purposes could exist, it doesn’t seem that the Home windows Imaging Part API permits such conduct.
Exploitability
As revealed by our root trigger evaluation, the core situation of CVE‑2025‑50165 resides in WindowsCodecs.dll’s dealing with of JPG pictures with an information precision worth apart from the traditional and normal 8-bit. The 2 precision-specific operate pointers (compress_data_12 and compress_data_16) have been uninitialized throughout the compression course of, creating two susceptible code paths that appear to be reachable solely when (re-)encoding a JPG picture. Merely opening, and subsequently decoding and rendering, a specifically crafted picture won’t set off the vulnerability. Nevertheless, the susceptible operate jpeg_finish_compress might be referred to as if the picture is saved or if a number software, such because the Microsoft Photographs software, creates thumbnails of pictures, as proven in Determine 8.

To ensure that a program to be thought-about susceptible, it wants the next traits:
- makes use of a susceptible model of WindowsCodecs.dll,
- doesn’t crash or abort whereas decoding a 12-bit or 16-bit JPG file, and
- permits the picture to be re-encoded.
Furthermore, as talked about by Zscaler researchers, an deal with leak and sufficient management over the heap are obligatory to use this vulnerability.
Conclusion
Though JPG is older, broadly used, and maybe the preferred digital picture format in fuzz testing, vulnerabilities can nonetheless be present in some codecs. This research of CVE‑2025‑50165 additionally highlights the significance of maintaining with safety updates when utilizing third-party libraries.
Root trigger evaluation together with patch diffing proved a really highly effective mixture that allowed us to reply our preliminary questions. We came upon that the bug could be triggered when WindowsCodecs.dll encodes a 12-bit or a 16-bit precision JPG stream as each precision-specific operate pointers have been neither initialized nor checked earlier than being dereferenced. Moreover, we discovered that this course of occurs when such a picture is saved or when a thumbnail is created from it.
This investigation led us to the same conclusion as Microsoft’s relating to the exploitability of this vulnerability. Certainly, as WindowsCodecs.dll is a library, a number software can be thought-about susceptible if it permits JPG pictures to be (re-)encoded, and exploitable provided that an attacker has sufficient management over the appliance (deal with leak, heap manipulation). Placing all of it collectively, it appears certainly that exploitation is unlikely.
Lastly, it’s price mentioning that, as of this writing and in accordance with our exams, newer variations of WindowsCodecs.dll (reminiscent of 10.0.22621.6133, SHA-1: 3F3767D05E5A91184005D98427074711F68D9950) implement the completely different adjustments talked about in libjpeg-turbo’s commit, successfully addressing the dearth of initialization and performance pointer verification.

