注:《木马编程DIY》由冷风(chinafe)创作完成。本文在其基础上将原文中的C++源代码修改为Delphi源代码,并加以相关说明。感谢冷风(chinafe)的无私奉献。

在02-03年之间常玩木马的朋友可能还记得,当时有款叫广外男生的木马比较流行。用过的朋友友可能也发现了,广外男生有个不大不小的BUG就是:如果服务端被运行多次的话,那么客户端就会有多个服务端上线,当然并不是说肉鸡变多了,而是同一个服务端被多次加载。还有,我写了一个CMD窗口的程序,如果运行一个是没问题的,但运行两个,嘿嘿,那家伙可是相当壮观,两个程序像得了疯牛病一样疯狂输出垃圾数据,停都停不了。

现在我们就来解决这个问题,如何让程序只能运行一个实例,这里根据程序是否有窗口,来分别介绍。

一、无窗口程序的实现

实现思路

这类程序的典型代表就是木马的服务端了,我们想要达到目的,会有这样的想法:程序运行时先检查有没有另一个实例在运行,没有的话就运行自己,有的话就退出自己。

编程实现

通常有两种方法可以实现,我们分别来介绍。

1. 使用互斥对像

使用API函数CreateMutex来创建命名互斥对象来实现程序互斥是一个比较通用的方法。

program Project1;{$APPTYPE CONSOLE}uses Windows;varMutexHand: THandle;s: string;
begin// 创建互斥对象,并命名为"LengFeng"MutexHand := CreateMutex(nil, False, 'LengFeng');// 判断该互斥对象是否存在if (MutexHand <> 0) and (GetLastError = 0) thenbegintryReadLn(s);finallyCloseHandle(MutexHand);  // 释放对象end;endelse begin  // 该互斥对象已经存在Write('程序已经运行。');end;
end.

以上的CreateMutext函数创建一个称为"LengFeng"的命名的互斥对象。当程序的第二个实例运例时,调用CreateMutex函数将显示名为"LengFeng"的互斥对像以存在,也就是说明程序以运行。

2. 用编译器创建新节

能不能为程序中加入一个全局变量?让这个全局变量可被程序的多个实例所共享,每当程序实例运行时就对该全局变量进行修改,通过对该全局变量的访问,就可以知道有多少个实例在运行了。当然为了系统的安全和稳定性,默认情况下是不允许这样做的,为了阻止这种事情的发生系统使用copy-on-write(写入时拷贝)机制,不过我们就使用创建新节的方法来绕过系统的copy-on-write机制其方法如下:

#pragma data_seg("Shared")
int volatile g_lAppInstance =0;
#pragma data_seg()

我们来看一下上面的内容:

第一句 #pragma data_seg("Shared") 创建一个称为Shared的新节。

第二句 int volatile g_lAppInstance =0 将 g_lAppInstance 放入Shared节中。注意此时只有将g_lAppInstance初始化,编译器才会将其放入Shared节中,否则,将放入Shared以外的节。

第三句指示编译器Shared节结束。

仅仅告诉编译器将某些变量放入它们自己的节中,是不足以实现对这些变量的共享的。还必须告诉链接程序某个节中的变量是需要加以共享的。若要进行这项操作,可以使用链接程序的命令行上的/SECTION开关,在冒号的后面,是想要改变其属性的节的名字。在我们的例子中,想要改变Shared节的属性因此应该创建下面的链接程序开关:

#pragma comment(linker,"/section:Shared,RWS")

这一句,我们使编译链接器知道我们的Shared节具有读,写,共享的属性。这是我们实现互斥运行的关键,这样我们就可以在应用程序之间的多个实例之间共享g_lAppInstance 变量了。

下面我们看一下在SDK程序中它的完整实现代码如下:

#include <windows.h>
#pragma data_seg("Shared")       // 创建新节
int volatile g_lAppInstance =0;  // 必须有初示化
#pragma  data_seg()              // 结束

#pragma comment(linker,"/section:Shared,RWS")int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR     lpCmdLine,int       nCmdShow)
{if (++g_lAppInstance > 1){MessageBox(NULL, "程序已经运行!", NULL, NULL);ExitProcess(0);}while(1) {}
}

注:此处提到的方法是“共享数据段”。这种方法在Delphi中无法直接实现,这也是Delphi与VC++相比的一个不足之处,Delphi还是不如VC++更靠近低层。如果在Delphi中想使用“共享数据段”方法,需要使用第三方的工具直接修改.exe文件,或者通过链接ASM的.OBJ文件来实现,但是这里,我个人不推荐大家这样做。另外,在Delphi中使用内存映射文件也可以模拟上述效果,但这里我们重点讨论的是单实例问题,而内存映射文件主要用于进程通讯,就不细说它了。

回头再看这两种方法,在实现上使用互斥对像比较简单,但功能却不如创建新节的方法强大,不过在无窗口程序中使用互斥对像还是比较实用的。

二、基于窗口程序的实现

基于窗口程序的实现,除了上面提到的为“互斥对像”方法和“共享数据段”之外,又多了一个“枚举窗口”的方法。但是我个人认为“枚举窗口”的方法可靠性不高,而且冷风(chinafe)同学此处也没有对“枚举窗口”的方法进行详细描述。

