200分询问,关于软件自毁的原理(200分)

  • 主题发起人 主题发起人 jiugui
  • 开始时间 开始时间
J

jiugui

Unregistered / Unconfirmed
GUEST, unregistred user!
软件自毁的原理,如果别人非法运行了软件,程序会自杀,并且用户不能阻止它自杀,只需要知道实现的原理就可以了。
 
转贴:
安装与卸载之卸载篇---程序自杀
陈经韬
电脑用得久了,安装的软件乱七八糟,怎么办?一般我们会打开控制面版里的添加删除程序选项,选择相应的卸载选项就可以了。但如果我们能在自己的程序中增加一个删除功能来实现“自杀”,则会令软件增色不少。
有点电脑常识的人都知道,在Windows下如果程序正在运行,那么是无法将其删除的,当然,也不是绝对不可以。CIH大家应该知道吧,它的核心有两个,一个就是取得Ring0级权限,然后就可以随便干想干的事(比如说修改正在运行的文件),而我们一般的程序是运行在Ring3级上的。顺便提一句---NT下没有Ring的概念,所以CIH对其无效。用Delphi内镶汇编也可以取得Ring0级权限,但如果我们的程序运行在NT或者Win2000下就没有效果了。在说句题外话,现在的编译器都很不错了,大多数程序员都编不出比编译器编译出的更理想的代码,象Delphi,如果将它的某些单元代码改用内镶汇编,在某些方面如字符串处理方面会提高5倍左右的效率,但NT不支持某些汇编代码,如果程序在NT下工作就会出错,怎么办?稳定第一!所以我们不用这个方法,而且,用这个方法有点杀鸡用牛刀的味道。
用过DOS的朋友应该还记得批处理文件吧,新建一个批处理文件a.bat,编辑其内容为:del %0,然后运行它,怎么样?a.bat把自己删除掉了!!!好,我们就用它来进行程序的“自杀”!
找一个EXE可执行文件,比如说abc.exe,新建一个批处理文件a.bat,编辑其内容为:
:pp
del abc.exe
if exist abc.exe goto pp
del %0
先运行abc.exe,再运行a.bat,然后将abc.exe退出,你会发现a.exe和a.bat都没有了!!!按照这个思路,我们可以在程序中根据文件名称写一个批处理,将上面的abc.exe换成自己的EXE文件名就可以了。运行Delphi,新建一个工程,添加一个Button到窗体上,点击Button,写下如下代码:
procedure TForm1.Button1Click(Sender: TObject);
var Selfname,BatFilename,s1,s2:string;
BatchFile: TextFile;
begin

Selfname:=Extractfilename(application.exename);//取EXE文件自己的名称
BatFilename:=ExtractFilePath(Application.ExeName)+ 'a.bat';//批处理文件名称
S1:='@del '+Selfname;
S2:='if exist '+Selfname+' goto pp';
assignfile(BatchFile,BatFilename);
rewrite(BatchFile);
writeln(BatchFile,':pp');
writeln(BatchFile,S1);
writeln(BatchFile,S2);
writeln(BatchFile,'@del %0');
closefile(BatchFile);
winexec(pchar(BatFilename),sw_hide);//隐藏窗口运行a.bat
application.Terminate;//退出程序
end;

那我们的事情是不是就完了?NO!上面的程序原理是对的,但如果你的程序是运行在系统目录下如Windows目录下或者Windows/System等目录下,除非你打开那个目录看着它删除,否则根本没法卸掉的。那怎么办?别急,我们请出一个函数CreateProcess,它的原型为:
BOOL CreateProcess(
LPCTSTR lpApplicationName, // pointer to name of executable module
LPTSTR lpCommandLine, // pointer to command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // pointer to process security attributes
LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to thread security attributes
BOOL bInheritHandles, // handle inheritance flag
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // pointer to new environment block
LPCTSTR lpCurrentDirectory, // pointer to current directory name
LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO
LPPROCESS_INFORMATION lpProcessInformation // pointer to PROCESS_INFORMATION
);
这个函数和OpenProcess、ReadProcessMemory、WriteProcessMemory使用可以用来读取和修改内存数据,常用的游戏修改器就是用它。由于这些不是本文的重点所以这里不作详细介绍,感兴趣的读者可自行翻阅Delphi自带的帮助文件。用CreateProcess函数创建一个进程就可以完美的完成我们的“程序自杀”了。
运行Delphi,新建一个工程,添加一个Button到窗体上,全部代码如下:
unit Unit1;

interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure My_DeleteMe;
//自定义程序自杀过程
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin

My_DeleteMe;
end;

procedure TForm1.My_DeleteMe;
//程序自杀
//-----------------------------------------------------------
function GetShortName(sLongName: string): string;
//转换长文件名
var
sShortName: string;
nShortNameLen: integer;
begin

SetLength(sShortName, MAX_PATH);
nShortNameLen := GetShortPathName(PChar(sLongName),
PChar(sShortName), MAX_PATH - 1);
if (0 = nShortNameLen) then

begin

// handle errors...
end;

SetLength(sShortName, nShortNameLen);
Result := sShortName;
end;

