阿八博客
  • 100000+

    文章

  • 23

    评论

  • 20

    友链

  • 最近新加了很多技术文章,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

[普及]程序自启动方式 - ActiveX

欢迎来到阿八个人博客网站。本 阿八个人博客 网站提供最新的站长新闻,各种互联网资讯。 喜欢本站的朋友可以收藏本站,或者加QQ:我们大家一起来交流技术! URL链接:https://www.abboke.com/rz/2019/1010/116815.html

    每次都是一个假期不开VC,可能都是在学校做的多了,回家了要换个口味。

    已经在学校呆了好几天,明天还要补考,想着想着就泪流满面了。正逢着大一新生到来的时间,我也想到了去年自己刚坐在这所学校的课堂里时,那份激动与不安。也是那时候,我写了我人生第一个Widnows程序,也就此跟VC结下了不解之缘。

    当时写的东西是“编程实现自启动”。当时还是懵懂初开,查了不少资料,写了一个基于修改注册表实现的自启动。实现自启动的方式还有很多,当时再就没有继续深入了。

    于是,在这一周年之际,我来继续完成我当年没有完成的任务。    


    这次先来个低烈度的,ActiveX自启动,基本也是通过修改注册表某个键值来达到自启动的效果。

    拿来开刀的是类似这个键:HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{C9B4C1CD-B018-4511-B0A1-5476DBF70821}

    我们win+R 输入regedit启动注册表,找到该键。

    呵呵,当你找的时候可能就发现,你注册表中并没有这个键。其实{C9B4C1CD-B018-4511-B0A1-5476DBF70821}这串字符串是可以更改的,随便更换几个字符,只要是16进制允许的字符都可以。(格式xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)

    在该键下增加一个子键,键名为“StubPath”,键值为我们待启动的程序。

    还有一点要注意的,我们系统在第一次ActiveX自启动完成后,会生成一个键:HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{C9B4C1CD-B018-4511-B0A1-5476DBF70821}

    注意哟,它在根节点HKEY_CURRENT_USER下,名字和之前那个相同。当该键存在时,下次自启动就不会加载这个ActiveX了。

    所以我们编程时候要注意,每次启动起来后,删除掉该键,这样下次才能继续自启动。

    废话不多说,我写了一个小小的示例代码。

