среда, 8 августа 2018 г.

bug in wtsapi32!WTSFreeMemoryExA

prototype
BOOL WTSFreeMemoryExA(
  WTS_TYPE_CLASS WTSTypeClass,
  PVOID          pMemory,
  ULONG          NumberOfEntries
);

WTS_TYPE_CLASS declared in WtsApi32.h as
enum _WTS_TYPE_CLASS {
  WTSTypeProcessInfoLevel0 = 0x0,
  WTSTypeProcessInfoLevel1 = 0x1,
  WTSTypeSessionInfoLevel1 = 0x2,
};

ok, check in disasm what happens:
WTSFreeMemoryExA proc near 
  push    rbx
  sub     rsp, 20h
  xor     ebx, ebx
  cmp     ecx, ebx
  jl      short loc_7FF70582EC2
  cmp     ecx, 1 ; whut ?
  jg      short loc_7FF70582EC2
  call    WTSFreeMemoryExW
  mov     ebx, eax
  jmp     short loc_7FF70582ECD

loc_7FF70582EC2: 
  mov     ecx, 87         ; dwErrCode - ERROR_INVALID_PARAMETER
  call    cs:__imp_SetLastError 

as you can see you cannot pass WTSTypeSessionInfoLevel1 to function WTSFreeMemoryExA - it gives error ERROR_INVALID_PARAMETER. As dirty workaround you can use WTSFreeMemoryExW - it has correct checking of WTSTypeClass. btw this lead to memory leaks and known at least since 2013