SDK完全接触——之Asprotect篇
SDK完全接触——之Asprotect篇转自:http://www.unpack.cn/thread-29538-1-1.html
....前言....
可能你发现,Unpack甚至网上,关于sdk的用法,是很少的,甚至没有,你可能遗憾的,这样一个壳的天下,竟然没有sdk教程可学习,缺少sdk,壳的强壮要大大降低.
我想可能有几个原因,
1,高手不屑写,或不愿写,
2.菜鸟不会.
我亦菜鸟,所以菜鸟一起飞.近期打算写个系列分享给大家.
--------------------------------------------------------------------
起初,我学Asprotect,我不会SDK,我说,我要学,我就开始学习.
我见Asprotect有带一个Asprotect.chm帮助,我就打开它,看它.
我又见Asprotect有个Examples例程,我又打开它,照着它,做些测试.
我发现Asprotect的SDK可以分几类,普通SDK,和注册相关SDK.
A.先要看普通SDK(这一共有3个.)
■1.Polymorphic Markers,变形标记,你不要把它用在循环中.
你可以放置它在程序的任意位置,就象是这样的:
Procedure Test;
begin
{$I Inc\UserPolyBuffer.inc}
// some code
end;
这样,从标记开始,到过程的结束位置之间的代码,将被替换为变形的,这使得解密将变得复杂甚至是不可能的.
自然,Polymorphic Markers并不一定要放置它在过程/函数的开头,事实上,你可以按照你的需要,被放置它在某个过程或函数的任意地方.
注意:不要把它使用在循环中.
■2.Envelope Checks,壳检测,使用它来检查程序的壳是否是完好的.
它的作用是外壳完整性检查,你看下面的代码:
program Test;
uses
Windows;
Function EnvelopeCheck: Boolean;
{$I Inc\DelphiEnvelopeCheckFunc.inc}
begin
{$I Inc\DelphiEnvelopeCheck.inc}
If EnvelopeCheck then
MessageBox(0,'我很好,我在壳的保护中!','',0)
else
MessageBox(0,'你已到此,不可逾越,你狂傲的浪要到此止住.','',0);
end.
你可以使用它在程序的任意位置来进行壳的完整性检查,一旦壳被脱掉,那么它是返回一个False值,这时你就适当干一些邪恶的事情,给脱壳作者一些警示.
你可以马上测试它,编译后运行它,会提示"你已到此,不可逾越...",因为它是无壳的,也相当于,它的壳是已经被脱掉,所以EnvelopeCheck是返回失败,而一旦你加壳以后再次测试它,它将返回真.
■3.CRC Checks,CRC检查,你不要把它嵌套使用.CRC之内的代码还要保证多于5字节.
这一功能对抗Loader内存修补是强壮的,它的作用你看名字就知,过多的介绍是无需的,它的用法是相当简单:
{$I Inc\DelphiCrcBegin.inc}
// some code
{$I Inc\DelphiCrcEnd.inc}
仅此而已.
B.再看注册相关SDK.
Asprotect的界面中,无法对程序加注册功能,我想让我的程序带有注册功能,所以我这样做:
■1.在工程中,是这样:
program Project1;
uses
Forms,SysUtils,aspr_api,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2}; //PS:Form2不是自动创建的窗体,你要在工程的选项中设置.
{$R *.res}
var
UserName: PChar;
UserKey: PChar;
begin
Application.Initialize;
GetRegistrationInformation(0,UserKey,UserName); //这个aspr函数是取系统中的注册信息.
if (UserKey<>nil) AND (StrLen(UserKey)>0) then//如果注册信息是存在的--这将表示是已经注册的.
begin
Application.CreateForm(TForm1, Form1); //那么,创建主窗体.
end
else //如果注册信息是不存在的,这将表示程序还没有注册.
begin
Form2:=tForm2.Create(Application); //那么,创建注册窗体.
Form2.ShowModal; //显示注册窗体.
end;
Application.Run;
end.
界面是如下:
■2.注册窗体的代码是这样:
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons;
type
TForm2 = class(TForm)
Label1: TLabel;
Edit1: TEdit;
Label2: TLabel;
Edit2: TEdit;
Label3: TLabel;
Edit3: TEdit;
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
procedure BitBtn2Click(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
uses aspr_api;
{$R *.dfm}
procedure TForm2.BitBtn2Click(Sender: TObject);
begin
close;
end;
procedure TForm2.BitBtn1Click(Sender: TObject);
begin
If CheckKeyAndDecrypt(PChar(Edit3.Text),PChar(Edit2.Text),True) then //检查你的输入,是不是合法的,如果是合法的,将自动存储它.
showmessage('注册信息是合法的,程序会关闭,请你再一次运行!')
else
showmessage('注册信息不是合法的,你要再一次检查!')
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
edit1.Text:=StrPas(GetHardwareID); //这是取机器码的函数,它的使用是简单的.
end;
end.
你可以看到一切使用都是简单的.
■3.主窗体的代码,并没有特别,在这里,你可以再学习一个区段加密的标记:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, jpeg, ExtCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Image1: TImage;
BitBtn1: TBitBtn;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
procedure BitBtn1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses aspr_api;
var
UserName: PChar;
UserKey: PChar;
{$R *.dfm}
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
close;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
GetRegistrationInformation(0,UserKey,UserName); //于当前系统中取注册信息
if (UserKey<>nil) AND (StrLen(UserKey)>0) then //如果是存在的
begin
{$I aspr_crypt_begin9.inc} //区段加密标记开始,等级9.(你可以取等级在1--15之间)
Label5.Caption:=StrPas(UserName); //显示一下而已.
Label6.Caption:=StrPas(UserKey);
{$I aspr_crypt_end9.inc} //区段加密标记结束.
end;
end;
end.
区段加密标记中的代码仅仅解码在已注册的程序,这将表示,如果你的程序是运行在试用状态,那么位于区段加密标记中的代码将保持加密的.
一切都已经完成了.你可以现在编译它.
■4.现在要对生成的程序加壳,你打开Asprtoect,我只对你说模式的设置,其他设置是简单的,你自己做.
先增加一个try模式,"Is This Mode Active?"是的,我想让我的程序不能试用,所以我设置"Expiredexecutions"是0,我也不想用内建的对话注册框,因为我刚才明明已经自己设计了注册框,所以我选择"Dont use built-in dialogs"是的.
再增加一个reg模式,"Is This Mode Active?"是的,"Is This Mode in Registered state?"是的,一样的我选择"Dont use built-in dialogs"是的,"Use Activation Keys"是的,我想让注册码绑定到硬件,所以我还选择"Use Hardware Locking"是的,并设置Hardware Locking为"S.M.A.T.infomation",并选择"Support GetHardwareID API"是的,由于还在主窗体中使用的区段加密标记,所以再选择"Unlock Encrypted Sections"是的,并设置"Choose Encrypted Sections"是"Section9",因为我在主窗体中是用的等级9.
那么一切都完成了,开始保护.保护过后,运行它,它先提示我设计的注册窗体,我在Asprtoect中为它计算了一个注册码,输入注册窗体,一切都象预期的那样很成功.
我很希望这个文章没有演示错什么,如果是有,那么你不能笑,你要指正,那样这个文章将来是更完美的
转载:http://www.unpack.cn/thread-85129-1-1.html
WinLicense的HWID就不一样。
楼主是WinLicense KeyCreator的作者,应该对WinLicense熟悉。
摘自我的"Winlicense - The Anatomy of File Key"笔记。
typedef struct _s_WL_LF_HWID
{
//Here just for "PC Hardware"; not for "External Hardware" such as "U3 USB device" or what else.
//"Hardware ID" Pattern: AAAA-BBBB-CCCC-DDDD-EEEE-FFFF-GGGG-HHHH
WORD HWID_CPUID; //0 :: PartA - AAAAXXXX
DWORD HWID_HDDID; //2 :: PartB - BBBBCCCC
DWORD HWID_BIOSID; //6 :: PartC - DDDDEEEE
DWORD HWID_MACID; //A :: PartD - FFFFGGGG
WORD HWID_CHECKSUMID; //E :: PartE - HHHHYYYY
} sMachineID, sHardwareID, sHWID;
复制代码
WinLicense的HWID格式:
AAAA-BBBB-CCCC-DDDD-EEEE-FFFF-GGGG-HHHH
复制代码
HWID_CPUID AAAAXXXX
计算自两次CPUID指令的结果:a) "Get vendor ID"; b) "Processor Info and Feature Bits",只用高字HIWORD。
HWID_HDDID BBBBCCCC
计算自硬盘的"HDD Serial"字符串。
在两台虚拟机上测试:IDE和SCSI。SCSI情况下API取"HDD Serial"失败,用"Volume Serial Number"数据。
HWID_BIOSID DDDDEEEE
两种情况:"Ring-0 option"为"Enabled"或"Disabled"时不同,请阅Oreans's KnowledgeBase文章。
"Disabled"时,仍用"HDD Serial"数据,但算法不同。
HWID_MACID FFFFGGGG
计算自API Iphlpapi.GetIfTable。
如果返回"Ethernet network interface"的MIB_IFROW.bDescr结构中,第一个双字为0x61774D56("VMwa"),不使用MAC数据,而用一组常数。
也就是说,只有这个字段在早期的VMware虚拟机中(WMware Tools版本差异)为常量。
HWID_CHECKSUMID HHHHYYYY
前四个HWIDs的Checksum DWORD,只用高字HIWORD。 写的真好,赞! 这个写的很好。经常使用加密类软件对SDK这块不是很在行。 这个长知识了,只是不知道能不能部分代码加密?aspr好像会解密到内存,这样应该没什么用. 主要还是看通过各种方式反内存调试的能力,否则只要能找到解压到内存的运行位置,还是很容易被破 太好了 N牛过真细心 跟着你走一定不会错 值 得学习,感谢 谢谢分享!回帖略表感激! 谢谢分享!回帖略表感激!
页:
[1]