brush: cpp;auto-links: false;">int WINAPI WinMain(  HINSTANCE hInstance,      // handle to current instance  HINSTANCE hPrevInstance,  // handle to previous instance  LPSTR lpCmdLine,          // command line  int nCmdShow              // show state){HKEY hKey;DWORD dwDpt = REG_OPENED_EXISTING_KEY;long lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{C9B4C1CD-B018-4511-B0A1-5476DBF70821}",REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, &hKey);if (ERROR_SUCCESS != lRet){char SelfFile[MAX_PATH];char SystemPath[MAX_PATH + 20];GetSystemDirectory(SystemPath, sizeof(SystemPath));strcat(SystemPath, "\\activexrun.exe");GetModuleFileName(NULL, SelfFile, MAX_PATH);CopyFile(SelfFile, SystemPath, FALSE);CreateStringReg(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{C9B4C1CD-B018-4511-B0A1-5476DBF70821}","StubPath", SystemPath);return 0;}MyCode();return 0;}


    首先使用RegOpenKeyEx函数打开HKEY_LOCAL_MACHINE下的键,如果打开成功,返回ERROR_SUCCESS。

    这里判断其打开成功或失败的原因是,如果打开成功,说明有该键不存在,进一步说明这个程序是第一次自启动,这时我们就执行if语句中的内容。

    if中代码作用,就是把本程序拷贝进系统目录,并新建该键,以备下次启动。

    其中有一个函数,CreateStringReg是我自己定义的。这个函数在这里就是创建一个键名为StubPath的子键,其值是我们需要自启动的程序的绝对地址。

brush: cpp;auto-links: false;">//修改或创建字符串类型的键值void CreateStringReg(HKEY hRoot, char *szSubkey, char * ValueName, char *Data){HKEY hKey; long lRet = RegCreateKeyEx(hRoot, szSubkey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);if (ERROR_SUCCESS != lRet){//TRACE("error on RegCreateKeyEx: %s\n", szSubkey);return ;}//修改或创建注册表键值lRet = RegSetValueEx(hKey, ValueName, 0, REG_SZ, (BYTE *)Data, strlen(Data));if (ERROR_SUCCESS != lRet){//TRACE("error on RegSetValueEx: %s\n", ValueName);return ;}RegCloseKey(hKey);}


    最后,我们的代码在MyCode函数中。这个其实都可以扩展了,我们可以开启一个线程,或者把代码注入到其他进程中。

    我的MyCode()函数很简单:

brush: cpp;auto-links: false;">void MyCode(){WinExec("C:\\windows\\system32\\calc.exe", SW_SHOWDEFAULT);WinExec("C:\\windows\\system32\\start.bat", SW_HIDE);}
    第一行是打开一个计算器。


    第二行很重要,是我写的一个批处理。我之前说到了,第一次ActiveX自启动成功后,会在HKEY_CURRENT_USER生成一个键:\\SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{C9B4C1CD-B018-4511-B0A1-5476DBF70821}。这个键直接导致下次不会再次自启动,所以我们每次自启动的时候要删除该键。

    start.bat:

brush: bash;auto-links: false;">reg delete "HKEY_CURRENT_USER\Software\Microsoft\Active Setup\Installed Components\{C9B4C1CD-B018-4511-B0A1-5476DBF70821}" /f


    原本我是预备在这个程序中删除该键的,但是试了很多次都没有成功。我估计原因是这样,第一次程序自启动成功后,在程序结束运行的时候系统才新建这个键。所以我程序中删除该键的时候,该键其实并不存在。所以,我只好调用一个外部程序(.bat),来删除这个讨厌的键。

    这只是一个简单的例子,可以删除这个键的方法还有很多,比如我们把代码注入explorer进程中,利用explorer来删除这个键。


    最后说一个小技巧,如何缩小可执行程序的体积。

    以前我一直抵触用VC6写程序,过了很久我才明白很多木马用VC6的原因:缩小体积。

    VS2010中,在编译的时候会加入很多乱七八糟的编译选项,导致生成物体积庞大。而VC6顾虑没有这么多,所以生成的可执行文件体积小。gh0st为什么把客户端和服务端分开编写的原因我也顿悟了,被控端放在VC6下编译,而主控端没有大小要求就放在VS2010下编译。

    还有一个小文件Tiny.h,大家把他include进你的程序最上面,它能极大地减小编译完成后的体积:

brush: cpp;auto-links: false;">/**************** Leavesongs.com* By phith0n****************/#ifdef NDEBUG #pragma optimize("gsy", on)#pragma comment(linker, "/RELEASE")#ifdef _MERGE_RDATA_#pragma comment(linker, "/merge:.rdata=.data")#endif#pragma comment(linker, "/merge:.text=.data")#pragma comment(linker, "/merge:.reloc=.data")#if _MSC_VER >= 1000#endif#endif#pragma comment(linker, "/ENTRY:WinMain")#pragma comment(linker, "/MERGE:.rdata=.data")#pragma comment(linker, "/MERGE:.text=.data")#pragma comment(lib, "msvcrt.lib")#if (_MSC_VER < 1300)#pragma comment(linker, "/IGNORE:4078")#pragma comment(linker, "/OPT:NOWIN98")#endif#define WIN32_LEAN_AND_MEAN
    可能有些地方还需要根据情况修改,倒数第9行的WinMain是入口点函数,大家要酌情修改。


    在没有include<tiny.h>时,编译好的程序有16k左右,而包含了该头后,程序只有1.50k了。

相关文章