0758 发表于 2010-8-26 16:09:18

au3 能不能实现禁止读取文件?

例如用Hips 这类的工具实现禁止读取指定文件

pusofalse 发表于 2010-8-26 17:15:34

能,方法很多。
1、CreateFile以独占模式打开文件取得其句柄,再将句柄复制到别的系统级进程中。
2、挂钩NtCreateFile、NtOpenFile函数。
3、我想到天都荒了,海都枯了,只想到上面2个方法。- -|||

xsjtxy 发表于 2010-8-26 18:12:27

回复 2# pusofalse


    P版大大,我只想知道第一个。教教吧。
#Include <WinAPI.au3>
_WinAPI_CreateFile("文件名.exe",2)
While 1
sleep(100)
WEnd
我只知道这样可以。但是要一直有进程才行,程序退出就玩完了。怎么把这个句柄给别个系统进程?

a000000 发表于 2010-8-26 18:19:38

呵呵,修改权限?

xsjtxy 发表于 2010-8-26 18:22:13

回复 4# a000000


    修改权限他又给你修改回来怎么办?
这年头NTFS权限已经落伍了。

pusofalse 发表于 2010-8-26 18:32:18

也能修改NTFS权限~ 怎么没想到呢 - -|||

DuplicateHandle是复制句柄的,复制到别的进程之后自己的程序退出就行了。
当然也不必复制到系统级进程中,普通的用户进程也可以,但进程一旦被结束,文件就又可以读取了。

参考:http://www.autoitx.com/forum.php?mod=viewthread&tid=9620&fromuid=7634069

0758 发表于 2010-8-26 18:43:00

修改权限就自动改回来,这个就是难题,能不能禁止他修改我的权限(类似hips应用)

xsjtxy 发表于 2010-8-26 19:37:23

本帖最后由 xsjtxy 于 2010-8-26 19:38 编辑

回复 6# pusofalse


    效果不错。用上了。非常感谢。

跟Fileopen的效果一样。但是跟_WinAPI_CreateFile的效果不一样。

0758 发表于 2010-8-26 20:29:55

楼上可不可以重新发一下源码,因为我的阅读权限不够

xsjtxy 发表于 2010-8-26 20:36:42

本帖最后由 xsjtxy 于 2010-8-26 20:40 编辑

回复 9# 0758


    用P版的方法后文件依然能够读取。只是不能重名和删除。以及修改和覆盖。
你如果要完全禁止访问的话。还得用_WinAPI_CreateFile

0758 发表于 2010-8-26 21:21:53

xsjtxy   我的SWF,wmv广告文件来的,你说不可以实现用Au3 来阻止读取(Hips),.

pei 发表于 2010-8-31 14:48:54

持续观注此帖~
小弟不才不能帮上什么忙= =

pusofalse 发表于 2010-8-31 14:50:39

回复 10# xsjtxy


    $fReadable参数被你无视了啊~ - - 很好~

xsjtxy 发表于 2010-8-31 15:24:07

回复 13# pusofalse


    。。。但是那个要怎么改呢?
我这样改的。对不对?
#include <WinAPI.au3>
#include <LocalSecurityAuthority.au3>

Const $tagCLIENT_ID = "long UniqueProcessId;long UniqueThreadId"
Const $tagOBJECT_ATTR = "long Size;long RootDirectory;long objName;long Attr;long SecurDescr;long SecurQualityofService"
Const $tagSYSTEM_HANDLE_INFO = "ulong Pid;ubyte ObjType;ubyte Flags;ushort Handle;ptr object;dword GrantedAccess"
Const $tagFILE_NAME_INFO = "ulong Length;wchar FileName"

