3131210 发表于 2023-5-5 09:59:24

【已解决】内存调用DLL 报错 250477278

本帖最后由 3131210 于 2023-5-5 12:50 编辑

附件里面有测试用的DLL和例子
例1通过内存调用和DllCall直接调用,都没问题

但是例2通过DLLCall调用没问题,通过内存调用就报错了,不知道是什么原因

haijie1223 发表于 2023-5-5 10:35:23

#NoTrayIcon
#PRE_UseX64=n
#include 'MemoryDll.au3'
Local $hFile = FileOpen('getdiskserial.dll',16)
Local $Binary = FileRead($hFile)
FileClose($hFile)
Local $Module = MemoryDllOpen($Binary)
Local $P = MemoryDllCall($Module, "str", "GetDllVer")
MemoryDllClose($Module)
If IsArray($P) Then MsgBox(0, 0, $P)

3131210 发表于 2023-5-5 11:46:28

本帖最后由 3131210 于 2023-5-5 11:48 编辑

haijie1223 发表于 2023-5-5 10:35

我才发现用GetDllVer这个函数确实没问题      但是用其它的函数就不行了


3131210 发表于 2023-5-5 11:53:58

本帖最后由 3131210 于 2023-5-5 11:55 编辑

不加注册码也可以用,只是会多一个弹窗提示要不要买         这只是测试,所以不加注册码
可以参考例2里面直接dllcall的部分

gyp2000 发表于 2023-5-5 11:54:25

Global Const $RegCode = "LEDN2-HRAC6-5P66D-RU1Y2-D59U9"
$DiskSerial = DllOpen("GetDiskSerial.dll")
DllCall($DiskSerial, "NONE", "SetLicenseKey", "STR", $RegCode)

3131210 发表于 2023-5-5 11:56:24

本帖最后由 3131210 于 2023-5-5 12:01 编辑

gyp2000 发表于 2023-5-5 11:54
Global Const $RegCode = "LEDN2-HRAC6-5P66D-RU1Y2-D59U9"
$DiskSerial = DllOpen("GetDiskSerial.dll")
...
因为这只是测试,所以不加注册码
可以参考例2里面直接dllcall的部分 是可以用的
但是我想实现从内存直接调用call 就报错了

像下面这段    获取版本号没问题   获取硬盘序列号就报错
#NoTrayIcon
#PRE_UseX64=n
#include 'MemoryDll.au3'
Local $hFile = FileOpen('getdiskserial.dll',16)
Local $Binary = FileRead($hFile)
FileClose($hFile)
Local $Module = MemoryDllOpen($Binary)
MemoryDllCall($Module, "NONE", "SetLicenseKey", "STR","LEDN2-HRAC6-5P66D-RU1Y2-D59U9")
Local $P = MemoryDllCall($Module, "str", "GetDllVer")
If IsArray($P) Then ConsoleWrite(@CRLF & $P & @CRLF)
Local $PP = MemoryDllCall($Module, "STR", "GetSerialNumber", "int", 0)
If IsArray($PP) ThenConsoleWrite(@CRLF & $PP & @CRLF)
MemoryDllClose($Module)


gyp2000 发表于 2023-5-5 12:39:23

本帖最后由 gyp2000 于 2023-5-5 12:50 编辑

这个问题大概是这个DLL自校验导致的,有可能是找不到文件做校验,所以直接退出了。
查询版本和查询是否是虚拟机的函数不会触发校验。
这个DLL有做防破解的防护,仅仅是将DLL的UPX解压也会触发防破解校验。

3131210 发表于 2023-5-5 12:50:36

没办法直接调用 那就算了

haijie1223 发表于 2023-5-5 13:00:11

获取硬盘序列号可以用纯代码,没必要调用dll

3131210 发表于 2023-5-5 13:08:15

直接纯代码的我也有


#include <WinAPI.au3>
#include <Crypt.au3>


MsgBox(0,0,_ReadPhysicalDriveInNTWithZeroRights())


