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