• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

黑客安全

软件护卫手艺

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/heikeanquan/2019/0415/458.html

软件护卫手艺

  第一节 多见护卫技巧

  1、序列号体例

  (1)序列号护卫机制

  数学算法一项都是常州微信小程序开发暗号加密的焦点,但在大凡的软件加密中,它宛若并不太为人们体贴,由于大多数时分软件加密本人实现的都是一种编程的技巧。但近几年来跟着序列号加密程序的遍及,数学算法在软件加密中的比重宛若是越来越大了。

  咱们先来看看在网络上大行其道的序列号加密的事情道理。当用户从网络高低载某个shareware——分享软件后,大凡都有使用光阴上的限制,当过了分享软件的试用期后,你必须到这个软件的公司去注册后方能连续使用。注册历程大凡是用户把本人的私家信息(大凡要紧指名字)连同信用卡号码报告给软件公司,软件公司会凭据用户的信息计较出一个序列码,在用户得到这个序列码后,按照注册必要的步骤在软件中输入注册信息和注册码,其注册信息的合法性由软件考证经历后,软件就会作废掉本人的种种限制,这种加密实现起来对照简单,不必要分外的老本,用户采购也很是利便,在互联网上的软件80%都因此这种体例来护卫的。

  咱们周密到软件考证序列号的合法性历程,实在即是考证用户名和序列号之间的换算关系是否正确的历程。其考证最根基的有两种,一种是按用户输入的姓名来生产注册码,再同用户输入的注册码对照,公式表示以下:

  序列号 = F(用户名)

  但这种要领即是在用户软件中再现了软件公司生产注册码的历程,现实上是很是不平安的,岂论其换算历程何等复杂,解密者只需把你的换算历程从程序中提掏出来就能够编制一个通用的注册程序。

  另外一种是经历注册码来考证用户名的正确性,公式表示以下:

  用户名称 = F逆(序列号) (如ACDSEE,小楼注)

  这实在是软件公司注册码计较历程的反算法,要是正向算法与反向算法不是对称算法的话,对于解密者来说,确凿有些困难,但这种算法相配欠好设计。

  于是有人思量到一下的算法:

  F1(用户名称) = F2(序列号)

  F1、F2是两种彻底不同的的算法,但用户名经历F1算法的计较出的特征字即是序列号经历F2算法计较出的特征字,这种算法在设计上对照简单,保密性相对以上两种算法也要好的多。要是能够把F1、F2算法设计成不可逆算法的话,保密性相配的好;可一旦解密者找到其中之一的反算法的话,这种算法就不平安了。一元算法的设计看来再若何起劲也很难有太大的突破,辣么二元呢?

  特定值 = F(用户名,序列号)

  这个算法看上去相配不错,用户名称与序列号之间的关系不再辣么清楚了,但同时也落空了用户名于序列号的逐一对应关系,软件开辟者必须本人护卫用户名称与序列号之间的唯独性,但这宛若不是难以办到的事,建个数据库就好了。固然你也能够凭据这一思路把用户名称和序列号分为几个片面来组织多元的算法。

  特定值 = F(用户名1,用户名2,...序列号1,序列号2...)

  现有的序列号加密算法大多是软件开辟者自行设计的,大片面相配简单。而且有些算法作者固然下了很大的工夫,效果却往往得不到它全部望的后果。实在现在有良多现成的加密算法能够用,如RSADES,MD4,MD5,只但是这些算法是为了加密密文或暗号用的,于序列号加密几许有些不同。我在这里试举一例,有望有抛砖引玉的感化:

  1、在软件程序中有一段加密过的密文S

  2、密钥 = F(用户名、序列号) 用上头的二元算法得到密钥

  3、明文D = F-DES(密文S、密钥) 用得到的密钥来解密密文得到明文D

  4、CRC = F-CRC(明文D) 对得到的明文运用种种CRC统计

  5、搜检CRC是否正确。最佳多设计几种CRC算法,搜检多个CRC后果是否都正确

  用这种要领,在没有一个已知正确的序列号情况下是始终推算不出正确的序列号的。

  (2)若何攻打序列号护卫

  要找到序列号,大概点窜掉校验序列号以后的跳转指令,最紧张的是要行使种种对象定位校验序列号的代码段。这些常用的API包孕 GetDlgItemInt, GetDlgItemTextA, GetTabbedTextExtentA, GetWindowTextA, Hmemcpy (仅仅Windows 9x), lstrcmp, lstrlen, memcpy (限于NT/2000)。

  1)数据约束性的诀要

  这个观点是+ORC提出的,只限于用明文对照注册码的那种护卫体例。在大多数序列号护卫的程序中,那个真确、正确的注册码或暗号(Password)会于某个时候发现在内存中,固然它发现的位置是未必的,但多数情况下它会在一个局限以内,即寄放用户输入序列号的内存地点±0X90 字节的处所。这是由于加密者所用对象内部的一个Windows数据传输的约束条件决意的。

  2)Hmemcpy函数(俗称万能断点)

  函数Hmemcpy是Windows9x体系的内部函数,位于KERNEL32.DLL中,它的感化是将内存中的一块数据拷贝到另一个处所。由于Windows9x体系频繁使用该函数处理种种字串,因此用它作为断点很适用,它是Windows9x平台最常用的断点。在Windows NT/2K中没有这个断点,由于其内核和Windows9x彻底不同。

  3)S号令

  由于S号令纰漏不在内存中的页面,因此你能够使用32位平面地点数据段形貌符30h在全部4GB(0~FFFFFFFFh )空间查找,大凡用在Windows9x底下。详细步骤为:先输入姓名或假的序列号(如: 78787878),按Ctrl+D切换到SoftICE下,下搜刮号令:

  s 30:0 L ffffffff '78787878'

  会搜刮出地点:ss:ssssssss(这些地点大概不止一个),然后用bpm断点监督搜刮到的假注册码,跟踪一下程序若哪里理输入的序列号,就有大概找到正确的序列号。

  4)行使消息断点

  在处理字串方面能够行使消息断点WM_GETTEXT和WM_COMMAND。前者用来读取某个控件中的文本,好比拷贝编纂窗口中的序列号到程序提供的一个缓冲区里;后者则是用来关照某个控件的父窗口的,好比当输入序列号以后点击OK按钮,则该按钮的父窗口将收到一个WM_COMMAND消息,以评释该按钮被点击。

  BMSG xxxx WM_GETTEXT (阻挡序列号)

  BMSG xxxx WM_COMMAND (阻挡OK按钮)

  能够用SoftICE提供的HWND号令获得窗口句柄的信息,也能够行使Visual Studio中的Spy++适用对象得到响应窗口的句柄值,然后用BMSG设断点阻挡。例:

  BMSG 0129 WM_COMMAND

  2、警告(NAG)窗口

  Nag的本义是烦人的意义。Nag窗口是软件设计者用来不时提醒用户采购正式版本的窗口。软件设计者大概觉得当用户受不了试用版中的这些烦人的窗口时就会思量采购正式版本。它大概会在程序启动或退出时弹出来,大概在软件运转的某个时候随机或定时地弹出来,确凿对照烦人。

  去除警告窗口常用的三种要领是:点窜程序的资源、静态阐发,动静阐发。

  去除警告窗口用资源点窜对象是个不错的要领,能够将可实行文件中的警告窗口的属性改成透明、不可见,这样就变相去除了警告窗口。

  要是是动静跟踪调试,只需找到确立此窗口的代码,跳过即可。常用的表现窗口的函数有MessageBoxA、MessageBoxExA、 MessageBeep 、DialogBoxParamA 、ShowWindow、CreateWindowExA等。然而某些警告窗口用这些断点无论用,就可尝尝行使消息设断点,大凡都应能阻挡下来。

  例:行使消息断点阻挡警告窗口:

  切换到SOFTICE下号令: HWND

  应看到以下的相似信息:

  

