打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Windows下实现进程保护

Windows下实现进程保护 [复制链接]

楼主
南昌航空大学空中社区 立即收听
沙发

然后,看一下我们可能需要的一些API第一个CreateProcess
这个函数很恶心啊,先看看他的声明(M$的东西一贯恶心,习惯就好)
  1. BOOL WINAPI CreateProcess(
  2.   __in_opt     LPCTSTR lpApplicationName,
  3.   __inout_opt  LPTSTR lpCommandLine,
  4.   __in_opt     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  5.   __in_opt     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  6.   __in         BOOL bInheritHandles,
  7.   __in         DWORD dwCreationFlags,
  8.   __in_opt     LPVOID lpEnvironment,
  9.   __in_opt     LPCTSTR lpCurrentDirectory,
  10.   __in         LPSTARTUPINFO lpStartupInfo,
  11.   __out        LPPROCESS_INFORMATION lpProcessInformation
  12. );
复制代码
对参数,不做太详细的解释,这里只对这个函数做一点简单说明lpApplicationName 进程名
lpCommandLine 进程路径+进程名
lpProcessAttributes 进程安全描述结构
lpThreadAttributes 线程安全描述结构
bInheritHandles 是否从父进程继承句柄
dwCreateFlags  进程优先级等等,看文档比较靠谱,参数比较复杂
lpEnvironment 进程的环境变量(不指定的话,默认继承父进程的所有环境变量)
lpStartupInfo  进程创建以后的状态(挂起,就绪...),这里能设置的和dwCreateFlags其实有类似的地方,具体不做太多讨论,看文档比较靠谱
lpCurrentDirectory 进程创建以后的路径,默认是可执行文件exe的路径
lpProcessInformation 返回的进程信息,包含进程句柄和线程句柄

接下来,就是用这玩意创建一个进程了。(想想linux和unix下的fork函数吧,多么简单,或者是exec函数...)

再下来,需要简单介绍下CreateThread,因为上文里说了,需要一个不影响当前进程执行的模块来负责做守护
那么,CreateThread又有啥呢?当然,CreateThread函数就相对简单的多了
  1. HANDLE WINAPI CreateThread(
  2.   __in_opt   LPSECURITY_ATTRIBUTES lpThreadAttributes,
  3.   __in       SIZE_T dwStackSize,
  4.   __in       LPTHREAD_START_ROUTINE lpStartAddress,
  5.   __in_opt   LPVOID lpParameter,
  6.   __in       DWORD dwCreationFlags,
  7.   __out_opt  LPDWORD lpThreadId
  8. );
复制代码
lpThreadAttributes 线程安全结构dwStackSize 线程栈大小
lpStartAddress 线程执行体函数
lpParameter 线程执行体函数的参数
dwCreateFlags 线程的优先级,线程状态等标志
lpThreadId 线程ID

参数确实相比进程简单了很多,但是还是复杂

如此复杂的API,如何调用?这确实是问题,不过好处是,对于绝大部分的情况,我们都可以传NULL(对于非指针和句柄传0代替)
API内部看到NULL(0)以后会用默认的参数来代替他们

那么,我们可以如何调用呢?
下面写2个简单的调用例子
  1. STARTUPINFO si;
  2. PROCESS_INFORMATION pi;

  3. ZeroMemory(&si, sizeof(si));
  4. si.cb = sizeof(si);
  5. ZeroMemory(&pi, sizeof(pi));
复制代码
以上就是创建一个进程的代码了,如果不出特殊需求
创建进程都可以用这种形式,对我们不关注的参数,直接传NULL 或者是 0

那么,线程呢?
线程可能有点麻烦的
现在的线程创建,一般是把一个函数当作一个线程来执行
所以,我们首先需要定义一个函数,作为线程的执行体。
和进程的入口函数main(其实main不是真正的入口,以后讲到PE文件的时候会讲到),线程的入口函数也是一个固定的格式
DWORD WINAPI ThreadProc(void *arg);
只有满足这个格式的函数才能当作线程函数
这里的函数声明又多了一个东西,叫做WINAPI
其实WINAPI是个宏,在windows.h里面是这样定义的
#define WINAPI __stdcall
他规定了函数的调用约定方式(这个涉及到一点点的汇编知识,所以就暂时不展开讲了),平时用的最多的C库,调用约定都是__cdecl的形式

好了,废话说完了,那么,如何创建一个线程呢?
  1. DWORD WINAPI ThreadProc(void *arg)
  2. {
  3.     return 0;
  4. }
  5. HANDLE hThread;
  6. DWORD dwThreadID;

  7. hThread = CreateThread(
  8.         NULL,
  9.         0,
  10.         MyThreadFunction,
  11.         pDataArray[i],
  12.         0,
  13.         &dwThreadID
  14. );
复制代码
如此,就能创建一个线程了
tinysniper 最后编辑于 2012-03-07 11:16:19
板凳

