一种模拟软件运行的方法

文档序号:6605033阅读:170来源:国知局
专利名称:一种模拟软件运行的方法
技术领域
本发明涉及软件保护领域,特别涉及一种模拟软件运行的方法。
背景技术
R7.Net外壳工具的保护原理是将被加壳程序中符合条件的(能够在加密锁中运行 的指令)、连续的指令序列提取出来,将这部分指令序列移植到加密锁中去运行,以达到 保护算法的目的。但是,当我们将一个被加壳程序中的若干指令序列移植到加密锁中以后,等我 们运行这个加壳后的程序时,无法知道移植到加密锁中的指令序列的运行情况,而现有 技术中,一般会有下面三种情况1)某些指令序列没有被执行,起不到保护作用,因为这部分指令序列没有被执 行,所以不会影响到程序的正常运行;2)某些指令序列过于频繁的被执行,严重影响效率,由于访问加密锁需要耗 时,所以如果过于频繁访问加密锁,有可能导致加壳后的程序无法正常运行;3)某些指令序列适当的被执行,在程序执行的某些关键步骤被执行,既起到了 保护算法的作用,又不会影响程序的正常执行。很明显,我们在为一个程序加壳时,应尽量选择符合第3种情况的指令序列, 放弃第1、2种情况的指令序列。并且,目前软件保护的可选择方案比较多,但经常在一个软件保护中为平衡安 全与效率,可能会选择其中的一种或多种方案进行软件保护,但通常这种平衡需要在保 护完成后才能去判断,并且判断的过程通常也不是很直观,特别是浪费资源和时间等。

发明内容
为了解决现有技术中的不足,本发明提供了一种模拟软件运行的方法,所述方 法包括对被加壳程序进行分析,查找出满足条件的指令序列,记录下所述指令序列在 所述被加壳程序中的具体位置;在被加壳程序的副本的所述具体位置上插入相关语句;启动并运行所述插入相关语句后的被加壳程序的副本,进行模拟运行,并且相 关语句在执行时记录模拟运行信息;读取模拟运行信息,进行分析和比较,查看模拟运行效果,选择保护方案。本发明的有益效果在于本发明提供了一种模拟软件运行的方法,通过该方法 预先模拟各种保护方案,并自动分析模拟得到的相关数据,提供评定保护效果,并且在 模拟过程中可预先处理保护信息,提升最终真正保护软件的效率,进一步实现了透明的 软件保护,提高了效率,节约了资源,方便直观得选择最合适的保护方案。


