Einzelnen Beitrag anzeigen

Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#7

AW: Function (WIMGetMountedImageInfo)

  Alt 17. Dez 2013, 01:44
When one image, everything works
I doubt that ...

You were just "lucky". The uninitialized size variable contained a sufficient size for the returned data struct. The api call in it's current form destroys a random memory region (directly behind the output buffer) in your program (buffer overflow), if there is more than one mounted image.

I cant really test it, because i have no mounted images, but it should work like this. Happy copy and paste:
Delphi-Quellcode:
type
  _WIM_MOUNT_LIST = packed record
    WimPath: array[0..MAX_PATH - 1] of WideChar;
    MountPath: array[0..MAX_PATH - 1] of WideChar;
    ImageIndex: DWord;
    MountedForRW: BOOL;
  end;
  WIM_MOUNT_LIST = _WIM_MOUNT_LIST;
  PWIM_MOUNT_LIST = ^WIM_MOUNT_LIST;
type
  WIM_MOUNT_INFO_LEVEL0 = _WIM_MOUNT_LIST;
  PWIM_MOUNT_INFO_LEVEL0 = ^WIM_MOUNT_LIST;
type
  MOUNTED_IMAGE_INFO_LEVELS = DWord;
const
  MountedImageInfoLevel0 = 1;
var
  WIMGetMountedImageInfo: function(fInfoLevelId: MOUNTED_IMAGE_INFO_LEVELS;
    var dwImageCount: DWord; pMountInfo: Pointer; cbMountInfoLength: DWord;
    var cbReturnLength: DWord): BOOL; stdcall;
type
  PWIM_MOUNT_INFO_LEVEL0_LIST = ^WIM_MOUNT_INFO_LEVEL0_LIST;
  WIM_MOUNT_INFO_LEVEL0_LIST = array[0..0] of WIM_MOUNT_INFO_LEVEL0;
var
  Success: Boolean;
  Buffer: PWIM_MOUNT_INFO_LEVEL0_LIST;
  BufferLength,
  ReturnLength,
  ImageCount: DWord;
  I: Integer;
begin
  @WIMGetMountedImageInfo := GetProcAddress(LoadLibrary('wimgapi.dll'), 'WIMGetMountedImageInfo');
  BufferLength := SizeOf(WIM_MOUNT_INFO_LEVEL0) * 8;
  GetMem(Buffer, BufferLength);
  try
    repeat
      Success := WIMGetMountedImageInfo(MountedImageInfoLevel0, ImageCount, Buffer, BufferLength,
        ReturnLength);
      if (Success) then
      begin
        for I := 0 to ImageCount - 1 do
        begin
          ShowMessage(StrPas(PChar(@Buffer^[I].WimPath[0])));
        end;
      end else if (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
      begin
        ReallocMem(Buffer, ReturnLength);
      end;
    until (Success) or (GetLastError <> ERROR_INSUFFICIENT_BUFFER);
  finally
    FreeMem(Buffer);
  end;
end;
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat