Jump to content

Recommended Posts

Posted (edited)

Hey,

i'm working with a dll which comes with Windows 10 (Pro x64) called dismapi.dll, which is located under C:\Windows\system32\dismapi.dll.

I tested some of it's functions with my compiled script on Windows 10 (x86) and it worked properly, but when i run my script on my x64 system with

#AutoIt3Wrapper_UseX64=y

 directive set, it doesn't work anymore (AutoIT breaks on line 1255 in DISM.au3). Without this directive it works.

Is there something i have to change to get it work? Thanks for help...(You can use my attach. If you use WIndows 10, it will work directly, on Windows 8 you might have to adjust the dism api path ($ghdismapi) in DISM.au3. On Windows 7, you will need Windows ADK to get DISM.) _DLLStructDisplay.au3 is only for debug.

https://msdn.microsoft.com/de-de/library/windows/desktop/hh825837.aspx

 

Misc.au3

_DLLStructDisplay.au3

DismConstants.au3

DismExample.au3

DISM.au3

Edited by Trolleule
Posted (edited)

sorry, it's line 1251. AutoIT crashes on this line, where i try to read the pointer in a array of WCHAR.

MsgBox(0, "ProductName", GetPCWSTR($tImageInfo_sub, "ProductName"))

 The function GetPCWSTR can be found in Misc.au3 and looks like:

Func GetPCWSTR(ByRef $struct, $sElementName) ; avoids memory access conflicts
    Local $char_struct
    Local $anz = 0 ; counter for signs
    Local $ptr = DllStructGetData($struct, $sElementName) ; ptr
    Do
        $char_struct = DllStructCreate("WCHAR", $ptr + $anz) ; get memory location
        $anz += 2
    Until DllStructGetData($char_struct, 1) = Chr(0) ; end of string
    Local $PCWSTR_struct = DllStructCreate("WCHAR[" & $anz / 2 & "]", $ptr) ; create struct with correct amount of bytes
    Local $PCWSTR = DllStructGetData($PCWSTR_struct, 1)
    _DISM_Delete($PCWSTR_struct) ; free resources
    Return $PCWSTR ; return string
EndFunc

The problem only occurs when i use 64-bit AutoIT and 64-bit dll version. I think some of the data types are not compatible with 64-bit anymore, although the first 6 elements are readable properly:

MsgBox(0, "ImageType", _DISM_GetImageType(DllStructGetData($tImageInfo_sub, "ImageType")))
            MsgBox(0, "ImageIndex", DllStructGetData($tImageInfo_sub, "ImageIndex"))
            MsgBox(0, "ImageName", GetPCWSTR($tImageInfo_sub, "ImageName"))
            MsgBox(0, "ImageDescription", GetPCWSTR($tImageInfo_sub, "ImageDescription"))
            MsgBox(0, "ImageSize", DllStructGetData($tImageInfo_sub, "ImageSize"))
            MsgBox(0, "Architecture", DllStructGetData($tImageInfo_sub, "Architecture"))
            MsgBox(0, "ProductName", GetPCWSTR($tImageInfo_sub, "ProductName")) ; autoit crashes

EDIT: The exact line where it crashes is in Misc.au3

$char_struct = DllStructCreate("WCHAR", $ptr + $anz) ; get memory location

, when i try to read the pointer of 

"ProductName" in DISM.au3 on line 1251.

I'm not able to read one char of this pointer :S

Edited by Trolleule
Posted (edited)
Local $tagDismImageInfo = "INT ImageType;UINT ImageIndex;PTR ImageName;PTR ImageDescription;UINT64 ImageSize;UINT Architecture;PTR ProductName;PTR EditionId;PTR InstallationType;" & _
                                 "PTR Hal;PTR ProductType;PTR ProductSuite;UINT MajorVersion;UINT MinorVersion;UINT Build;UINT SpBuild;UINT SpLevel;INT Bootable;PTR SystemRoot;" & _
                                 "PTR Language;UINT LanguageCount;UINT DefaultLanguageIndex;PTR CustomizedInfo"