Func _ProtectFile($sFile, $iProcessId = Default, $fReadable = True)
      Local $aPrivilege = [[$SE_DEBUG_NAME, 2]]
      Local $iResult, $hFile, $hSource, $hTarget, $hDup, $iError, $hToken

      $sFile = _GetFullPathName($sFile)                        ; 获取文件完整路径
      If Not FileExists($sFile) Then Return SetError(2, 1, 0)
      If $iProcessId = Default Then $iProcessId = "Winlogon.exe"      ; 默认挂接到winlogon.exe进程
      $iProcessId = ProcessExists($iProcessId)                        ; 获取进程PID
      If $iProcessId = 0 Then Return SetError(2, 2, 0)

      If $fReadable = True Then                ; 打开文件句柄
                $hFile = _WinAPI_CreateFile($sFile, 2, 2, 2, 1, 0)      ; 挂接到宿主进程后,文件可以访问
      Else
                $hFile = _WinAPI_CreateFile($sFile, 2)      ; 挂接到宿主进程后,文件不能访问
      EndIf
      If $hFile < 1 Then Return SetError(_WinAPI_GetLastError(), 0, 0)

      $hToken = _OpenProcessToken(-1)      ; 提升到DEBUG权限,打开进程句柄所需
      If Not _IsPrivilegeEnabled($hToken, $SE_DEBUG_NAME) Then
                _AdjustTokenPrivileges($hToken, $aPrivilege)
      EndIf
      _NtClose($hToken)      ; 关闭令牌句柄

      $hSource = _NtOpenProcess(@AutoItPid) ; 打开本进程句柄
      If $hSource= 0 Then Return SetError(@error, 0, 0)
      $hTarget = _NtOpenProcess($iProcessId) ; 宿主进程句柄
      If $hTarget = 0 Then Return SetError(@error, 0, 0)

      $hDup = _DuplicateHandle($hSource, $hFile, $hTarget, 0, 0, 3) ; 将本进程中打开的文件句柄挂接到目标进程中。
      $iError = @error
      _NtClose($hFile)      ; 关闭所有打开的句柄
      _NtClose($hDup)
      _NtClose($hSource)
      _NtClose($hTarget)
      If $hDup = 0 Then Return SetError($iError, 0, 0)
      Return 1
EndFunc      ;==>_ProtectFile

Func _UnprotectFile($sFile, $iProcessId)
      Local $aPrivilege = [[$SE_DEBUG_NAME, 2]], $hToken
      Local $iError, $tNum, $iNum, $sPath, $pBuffer, $tBuffer, $hHandle, $iPid
      Local $iResult, $pHandleList, $tHandleList, $iType, $hDup, $hSrc, $hTarget

      $iProcessId = ProcessExists($iProcessId)      ; 获取进程PID
      If $iProcessId = 0 Then Return SetError(2, 0, 0)

      $sFile = _GetFullPathName($sFile)      ; 获取文件完整路径
      $iType = _GetFileHandleType()      ; 不同的系统,文件句柄类型的值将不同。获取文件句柄所对应的值,方法是本进程中打开NUL设

备,然后与枚举到的句柄相比较,就可以知道文件句柄所对应的值了。
      If $iType = -1 Then Return SetError(24, 0, 0)

      $pHandleList = _NtQuerySystemInformation(0x10) ; 枚举系统中的所有句柄,返回long + SYSTEM_HANDLE_INFO指针。
      $iError = @error
      $tNum = DllStructCreate("long NumberOfHandles", $pHandleList) ; 获取句柄数量。
      $iNum = DllStructGetData($tNum, "NumberOfHandles")
      If $iNum < 1 Then Return SetError($iError, 0, 0)
      _FreeVariable($tNum)
      $pHandleList += 4      ; 指针地址右移2位,指向SYSTEM_HANDLE_INFO结构。

      $hToken = _OpenProcessToken(-1)      ; 提升至DEBUG权限,打开进程句柄所需。
      If Not _IsPrivilegeEnabled($hToken, $SE_DEBUG_NAME) Then
                _AdjustTokenPrivileges($hToken, $aPrivilege)
      EndIf
      _NtClose($hToken)

      $hTarget = _NtOpenProcess(-1)      ; 打开当前进程句柄
      $hSrc = _NtOpenProcess($iProcessId)      ; 打开宿主进程句柄
      If $hSrc = 0 Then Return SetError(@error, 0, 0)

      For $i = 1 to $iNum                ; 枚举句柄,获得目标进程中句柄的值。
                $tHandleList = DllStructCreate($tagSYSTEM_HANDLE_INFO, $pHandleList)
                $pHandleList += DllStructGetSize($tHandleList); 指针偏移DllStructGetSize($tHandleList)字节,指向下一句柄。
                If DllStructGetData($tHandleList, "Pid") <> $iProcessId Then ContinueLoop ; 判断句柄所属的进程PID,不是目标进程则跳

