找回密码
 加入
搜索
查看: 4776|回复: 15

[系统综合] au3 能不能实现禁止读取文件?

 火.. [复制链接]
发表于 2010-8-26 16:09:18 | 显示全部楼层 |阅读模式
例如用Hips 这类的工具实现禁止读取指定文件
发表于 2010-8-26 17:15:34 | 显示全部楼层
能,方法很多。
1、CreateFile以独占模式打开文件取得其句柄,再将句柄复制到别的系统级进程中。
2、挂钩NtCreateFile、NtOpenFile函数。
3、我想到天都荒了,海都枯了,只想到上面2个方法。- -|||
发表于 2010-8-26 18:12:27 | 显示全部楼层
回复 2# pusofalse


    P版大大,我只想知道第一个。教教吧。
#Include <WinAPI.au3>
_WinAPI_CreateFile("文件名.exe",2)
While 1
sleep(100)
WEnd
我只知道这样可以。但是要一直有进程才行,程序退出就玩完了。怎么把这个句柄给别个系统进程?
发表于 2010-8-26 18:19:38 | 显示全部楼层
呵呵,修改权限?
发表于 2010-8-26 18:22:13 | 显示全部楼层
回复 4# a000000


    修改权限他又给你修改回来怎么办?
这年头NTFS权限已经落伍了。
发表于 2010-8-26 18:32:18 | 显示全部楼层
也能修改NTFS权限~ 怎么没想到呢 - -|||

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

参考:http://www.autoitx.com/forum.php ... amp;fromuid=7634069
 楼主| 发表于 2010-8-26 18:43:00 | 显示全部楼层
修改权限就自动改回来,这个就是难题,能不能禁止他修改我的权限(类似hips应用)
发表于 2010-8-26 19:37:23 | 显示全部楼层
本帖最后由 xsjtxy 于 2010-8-26 19:38 编辑

回复 6# pusofalse


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

跟Fileopen的效果一样。但是跟_WinAPI_CreateFile的效果不一样。
 楼主| 发表于 2010-8-26 20:29:55 | 显示全部楼层
楼上可不可以重新发一下源码,因为我的阅读权限不够
发表于 2010-8-26 20:36:42 | 显示全部楼层
本帖最后由 xsjtxy 于 2010-8-26 20:40 编辑

回复 9# 0758


    用P版的方法后文件依然能够读取。只是不能重名和删除。以及修改和覆盖。
你如果要完全禁止访问的话。还得用_WinAPI_CreateFile
 楼主| 发表于 2010-8-26 21:21:53 | 显示全部楼层
xsjtxy   我的SWF,wmv广告文件来的,你说不可以实现用Au3 来阻止读取(Hips),.
发表于 2010-8-31 14:48:54 | 显示全部楼层
持续观注此帖~
小弟不才不能帮上什么忙= =
发表于 2010-8-31 14:50:39 | 显示全部楼层
回复 10# xsjtxy


    $fReadable参数被你无视了啊~ - - 很好~
发表于 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[528]"

Func _ProtectFile($sFile, $iProcessId = Default, $fReadable = True)
        Local $aPrivilege[1][2] = [[$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[1][2] = [[$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[3]
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]), 0, $iResult[1])
EndFunc        ;==>_NtOpenProcess

Func _NtClose($hHandle)
        Local $iResult
        $iResult = DllCall("Ntdll.dll", "long", "NtClose", "long", $hHandle)
        Return SetError(_LsaNtStatusToWinError($iResult[0]), 0, $iResult[0] = 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[4])
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[4])
        $iResult = DllCall("Ntdll.dll", "long", "NtQuerySystemInformation", _
                        "int", $iClass, "ptr", $pBuffer, "dword", $iResult[4], "long*", 0)
        Return SetError(_LsaNtStatusToWinError($iResult[0]), 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[0]), _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
发表于 2010-8-31 15:28:07 | 显示全部楼层
像上面这样改了就可以。是我没参悟透True到底是什么
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-20 10:11 , Processed in 0.084678 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表