基于窗口程序的实现,除了要求阻止多实例运行,还有一个要求就是激活前一个实例的窗口,使其窗口提前引起用户注意。

关于这个实现,大家可以看一下ysai同学在《Delphi 5 开发人员指南》中第13章中一篇"防止同时出现多个应用程序实例"的代码基础上的修改版。

http://www.qqgb.com/Program/Delphi/DelphiSL/Program_151574.html

转载于:https://www.cnblogs.com/colajar/archive/2008/08/13/1266592.html

木马编程DIY (Delphi版) - 第2篇 单实例运行相关推荐

  1. 木马编程DIY (Delphi版) - 第3篇 星号密码查看工具

    注:<木马编程DIY>由冷风(chinafe)创作完成.本文在其基础上将原文中的C++源代码修改为Delphi源代码,并加以相关说明. 感谢冷风(chinafe)的无私奉献. 星号密码查看 ...

  2. ***编程DIY (Delphi版) - 第3篇 星号密码查看工具

    星号密码查看工具大家都用过吧,现在我们自己来写个超级简单的.其实密码框是一个Window子窗体,显示星号是因为密码框设置了EM_SETPASSWORDCHAR属性,只要我们把密码框的EM_SETPAS ...

  3. 木马编程DIY第8篇服务启动技术

    随意打开一个 木马的服务生成端,你都能发现里面有一种启动方式叫"服务启动",也就是说这个技术以经是大众化的了,但是你写过这样的 程序吗?如果写过的话,你就可以泡杯茶先休息一下,如果 ...

  4. 木马编程DIY之星号密码查看

    原文链接:http://blog.csdn.net/chinafe 星号密码查看工具大家都用过吧,现在我们自己来写个超级简单的.其实密码框是一个 Windows 的一个子窗口,显示星号是因为密码框设置 ...

  5. python编程输入标准-《Python编程 第四版》 -第3章 脚本运行上下文

    本章重点内容: 1.当前工作路径 2.命令行参数 3.shell环境变量 4.标准流 接下来展开详细的说明: 1.当前工作路径 当前工作路径,英文简写"CWD" 当前工作路径是系统 ...

  6. 《安富莱嵌入式周报》第280期:支持在线仿真编程的网页版电子开发,CAN总线防攻击实现,BigFAT 规范打破了 FAT 每个文件 4GB 的限制

    往期周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - P ...

  7. 木马编程入门_逆向入门分析实战(一)

    原创xiaoyuer合天智汇 木马分析入门 大家好,我最近从Web安全开始学习二进制安全,分享一下自己学习过程的收获和心得体会.由于是入门的内容,所以对于二进制大佬来说这很简单,所以本文主要面向的对象 ...

  8. 面试分析《疯狂Python讲义》PDF代码+《Python核心编程第3版》PDF代码问题

    python语言现在很流行了,除了用在学校,也用在很多行业.python学起来较为简单,语法容易理解,也可用于数据分析. 国内的教材推荐看<疯狂python讲义>,对比国外也有很多好的参考 ...

  9. Delphi 版 everything、光速搜索代码

    近日没啥事情,研究了一下 everything.光速搜索原理.花了一个礼拜时间,终于搞定. 废话不多说,直接上代码: unit uMFTSearchFile; {dbyoung@sina.com201 ...

最新文章

  1. qt 找不到 -lpulse-mainloop-glib,找不到 -lpulse问题
  2. JSP:1. 指令(page  ;include ;taglib)2. 内置对象
  3. 【Storm篇】--Storm并发机制
  4. VTK:可视化算法之DecimateHawaii
  5. 本田da屏怎么进wince系统_东风本田LIFE“来福酱”上市
  6. zookeeper watch笔记
  7. oracle高水位线
  8. 从里面学到的关于过去的经验 后篇
  9. 2017-2018网络攻防第四周作业
  10. [日志]说一个人长的丑!如何说?
  11. 如何使用组策略映射网络驱动器
  12. SSM-MyBatis框架学习笔记
  13. unity3d UI粒子特效裁剪
  14. matlab神经网络训练方法,matlab神经网络模型导出
  15. java中CheckException和UnCheckException的区别
  16. MacBook Pro 2018款充电口不能用解决办法
  17. 国庆七天乐,要猛! ——经典迷宫问题
  18. JavaScript中的常用浏览器对象
  19. 码神-day8-java
  20. 第 1-1 课:为什么要掌握 Flutter?

热门文章

  1. 中国3亿中年男人都在花钱买什么?数据分析后告诉你答案,很现实
  2. 数据分析、python速成班?包就业?扒一扒数据行业黑幕
  3. 摩擦力特点用计算机绘制出,AGC液压缸模拟工况摩擦力特性测试方法研究
  4. 小程序 php wecahtpay,PHP 微信公众号,小程序获取支付参数。微信支付
  5. signature=4c9125bac76ec40553ba356eaca47964,2008 SEM Honorary Members Conversations
  6. PL-SLAM: a Stereo SLAM System through the Combination of Points and Line Segments
  7. SQLite基础知识学习
  8. GAN——流形(manifold)
  9. windows 设置ssh登录
  10. GO语言中的几个关键思想