学习

原创 2007年09月16日 14:17:00
公司让我写了一个软件,并且不能让别人结束这个程序的进程。前面看到我过一些相关的文章,有创建一个线程不停检测进程名(通过枚举进程列表)的方法,但我觉得这种方法可能有些占资源。还有将自己进程提升为系统进程的,这种我也没有试过,如果谁有这种方法的实现代码给我一份将不甚感激,我今天用到是另外一种方法,拦截API函数,有两种方法:
1.在强行关闭一个进程时系统调用的是
BOOL WINAPI TerminateProcess(
  HANDLE hProcess,
  UINT uExitCode
);
我们如果利用钩子拦截TerminateProcess这个API函数,在系统调用这个函数是先判断是不是我们不让关闭进程的句柄就行了。

2.在调用BOOL WINAPI TerminateProcess(
  HANDLE hProcess,
  UINT uExitCode
);之前系统必须要先用
HANDLE WINAPI OpenProcess(
  DWORD dwDesiredAccess,
  BOOL bInheritHandle,
  DWORD dwProcessId
);在开进程的句柄,如果我们发现第一参数是PROCESS_TERMINATE方式,说明是要强行结束此进程,我们可以这以这种方打开的调用进程分析,看进程ID是不是我们不让关闭的进程的ID,下面我们着重来讲一下这种方法:
因为要用到钩子,所以们先来创建一个DLL工程,创建的过程我在这里就不说了。在这里我使用了windows核心编程里面的APIHOOK类,将这个类拷贝到工程目录下,加入自己的工程。
在DLL工程里加入一个WH_SHELL的钩子,它的作用是进程创建时将DLL文件插入到每一个进程里面,从而达到拦截API函数的目的。

下面是钩子实现部分代码:

 

// Defines
#pragma data_seg(".SHARED")    
    HHOOK     glhHook 
= NULL; //安装勾子句柄 
#pragma data_seg()
#pragma comment( linker, "/section:shared,rws" )
HINSTANCE glhInstance 
= NULL; //DLL实例句柄 

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                     )
...{
    glhInstance 
=
 (HINSTANCE)hModule;
        
return
 TRUE;
}


static LRESULT WINAPI ShellHookProc(int code, WPARAM wParam, LPARAM lParam) 
...
{
    
return
 ::CallNextHookEx(glhHook, code, wParam, lParam);
}

extern "C"__declspec(dllexport) BOOL StartHook(DWORD pid)
...
{    
    BOOL bResult
=
FALSE;
    
if(!
glhHook)
    
...
{
        glhHook 
= SetWindowsHookEx(WH_SHELL,ShellHookProc,glhInstance, 0
);
        
if(glhHook!=
NULL)
        
...
{
            bResult
=
TRUE;
        }

    }

    
return bResult; 
}


extern "C"__declspec(dllexport) BOOL StopHook()
...
{    
    BOOL bResult
=
FALSE;
    
if
(glhHook)
    
...
{
        bResult
=
 UnhookWindowsHookEx(glhHook);
        
if
(bResult)
        
...
{
            glhHook
=
NULL;
        }

    }

    
return bResult;
}


DLL文件插入其它进程里了,下面的工作就是替换OpenProcess函数了,

 

//...............................................................................................*/
typedef HANDLE (WINAPI *PFNOPENPROCESS)(DWORD,BOOL,DWORD);
extern
 CAPIHook g_OpenProcess;
// 自定义OpenProcess函数

HANDLE WINAPI Hook_OpenProcess(DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwProcessId);
//.............................................................................................../*

HANDLE WINAPI Hook_OpenProcess(DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwProcessId)
...
{
    
if(dwDesiredAccess == PROCESS_TERMINATE && dwProcessId == dwProcessId == lpData->dwProcessId/**//*这个值是不让关闭进程的ID*/
)
    
...
{
        
char sz[2048
];
        wsprintf(sz, 
"%d,%d,%d",dwDesiredAccess,dwProcessId,lpData->
dwProcessId);
        MessageBox(NULL,sz,
"d"
,MB_OK);
        
return
 NULL;
    }

    
    
return ((PFNOPENPROCESS)(PROC)g_OpenProcess)(dwDesiredAccess,bInheritHandle,dwProcessId);
}

// 挂钩OpenProcess函数
CAPIHook g_OpenProcess("kernel32.dll", "OpenProcess",(PROC)Hook_OpenProcess,TRUE);
把上面这代码加入到刚才创建的DLL里就行了。

刚才大家在查看上面代码时看到了lpData->dwProcessId这个参数,这就是我不让关闭的进程ID,那么这个值怎么得到呢。当然方法很多,可以通过窗口名获取窗口句柄

HWND hwnd = ::FindWindow(NULL,"你程序窗口名");
DWORD hpid;
//进程ID

GetWindowThreadProcessId( hwnd , &hpid );
但如果你的进程没有窗口应该怎么办呢?那么就只能在进程运行时用::GetCurrentProcessId(); 取得,然后通过内存映射的方式传给DLL文件。如下面的代码
typedef struct SHWP_STRUCT_ ...{
    DWORD dwProcessId;
    
char
 szModuleFileName[MAX_PATH];
}
 SHWP_STRUCT, *LPSHWP_STRUCT;

//全局变量定义

HANDLE            hMapping;//内存映射名柄 
LPSHWP_STRUCT        lpData; //共享内存
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     
int
       nCmdShow)
...
{
    
//创建内存共享

    hMapping=CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,0x100,"PCMONITOR."); 
    
if(hMapping !=
 NULL) 
    
...

        lpData
=(LPSHWP_STRUCT)MapViewOfFile(hMapping,FILE_MAP_ALL_ACCESS,0,0,0
); 
    }
 

    lpData