图1为本实施例提供的一种模拟软件运行功能的方法的流程图;图2为本实施例提供的另一种模拟软件运行功能的方法的流程图;图3为本实施例提供的又一种模拟软件运行功能的方法的流程图。
具体实施例方式为使本发明的目的、技术方案和优点更加清楚,下面将结合附图对本发明实施 方式做进一步地详细描述。实施例1本实施例提供了一种模拟软件运行功能的方法。参见图1,一种模拟软件运行功能的方法,具体实现步骤如下步骤101:外壳工具接收用户输入的对被加壳程序进行分析的信息,调用入口 函数准备对被加壳程序进行分析;在本实施例中,入口函数具体为OnAppOperateAnalyseIl O。步骤102:判断上述被加壳程序中是否存在连续的指令序列,若不存在,则提 示出错,若存在,则执行步骤103;其中,指令序列具体可以为运算指令序列、常量加载指令序列、局部变量加载 指令序列和局部变量存储指令序列;在实施例步骤102中,外壳工具一次性从被加壳程序中查找出所有的连续的指 令序列,再判断上述所有的连续的指令序列是否满足步骤103到步骤105所说的条件,最 后步骤105得到的连续的指令序列则为满足所有条件的指令序列;具体地,在本实施例中,以如下被加壳程序为例进行说明,被加壳程序如下.method assembly instance void DrawIsoMap (class[Sy stem .Drawing] Sy stem.Drawing. Graphics A—1,uintl6A—2,uintl6A_3)cilmanaged{.locals init(intl6V_0,intl6V—1,uintl6V—2,uintl6V—3,uintl6V_4,uintl6V—5,uint8V—6,uint8V—7,uint8V—8,uint8V—9,intl6V 10,
intl6V_11,
intl6V_12,
intl6V_13,
intl6V_14,
intl6V_15,
intl6V—16,
intl6V—17,
int32V—18,
int32V—19,
int32V—20,
int32V_21,
int32V—22,
int32V—23,
int32V—24,
int32V—25,
int32V—26,
uintl6V—27)
IL0000 ldc.i4.0
IL0001 stl oc. sV—6
IL0035 ldarg.3
IL0036 ldc.i4.s15
IL0038 and
IL0039 stl oc. sV—15
IL003b ldloc.sV—14
IL003d conv.i4
IL_003e ldloc.sV—15
IL0040conv.i4
IL0041sub
IL0042conv.i2
IL0043stl oc. sV—16
IL0045ldloc.sV—14
IL0047conv.i4
IL0048ldc.i4.1
IL0049shr.un
IL_004a ldloc.sV—15
IL_004cconv.i4
IL_004dldc.i4.1
IL004eshr.un
6
IL 004fadd
IL 0050cony。i2
IL 005lstloc。S V 17
IL 0053ldc。i40xff
IL 0058stloc。S V 8
IL 005aldloc。S V 10
IL 005cstloc。S V 12
IL 005eldloc。S V 11
IL 0060stloc。S V 13
IL 0062ldc。i4。8
IL 0063ldloc。S V 17
IL 0065cony。i4
IL 0066sub
IL 0067stloc。S V 19
IL 0069ldc。i4。0
IL 006astloc。S V 4
IL 006cldloc。S V 12
] IL 006estloc。0
IL 006fldloc。S V 13
IL 007lstloc。l
IL 0072ldc。i4。S 16
IL 0074ldloc。S V 16
IL 0076conv。i4
IL 0077sub
IL 0078stloc。S V 18
IL 007aldc。i4。S 24
IL 007cstloc。S V 20
] IL 007eldloc。S V 4
IL 0080conv。u4
IL 008lldC。i4。l
IL 0082and
IL 0083brfalse。S IL 0092
IL 0085ldloc。S V 20
……
几0160ldarg。0
几o 16 lldfld intl6Ma in。TIsoFormFSpriteY
几0166ldc。i4。S 15
] 几0168and
几0169stloc。S V 15IL_016b ldloc.sV_14IL016d conv.i4IL016e ldloc.sV_15IL0170 conv.i4IL0171 subIL0172 stloc.sv_25IL0174 ldloc. sv__14IL0176 conv.i4IL_0177 ldc.i4.1IL0178 shr.unIL0179 ldloc. sv__15IL_017b conv.i4IL_017c ldc.i4.1 IL017d shr.unIL017e add
IL_017f stloc.s V—26 IL—0181 ldarg.l
IL_02cd ble.un IL—0053 IL_02d2 ret
}
经过判断之后可以得到上述被加壳程序中存在两段连续的指令序列,分别如
IL0038 andIL0039 stloc.sV一15IL003b ldloc. sv_14IL003d conv.i4IL003e ldloc.sv_15IL0040 conv.i4IL0041 subIL0042 conv.i2IL0043 stloc.sv_16IL0045 ldloc. sv__14IL0047 conv.i4IL0048 ldc.i4.1IL0049 shr.unIL_004a ldloc. sv__15IL_004c conv.i4IL004d :ldc.i4.1
CN 102012858 A
说明 书5/16页] IL 004eshr。un
IL 004fadd
IL 0050cony。i2
IL 005lstloc。S V 17
IL 0053ldc。i4 Oxff
IL 0058stloc。S V 8
IL 005aldloc。S V 10
IL 005cstloc。S V 12
IL 005eldloc。S V 11
IL 0060stloc。S V 13
] IL 0062ldc。i4。8
IL 0063ldloc。S V 17
IL 0065cony。i4
IL 0066sub
IL 0067stloc。S V 19
IL 0069ldc。i4。0
IL 006astloc。S V 4
IL 006cldloc。S V 12
IL 006estloc。0
IL 006fldloc。S V 13
] IL 007lstloc。l
IL 0072ldc。i4。S 16
IL 0074ldloc。S V 16
IL 0076conv。i4
IL 0077sub
IL 0078stloc。S V 18
IL 007aldc。i4。S 24
IL 007cstloc。S V 20
IL 007eldloc。S V 4
IL 0080conv。u4
] IL 008lldC。i4。l
IL 0082and

几0168and
几0169stloc。S V 15
几016bldloc。S V 14
几016dconv。i4
几016eldloc。S V 15
几0170conv。i4