Window-Handle hQueue SZ QOwner Class-Name Window-Procedure
0080 (0) 2057 32 MSGSVR32 #32711 (switch_win) 17EF:00004B6E
0084 (1) 2057 32 EXPLORER shell_trayWnd 1487:0000016C
... ... ... ... ... ...

 

  在这些列表中查找相关运用程序的窗口句柄。要是NAG窗口上有OK按钮,在class name查找“button”。要是NAG窗口上什么都没有,那可实验找出正确的句柄。句柄列表大概很是长,但平时NAG窗口的句柄大凡在列表的前方。

  注:在这里保举用SMU Winspector对象帮忙破解NAG.它能表现你所必要的信息:Window-Handle, Window-Class Name, Window-Text, Parent Window-Handle, Parent-Window Class Name, Parent Window-Text, Module ...

  一但找到NAG窗口的句柄,运用BMSG号令在Windows的消息高低断点。现在假定NAG窗口有OK按钮,你己找到正确的句柄(handle),这时下号令:BMSG 0084 WM_DESTROY0084是NAG窗口的句柄(handle)。这条号令是NAG窗口从屏幕上消散时,SoftICE将中缀。此时将深入到少许不分解的API函数,可按F12返回程序。必要指出,跟踪的目的是发现NAG窗口在哪里初始化(在返回的CALL用设断)。NAG窗口大多用 Created/Destroyed相似的CALL,因此如发现这些,就可按必要跟踪下去。

  3、光阴限制

  (1) 定时器

  有些程序的试用版每次运转都偶然间限制,例如运转10分钟或20分钟就休止事情,必须重新运转该程序才气平常事情。这些程序内部天然有个定时器来统计程序运转的光阴。

  1)使用Settimer()

  常用的计数器是函数Settimer(),调用这个函数确立的定时器能够发出消息VM_TIMER,大概在定时期满时调用一个回调函数。 使用这个函数会使光阴延时,精度不高。

  2)使用timeSetEvent()

  给Windows驱动程序最精确的周期性关照是由Windows的多媒体服无timeSetEvent()提供的。它的光阴能够精确到1毫秒。

  3)使用VXD

  能够使用VMM的Set_Global_time_Out()服无来迫使回调函数的几个毫秒再实行,这就创造了一个“惟有一次”的定时器。VXD能够在回调中再次调用Set_Global_time_Out()来滥觞下一个定时器,这样提供了一个陆续运转的定时器了。

  4)别的

  GetTickCount():精度不高;

  timeGetTime(): 能够以毫秒级返回windows滥觞后的光阴。

  (2)光阴限制

  大凡这类护卫的软件都偶然间上的限制,如试用30天等,当过了分享软件的试用期后,就不予运转,惟有向软件作者付费注册以后才气得到一个无光阴限制的注册版本。

  这品种型程序良多,让你有10天、20天、30天等,它们在安置时,在你的体系某处做上光阴标记,每次运转时用目前体系光阴和安置时的光阴对照,校验你还否能使用。

  如最典范的30天限制的一种情况:

  mov ecx,1E ;把1E (30天 十进制) 放入 ecx

  mov eax,[esp+10] ;把用过天数放到eax

  cmp eax,ecx ;在此对照

  jl ...

  如碰到这种情况,只需把"mov eax,[esp+10]"改成"mov eax,1" 。

  要记住目前年份、月份的十六进制的少许表示要领,如:2000年的十六进制是07D0,然后用W32DASM反汇编你的程序,用查找字符串的要领找D007(在机械码中位置颠倒了一下)或别的相似光阴的数字,有大概会找到有代价的线索。你别漠视这种要领,对那些没怎么提防的程序,此招很有用。

  如:一程序限定在2000年使用,大概有以下一代码:

  :00037805 817C2404D0070000 cmp dword ptr [esp+04], 000007D0 对照是否在2000年。

  (3)与光阴相关函数

  1、GetSystemTime 恰目前体系光阴

  申明:

  在一个SYSTEMTIME中载入目前体系光阴,这个光阴接纳的是“协同世界光阴”(即UTC,也叫做GMT)花样。

  VOID GetSystemTime(

  LPSYSTEMTIME lpSystemTime // SYSTEMTIME,伴同目前光阴载入的布局

  );

  2、GetLocalTime 恰目前本地光阴

  VOID GetLocalTime(

  LPSYSTEMTIME lpSystemTime // SYSTEMTIME,用于装载本地光阴的布局

  );

  3、SystemTimeToFileTime 凭据一个FILETIME布局的内容,载入一个SYSTEMTIME布局

  BOOL SystemTimeToFileTime(

  CONST SYSTEMTIME * lpst, // SYSTEMTIME,包含了体系光阴信息的一个布局

  LPFILETIME lpft //FILETIME,用于装载文件光阴的一个布局

  );

  返回值 :非零表示胜利,零表示腐朽。

  4、SetTimer 确立一定时器,在指定光阴内停息

  UINT SetTimer(

  HWND hwnd, // 光阴信息句柄

  UINT idtimer, // 定时器ID 标识符

  UINT uTimeout, // 停息光阴

  TIMERPROC tmprc // 处理定时历程的程序进口地点

  );

  4、Key File护卫

  Key File(注册文件)是一种行使文件来注册软件的护卫体例。Key File大凡是一个小文件,能够是纯文本文件,也能够是包含不可表现字符的二进制文件,其内容是少许加密过或未加密的数据,其中大概有用户名、注册码等信息。文件花样则由软件作者本人定义。试用版软件没有注册文件,当用户向作者付费注册以后,会收到作者寄来的注册文件,其中大概包含用户的个人信息。用户只有将该文件放入指定的目次,就能够让软件成为正式版。该文件大凡是放在软件的安置目次中或体系目次下。软件每次启动时,从该文件中读取数据,然后行使某种算法进行处理,凭据处理的后果校验是否为正确的注册文件,要是正确则以注册版形式来运转。

  (1)破解Key File大凡思路

  1. 最佳阐发Key File的对象是十六进制对象,普通的文本编纂对象不太适用。

  2. 对付这类程序,你起首确立一假的Key File文件。大凡的软件允许Key File有不同的大小和文件名,你确立的文件内容必须易读,跟据情况调整Key File的大小和文件名。为何要易读呢?由于指标程序从Key File中读取数据,然后进行处理,易读有益于你阐发其运算历程。

  3. Key File文件在大多数情况下,因此'*.key'形式存在的。

  4. Key File文件名可用W32DASM或十六进制对象翻开程序用查找字符串体例断定;

  5. 读用户手册(偶然作者大概会提到);

  6. 用Filemon 这一对象,它能及时监督体系各文件的状况,因此运转程序时,如它去读指定文件名的Key File时,会在Filemon表现Key File文件名。一但你发现Key File文件名,就确立一假的Key File到要被crack软件目次下,然后去crack。

  (2)Windows下破解Key File几个常用的函数:

  函数ReadFile

  感化:从文件中读出数据

  参数:其中Long,非零表示胜利,零表示腐朽。

  BOOL ReadFile(

  HANDLE hFile, // Long,文件的句柄

  LPVOID lpBuffer, // Any,用于留存读入数据的一个缓冲区

  DWORD nNumberOfBytesToRead, //Long,要读入的字符数

  LPDWORD lpNumberOfBytesRead, // Long,从文件中现实读入的字符数

  LPOVERLAPPED lpOverlapped // address of structure for data

  );

  函数CreateFileA

  感化:可翻开和确立文件、管道、邮槽、通讯服无、建筑以及控制台

  HANDLE CreateFileA(

  LPCTSTR lpFileName, // String,要翻开的文件的名字

  DWORD dwDesiredAccess, // 允许对建筑进行读写走访;

  DWORD dwShareMode, // 分享形式

  LPSECURITY_ATTRIBUTES lpSecurityAttributes// 指向一个SECURITY_ATTRIBUTES布局的指针,定义了文件的平安特征(要是操纵体系支持的)

  DWORD dwCreationDistribution, // 若何确立文件

  DWORD dwFlagsAndAttributes, // file attributes

  HANDLE hTemplateFile //Long,要是不为零,则指定一个文件句柄。新文件将从这个文件中复制 扩大属性

  );

  函数_lopen( )

  感化:以二进制形式翻开指定的文件

  HFILE _lopen(

  LPCSTR lpPathName, // 欲翻开文件的名字

  int iReadWrite // 走访形式和分享形式常数的一个组合

  );

  函数FindFirstFileA( )

  感化:凭据文件名查找文件

  HANDLE FindFirstFile(

  LPCTSTR lpFileName, // 欲搜刮的文件名。可包含通配符,并可包含一个路径或相对路径名

  LPWIN32_FIND_DATA lpFindFileData // WIN32_FIND_DATA,这个布局用于装载与找到的文件有关的信息。该布局可用于后续的搜刮

  5、功效限制的程序

  这种程序大凡是DEMO版或菜单中片面选项是灰色。有些DEMO版本的片面功效内部基础就没有。而有些程序功效全有,只有注册后就平常了。

  你使用这些DEMO程序片面被不准的功效时,会跳出提示框,说这是DEMO版等话,它们大凡都是调用MessageBox[A]或 DialogBox[A]等函数。你可在W32DASM反汇编它,大凡能找到以下字符串:"Function Not Avaible in Demo" 或 "Command Not Avaible" 或 "Can't save in Shareware/Demo"等,这些CALL会被响应的调用,可作为你破解的一指导器。

  另外,即是菜单中片面选项是灰色的不行用,大凡它们是经历以下两种函数实现的:

  (1)EnableMenuItem

  允许、不准或变灰指定的菜单条目

  BOOL EnableMenuItem(

  HMENU hMenu, // 菜单句柄

  UINT uIDEnableItem, // 菜单ID,形式为:充许,不准,或灰

  UINT uEnable //菜单项目旌旗

  );

  Returns

  在ASM代码形式以下:

  PUSH uEnable  //uEnable=0 则菜单选项允许

  PUSH uIDEnableItem

  PUSH hWnd

  CALL [KERNEL32!EnableMenuItem]

  (2)EnableWindow

  允许或不准鼠标和键盘控制指定窗口和条目(不准时菜单变灰)

  BOOL EnableWindow(

  HWND hWnd, // 窗口句柄

  BOOL bEnable // 允许/不准输入

  );

  Returns

  如窗口曩昔被不准则返回一TRUE,不然返回 FALSE。

  6、CD-check

  最简单也多见的光盘护卫即是程序在启动时校验光驱中的光盘上是否存在特定的文件,要是不存在则觉得用户没有正版光盘,回绝运转。在程序运转的历程中间大凡不再搜检光盘的存在与否。Windows下的详细实现大凡是这样的:先用GetLogicalDriveStrings( )或GetLogicalDrives( )得到体系中安置的全部驱动器的列表,然后再用GetDriveType( )搜检每一个驱动器,要是是光驱则用CreateFileA( )或FindFirstFileA( )等函数搜检特定的文件存在与否,并大概进一步地搜检文件的属性、大小、内容等。 这种光盘搜检是对照容易被破解的,解密者只有行使上述函数设断点找到程序启动时搜检光驱的处所,点窜校验指令就能够跳过光盘搜检。

  (1)可将游戏(或别的程序)的光盘拿出,运转游戏,将发现少许错误提示,如: Please insert the - CD, or: You need the CD to play the - . 行使这提示可在W32DASM中行使串式数据参考功效查找响应的代码进行阐发。

  (2)相关函数

  1、GetDrivetype(a) 校验一个磁盘驱动器的范例

  

UINT GetDriveType(

LPCTSTR lpRootPathName // String,包含了驱动器根目次路径的一个字串
);

返回值
0
驱动器不行辨认
1
指定的目次不存在
2
DriveRemoveable
3
A Fixed Disk (HardDrive)
4
Remote Drive(Network)
5
Cd-Rom驱动器
6
RamDisk

 

  要是是普通的程序,你可将EAX由5改成3即可。

  周密:有些程序大概检测光盘根目次相关文件,CD的卷标也大概被检测。

  2、GetLogicalDrives 校验体系中存在哪些逻辑驱动器字母

  这函数没有参数

  返回值

  这个布局中的二进制位标记着存在哪些驱动器。其中,位0设为1表示驱动器A:存在于体系中;位1设为1表示存在B:驱动器;以次类推

  3、GetLogicalDriveStrings 获得一个字串,其中包含了目前全部逻辑驱动器的根驱动器路径

  DWORD GetLogicalDriveStrings(

  DWORD nBufferLength, // 字串的长度

  LPTSTR lpBuffer // 用于装载逻辑驱动器名称的字串。每个名字都用一个NULL字符分开,在末了一个名 字背面用两个NULL表示中缀(空中缀)

  );

  返回值

  装载到lpBuffer的字符数目(破除空中缀字符)。如缓冲区的长度不敷,不行容下路径,则返回值就造成请求的缓冲区大小。零表示腐朽。会设置GetLastError

  4、GetFileAttributesA 校验指定文件的属性

  DWORD GetFileAttributes(

  LPCTSTR lpFileName //指定欲获得属性的一个文件的名字

  );

  5、GetFileSize 校验文件长度

  DWORD GetFileSize(

  HANDLE hFile, // 文件的句柄

  LPDWORD lpFileSizeHigh, // 指定一个长整数,用于装载一个64位文件长度的头32位。如这个长度没有跨越 2^32字节,则该参数能够设为NULL(造成ByVal)

  );

  返回值

  返回文件长度。&HFFFFFFFF表示失足。周密如lpFileSizeHigh不为NULL,且后果为&HFFFFFFFF,辣么必须调用GetLastError,校验是否现实发生了一个错误,由于这是一个有用的后果

  6、GetLastError 针对之前调用的api函数,用这个函数获得扩大错误信息

  

返回值
由api函数决意。请参考api32.txt文件,其中列出了一系列错误常数;都以ERROR_前缀滥觞。常用的错误代码见下表
ERROR_INVALID_HANDLE 无效的句柄作为一个参数相传
ERROR_CALL_NOT_IMPLEMENTED 在win 95下调用专为win nt设计的win32 api函数
ERROR_INVALID_PARAMETER 函数中有个参数不正确

 

  7、ReadFile 从文件中读出数据

  详细参考KEYFILE一节。

  8、别的少许CDROM信息

  中缀2F是mscdex中缀,可用bpint 2f, al=0 ah=15检测Mmscdex是否安置。

  也可试着用文件存取设断 

 


上篇:上一篇:常州微信开发-BackTrack5正确在虚拟机上网配置
下篇:下一篇:OD断点大全