过。
                If DllStructGetData($tHandleList, "objType") <> $iType Then ContinueLoop ; 判断句柄类型,不是文件句柄则跳过。
                $hHandle = DllStructGetData($tHandleList, "Handle") ; 宿主中的句柄值。
                $hDup = _DuplicateHandle($hSrc, $hHandle, $hTarget, 0, 0, 0) ; 先复制到当前进程中。
                $pBuffer = _NtQueryInformationFile($hDup, 9)      ; 根据文件句柄获取文件名,返回FILE_NAME_INFO指针。
                If @error Then
                        _NtClose($hDup)
                        _HeapFree($pBuffer)
                        ContinueLoop
                EndIf
                _NtClose($hDup)
                $tBuffer = DllStructCreate($tagFILE_NAME_INFO, $pBuffer)
                $sPath = DllStructGetData($tBuffer, "FileName")      ; 获取句柄所对应的文件名。
                $iPid = DllStructGetData($tHandleList, "Pid") ; 获取句柄所属的进程PID。
                _HeapFree($pBuffer)

                ; 判断是否是指定文件,并是否位于指定进程中。
                If StringTrimLeft($sFile, 2) = $sPath AND $iPid = $iProcessId Then
                        $hSrc = _NtOpenProcess($iProcessId) ; 再次打开宿主进程。
                        $hDup = _DuplicateHandle($hSrc, $hHandle, $hTarget, 0, 0, 3) ; 卸载句柄,3 -- 复制到目标进程的同时,关闭源

句柄。
                        If $hDup <> 0 Then
                              $iResult = _NtClose($hSrc) & _NtClose($hDup) & _NtClose($hTarget) & _HeapFree($pHandleList)
                              Return SetExtended(_FreeVariable($tBuffer), Not _FreeVariable($tHandleList))
                        Else
                              $iResult = _NtClose($hSrc) & _NtClose($hTarget) & _HeapFree($pHandList)
                              Return SetError(@error, _FreeVariable($tBuffer), _FreeVariable($tHandleList))
                        EndIf
                EndIf
      Next
      $iResult = _NtClose($hSrc) & _NtClose($hTarget) & _HeapFree($pHandleList)
      Return SetError(2, _FreeVariable($tHandleList), _FreeVariable($tBuffer))
EndFunc      ;==>_UnprotectFile

Func _GetFullPathName($sFile)
      Local $iResult
      $iResult = DllCall("Kernel32.dll", "int", "GetFullPathName", _
                        "str", $sFile, "dword", 260, "str", "", "str", "")
      Return $iResult
EndFunc      ;==>_GetFullPathName

Func _NtOpenProcess($iPid, $iAccessMask = 0x1F0FFF)
      Local $iResult, $tClientId, $tObjAttr

      If $iPid = -1 Then $iPid = @AutoItPid
      $iPid = ProcessExists($iPid)
      If $iPid = 0 Then Return SetError(2, 0, 0)

      $tClientId = DllStructCreate($tagCLIENT_ID)
      $tObjAttr = DllStructCreate($tagOBJECT_ATTR)
      DllStructSetData($tClientId, "UniqueProcessId", $iPid)
      DllStructSetData($tObjAttr, "Size", DllStructGetSize($tObjAttr))
      $iResult = DllCall("Ntdll.dll", "dword", "NtOpenProcess", _
                        "long*", 0, "dword", $iAccessMask, _
                        "ptr", DllStructGetPtr($tObjAttr), _
                        "ptr", DllStructGetPtr($tClientId))
      _FreeVariable($tObjAttr)
      _FreeVariable($tClientId)
      Return SetError(_LsaNtStatusToWinError($iResult), 0, $iResult)
