【已解决】内存调用DLL 报错 250477278
本帖最后由 3131210 于 2023-5-5 12:50 编辑附件里面有测试用的DLL和例子
例1通过内存调用和DllCall直接调用,都没问题
但是例2通过DLLCall调用没问题,通过内存调用就报错了,不知道是什么原因
#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:48 编辑
haijie1223 发表于 2023-5-5 10:35
我才发现用GetDllVer这个函数确实没问题 但是用其它的函数就不行了
本帖最后由 3131210 于 2023-5-5 11:55 编辑
不加注册码也可以用,只是会多一个弹窗提示要不要买 这只是测试,所以不加注册码
可以参考例2里面直接dllcall的部分
Global Const $RegCode = "LEDN2-HRAC6-5P66D-RU1Y2-D59U9"
$DiskSerial = DllOpen("GetDiskSerial.dll")
DllCall($DiskSerial, "NONE", "SetLicenseKey", "STR", $RegCode) 本帖最后由 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:50 编辑
这个问题大概是这个DLL自校验导致的,有可能是找不到文件做校验,所以直接退出了。
查询版本和查询是否是虚拟机的函数不会触发校验。
这个DLL有做防破解的防护,仅仅是将DLL的UPX解压也会触发防破解校验。
没办法直接调用 那就算了 获取硬盘序列号可以用纯代码,没必要调用dll 直接纯代码的我也有
#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
没想到这么快你就放弃了,如此这般处理吧
#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)
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]