话说,我想多开,然后就研究了一下怎么多开,在看雪看到了这份代码,不全,左搜搜,右搜搜,终于弄全了,编译没问题。于是写了个例子程序,来多开的。结果找不到对应的系统内核对象,话不多说了,上代码,代码之下无秘密。求高人指点出的问题在哪。
一:例 子程序(对话框。)
HANDLE h;
if (!(h=CreateMutex(NULL,TRUE, "Design")))
{
MessageBox(NULL, "创建Mutex失败! ", "Design1 ",MB_OK|MB_SYSTEMMODAL);
return FALSE;
}
if (GetLastError()==ERROR_ALREADY_EXISTS)
{
MessageBox(NULL, "已有design的一个实例在运行, 当前实例将被终止! ",
"design ",MB_OK|MB_SYSTEMMODAL);
return FALSE;
}else ReleaseMutex(h);
二:枚举内核对象并关闭
bool CloseObjectByName(char *pObjectName, DWORD porcessid)
{
int i;
ULONG pid;
ULONG ulSize;
ULONG* pHandleInfor;
CHAR pName[200];
NTSTATUS ntStatus;
HMODULE hHanlde;
POBJECT_NAME_INFORMATION ObjName;
PSYSTEM_HANDLE_INFORMATION_EX Handles;
ZWQUERYOBJECT ZwQueryObject;
ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation;
//初始化变量
ulSize = 0x4000;
pHandleInfor = NULL;
ZwQueryObject = NULL;
ZwQuerySystemInformation =NULL;
//由于ZwQueryObject和ZwQuerySystemInformation是未导出的函数,需要动态加载Ntdll,dll,然后通过函数GetProcAddress
//得到它们的函数地址,由于这个dll一般的进程都会在创建的时候加载,所以省略加载,直接获取其模块地址
hHanlde = GetModuleHandle("ntdll.dll");
if(NULL == hHanlde)
{
//加载Ntdll.dll失败
return false;
}
//获取ZwQuerySystemInformation函数地址
ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(hHanlde, "ZwQuerySystemInformation");
if(NULL == ZwQuerySystemInformation)
{
//获取ZwQuerySystemInformation函数地址失败
return false;
}
//获取ZwQueryObject函数地址
ZwQueryObject = (ZWQUERYOBJECT)GetProcAddress(hHanlde, "ZwQueryObject");
if(NULL == ZwQueryObject)
{
//获取ZwQueryObject函数地址失败
return false;
}
//获取系统所有句柄信息
do
{
//申请内存
pHandleInfor = (ULONG*)malloc(ulSize);
if(NULL == pHandleInfor)
{
//申请内存失败
return false;
}
ntStatus = ZwQuerySystemInformation( SystemHandleInformation, pHandleInfor, ulSize, NULL);
if(!NT_SUCCESS(ntStatus))
{
//空间不足继续申请。
free(pHandleInfor);
ulSize = ulSize * 2;
//为防止ZwQuerySystemInformation一直失败,程序陷入死循环,当申请的空间超过64M时则返回失败
if(ulSize > 0x4000000)
{
return false;
}
}
}while(!NT_SUCCESS(ntStatus));
//转换数据结构类型
Handles = (PSYSTEM_HANDLE_INFORMATION_EX)pHandleInfor;
if(NULL == Handles)
{
return false;
}
//获取当前进程pid
//pid = GetCurrentProcessId();
pid = porcessid;
//申请空间,用于存储对象的名字信息
ObjName = (POBJECT_NAME_INFORMATION)malloc(0x2000 );
//开始搜索获取的句柄信息,并对句柄对应的对象名进行比较,如果与要求关闭的名字相同,则关闭此句柄
for(i = 0; i < Handles->NumberOfHandles; i++)
{
//对于不是本进程的句柄对象,直接pass掉,如果要实现关闭其它进程的对象,则可以首先根据PID打开这个句柄所在的进程,
//然后复制此对象,然后进行名字比较,如果相同,则可以通过创建远程线程的方式,关闭掉。
if(pid != Handles->Information[i].ProcessId)
{
continue;
}
//获取这个对象的名字信息
ntStatus = ZwQueryObject((HANDLE)Handles->Information[i].Handle, ObjectNameInformation, ObjName, 0x2000, NULL);
if(!NT_SUCCESS(ntStatus))
{
//查询对象失败,进行下一个
continue;
}
//将unicode 字串转换为 ansi字串
WideCharToMultiByte(CP_ACP, 0, ObjName->Name.Buffer, -1, pName, 200, NULL, NULL);
if (0 == strcmp(pName, "Design"))
{
CloseHandle((HANDLE)Handles->Information[i].Handle);
}
if( 0 == strcmp(pName, pObjectName))
{
//找到对应名字的对象,将其关闭
CloseHandle((HANDLE)Handles->Information[i].Handle);
}
}
//释放申请的空间
free(Handles);
free(ObjName);
return true;
}
结果:悲具呀,不管咋样,都找不到名为 Design 的对象,也就关闭不了,打开不了多份那个对话框程序了。求指点。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课