Func _ReadPhysicalDriveInNTWithZeroRights($METHOD = 'SerialNumber', $ID = 0) ;非管理员权限
        Local Const $tagSTORAGEPROPERTYQUERY = "int PropertyId;int QueryType;byte AdditionalParams"
        Local Const $tagSTORAGEDEVICEDESCRIPTOR = "ulong Version;ulong Size;byte DeviceType;" & _
                        "byte DeviceTypeModifier;byte RemovableMedia;" & _
                        "byte CommandQueueing;ulong VendorIdOffset;" & _
                        "ulong ProductIdOffset;ulong ProductRevisionOffset;" & _
                        "ulong SerialNumberOffset;int BusType;" & _
                        "ulong RawPropertiesLength;byte RawDeviceProperties"

        Local Const $sPhysDisk = "\\.\PhysicalDrive" & $ID
        Local $aResult = DllCall("kernel32.dll", "handle", "CreateFileW", "wstr", $sPhysDisk, "dword", 0, "dword", BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE), _
                        "struct*", Null, "dword", $OPEN_EXISTING, "dword", 0, "ptr", Null)
        If @error Or ($aResult = $INVALID_HANDLE_VALUE) Then Return SetError(@error, @extended, 'CreateFile fails,error code:' & @error)
        Local $hDisk = $aResult
        Local $tQuery = DllStructCreate($tagSTORAGEPROPERTYQUERY)
        Local $tDescr = DllStructCreate($tagSTORAGEDEVICEDESCRIPTOR)
        Local $tDescrSize = DllStructGetSize($tDescr)
        Local $tBuffer = DllStructCreate($tagSTORAGEDEVICEDESCRIPTOR & ";char Buffer")
        DllStructSetData($tQuery, "PropertyId", 0)
        DllStructSetData($tQuery, "QueryType", 0)
        Local $iResult = _WinAPI_DeviceIoControl($hDisk, $IOCTL_STORAGE_QUERY_PROPERTY, _
                        $tQuery, DllStructGetSize($tQuery), _
                        $tBuffer, DllStructGetSize($tBuffer))
        If $iResult = 0 Then Return SetError(@error, @extended, '_DeviceIoControl IOCTL_STORAGE_QUERY_PROPERTY fails, error code: ' & @error)
        Local $ProductIdOffset = DllStructGetData($tBuffer, 'ProductIdOffset')
        Local $SerialNumberOffset = DllStructGetData($tBuffer, 'SerialNumberOffset')
        Local $ProductRevisionOffset = DllStructGetData($tBuffer, 'ProductRevisionOffset')
        Local $BusType = DllStructGetData($tBuffer, 'BusType')
        DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hDisk)
        Local $ReturnVal
        Switch StringLower($METHOD)
                Case 'productid'
                        Dim $sModel
                        If $ProductIdOffset <= 0 Then Return SetError(-1, 0, 'Unknown ProductId')
                        Local $i = $ProductIdOffset - $tDescrSize + 4
                        While True
                                Local $GetByte = DllStructGetData($tBuffer, "Buffer", $i)
                                If $GetByte <> Chr(0) Then
                                        $sModel &= $GetByte
                                Else
                                        ExitLoop
                                EndIf
                                $i += 1
                        WEnd
                        $ReturnVal = StringStripWS(_CodeBytes($sModel), 3)
                Case 'serialnumber'
                        If $SerialNumberOffset <= 0 Then Return SetError(-1, 0, 'Unknown SerialNumber')
                        Dim $sSerialNum
                        Local $i = $SerialNumberOffset - $tDescrSize + 4
                        While True
                                Local $GetByte = DllStructGetData($tBuffer, "Buffer", $i)
                                If $GetByte <> Chr(0) Then
                                        $sSerialNum &= $GetByte
                                Else
                                        ExitLoop
                                EndIf
                                $i += 1
                        WEnd
                        $ReturnVal = StringStripWS(_CodeBytes($sSerialNum), 8)
                Case 'productrevision'
                        If $ProductRevisionOffset <= 0 Then Return SetError(-1, 0, 'Unknown ProductRevision')
                        Dim $sProductRevision
                        Local $i = $ProductRevisionOffset - $tDescrSize + 4
                        While True
                                Local $GetByte = DllStructGetData($tBuffer, "Buffer", $i)
                                If $GetByte <> Chr(0) Then
                                        $sProductRevision &= $GetByte
                                Else
                                        ExitLoop
                                EndIf
                                $i += 1
                        WEnd
                        $ReturnVal = StringStripWS(_CodeBytes($sProductRevision), 3)
                Case 'bustype'
                        Switch Hex($BusType, 2)
                                Case '00'
                                        $ReturnVal = 'Unknown'
                                Case '01'
                                        $ReturnVal = 'Scsi'
                                Case '02'
                                        $ReturnVal = 'Atapi'
                                Case '03'
                                        $ReturnVal = 'Ata'
                                Case '04'
                                        $ReturnVal = '1394'
                                Case '05'
                                        $ReturnVal = 'Ssa'
                                Case '06'
                                        $ReturnVal = 'Fibre'
                                Case '07'
                                        $ReturnVal = 'Usb'
                                Case '08'
                                        $ReturnVal = 'RAID'
                                Case '09'
                                        $ReturnVal = 'iScsi'
                                Case '0A'
                                        $ReturnVal = 'Sas'
                                Case '0B'
                                        $ReturnVal = 'Sata'
                                Case '0C'
                                        $ReturnVal = 'Sd'
                                Case '0D'
                                        $ReturnVal = 'Mmc'
                                Case '0E'
                                        $ReturnVal = 'Virtual'
                                Case '0F'
                                        $ReturnVal = 'FileBackedVirtual'
                                Case '10'
                                        $ReturnVal = 'Max'
                                Case '7F'
                                        $ReturnVal = 'MaxReserved'
                        EndSwitch
                Case Else
                        $tQuery = 0
                        $tDescr = 0
                        $tBuffer = 0
                        Return SetError(-1, 0, 'Unknown Method')
        EndSwitch
        $tQuery = 0
        $tDescr = 0
        $tBuffer = 0
        Return SetError(0, 0, $ReturnVal)
