对话框程序通过使用CreateMutexA 来达到防止重复运行的问题,我想通过APIHOOK 来解决这个问题,使得进程可以重复运行,我用APIHOOK 钩到了 CreateMutexA ,然后直接Return NULL; 可是进程中的CreateMutexA 还是成功创建了互斥对象,好奇怪对话框中的CreateMutex 代码:
===========================================================================
HANDLE hMutex;
hMutex = CreateMutex(NULL, FALSE, "TestAPP");
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
MessageBox(NULL,"程序已经运行!","test",0);
return FALSE;
} ===========================================================================
钩子函数:
===========================================================================
HANDLE WINAPI CModuleScope::MyCreateMutexA( LPSECURITY_ATTRIBUTES lpMutexAttributes,BOOL bInitiaOwner, LPCSTR lpName)
{
char szBuffer[MAX_PATH];
sprintf_s(szBuffer, "Process (%u%d) CreateMutex Now ! Let's Return NULL", ::GetCurrentProcessId(),u);
LogMessage(szBuffer);
return NULL;
}
============================================================================
api hook 是以SetWindowsHookEx来实现的,后来我尝试钩住进程的GetLastError() ,在我的钩子函数中直接SetLastError(0),结果还是不行。请问各位大侠,用api hook 应该怎么做才能解决进程通过CreateMutexA 来防止重复运行的问题??
===========================================================================
HANDLE hMutex;
hMutex = CreateMutex(NULL, FALSE, "TestAPP");
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
MessageBox(NULL,"程序已经运行!","test",0);
return FALSE;
} ===========================================================================
钩子函数:
===========================================================================
HANDLE WINAPI CModuleScope::MyCreateMutexA( LPSECURITY_ATTRIBUTES lpMutexAttributes,BOOL bInitiaOwner, LPCSTR lpName)
{
char szBuffer[MAX_PATH];
sprintf_s(szBuffer, "Process (%u%d) CreateMutex Now ! Let's Return NULL", ::GetCurrentProcessId(),u);
LogMessage(szBuffer);
return NULL;
}
============================================================================
api hook 是以SetWindowsHookEx来实现的,后来我尝试钩住进程的GetLastError() ,在我的钩子函数中直接SetLastError(0),结果还是不行。请问各位大侠,用api hook 应该怎么做才能解决进程通过CreateMutexA 来防止重复运行的问题??
{
char szBuffer[MAX_PATH];
sprintf_s(szBuffer, "Process (%u%d) CreateMutex Now ! Let's Return NULL", ::GetCurrentProcessId(),u);
LogMessage(szBuffer); // 改变一下名字,方法是在名字后面附加一个实例ID——nInstances,
// 这个ID位于你各个实例都可以访问并修改的一个内存区域,如文件映射
sprintf(szBuffer, _T("%s%u"), lpName, nInstances);
return CreateMutexA(lpMutexAttributes, bInitiaOwner, lpName);
}
不行啊
我的进程中CreateMutex 的代码是这样写的:
HANDLE hMutex;
hMutex = CreateMutex(NULL, FALSE, "TestAPP");
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
MessageBox(NULL,"程序已经运行!","test",0);
return FALSE;
} 我将HOOK截获的 LPCSTR lpName 打印出来发现,是 MSCTF.Shared.MUTEX.MCG ,并不是我传进去"TestApp" ,为什么回这样?
已经按照你的方法试过了,结果还是一样,下面是修改后的函数:HANDLE WINAPI CModuleScope::MyCreateMutexA( LPSECURITY_ATTRIBUTES lpMutexAttributes,BOOL bInitiaOwner, LPCSTR lpName)
{
char szBuffer[MAX_PATH];
sprintf_s(szBuffer, "Process (%u_%s) CreateMutex Now !", ::GetCurrentProcessId(),lpName);
sm_pInstance->LogMessage(szBuffer);
sprintf_s(szBuffer,"%s%u",lpName,::GetCurrentProcessId());
return ::CreateMutexA(NULL,FALSE,(LPCSTR)szBuffer);
}代码运行log日志 如下:
HookSrv.exe(83604) - ------- Hook server loads HookTool library -------
TestApp.exe(83636) - Process (83636) CreateMutex Now !
TestApp.exe(80084) - Process (80084) CreateMutex Now !
TestApp.exe(80084) - Process (80084) GetLastError()
TestApp.exe(80084) - The hook engine has been deactivated.
TestApp.exe(83636) - Process (83636) GetLastError()
TestApp.exe(83636) - Process (83636) CreateMutex Now !
TestApp.exe(83636) - The hook engine has been deactivated.
HookSrv.exe(83604) - ------- Hook server shuts down and unloads HookTool library -------
通过日志我发现,TestApp 其实是创建了2次互斥量,PID 分别是 83636 和 80084可是TestApp 的代码中,我只调用了一次CreaetMutex 啊,奇怪了
原来是我自己晕了,执行的第2次是因为我自己重复执行 TestApp 时,得到“程序已经运行”的那次
另外,既然你要让EXE可以重复运行,在CreateMutex的Hook函数中,应该判断Mutex的名称,并设法让其创建成功才对。
VOID WINAPI CModuleScope::MyGetLastError()
{
char szBuffer[MAX_PATH];
sprintf_s(szBuffer, "Process (%u) GetLastError()", ::GetCurrentProcessId());
sm_pInstance->LogMessage(szBuffer);
if (::GetLastError() == ERROR_ALREADY_EXISTS)
{
::SetLastError(ERROR_SUCCESS);
}
}结果还是一样,对话框第2个实例运行仍然因为互斥量的存在而失败,应该怎么做呢??
参考“cnzdgs ”这位大侠的,可能是你勾子下得晚了。你是DLL注入的吗?
我的意思是让所有实例都创建成功。你可以在Hook函数中,自己调用真正的CreateMutex,把名称参数给NULL,将得到的句柄返回。
注入是在调用CreateMutex之前吗?
HOOK API与系统提供的HOOK完全是两回事,HOOK API是需要自己写的。其次,即使你确实已经HOOK了API,仍有下述问题.
将DLL注入进程,必须是进程存在的时候才能注入,如果进程不存在,如何注入?
所以,只有当进程已经启动的时候才能注入,而进程启动后,你又无法控制你注入的时机,
是在CreateMutex执行后,还是在CreateMutex执行前?你无法得知。如果这一个试验性的东西,就没必要继续了,思路错了。
如果是要解决现实的问题,我提供一种思路。就是给那个程序加一个壳,这样,才能确保在CreateMutex调用之前挂接它。