简单那守护进程实现:
  1. #include <stdio.h>
  2. #include <windows.h>
  3. #include <psapi.h>

  4. #ifdef DBG
  5. #define ErrorInfo(proc) \
  6.     fprintf(stderr, "%s failed in FILE:[%s] FUNCTION:[%s] LINE:[%d] ---- ERRORNUM:[%d]\r\n", #proc, __FILE__, __FUNCTION__, __LINE__, GetLastError())
  7. #else
  8. #define ErrorInfo(proc) do { } while(0)
  9. #endif

  10. /*++
  11. *
  12. * 函数名           FindProcessByName
  13. *
  14. * 函数说明         从当前进程列表中查询,是否有指定的进程
  15. *
  16. * 参数             pszName - 需要查询的进程名
  17. *
  18. * 返回值           TRUE  - 指定进程存在
  19. *                  FALSE - 指定进程不存字在
  20. *
  21. --*/
  22. BOOL FindProcessByName(const CHAR *pszName)
  23. {
  24.     BOOL bRet;
  25.     DWORD dwProcessArray[1024];
  26.     DWORD dwTotalSize;
  27.     DWORD dwProcessCount;
  28.     DWORD i;

  29.     HANDLE hProcess;
  30.     HMODULE hModule;
  31.     DWORD dwSize;

  32.     CHAR szProcessName[MAX_PATH];

  33.     bRet = EnumProcesses(
  34.             dwProcessArray,
  35.             sizeof(dwProcessArray),
  36.             &dwTotalSize);
  37.     if ( !bRet ) {
  38.         ErrorInfo(EnumProcesses);
  39.         return FALSE;
  40.     }

  41.     //
  42.     // 获得当前系统中的进程个数
  43.     //
  44.     dwProcessCount = dwTotalSize / sizeof(DWORD);
  45.     for ( i = 0; i < dwProcessCount; i++ ) {
  46.         if ( !dwProcessArray[i] ) {
  47.             continue;
  48.         }
  49.         hProcess = OpenProcess(
  50.                 PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
  51.                 FALSE,
  52.                 dwProcessArray[i]
  53.                 );
  54.         if ( !hProcess ) {
  55.             printf("Error OpenProcess ID - %d\n", dwProcessArray[i]);
  56.             ErrorInfo(OpenProcess);
  57.             continue;
  58.         }

  59.         //
  60.         // 枚举进程模块
  61.         //
  62.         bRet = EnumProcessModules(
  63.                 hProcess,
  64.                 &hModule,
  65.                 sizeof(hModule),
  66.                 &dwSize
  67.                 );
  68.         if ( !bRet ) {
  69.             printf("Error EnumProcessModules ID - %d\n", dwProcessArray[i]);
  70.             ErrorInfo(EnumProcessModules);
  71.             CloseHandle(hProcess);
  72.             continue;
  73.         }

  74.         //
  75.         // 获得进程模块名
  76.         //
  77.         bRet = GetModuleBaseName(
  78.                 hProcess,
  79.                 hModule,
  80.                 szProcessName,
  81.                 sizeof(szProcessName) / sizeof(CHAR)
  82.                 );
  83.         if ( !bRet ) {
  84.             ErrorInfo(GetModuleBaseName);
  85.             CloseHandle(hProcess);
  86.             continue;
  87.         }

  88.         //
  89.         // 如果抓取到的模块名和进程名一样
  90.         //
  91.         if ( strcmp(szProcessName, pszName) == 0 ) {
  92.             CloseHandle(hProcess);
  93.             return TRUE;
  94.         }
  95.     }
  96.     return FALSE;
  97. }

  98. int main()
  99. {
  100.     STARTUPINFO si;
  101.     PROCESS_INFORMATION pi;
  102.     BOOL bRet;

  103.     while ( TRUE ) {

  104.         ZeroMemory(&si, sizeof(si));
  105.         si.cb = sizeof(si);
  106.         ZeroMemory(&pi, sizeof(pi));

  107.         //
  108.         // 在系统进程列表里面查询calc进程是否存在
  109.         //
  110.         if ( FindProcessByName("calc.exe") ) {
  111.             Sleep(1000);
  112.             continue;
  113.         }

  114.         //
  115.         // 创建calc进程
  116.         //
  117.         bRet = CreateProcess(
  118.                 NULL,  
  119.                 "C:\\Windows\\System32\\calc.exe",       // windows自带的计算器
  120.                 NULL,        
  121.                 NULL,        
  122.                 FALSE,        
  123.                 0,            
  124.                 NULL,        
  125.                 NULL,        
  126.                 &si,          
  127.                 &pi
  128.                 );
  129.         if ( bRet ) {
  130.             //
  131.             // XXX 如果进程创建成功,一定记得关闭进程句柄和线程句柄
  132.             //
  133.             CloseHandle(pi.hProcess);
  134.             CloseHandle(pi.hThread);
  135.         }

  136.         Sleep(1000);
  137.     }
  138.     return 0;
  139. }
复制代码
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
windows下编程常用API函数
VC 中进程与多进程管理的方法
打造属于自己的任务管理器(邀请码已发)
[翻译]多种DLL注入技术原理介绍
[Win32] DLL注入技术
更新了已经过测试-Windows下如何改写目标进程的窗口函数来注入DLL
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服