科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网安全频道一步一步教你加密解密技术——软件保护技术(1)

一步一步教你加密解密技术——软件保护技术(1)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

一步一步教你加密解密技术——软件保护技术

作者:看雪 来源:看雪 2008年10月16日

关键字: 软件保护 加密解密

  • 评论
  • 分享微博
  • 分享邮件

在本页阅读全文(共2页)

  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是否安装。

  也可试着用文件存取设断

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章