Local $tImageInfo_sub = DllStructCreate($tagDismImageInfo, $pImageInfo)

My first expection was to change some of these data types... otherwise it might be more complicated :S

Perhaps you can test it. You only need Windows ADK + some .wim file. Thanks in advance!

EDIT: Try this DISM.au3, it's better to understand :) (i updated the DISM.au3 in my first post too)

DISM.au3

Edited by Trolleule
Posted

A friend tested it in C++, the x64 dismapi.dll works properly.

Are there some debug techniques i can use to check what is wrong with pointers or a possibility to read the pointer byte by byte?

Posted (edited)

ui that sounds nice. What do you mean with reverse? ->

Local $tagDismImageInfo = "INT ImageType;UINT ImageIndex;PTR ImageName;PTR ImageDescription;UINT64 ImageSize;UINT Architecture;" & _
                              "PTR;SystemRoot;PTR ProductType;PTR Hal;PTR InstallationType;PTR EditionId;PTR ProductName;" & _
                              "PTR ProductSuite;UINT MajorVersion;UINT MinorVersion;UINT Build;UINT SpBuild;UINT SpLevel;INT Bootable;" & _
                              "PTR Language;UINT LanguageCount;UINT DefaultLanguageIndex;PTR CustomizedInfo"

instead of

Local $tagDismImageInfo = "INT ImageType;UINT ImageIndex;PTR ImageName;PTR ImageDescription;UINT64 ImageSize;UINT Architecture;" & _
                              "PTR ProductName;PTR EditionId;PTR InstallationType;PTR Hal;PTR ProductType;PTR ProductSuite;" & _
                              "UINT MajorVersion;UINT MinorVersion;UINT Build;UINT SpBuild;UINT SpLevel;INT Bootable;PTR SystemRoot;" & _
                              "PTR Language;UINT LanguageCount;UINT DefaultLanguageIndex;PTR CustomizedInfo"

?

Reversed:

reversed.png

Normal:

normal.png

Edited by Trolleule
Posted

No, reverse the actual high / low order values. Here's how I did it:

MsgBox(0, "ProductName", GetPCWSTR($tImageInfo, "ProductName", True))
Func GetPCWSTR(ByRef $struct, $sElementName, $lSwap = False) ; avoids memory access conflicts
    Local $char_struct
    Local $anz = 0 ; counter for signs
    Local $ptr = DllStructGetData($struct, $sElementName) ; ptr

    If $lSwap Then
        $ptr = '0x' & hex(_WinAPI_LoDWord($ptr), 8) & hex(_WinAPI_HiDWord($ptr), 8)
    EndIf

    Do
        $char_struct = DllStructCreate("WCHAR", $ptr + $anz) ; get memory location
        $anz += 2
    Until DllStructGetData($char_struct, 1) = Chr(0) ; end of string
    Local $PCWSTR_struct = DllStructCreate("WCHAR[" & $anz / 2 & "]", $ptr) ; create struct with correct amount of bytes
    Local $PCWSTR = DllStructGetData($PCWSTR_struct, 1)
    _DISM_Delete($PCWSTR_struct) ; free resources
    Return $PCWSTR ; return string
EndFunc

You'll need to add "#include <WinAPIMisc.au3>" to Misc.au3.

 

Posted (edited)

big thanks! Now i can read from pointer, but something is strange:

ConsoleWrite("ImageType: " & DllStructGetData($tImageInfo, "ImageType") & @CRLF) ; ok
ConsoleWrite("ImageIndex: " & DllStructGetData($tImageInfo, "ImageIndex") & @CRLF) ; ok
ConsoleWrite("ImageName: " & GetPCWSTR($tImageInfo, "ImageName") & @CRLF) ; ok
ConsoleWrite("ImageDescription: " & GetPCWSTR($tImageInfo, "ImageDescription") & @CRLF) ; ok
ConsoleWrite("ImageSize: " & DllStructGetData($tImageInfo, "ImageSize") & @CRLF) ; ok
ConsoleWrite("Architecture: " & DllStructGetData($tImageInfo, "Architecture") & @CRLF) ; ok
ConsoleWrite("ProductName: " & GetPCWSTR($tImageInfo, "ProductName", True) & @CRLF) ; x86: Betriebssystem Microsoft® Windows® x64: Professional
ConsoleWrite("EditionId: " & GetPCWSTR($tImageInfo, "EditionId", True) & @CRLF) ; x86: Professional x64: Client
ConsoleWrite("InstallationType: " & GetPCWSTR($tImageInfo, "InstallationType", True) & @CRLF) ; x86: Client x64:
ConsoleWrite("Hal: " & GetPCWSTR($tImageInfo, "Hal", True) & @CRLF) ; x86:  x64: WinNT
ConsoleWrite("ProductType: " & GetPCWSTR($tImageInfo, "ProductType", True) & @CRLF) ; x86: WinNT x64: Terminal Server
ConsoleWrite("ProductSuite: " & DLLStructGetData($tImageInfo, "ProductSuite") & @CRLF) ; x86: Terminal Server x64: 0x0000000A000000C8 (PCWSTR will crash AutoIT)
ConsoleWrite("MajorVersion: " & DllStructGetData($tImageInfo, "MajorVersion") & @CRLF) ; x86: 10 x64: 0
ConsoleWrite("MinorVersion: " & DllStructGetData($tImageInfo, "MinorVersion") & @CRLF) ; x86: 0 x64: 10586
ConsoleWrite("Build: " & DllStructGetData($tImageInfo, "Build") & @CRLF) ; x86: 10586 x64: 0
ConsoleWrite("SpBuild: " & DllStructGetData($tImageInfo, "SpBuild") & @CRLF) ; x86: 0 x64: 0
ConsoleWrite("SpLevel: " & DllStructGetData($tImageInfo, "SpLevel") & @CRLF) ; x86: 0 x64: 1
ConsoleWrite("Bootable: " & DllStructGetData($tImageInfo, "Bootable") & @CRLF) ; x86: 1 x64: -1950295936
ConsoleWrite("SystemRoot: " & GetPCWSTR($tImageInfo, "SystemRoot", True) & @CRLF) ; x86: WINDOWS x64: ??o
ConsoleWrite("Language: " & DllStructGetData($tImageInfo, "Language") & @CRLF) ; x86: ok x64: 0x000000010000006F
ConsoleWrite("LanguageCount: " & DllStructGetData($tImageInfo, "LanguageCount") & @CRLF) ; x86: 1 x64: 0
ConsoleWrite("DefaultLanguageIndex: " & DllStructGetData($tImageInfo, "DefaultLanguageIndex") & @CRLF) ; x86: 0 x64: 2291066752
ConsoleWrite("CustomizedInfo: " & DllStructGetData($tImageInfo, "CustomizedInfo") & @CRLF) ; x86: ok x64: 0x000000000000006F

the order is messy. "ProductName" keeps information of "EditionId" and so on, but i think if we can get the order right, the rest would be right too...

Do you know why this happens and do you have a solution?

 

EDIT:

I tested around and campe up with this:

Local $tagDismImageInfo = "INT ImageType;UINT ImageIndex;PTR ImageName;PTR ImageDescription;UINT64 ImageSize;" & _
                          "UINT Architecture;PTR EditionId;PTR InstallationType;" & _
                          "PTR Hal;PTR ProductType;PTR ProductSuite;UINT MajorVersion;UINT MinorVersion;" & _
                          "UINT Build;UINT SpBuild;UINT SpLevel;UINT Bootable;INT SystemRoot;" & _
                         "PTR Language;PTR LanguageCount;UINT DefaultLanguageIndex;UINT CustomizedInfo;PTR ProductName"

