1.恶意软件中的防双开

目录

1.防双开代码(互斥体、绑定端口检测)

2.逆向分析

3.号外

4.参考

防双开代码

还是看到别人的文章才知道防双开这个词,防双开是指一个程序在运行后会禁止重复运行。在生活中用到的一些软件也会使用了这个功能,毕竟一个应用程序被重复运行后,其中的行为是相同的,但是这种相同的行为可能会产生冲突而导致程序崩溃。程序在防多开时可能用到的方法有:1.使用FindWindow APi函数;2.Mutex/Event/Semaphore ;3.内存映射文件;4.DLL全局共享区 ;5.全局Atom ;6.检查窗口属性 。这里具体的解释可以看下面参考哪里。

同样,病毒为了确保自己进行传播感染时的正常运行,也会有部分存在防双开这个功能,不过为了减少自己的代码量,所使用的"姿势"可能就那几种。目前我就遇到了两种,所以这里就写一下这两种,如果之后遇到新的会对文章进行实时更新。

1.互斥体

创建互斥体是大多数病毒都会使用的一种方法,毕竟使用互斥体防双开的代码量小而且非常简单粗暴。这种方式主要是利用CreateMutex函数创建互斥体,如果互斥体不存在则创建互斥体对象,如果存在则获得GeekFZ互斥体的句柄但是会返回错误ERROR_ALREADY_EXISTS。

 1 #include "Windows.h"
 2 #include "stdio.h"
 3 
 4 int main()
 5 {
 6      HANDLE Mutex = CreateMutex(NULL, TRUE ,"GeekFZ");
 7      DWORD ErrorCode = GetLastError();
 8      if (ErrorCode == ERROR_ALREADY_EXISTS)
 9      {
10          printf("process already exist!!!!");
11          Sleep(10000);
12          return 0;
13      }
14 
15      printf("this is the first run the process!!!");
16      Sleep(10000);
17 
18     return 0;
19 }

2.绑定端口检测

通过使用bind函数绑定一个本地端口后,再次调用这个函数尝试绑定相同的端口就会返回错误。我给出的代码中存在一些检测错误的部分,在平常分析病毒时可能不存在。之前遇到这种方式来防双开是在驱动人生利用病毒的一个python模块中,哪里就几行python代码就实现了防双开的功能,不过python代码和这里给出的代码原理是相同的。 

 1 #include <Windows.h>
 2 #include <stdio.h>
 3 #include <winsock.h>
 4 
 5 #pragma comment(lib,"Ws2_32.lib")
 6 
 7 int main()
 8 {
 9     int result;
10     WSADATA wsaData;
11     struct sockaddr_in service;
12 
13     //开启socket通信
14     result = WSAStartup(MAKEWORD(2, 2), &wsaData);
15     if (result != NO_ERROR)
16     {
17         wprintf(L"Error at WSAStartup()
");
18         return 1;
19     }
20     //设置socket
21     SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
22     if (s == INVALID_SOCKET)
23     {
24         wprintf(L"socket function failed with error: %u
", WSAGetLastError());
25         WSACleanup();
26         return 1;
27     }
28     //设置绑定的信息
29     service.sin_family = AF_INET;
30     service.sin_port = htons(60124);
31     service.sin_addr.s_addr = inet_addr("127.0.0.1");
32     //进行bind
33     result = bind(s, (SOCKADDR *)&service, sizeof(service));
34     if (result == SOCKET_ERROR)
35     {
36         wprintf(L"process already exist!!!
");
37         //wprintf(L"bind failed with error %u
", WSAGetLastError());
38     }
39     else
40     {
41         wprintf(L"this is the first run the process");
42         //wprintf(L"bind returned success
");
43     }
44 
45     Sleep(10000);
46     WSACleanup();
47     return 0;
48 }

 

逆向分析

防双开在病毒分析中一般出现在病毒的开头处,用来判断病毒程序是否重复打开了,如果重复打开就结束病毒程序的运行,如果没有就正常执行病毒中的恶意功能。

1 if(判断是否重复运行病毒程序)
2 {
3     是则退出    
4 }        
5 else
6 {
7     不是就执行病毒的恶意功能
8 }    

号外

在学习逆向时,一般写完代码后用汇编调试一下可以更好的学习汇编,这里我使用的是VS2015,在编写完代码后在函数中下断点,接着就可以进行调试了

进行调试时,你可以在调试->窗口里选择你想看的窗口,我一般是显示反汇编窗口,局部变量和调用堆栈,然后就可以开始调试了

最后的显示情况是这样

 

参考

程序多开原理记录:http://www.cppblog.com/elva/archive/2008/02/19/42923.html

bind function:https://docs.microsoft.com/en-us/windows/desktop/api/winsock/nf-winsock-bind

原文地址:https://www.cnblogs.com/QKSword/p/10493349.html