//-------------------------------------------------
var
BatchFile: TextFile;
BatchFileName: string;
ProcessInfo: TProcessInformation;
StartUpInfo: TStartupInfo;
begin

BatchFileName := ExtractFilePath(ParamStr(0)) + '$$a$$.bat';
AssignFile(BatchFile, BatchFileName);
Rewrite(BatchFile);
Writeln(BatchFile, ':try');
Writeln(BatchFile, 'del "' + GetShortName(ParamStr(0)) + '"');
Writeln(BatchFile, 'if exist "' + GetShortName(ParamStr(0)) + '"' + ' goto try');
Writeln(BatchFile, 'del %0');
Writeln(BatchFile, 'cls');
Writeln(BatchFile, 'exit');
CloseFile(BatchFile);
FillChar(StartUpInfo, SizeOf(StartUpInfo), $00);
StartUpInfo.dwFlags := STARTF_USESHOWWINDOW;
StartUpInfo.wShowWindow := SW_Hide;
if CreateProcess(nil, PChar(BatchFileName), nil, nil,
False, IDLE_PRIORITY_CLASS, nil, nil, StartUpInfo,
ProcessInfo) then

begin

CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
end;

Application.Terminate;
end;

end.

补充:1、上面的批处理的 del %0等同于 del a.bat,用del a.bat则批处理文件必须为a.bat,用del %0则可以随意。
2、所有程序在Pwin98+Delphi5、Win2000+Delphi5下运行通过。
本文的标题为《安装与卸载之卸载篇》,下次将介绍如何用Delphi制作自己的安装程序。记得有一位著名的黑客说过:我从来不去找什么工具软件,需要的话就自己写一个。如果我们也持这种态度,则编程水平一定会越来越高。

 
把关键的函数写在dll里,然后如果非法运行了软件就把那个dll删了,反正删一个文件也很快,不需要把整个软件给删了
 
程序自删除吧?
先加入CRC校验机制, 检查软件本身有没有受到修改, 如果无, 执行正常流程,
如果有, 调用自删除过程, 将自己的应用程序文件删除掉并将自己关闭掉。
关于自删除, 已有成功例子。
 
谢谢,200分值了,本人属于菜鸟,知道点原理也不错了,谢谢三位朋友,
 
怎么判断是“非法运行”呢?
 
我认为比较好的方法,就是将校验写到 DLL 里面。判断主程序是补被修改。如果被改就删除自己。。
上面有位DFW说了如果自杀。
现在我附一个获得文件校验码的例子给你。(有汇编代码)
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, TFlatButtonUnit, StdCtrls, TFlatEditUnit;
type
TForm1 = class(TForm)
Label1: TLabel;
CRCEdit: TFlatEdit;
CRCBtn: TFlatButton;
OpenDialog1: TOpenDialog;
procedure CRCBtnClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
{定义校验函数}
Function GetCheckSun(FileName:string):DWORD;
var
F:File of DWORD;
P:Pointer;
FSize:DWORD;
Buffer:Array[0..500]of DWORD;
begin
FileMode := 0;
AssignFile(F,FileName);
Reset(F);
Seek(F,FileSize(F) div 2);
Fsize := FileSize(F) -1 -FilePos(F);
if Fsize > 500 then
Fsize := 500;
BlockRead(F,Buffer,Fsize);
Close (F);
P := @Buffer;
asm
xor eax,eax
xor ecx,ecx
mov edi,p
@again:
add eax,[edi + 4*ecx]
inc ecx
cmp ecx,fsize
jl @again
mov @result,eax
end;
end;

procedure TForm1.CRCBtnClick(Sender: TObject);
var
CRCResult :dword;
begin
//打开对话框选择文件
if OpenDialog1.Execute then

begin

CRCResult:=GetCheckSun(OpenDialog1.FileName);
if CRCResult<>0 then
CRCEdit.text:=IntToHex(CRCResult,8)
else
ShowMessage('The CRC check failed');
end;

end;

end.
 
程序自杀有很多种,有野蛮的,有温柔的
Walter
finalrinoa
上面两个兄弟讲的是野蛮的做法:
我来讲个温柔的
如果你的程序发现有人非法运行这时候你要保持理智,因为你一冲动别人就知道你的动机,根据你的动机就很容易找到,你执行删除代码,所以很容就会破解掉。。。。。
我给个温柔的陷阱给你,例如你发现了别人非法使用了你的程序,你应该不动声色的干,例如.Free掉几个From,记住刚刚Free的From还是可以使用的,但是这个Free为以后的xxxx read 错误埋下了祸根,但是这时候他还在享受着幸福,但是没过多久,他就发现程序里面到处都是 xxx read error 的异常,这时候他脑子里第一个念头就是“是不是我的系统有病毒了”,防火墙、杀毒半个小时过去了,老样子,如果你的程序对他很重要,他估计会重装系统,然后在继续使用发现没多久又 xxxxx ,还是不行,他开始怀疑 98 不稳定不安全,应该装个 2000 ,可是没多久又 xxxx 异常,经过这么多折腾,在盛怒之下他会把你的程序彻底从硬盘里删除。
 
后退
顶部