EndFunc   ;==>_ReadPhysicalDriveInNTWithZeroRights

Func _CodeBytes($str)
        Local $ReturnVal
        If StringRegExp($str, '[^0-9A-Fa-f]') Then Return $str
        Local $aStr = StringSplit($str, '', 2)
        If Mod(UBound($aStr), 2) <> 0 Then Return $str
        If StringRegExp($str, '^(00{2})+$') Then ;utf16 大编码
                $ReturnVal = BinaryToString('0x' & $str, 3)
                If StringRegExp($ReturnVal, '^([\x20-\x7e])+$') Then
                        Return $ReturnVal
                Else
                        Return $str
                EndIf
        ElseIf StringRegExp($str, '^({2}00)+$') Then ;utf16 小编码
                $ReturnVal = BinaryToString('0x' & $str, 2)
                If StringRegExp($ReturnVal, '^([\x20-\x7e])+$') Then
                        Return $ReturnVal
                Else
                        Return $str
                EndIf
        ElseIf StringRegExp($str, '^(|7)+$') Then ;utf8 编码 \x20-\x7e
                If Mod(UBound($aStr), 4) = 0 Then
                        Local $NewStr
                        For $i = 0 To UBound($aStr) - 1 Step 4
                                $NewStr &= $aStr[$i + 2]
                                $NewStr &= $aStr[$i + 3]
                                $NewStr &= $aStr[$i + 0]
                                $NewStr &= $aStr[$i + 1]
                        Next
                        $ReturnVal = BinaryToString('0x' & $NewStr, 4)
                Else
                        $ReturnVal = BinaryToString('0x' & $str, 4)
                EndIf
                If StringRegExp($ReturnVal, '^([\x20-\x7e])+$') Then
                        Return $ReturnVal
                Else
                        Return $str
                EndIf
        Else
                Return $str
        EndIf
EndFunc   ;==>_CodeBytes


haijie1223 发表于 2023-5-5 18:03:22


没想到这么快你就放弃了,如此这般处理吧
#NoTrayIcon
#RequireAdmin
#PRE_UseX64=n
#PRE_Res_requestedExecutionLevel=requireAdministrator
#include 'MemoryDll.au3'
Local $hFile = FileOpen('getdiskserial.dll', 16)
Local $Binary = FileRead($hFile)
FileClose($hFile)
Local $Module = MemoryDllOpen($Binary)
MemoryFuncSet(DllStructGetPtr($_MDCodeBuffer) + $_MDGetOffset)
Local $Ret = DllCall($_MDKernel32Dll, "uint", $_MFHookApi, "uint", $Module, "str", 'GetDriveInfo')
Local $thdcode = DllStructCreate('byte')
DllStructSetData($thdcode, 1, '0xB800D80200')
DllCall("kernel32.dll", "none", "RtlMoveMemory", "struct*", $Ret + 0x34, "struct*", $thdcode, "DWORD", 5)
Local $PP = MemoryDllCall($Module, "str", "GetSerialNumber", "int", 0)
MemoryDllClose($Module)
ConsoleWrite($PP & @CRLF)
MsgBox(0, 0, $PP)


3131210 发表于 2023-5-5 22:00:36

haijie1223 发表于 2023-5-5 18:03
没想到这么快你就放弃了,如此这般处理吧

感谢大佬的思路
附件是用最新5.11的dll直接从内存调用获取硬盘信息
里面去掉了试用的弹窗

关键代码

Global $DiskSerial = MemoryDllOpen(_Base64String())
MemoryFuncSet(DllStructGetPtr($_MDCodeBuffer) + $_MDGetOffset)
Local $Ret = DllCall($_MDKernel32Dll, "uint", $_MFHookApi, "uint", $DiskSerial, "str", 'GetDriveInfo')
Local $thdcode = DllStructCreate('byte')
DllStructSetData($thdcode, 1, '0xEB4D')
DllCall($_MDKernel32Dll, "int", "WriteProcessMemory", "ptr", -1, "ptr", $Ret + 0x32, "ptr", DllStructGetPtr($thdcode), "ptr", DllStructGetSize($thdcode), "uint*", 0)


页: [1]
查看完整版本: 【已解决】内存调用DLL 报错 250477278