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 crucial however deemed its exploitability as much less probably. Our root trigger evaluation allowed us to pinpoint the precise location of the defective code and reproduce the crash. We consider that the exploitation state of affairs is tougher 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 technique 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 printed 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’ predominant interface library chargeable for dealing with most typical picture file codecs, reminiscent of JPG, PNG, GIF, BMP, and many others. Zscaler’s findings, in addition to the description supplied 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 Element. The previous managed to trace down the dereference difficulty 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 relation to image-handling vulnerabilities, one would first consider parsing and decoding bugs that occur as quickly because the picture is rendered. So this relatively particular susceptible code path left us with some questions we needed to reply:
- What are the precise circumstances 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 widespread JPG photos are on the internet, we needed solutions, so we began by investigating the code that triggered the crash.
Crash web site
In response to 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 regarded on the crashing operate, jpeg_finish_compress. In response to a model string current in WindowsCodecs.dll – libjpeg-turbo model 3.0.2 (construct 20250529) – the DLL depends on a relatively previous implementation of the libjpeg-turbo library (launched on January 24th, 2024) to deal with JPG photos. The publicly obtainable repository allowed us to map many of the related binary code and constructions to their supply code equivalents. As an illustration, 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 situated at offset 0x10 of an unknown construction (pub). In response to libjpeg-turbo source code, this corresponds to a operate pointer named compress_data_12. To be able 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. Basically, 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 instrument, 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 isn’t current. Nevertheless, two encoding-related features had 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.

Observe that the sphere compress_data_16, which was additionally not initialized within the susceptible model, can 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 photos.
Reproducing the crash
As talked about in Zscaler’s article, one can compile the code snippet proposed by Microsoft (https://be taught.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 accessible for obtain at https://github.com/libjpeg-turbo/libjpeg-turbo/blob/predominant/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 handle 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 photos. However when testing such photos, the re-encoding software crashes when dereferencing the compress_data_16 operate pointer, as noticed in Determine 6.

Having reproduced the crash, we puzzled 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 had been resolved on December 18th, 2024, with commit e0e18de, introducing model 3.1.1. Basically, the commit makes certain that constructions are zero-initialized and that an error is raised if a pointer is NULL. It seems that every 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 may additionally 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 modifications the data_precision discipline after calling the jpeg_start_compress or jpeg_start_decompress routines. This creates a relatively particular and sure unrealistic state of affairs the place an software utilizing WindowsCodecs.dll would alter the state of inner constructions. Whereas such purposes might exist, it doesn’t seem that the Home windows Imaging Element API permits such habits.
Exploitability
As revealed by our root trigger evaluation, the core difficulty of CVE‑2025‑50165 resides in WindowsCodecs.dll’s dealing with of JPG photos with a knowledge precision worth aside from the traditional and commonplace 8-bit. The 2 precision-specific operate pointers (compress_data_12 and compress_data_16) had been uninitialized in the course of the compression course of, creating two susceptible code paths that appear to be reachable solely when (re-)encoding a JPG picture. Merely opening, and due to this fact decoding and rendering, a specifically crafted picture won’t set off the vulnerability. Nevertheless, the susceptible operate jpeg_finish_compress may very well be referred to as if the picture is saved or if a number software, such because the Microsoft Images software, creates thumbnails of photos, as proven in Determine 8.

To ensure that a program to be thought of 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 handle leak and sufficient management over the heap are necessary to take advantage of 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 had 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 an identical conclusion as Microsoft’s concerning the exploitability of this vulnerability. Certainly, as WindowsCodecs.dll is a library, a number software can be thought of susceptible if it permits JPG photos to be (re-)encoded, and exploitable provided that an attacker has sufficient management over the appliance (handle leak, heap manipulation). Placing all of it collectively, it appears certainly that exploitation is unlikely.
Lastly, it’s value mentioning that, as of this writing and in accordance with our checks, newer variations of WindowsCodecs.dll (reminiscent of 10.0.22621.6133, SHA-1: 3F3767D05E5A91184005D98427074711F68D9950) implement the completely different modifications talked about in libjpeg-turbo’s commit, successfully addressing the dearth of initialization and performance pointer verification.