->dwProcessId = ::GetCurrentProcessId(); //当前进程ID

    ...............................其它代码 
DLL里面的内存映射部分代码

 

 

//全局变量定义
HANDLE            hMapping;//内存映射名柄 
LPSHWP_STRUCT        lpData; //共享内存
//........................................................................../*

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                     )
...
{
    
//创建内存共享

    hMapping=CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,0x100,"PCMONITOR."); 
    
if(hMapping !=
 NULL) 
    
...

        lpData
=(LPSHWP_STRUCT)MapViewOfFile(hMapping,FILE_MAP_ALL_ACCESS,0,0,0
); 
    }
 
    
return
 TRUE;
}

这样我们的进程在运行时它的进程ID通过lpData->dwProcessId = ::GetCurrentProcessId(); 得到并以内存映射的方式传给DLL文件。
DLL里面拦截了OpenProcess函数里面的DWORD dwProcessId参数,如果这个数据是我们自己进程的ID就直接反回一个NULL值,也就是打开我们进程失败,这样系统就没有办法掉用TerminateProcess强行关闭我们的进程了。如果我们直接拦截TerminateProcess函数,然后不管哪个函数掉用它直接返回TRUE值,那完了,你就永远没想在你机子上强行关闭任何程序,呵,我说的是强行,发送WM_CLOSE消息关了不算哟。

拦截TerminateProcess函数部分代码:

 

//...............................................................................................*/
typedef BOOL (WINAPI *PFNTERMINATEPROCESS)(HANDLE, UINT);
extern
 CAPIHook g_TerminateProcess;
BOOL WINAPI Hook_TerminateProcess(HANDLE hProcess, UINT uExitCode);
//
 自定义TerminateProcess函数
//
.............................................................................................../*

// 自定义TerminateProcess函数

BOOL WINAPI Hook_TerminateProcess(HANDLE hProcess, UINT uExitCode)
...
{
    
// 取得主模块的文件名称

    char szPathName[MAX_PATH];
    ::GetModuleFileName(NULL, szPathName, MAX_PATH);
    
// 构建发送给主窗口的字符串


    
char sz[2048];
    wsprintf(sz, 
"  进程:(%d)%s  进程句柄:%X  退出代码:%d (%x)",::GetCurrentProcessId(), szPathName, hProcess, uExitCode,lpData->
dwProcessId);
    MessageBox(NULL,sz,
"d"
,MB_OK);



    
return
 ((PFNTERMINATEPROCESS)(PROC)g_TerminateProcess)(hProcess, uExitCode);
}

// 挂钩TerminateProcess函数
CAPIHook g_TerminateProcess("kernel32.dll""TerminateProcess",(PROC)Hook_TerminateProcess,TRUE);
 

为什么说深度学习和机器学习截然不同?

[转] http://www.leiphone.com/news/201612/ivLxiAXyHTCqGu0K.html 导语:Andreesen说“软件正在占领全世界”,那么深度...
  • xiangz_csdn
  • xiangz_csdn
  • 2017年01月05日 08:51
  • 11493

Oracle学习——扫盲篇

关于Oracle数据库、oracle数据库实例、SID、表空间、用户、表,这些都是什么,他们之间有什么关系,它们又是如何创建的!最后关于Oracle的使用总结,首先安装oracle数据库软件、然后创建...
  • zwk626542417
  • zwk626542417
  • 2014年09月17日 14:47
  • 6769

深度学习如何设置学习率

学习率是深度学习中的一个重要的超参,如何调整学习率是训练出好模型的关键要素之一。在通过SGD求解问题的极小值时,梯度不能太大,也不能太小。太大容易出现超调现象,即在极值点两端不断发散,或是剧烈震荡,总...
  • mao_feng
  • mao_feng
  • 2016年10月23日 16:33
  • 9086

增强学习系列之(一):增强学习介绍

增强学习介绍
  • superCally
  • superCally
  • 2017年01月27日 09:38
  • 2598

【机器学习-斯坦福】学习笔记13 在线学习(Online Learning)

原题目叫做The perception and large margin classifiers,其实探讨的是在线学习。这里将题目换了换。以前讨论的都是批量学习(batch learning),就是给...
  • u012409883
  • u012409883
  • 2013年12月03日 09:55
  • 4527

一张图看懂AI、机器学习和深度学习的区别

AI(人工智能)是未来,是科幻小说,是我们日常生活的一部分。所有论断都是正确的,只是要看你所谈到的AI到底是什么。   例如,当谷歌DeepMind开发的AlphaGo程序打败韩国职业围棋高手Lee...
  • dukai392
  • dukai392
  • 2017年04月20日 16:54
  • 9808

深度学习进阶之路 - 从迁移学习到强化学习

一. 深度学习及其适用范围        大数据造就了深度学习,通过大量的数据训练,我们能够轻易的发现数据的规律,从而实现基于监督学习的数据预测。                 没错,这里要强调的...
  • linolzhang
  • linolzhang
  • 2017年06月06日 23:17
  • 4802

机器学习之深度强化学习

机器学习之深度强化学习
  • qq_26609915
  • qq_26609915
  • 2016年03月21日 15:29
  • 3025

迁移学习资源整理

杨强:http://home.cse.ust.hk/~qyang/ Sinno Jialin Pan: http://www1.i2r.a-star.edu.sg/~jspan/
  • researchstep
  • researchstep
  • 2015年09月07日 09:16
  • 2803

Deep Learning(深度学习)学习笔记整理系列之(一)

Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0  20...
  • zouxy09
  • zouxy09
  • 2013年04月08日 23:35
  • 778432
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:学习
举报原因:
原因补充:

(最多只允许输入30个字)