ConsoleWrite("ImageType: " & DllStructGetData($tImageInfo, "ImageType") & @CRLF)
ConsoleWrite("ImageIndex: " & DllStructGetData($tImageInfo, "ImageIndex") & @CRLF)
ConsoleWrite("ImageName: " & GetPCWSTR($tImageInfo, "ImageName") & @CRLF)
ConsoleWrite("ImageDescription: " & GetPCWSTR($tImageInfo, "ImageDescription") & @CRLF)
ConsoleWrite("ImageSize: " & DllStructGetData($tImageInfo, "ImageSize") & @CRLF)
ConsoleWrite("Architecture: " & DllStructGetData($tImageInfo, "Architecture") & @CRLF)
ConsoleWrite("ProductName: " & DllStructGetData($tImageInfo, "ProductName") & @CRLF)
ConsoleWrite("EditionId: " & GetPCWSTR($tImageInfo, "EditionId", True) & @CRLF)
ConsoleWrite("InstallationType: " & GetPCWSTR($tImageInfo, "InstallationType", True) & @CRLF)
ConsoleWrite("Hal: " & GetPCWSTR($tImageInfo, "Hal", True) & @CRLF)
ConsoleWrite("ProductType: " & GetPCWSTR($tImageInfo, "ProductType", True) & @CRLF)
ConsoleWrite("ProductSuite: " & GetPCWSTR($tImageInfo, "ProductSuite", True) & @CRLF)
ConsoleWrite("MajorVersion: " & DllStructGetData($tImageInfo, "MajorVersion") & @CRLF)
ConsoleWrite("MinorVersion: " & DllStructGetData($tImageInfo, "MinorVersion") & @CRLF)
ConsoleWrite("Build: " & DllStructGetData($tImageInfo, "Build") & @CRLF)
ConsoleWrite("SpBuild: " & DllStructGetData($tImageInfo, "SpBuild") & @CRLF)
ConsoleWrite("SpLevel: " & DllStructGetData($tImageInfo, "SpLevel") & @CRLF)
ConsoleWrite("Bootable: " & DllStructGetData($tImageInfo, "Bootable") & @CRLF)
ConsoleWrite("SystemRoot: " & DllStructGetData($tImageInfo, "SystemRoot") & @CRLF)
ConsoleWrite("Language: " & GetPCWSTR($tImageInfo, "Language", True) & @CRLF)
ConsoleWrite("LanguageCount: " & DllStructGetData($tImageInfo, "LanguageCount") & @CRLF)
ConsoleWrite("DefaultLanguageIndex: " & DllStructGetData($tImageInfo, "DefaultLanguageIndex") & @CRLF)
ConsoleWrite("CustomizedInfo: " & DllStructGetData($tImageInfo, "CustomizedInfo") & @CRLF)

You can see, the order is wrong, but this gives the best results...

Output:

ImageType: 0
ImageIndex: 1
ImageName: Windows 10 Pro Technical Preview
ImageDescription: Windows 10 Pro Technical Preview
ImageSize: 13298258120
Architecture: 9
EditionId: Professional
InstallationType: Client
Hal: 
ProductType: WinNT
ProductSuite: Terminal Server
MajorVersion: 224
MinorVersion: 10
Build: 0
SpBuild: 10586
SpLevel: 0
Bootable: 0
SystemRoot: 1
Language: ?°Ã
LanguageCount: 0x00000001000000E0
DefaultLanguageIndex: 0
CustomizedInfo: 572084256

Something is really strange :S

 

testing.png

Edited by Trolleule
Posted

Fuck...i got it and i don't know why :D

I only add "align 4" to my struct, default is "align 8". Now it works properly and without Lo/Hi reverse.

$tagDismImageInfo = "align 4;INT ImageType;UINT ImageIndex;PTR ImageName;PTR ImageDescription;UINT64 ImageSize;" & _
                    "UINT Architecture;PTR ProductName;PTR EditionId;PTR InstallationType;" & _
                    "PTR Hal;PTR ProductType;PTR ProductSuite;UINT MajorVersion;UINT MinorVersion;UINT Build;UINT SpBuild;" & _
                    "UINT SpLevel;INT  Bootable;PTR SystemRoot;" & _
                    "PTR Language;UINT LanguageCount;UINT DefaultLanguageIndex;PTR CustomizedInfo"

Big thanks Danp2! I think i have to change the topic title to mark this as resolved right?

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...