EndFunc      ;==>_NtOpenProcess

Func _NtClose($hHandle)
      Local $iResult
      $iResult = DllCall("Ntdll.dll", "long", "NtClose", "long", $hHandle)
      Return SetError(_LsaNtStatusToWinError($iResult), 0, $iResult = 0)
EndFunc      ;==>_NtClose

Func _DuplicateHandle($hSrcProcess, $hSrc, $hTarget, $iAccess, $iInherit = 0, $iOption = 0)
      Local $iResult
      $iResult = DllCall("Kernel32.dll", "int", "DuplicateHandle", _
                        "hWnd", $hSrcProcess, "hWnd", $hSrc, _
                        "hWnd", $hTarget, "long*", 0, _
                        "dword", $iAccess, "int", $iInherit, "int", $iOption)
      Return SetError(_GetLastError(), 0, $iResult)
EndFunc      ;==>_DuplicateHandle

Func _NtQuerySystemInformation($iClass)
      Local $pBuffer, $iResult

      $pBuffer = _HeapAlloc(0x800)

      $iResult = DllCall("Ntdll.dll", "long", "NtQuerySystemInformation", _
                        "int", $iClass, "ptr", $pBuffer, "dword", 0x800, "long*", 0)
      _HeapFree($pBuffer)
      $pBuffer = _HeapAlloc($iResult)
      $iResult = DllCall("Ntdll.dll", "long", "NtQuerySystemInformation", _
                        "int", $iClass, "ptr", $pBuffer, "dword", $iResult, "long*", 0)
      Return SetError(_LsaNtStatusToWinError($iResult), 0, $pBuffer)
EndFunc      ;==>_NtQuerySystemInformation

Func _NtQueryInformationFile($hFile, $iClass)
      Local $iResult, $pBuffer, $pStatus

      $pBuffer = _HeapAlloc(532)
      $pStatus = _HeapAlloc(12)
      $iResult = DllCall("Ntdll.dll", "dword", "NtQueryInformationFile", "long", $hFile, _
                        "ptr", $pStatus, "ptr", $pBuffer, "ulong", 532, "int", $iClass)
      Return SetError(_LsaNtStatusToWinError($iResult), _HeapFree($pStatus), $pBuffer)
EndFunc      ;==>_NtQueryInformationFile

Func _GetFileHandleType()
      Local $iResult, $hFile, $pBuffer, $tBuffer, $tNum, $iType = -1

      $hFile = _WinAPI_CreateFile("NUL", 2, 6, 6, 1, 0)
      $pBuffer = _NtQuerySystemInformation(16)
      $tNum = DllStructCreate("ulong Number", $pBuffer)
      $iNum = DllStructGetData($tNum, "Number")
      $pBuffer += 4
      For $i = 1 to $iNum
                $tSysHandle = DllStructCreate($tagSYSTEM_HANDLE_INFO, $pBuffer)
                $iPid = DllStructGetData($tSysHandle, "Pid")
                $hHandle = DllStructGetData($tSysHandle, "Handle")
                If $iPid = @AutoItPid AND $hHandle = $hFile Then
                        $iType = DllStructGetData($tSysHandle, "objType")
                        ExitLoop
                EndIf
                $pBuffer += DllStructGetSize($tSysHandle)
      Next
      _NtClose($hFile)
      _HeapFree($pBuffer)
      _FreeVariable($tNum)
      _FreeVariable($tSysHandle)
      Return $iType
EndFunc      ;==>_GetFileHandleType

xsjtxy 发表于 2010-8-31 15:28:07

像上面这样改了就可以。是我没参悟透True到底是什么
页: [1] 2
查看完整版本: au3 能不能实现禁止读取文件?