IL—0171 IL—0172 IL—0174 IL—0176 IL—0177 IL—0178 IL—0179 IL_017b IL—017c IL_017d IL_017e IL 017f
sub
stloc.s V—25 ldloc.s V—14 conv.i4 ldc.i4.1 shr.un
ldloc.s V—15
conv.i4
ldc.i4.1
shr.un
add
stloc.s V 26具体地,在实际操作中从被加壳程序中得到的连续的指令序列可能为两个以上 的多个,而本实施例具体以两个连续的指令序列为例进行说明。步骤103 判断步骤102得到的连续的指令序列中是否存在其所访问的局部变量 的类型为卡片中所支持类型的连续的指令序列,若否,则提示出错,若是,则执行步骤 104 ;在本实施例中,根据方法头中的信息可以知道上述两段连续的指令序列所访问 的局部变量的类型具体为uintl6、uint 8、intl6和int32,并且局部变量的类型uintl6、 uintS, intl6和int32均是卡片所支持的类型,因此上述两段连续的指令序列均满足条件, 执行步骤104。步骤104 判断将上述连续的指令序列分别组装成卡内服务后得到的堆栈中是 否存在平衡的堆栈,若否,则提示出错,若是,则执行步骤105;在本实施例中,将上述两段连续的指令序列组装成卡内服务后,第一段连续的 指令序列得到的堆栈不为0,不是平衡的,第二段连续的指令序列得到的堆栈为0,是平 衡的,因此第二段连续的指令序列满足步骤104所说的条件,继续执行步骤105。步骤105:判断堆栈平衡的连续指令序列是否为其他指令的跳转目的地,若 是,则提示出错信息,若否,则执行步骤106;在本实施例中,对上述被加壳程度中的所有指令逐行进行分析,没有发现有跳 转指令的目的地址,因此可以知道上述堆栈平衡的连续指令序列也不是其他指令的跳转 目的地,继续执行步骤106;并且本实施例中的步骤102-步骤105具体为被加壳程序进行分析的步骤,通过 上述步骤就可以分析出满足条件的指令序列,并且步骤102-步骤105的4个步骤之间 的执行可以是没有顺序的,可以是先执行步骤102,再执行步骤105,然后执行步骤103 和步骤104等等,本实施例中为了提高对加壳程序的分析的效率,选择了顺序执行步骤 102-步骤105,但不以此执行顺序为限制;进一步地,本实施例中对被加壳程序进行分析的方法还可以为从被加壳程序 中查找连续的指令序列,每查找到一个指令序列就判断该指令序列是否满足步骤103至 步骤105所说的条件,如果不满足,则继续查找下一个连续的指令序列,并对该指令序
10列进行判断,若满足,则记录下该指令序列的具体位置,并判断是否已查找完上述被加 壳程序,若否,则继续查找下一个连续的指令序列,并进行判断,若是,则执行步骤 107 ;具体地,在实际操作中经过分析满足上述条件的连续的指令序列一般要大于一 个,而本实施例具体以一个满足条件的连续的指令序列为例进行说明。步骤106 记录下满足条件的连续指令序列的具体位置;其中,具体位置可以是上述满足条件的指令序列的起始位置,也可以是上述指 令序列的终止位置。步骤107 生成被加壳程序的副本,在被加壳程序的副本的上述具体位置上插 入对本地动态库的调用语句;在本实施例中,可以在步骤107生成被加壳程序的副本,也可以在步骤102判 断被加壳程序中是否存在连续的指令序列之前生成被加壳程序的副本,相应地,步骤102 至步骤105也可以是对被加壳程序的副本进行分析;由于具体位置可以是分析得到的指令序列的起始位置或终止位置,因此可以是 在指令序列的起始位置插入对本地动态库的调用语句,也可以是在指令序列的终止位置 插入对本地动态库的调用语句;其中插入的对本地动态库的调用语句具体为CallFUn2();具体地,当分析得到有多个连续的指令序列都满足条件时,则步骤106中会相 应地记录下多个具体位置,因此本步骤中外壳工具根据用户的选择在被加壳程序的副本 的相应的具体位置上插入对本地动态库的调用语句,其中用户可以选择一个具体位置, 也可以选择多个具体位置;进一步地,在本实施例中,本地动态库是通过对如下的源代码进行编译来实现的,是--个标准的Win32动态库文件,源代码具体如下
Il
//动态库入口函数
Il
int WINAPI DllMain (HINSTANCE hlnstance,DWORD dwReason,VOID *
pReserved)
{
g—hModule = hlnstance ;
switch (dwReason)
{
case DLL—PROCESS—ATTACH H动态链接库被加载
Attach ();
break ;
case DLL—PROCESS—DETACH //动态链接库被卸载
Detach ();
break ;
case DLL THREAD ATTACH 丨V宿主程序中创建了一个新的线程
break ;case DLL—THREAD—DETACH //宿主程序中结束了一个线程break ;}hMutex = CreateMutex (NULL, FALSE, NULL);return TRUE ;}H//创建共享内存Hextern “ C “ void—declspec (dllexport) Fun2 (int methodSerial){H打开或创建指定名称的共享内存ghSimulantFile = OpenFileMapping (FILE—MAP—READ|FILE—MAP—WRITE, 0, “ R7—Simulant—Share 〃 );if( ! g hSimulantFile){g—hSimulantFile = ::CreateFileMapping((HANDLE)-1,NULL,PAGE READWRITE, 0,1024, “ R7—Simulant—Share 〃 );if( ! g hSimulantFile){return ;}}//获取共享内存基址g_pSimulantMemory = :Map ViewOfFile (g_hSimulantFile,FILE—MAP—READ|FILE—MAP—WRITE,0,0,0);if( ! g_pSimulantMemory){return ;}H记录相应函数被调用的次数* (DWORD*) ((DWORD*) g_pSimulantMemory+methodSerial) + = 1 ;具体地,在动态库中包括一个固定的方法,每次动态库被调用时都是调用该方
法,该方法中有具体的参数,通过对参数的设置可以将该方法模拟为具体地将连续的指 令序列组装成锁内服务后的方法,因此通过将该方法中设置不同参数就可以表示将不同 的连续的指令序列组装成锁内服务后的方法,这样通过对动态库的调用就可以模拟为对 加密锁内的组装成卡内服务的方法的调用,而不用实际的将连续的指令序列放入加密锁 中,再访问加密锁就可以预先知道相应的效果;
12
进一步地,当上述动态库被调用时,动态库中的Fun2函数模块会判断是否存在 预先约定名称的共享内存,若不存在,则创建一个预先约定名称的共享内存,若存在, 则打开上述预先约定名称的共享内存,其中共享内存用来与外壳工具之间进行传递有关 模拟运行信息,具体地也可以用文件来替代共享内存,用文件来记录有关模拟运行信 息;在本实施例中,共享内存的具体格式是一个DWORD数组,具体如下所示,每 一项中存储了一个数值,该数值代表了不同参数的方法被调用的次数,因此当上述被加 壳程序模拟运行完成后,外壳工具就可以从该共享内存中读取并分析出来的连续的指令 序列组装成完整锁内服务的方法后被调用的次数。
权利要求
1. 一种模拟软件运行的方法,其特征在于,所述方法包括对被加壳程序进行分析,查找出满足条件的指令序列,记录下所述指令序列在所述 被加壳程序中的具体位置;在被加壳程序的副本的所述具体位置上插入相关语句;启动并运行所述插入相关语句后的被加壳程序的副本,进行模拟运行,并且相关语 句在执行时记录模拟运行信息;读取模拟运行信息,进行分析和比较,查看模拟运行效果,选择保护方案。
2.如权利要求1所述的模拟软件运行的方法,其特征在于,所述对被加壳程序进行分 析,查找出满足条件的指令序列的方法具体为从所述被加壳程序中查找出所有的连续的指令序列;若没有查找到,则提示出错;若查找到,则判断所述所有的连续的指令序列中是否存在连续的指令序列满足其所 访问的局部变量的类型为卡片中所支持的类型、将其组装成卡内服务后得到的堆栈是平 衡的以及所述连续的指令序列不为其他指令的跳转目的地这三个条件,若不存在,则提 示出错,若存在,则所述连续的指令序列即为满足条件的指令序列。
3.如权利要求1所述的模拟软件运行的方法,其特征在于,所述对被加壳程序进行分 析,查找出满足条件的指令序列的方法具体为从所述被加壳程序中查找出一个连续的指令序列;若没有查找到,则提示出错;若查找到,则判断所述连续的指令序列中是否满足其所访问的局部变量的类型为卡 片中所支持的类型、将其组装成卡内服务后得到的堆栈是平衡的以及所述连续的指令序 列不为其他指令的跳转目的地这三个条件,若不满足,则继续在所述被加壳程序中查找 下一个连续的指令序列,并进行判断,若满足,则所述连续的指令序列为满足条件的指 令序列。
4.如权利要求3所述的模拟软件运行的方法,其特征在于,在记录下所述指令序列在 所述被加壳程序中的具体位置之后,在被加壳程序的副本的所述具体位置上插入相关语 句之前,所述方法还包括判断是否已查找完所述被加壳程序;若否,则继续在所述被加壳程序中查找下一个连续的指令序列,并进行判断;若是,则在被加壳程序的副本的所述具体位置上插入相关语句。
5.如权利要求1所述的模拟软件运行的方法,其特征在于,所述插入的相关语句具体 为对动态库的调用语句。
6.如权利要求5所述的模拟软件运行的方法,其特征在于,所述动态库中包含一个方 法,通过对所述方法的参数进行设置将所述方法模拟为将不同的连续的指令序列组装成 锁内服务后的方法。
7.如权利要求1所述的模拟软件运行的方法,其特征在于,所述插入的相关语句具体 为跳转语句。
8.如权利要求7所述的模拟软件运行的方法,其特征在于,所述跳转语句具体用于跳 转到在插入跳转语句时嵌入到所述被加壳程序的副本中的代码段,所述代码段中包含一个方法,通过对所述方法的参数进行设置将所述方法模拟为将不同的连续的指令序列组 装成锁内服务后的方法。
9.如权利要求1所述的模拟软件运行的方法,其特征在于,所述插入的相关语句具体 为对软加密锁的调用语句。
10.如权利要求9所述的模拟软件运行的方法,其特征在于,所述软加密锁中包含一 个方法,外壳工具将需要调用的方法的相关内容以参数的形式通过所述软加密锁提供的 接口传给所述方法,并对所述方法的参数进行设置,从而将所述方法模拟为将不同的连 续的指令序列组装成锁内服务后的方法。
11.如权利要求5所述的模拟软件运行的方法,其特征在于,所述记录模拟运行信息 的方法具体为所述动态库中的函数将所述模拟运行信息记录在预先约定名称的共享内 存中。
12.如权利要求5所述的模拟软件运行的方法,其特征在于,所述记录模拟运行信 息的方法具体为所述动态库中的函数将所述模拟运行信息记录在预先约定名称的文件 中。
13.如权利要求7所述的模拟软件运行的方法,其特征在于,所述记录模拟运行信息 的方法具体为所述嵌入的代码段中的函数将所述模拟运行信息记录在预先约定名称的 共享内存中。
14.如权利要求7所述的模拟软件运行的方法,其特征在于,所述记录模拟运行信息 的方法具体为所述嵌入的代码段中的函数将所述模拟运行信息记录在预先约定名称的 文件中。
15.如权利要求9所述的模拟软件运行的方法,其特征在于,所述记录模拟运行信息 的方法具体为所述软加密锁中的函数将所述模拟运行信息记录在预先约定名称的共享 内存中。
16.如权利要求9所述的模拟软件运行的方法,其特征在于,所述记录模拟运行信息 的方法具体为所述软加密锁中的函数将所述模拟运行信息记录在预先约定名称的文件 中。
全文摘要
本发明公开了一种模拟软件运行的方法,属于软件保护领域,所述方法包括外壳工具对被加壳程序进行分析,查找出满足条件的指令序列,记录下所述指令序列在所述被加壳程序中的具体位置,在被加壳程序的副本的所述具体位置上插入相关语句,启动并运行所述插入相关语句后的被加壳程序的副本,进行模拟运行,并且相关语句在执行时记录模拟运行信息,读取模拟运行信息,进行分析和比较,查看模拟运行效果,选择保护方案。通过本发明提供的方法可以预先模拟各种保护方案,并自动分析模拟得到的相关数据,提供评定保护效果,并且在模拟过程中可预先处理保护信息,提升最终真正保护软件的效率,节约了资源,方便直观得选择最合适的保护方案。
文档编号G06F11/36GK102012858SQ20101021412
公开日2011年4月13日 申请日期2010年6月29日 优先权日2010年6月29日
发明者于华章, 陆舟 申请人:北京飞天诚信科技有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1