一直有一个问题不明白,比如我要hook createfilew(),返回一个NULL和返回一个自定义的createfile()有什么不同,具个例子,这里有3种情况,第一种情况同时返回NULL和自定义的createfileDETOUR_TRAMPOLINE(HANDLE WINAPI MyCreateFileW(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile), CreateFileW);
HANDLE WINAPI NewCreateFileW(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile){ CString Drive="G";
if(strncmp(lpFileName,Drive,2) ==0 )
{ return 0; }
return MyCreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}这种情况是,g drive不可以打开文件,其他drive不受影响,并且不可以从g drive复制文件到别的dirve,但可以从别的drive复制文件到g dirve。
第二种情况是,只返回NULL,不返回MyCreateFileW
DETOUR_TRAMPOLINE(HANDLE WINAPI MyCreateFileW(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile), CreateFileW);
HANDLE WINAPI NewCreateFileW(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile){ CString Drive="G";
if(strncmp(lpFileName,Drive,2) ==0 )
{ return 0; }}这种情况是整个电脑都hook住了,不管是什么drive都不可以打开文件和相互复制文件,这我就不明白了,我只是hook g drive,为什么连其他drive都受影响了??如果只是加上返回MyCreateFileW,变成第一种情况,又完全不同拉???第三中情况只返回MyCreateFileW,不返回NULL
DETOUR_TRAMPOLINE(HANDLE WINAPI MyCreateFileW(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile), CreateFileW);
HANDLE WINAPI NewCreateFileW(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile){ CString Drive="G";
if(strncmp(lpFileName,Drive,2) ==0 )
{ return MyCreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}}这种情况跟第二种相似。唯一不同是可以从g drive复制文件到别的drive,但不可以从别的drive复制到g drive,
到底返回NULL和返回MyCreateFileW是什么意思??同时返回又是什么意思?请大家帮帮忙
HANDLE WINAPI NewCreateFileW(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile){ CString Drive="G";
if(strncmp(lpFileName,Drive,2) ==0 )
{ return 0; }
return MyCreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}这种情况是,g drive不可以打开文件,其他drive不受影响,并且不可以从g drive复制文件到别的dirve,但可以从别的drive复制文件到g dirve。
第二种情况是,只返回NULL,不返回MyCreateFileW
DETOUR_TRAMPOLINE(HANDLE WINAPI MyCreateFileW(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile), CreateFileW);
HANDLE WINAPI NewCreateFileW(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile){ CString Drive="G";
if(strncmp(lpFileName,Drive,2) ==0 )
{ return 0; }}这种情况是整个电脑都hook住了,不管是什么drive都不可以打开文件和相互复制文件,这我就不明白了,我只是hook g drive,为什么连其他drive都受影响了??如果只是加上返回MyCreateFileW,变成第一种情况,又完全不同拉???第三中情况只返回MyCreateFileW,不返回NULL
DETOUR_TRAMPOLINE(HANDLE WINAPI MyCreateFileW(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile), CreateFileW);
HANDLE WINAPI NewCreateFileW(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile){ CString Drive="G";
if(strncmp(lpFileName,Drive,2) ==0 )
{ return MyCreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}}这种情况跟第二种相似。唯一不同是可以从g drive复制文件到别的drive,但不可以从别的drive复制到g drive,
到底返回NULL和返回MyCreateFileW是什么意思??同时返回又是什么意思?请大家帮帮忙
返回结果大体上有两种情况:
1、返回一个有效的句柄值。
这种情况下,调用者会认为打开成功,通常会使用这个句柄去访问文件,最终还要关闭句柄。因为自己的代码本身并不能打开文件,必须要通过系统来打开,通常的做法是调用真正的CreateFile函数并保存结果。因为Detour是把真正的CreateFile的入口处代码改成了跳转指令,所以需要自己定义一个函数,将真正CreateFile的前几行代码复制过来,执行后再跳转到真正CreateFile的这几行代码的后面继续执行。这样调用这个函数就相当于调用了真正的CreateFile函数,直接使用Hook函数的参数调用这个函数,并返回就等于让调用者调用了真正的CreateFile函数。
2、返回一个无效的句柄值。
但不允许调用者打开文件时使用这种方法。不过不应该简单地返回NULL,应该先SetLastError设置一个错误码,通常可以用ERROR_ACCESS_DENIED,然后返回INVALID_HANDLE_VALUE。通常调用者会判断,当返回值为INVALID_HANDLE_VALUE时认为打开失败,可能还会用GetLastError来取错误码,判断失败原因。
如果lpFileName=="G"什么也不做,直接返回NULL; 否则执行MyCreateFileW(...),我想你这个MyCreateFileW应该就是原CreateFileW代码吧。所以只会对于G这个文件操作有影响,其它与普通CreateFileW无异。第二种情况:
如果lpFileName=="G"什么也不做,直接返回NULL; 否则还是什么也没做,只是返回值不可预测。 这样当然都受影响了,CreateFileW功能已经完全丧失了。第三种情况:
如果lpFileName=="G"执行MyCreateFileW(...),否则什么也不做,这样只有G文件正常,对其它文件CreateFileW无效。
MyCreateFileW 就是替换前我们保留下来的Windows的API的地址。
即处理完后,还要调用Windows的API才能创建文件。
不是 返回NULL;要么返回INVALID_HANDLE_VALUE
CString Drive_Letter;CString Drive="G:";UINT fixed=GetDriveType(Drive); if (fixed==DRIVE_REMOVABLE)
{
Drive_Letter=Drive.Mid(0,1);if(strncmp(lpFileName,Drive_Letter,1) ==0 )
{
return 0; }
}return MyCreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
我的想法是判断G drive是否为u盘,如果是u盘就直接返回NULL,其他drive返回MyCreateFileW
这种方法其实跟上面第一种做法是一样的,只是加上了GetDriveType()来判断,结果应该是g drive不可以打开文件,其他drive不受影响,并且不可以从g drive复制文件到别的dirve,但可以从别的drive复制文件到g dirve。
但出来的结果变成了全部drive都不可以打开文件了,为什么会这样呢??
前面已经提到,CreateFile返回INVALID_HANDLE_VALUE(值为-1)表示失败,并且要用SetLastError设置错误码,否则调用者可能发生无法预知的错误。
CreateFileW的参数应该是LPCWSTR,而不是LPCSTR。
还有当我返回INVALID_HANDLE_VALUE,进入g drive时,会出现Windows Explorer has encountered a problem and needs to close. We are sorry for the inconvenience.的错误,为什么??
另外提一下,很多人在写程序的时候,在调用某个函数时会认为肯定会调用程序,因此不去判断函数的返回值,这是就可能造成程序异常。当遇到这种情况的时候,Hook函数就不能返回失败。
HANDLE WINAPI NewCreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile){TCHAR szBuffer[1024];
UINT fixed; CString Drive_Letter;CString Drive="G:";fixed=GetDriveType(Drive); if (fixed==DRIVE_REMOVABLE)
{Drive_Letter=Drive.Mid(0,1);
wsprintf(szBuffer,TEXT("%s"),Drive_Letter);if(wcsncmp(lpFileName, (LPCWSTR)szBuffer,1) ==0 )
{
SetLastError(ERROR_ACCESS_DENIED); return INVALID_HANDLE_VALUE;
}
}return MyCreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);}请大家帮帮忙看看那里错了?
按第三种情况重译编译了一次#include <atlconv.h>
DETOUR_TRAMPOLINE(HANDLE WINAPI MyCreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile), CreateFileW);HANDLE WINAPI NewCreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile){
CString str=_T("G");USES_CONVERSION;LPCWSTR lpw=T2W(str);
if(wcsncmp(lpFileName,lpw,2) ==0)
{
return MyCreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}
}按Waiting4you 的说法是如果lpFileName=="G"执行MyCreateFileW(...),否则什么也不做,这样只有G文件正常,对其它文件CreateFileW无效。但出来的结果是现在连g drive都hook住了,不可以复制文件到别的drive了