- #include < stdio.h >
- #include < Windows.h >
- #include < Icm.h >
- #pragma comment(lib, "mscms.lib")
- int main(int argc, char** argv)
- {
- char dstProfilePath[] = "sRGB Color Space Profile.icm";
- tagPROFILE destinationProfile;
- HPROFILE hDstProfile = nullptr;
- destinationProfile.dwType = PROFILE_FILENAME;
- destinationProfile.pProfileData = dstProfilePath;
- destinationProfile.cbDataSize = (strlen(dstProfilePath) + 1);
- hDstProfile = OpenColorProfileA(&destinationProfile, PROFILE_READ,
- FILE_SHARE_READ, OPEN_EXISTING);
- if (nullptr == hDstProfile)
- {
- return -1;
- }
- tagPROFILE sourceProfile;
- HPROFILE hSrcProfile = nullptr;
- HTRANSFORM hColorTransform = nullptr;
- DWORD dwIntent[] = { INTENT_PERCEPTUAL, INTENT_PERCEPTUAL };
- HPROFILE hProfileList[2];
- sourceProfile.dwType = PROFILE_FILENAME;
- sourceProfile.pProfileData = argv[1];
- sourceProfile.cbDataSize = (strlen(argv[1]) + 1);
- hSrcProfile = OpenColorProfileA(&sourceProfile, PROFILE_READ,
- FILE_SHARE_READ, OPEN_EXISTING);
- if (nullptr == hSrcProfile)
- {
- return -1;
- }
- hProfileList[0] = hSrcProfile;
- hProfileList[1] = hDstProfile;
- hColorTransform = CreateMultiProfileTransform(
- hProfileList,
- 2,
- dwIntent,
- 2,
- USE_RELATIVE_COLORIMETRIC | BEST_MODE,
- INDEX_DONT_CARE
- );
- if (nullptr == hColorTransform)
- {
- return -1;
- }
- DeleteColorTransform(hColorTransform);
- CloseColorProfile(hSrcProfile);
- CloseColorProfile(hDstProfile);
- return 0;
- }
- 0:000 > r
- rax=0000023690497000 rbx=0000000000000000 rcx=00000000000000ff
- rdx=000000000000ffff rsi=0000023690496f00 rdi=0000023690496fee
- rip=00007ffa46bf3790 rsp=000000c2a56ff5a8 rbp=0000000000000001
- r8=0000000000000014 r9=0000023690497002 r10=0000000000000014
- r11=0000000000000014 r12=000000c2a56ff688 r13=0000023690492de0
- r14=000000000000000a r15=000000004c616220
- iopl=0 nv up ei ng nz ac pe cy
- cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000293
- icm32!SwapShortOffset+0x10:
- 00007ffa`46bf3790 0fb610 movzx edx,byte ptr [rax] ds:00000236`90497000=??
- 0:000 > !heap -p -a @rax
- address 0000023690497000 found in
- _DPH_HEAP_ROOT @ 23690411000
- in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
- 23690412b60: 23690496f00 100 - 23690496000 2000
- 00007ffa51644807 ntdll!RtlDebugAllocateHeap+0x000000000000003f
- 00007ffa515f49d6 ntdll!RtlpAllocateHeap+0x0000000000077ae6
- 00007ffa5157babb ntdll!RtlpAllocateHeapInternal+0x00000000000001cb
- 00007ffa51479da0 msvcrt!malloc+0x0000000000000070
- 00007ffa46bf3805 icm32!SmartNewPtr+0x0000000000000011
- 00007ffa46bf37c8 icm32!SmartNewPtrClear+0x0000000000000014
- 00007ffa46c02d05 icm32!InitNamedColorProfileData+0x0000000000000085
- 00007ffa46bf6e39 icm32!Create_LH_ProfileSet+0x0000000000004e15
- 00007ffa46bf1973 icm32!PrepareCombiLUTs+0x0000000000000117
- 00007ffa46bf1814 icm32!CMMConcatInitPrivate+0x00000000000001f4
- 00007ffa46bf12a1 icm32!CWConcatColorWorld4MS+0x0000000000000075
- 00007ffa46bf11f4 icm32!CMCreateMultiProfileTransformInternal+0x00000000000000e8
- 00007ffa46bf1039 icm32!CMCreateMultiProfileTransform+0x0000000000000029
- 00007ffa48f16e6c mscms!CreateMultiProfileTransform+0x000000000000024c
- 00007ff774651191 ldr+0x0000000000001191
- 00007ff7746514b4 ldr+0x00000000000014b4
- 00007ffa505a7bd4 KERNEL32!BaseThreadInitThunk+0x0000000000000014
- 00007ffa515aced1 ntdll!RtlUserThreadStart+0x0000000000000021
- unsigned __int16 *__fastcall SwapShortOffset(void *sourceBuff, unsigned int offset, unsigned int len)
- {
- unsigned __int16 *endBuff; // r9
- unsigned __int16 *result; // rax
- endBuff = (sourceBuff + len);
- for ( result = (sourceBuff + offset); result < endBuff; ++result )
- *result = _byteswap_ushort(*result); // read, bswap and write
- return result;
- }
- __int64 __fastcall InitNamedColorProfileData(__int64 a1, void *hProfile, int a3, _DWORD *a4)
- {
- ...
- ...
- errCode = CMGetPartialProfileElement(hProfile, 'ncl2', 0, pBuffSize, 0i64); // getting size of ncl2 element
- if ( errCode )
- return errCode;
- minSize = pBuffSize[0];
- if ( pBuffSize[0] < 0x55 )
- minSize = 0x55;
- pBuffSize[0] = minSize;
- outBuff = SmartNewPtrClear(minSize, &errCode); // allocating the buffer for ncl2
- ...
- ...
- errCode = CMGetPartialProfileElement(hProfile, 'ncl2', 0, pBuffSize, outBuff); // reading ncl2 elements to buffer
- if ( !errCode )
- {
- ...
- ...
- totalSizeToRead = count * totalDeviceCoord;
- if ( totalSizeToRead < 0xFFFFFFFFFFFFFFAEui64 && totalSizeToRead + 0x51 <= pBuffSize[0] ) // totalSizeToRead + 0x51 <= element size?
- {
- currPtr = outBuff + 0x54; // wrong offset of 0x54 is used
- ...
- ...
- do
- {
- SwapShortOffset((currPtr + 0x20), 0, 6u);
- ...
- --count;
- }while(count)
- __int64 __fastcall CMConvIndexToNameProfile(HPROFILE hProfile, __int64 a2, __int64 a3, unsigned int a4)
- {
- ...
- ...
- errCode = CMGetPartialProfileElement(hProfile, 'ncl2', 0, pBuffSize, 0i64); // read size
- if ( !errCode )
- {
- allocBuff = SmartNewPtr(pBuffSize[0], &errCode);
- if ( !errCode )
- {
- errCode = CMGetPartialProfileElement(hProfile, 'ncl2', 0, pBuffSize, allocBuff); // read to buffer
- if ( !errCode )
- {
- SwapLongOffset((allocBuff + 12), 0, 4u); // 12 > *pBuffSize ?
- SwapLongOffset((allocBuff + 16), v12, v13);
本文翻译自:https://www.fireeye.com/blog/threat-research/2020/09/fuzzing-image-parsing-in-windows-color-profiles.html如若转载,请注明原文地址。