子程序花指令加算法
花指令
je 或jz 若相等则跳(机器码74 或0F84)
jne或jnz 若不相等则跳(机器码75或0F85)
jmp 无条件跳(机器码EB)
jb 若小于则跳
ja 若大于则跳
jg 若大于则跳
jge 若大于等于则跳
jl 若小于则跳
jle 若小于等于则跳
pop 出栈
push 压栈
程序顺利来到紧跟其后的正确信息处
xxxxxxxxxxxx 正确信息,例如:注册成功,谢谢您的支持等(我们希望它不被跳过,让它出现,程序一定要顺利来到这里)
。。。
。。。
xxxxxxxxxxxx 出错信息(我们希望不要跳到这里,不让它出现)它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据.
五、程序转移指令
1>无条件转移指令 (长转移)
JMP 无条件转移指令
CALL 过程调用
RET/RETF过程返回.
2>条件转移指令 (短转移,-128到+127的距离内)
( 当且仅当(SF XOR OF)=1时,OP1<OP2 )
JA/JNBE 不小于或不等于时转移.
移位>1次时, 则由寄存器CL给出移位次数.
如 MOV CL,04
SHL AX,CL
四、串指令
───────────────────────────────────────
DS:SI 源串段寄存器 :源串变址.
ESI 目标串段寄存器:目标串变址.
CX 重复次数计数器.
3. 目的地址传送指令.
LEA 装入有效地址.
例: LEA DX,string ;把偏移地址存到DX.
3.3.2 算术运算类指令
1. 加法指令(s 代表源操作数,d 代表目标操作数)(1)不带进位的加法指令add d,ss和d相加的结果存入d。
(2)带进位的加法指令adc d,sS和d相加后再加上标志位CF,结果存入dAdd主要用来计算低位字加法,adc用来计算高位字加法,实现32位加法比如一个32位数,高16位存在dx中,低16位存在ax中另一个32位数,高16位置存在cx中,低16位存在bx中计算加法add ax,bxAdc dx,cx(3)加1指令inc d 则d=d+1Inc axInc bl2. 减法指令(1)不带借位的减法sub d, sd-s结果存入d(2)带借位的减法sbb d,sd-s-CF,结果存入d比如一个32位数,高16位存在dx中,低16位存在ax中另一个32位数,高16位置存在cx中,低16位存在bx中计算减法,第一个数减第二个数sub ax,bxsbb dx,cx(3)减1指令dec d 则d=d-1dec axdec bl(4)求补NEG d将d包括符号位在内各位取反,末位加1相当于d=0-d比如字节型-5计算机中存的是11111011求补后是00000101,即5比如字节型+7计算机中存的是00000111求补后是11111001即-7 (5)比较cmp d,s类似做减法sub,但不保存结果,只用来影响标志位,主要通过执行后的标志位来判断两个数的大小关系比如cmp ax,bx (类似做ax-bx)Jz label1 (JZ意思是两数相等则跳转, jmp if zf=1)3. 乘法指令(1)无符号数乘法(用于正数)Mul s (该指令隐含了操作数ax或al)s为无符号word型,将s与AX相乘,结果存入DX,AX;s为无符号byte型,将s与AL相乘,结果存入AX(2)有符号数乘法(用于负数)imul s (该指令隐含了操作数ax或al)s为有符号word型,将s与AX相乘,结果存入DX,AX;s为有符号byte型,将s与AL相乘,结果存入AX乘法指令影响of位和cf位,乘积结果用到高字(节)寄存器,则of=1,cf=1;没用到高字(节)寄存器(结果在8位或16位范围内) 则of=0,cf=0 书p974. 除法指令(隐含被除数在ax或dx,ax中)(1)无符号数除法Div sS为无符号byte型,则用ax/s ,商存在al中,余数存在ah中S为无符号word型,则用dx,ax/s,商存在ax中,余数存在dx中(2)有符号数除法idiv s和无符号数除法类似,用于有符号数假设用30001/2 ,代码如下Mov ax, 30001Mov bl, 2Div bl得到的是divide override,这样的情况暂不考虑,只考虑结果能够存放到相应寄存器中的情况(3)字节转换成字(隐含操作数为al)CBW将al中的符号位扩展到ah中,比如-5,mov al,-5<=> mov al, 11111011bal中的11111011b经cbw扩展后AX中为1111111111111011b;al存的如果是正数,直接在ah中存入00000000b(4)字转换成双字(隐含操作数为ax)Cwd (convert word to dword)和cbw类似,将ax中的符号位扩展到dx中。
花指令原理 -回复
花指令原理-回复花指令原理是今天计算机科学领域中的一个热门话题。
它涉及到计算机指令的执行过程以及与之相关的概念。
在本文中,我们将详细讨论花指令的原理,并解释其在计算机体系结构中的作用。
首先,让我们先了解一下计算机指令的概念。
计算机指令是计算机内部用于执行特定任务的基本命令。
它们由二进制代码表示,由计算机处理器识别和执行。
计算机指令可以包括算术运算、逻辑运算、存取内存等操作。
花指令则是一种特殊的指令,它的存在可以为其他指令提供有用的附加功能。
花指令的原理可以简单地解释为在计算机执行指令的过程中,将某些指令的执行与其他指令的执行相结合,以提高计算机系统的性能。
花指令可以通过减少总执行时间、提高指令并行性或减少指令冲突来实现这一目的。
指令并行性是花指令原理的一个重要概念。
它涉及到多个指令同时执行的能力。
在传统的计算机体系结构中,指令是按顺序执行的,即一条指令执行完毕后才能执行下一条指令。
这种顺序执行的模式有时会导致计算机的性能瓶颈。
花指令原理通过将多条指令的执行重叠在一起,从而提高计算机系统的效率。
为了实现指令并行性,计算机体系结构通常会采用流水线处理技术。
流水线是一种将指令的执行过程划分为多个阶段的技术。
每个阶段都专门处理指令的某个部分,使得多个指令可以同时在不同的阶段进行处理。
通过这种方式,计算机可以同时执行多个指令,从而提高整体的执行速度。
然而,指令并行性也会面临一些挑战,例如指令间的依赖关系和数据冒险。
指令依赖发生在一个指令需要在另一个指令执行完成后才能执行的情况下。
数据冒险则发生在一个指令需要访问另一个指令还未完成的数据时。
这些问题都可能导致指令的执行顺序被打乱,从而降低整体性能。
花指令原理通过插入一些无效或者冗余的指令来解决指令并行性面临的问题。
这些花指令在计算的角度上没有实际意义,但它们可以用来填充指令流水线中的空闲周期,以保证指令的连续执行。
这样一来,指令间的依赖关系和数据冒险问题就可以得到解决。
花指令(精)
花指令的概念与认识花指令 1、什么是花指令什么是花指令?实际上,把它按照“乱指令”来理解可能更贴切一些,我们知道,汇编语言其实就是机器指令的符号化,从某种程度上看,它只是更容易理解一点的机器指令而已。
每一条汇编语句,在汇编时,都会根据cpu特定的指令符号表将汇编指令翻译成二进制代码。
而日常应用中,我们通过VC的IDE或其它如OD等反汇编、反编译软件也可以将一个二进制程序反汇编成汇编代码。
机器的一般格式为:指令+数据。
而反汇编的大致过程是:首先会确定指令开始的首地址,然后根据这个指令字判断是哪个汇编语句,然后再将后面的数据反汇编出来。
由此,我们可以看到,在这一步的反汇编过程中存在漏洞:如果有人故意将错误的机器指令放在了错误的位置,那反汇编时,就有可能连同后面的数据一起错误地反汇编出来,这样,我们看到的就可能是一个错误的反汇编代码。
这就是“花指令”,简而言之,花指令是利用了反汇编时单纯根据机器指令字来决定反汇编结果的漏洞。
2、花指令与免杀的关系加花就是,在程序汇编中,加了一些无用的废话,用来扰乱杀软对特征码的扫描对比,来达到免杀的目的。
是一种逃避方式,主要用于表面免杀。
加花指令的确没有改变特征码的位置,但是他改变了程序执行顺序,有的也能改变文件结构。
使杀毒软件扫描的时候跳到花指令处,即判断没有病毒。
通常情况下,在文件免杀的时候,加花指令是最简单、有效的方法,而且一般能通杀很多杀毒软件,所以一般文件免杀通用此法,前提是你的花指令不是常用的,最好能自己做出你个人的花指令,才会很有效。
3.花指令执行顺序花指令一般添加到程序的头部。
执行顺序:花指令入口-->执行花指令-->程序原入口-->执行原程序花指令的好坏直接决定程序是否可以躲避杀毒软件的查杀,花指令和壳的本质差不多,都是为了保护程序而做,所以我们做免杀的时候,可以多结合壳和花指令各自的优点对程序进行处理,达到更好的免杀效果。
大概步骤总结: 第一步:从编写手册中成对的提取几对第二步:打乱它们之间的顺序,也可不打乱第三步:中间插入几个nop或jmp,也可不插入第四步:最后添加跳转到入口地址指令第五步:把编写好的花指令添加到程序中后,测试是否可以正常运行,然后再用杀毒软件查杀 3、花指令的样本 PUSH EBP MOV EBP,ESP DEC EBP INC EBP ADD ECX,1 SUB ECX,-1 MOV EAX,DWORDPTR FS:[0] PUSH EAX MOV DWORD PTR FS:[0],ESP POP EAX MOV DWORD PTR FS:[0],EAX MOV CL,1 PUSH EAX SUB AL,90 POP EAX ADD ESP,-0C ADD ESP,0C PUSH EAX JNO 原始入口 ________________ push ebp mov ebp ,esp //常见的入口代码 add esp ,68 //以下的指令都是对称的(成对的) sub esp ,68 inc ecx dec ecx push edi pop edi push eax pop eax push edi pop edi inc ecx dec ecx nop jz 跳回入口点 //跳到程序的入口,执行原程序 jnz 跳回入口点 ____________ push ebp mov ebp, esp push eax push eax nop pop eax pop aex sub eax, 1 inc eax, 1 push 入口地址 retn。
汇编语言之子程序
汇编语言之子程序汇编语言是一种底层编程语言,是计算机指令的集合表示形式。
在汇编语言中,子程序是一段独立的、可重复使用的代码片段,可以在程序中被多次调用。
子程序可以帮助我们实现代码的模块化,提高代码的可读性和可维护性。
本文将介绍如何在汇编语言中使用子程序以及其工作原理。
一、子程序的定义和使用在汇编语言中,子程序由一系列指令组成,这些指令可以完成特定的功能。
子程序可以通过call指令被调用,执行完子程序后会返回到调用子程序的指令处,继续执行程序的下一条指令。
在使用子程序前,我们需要先定义子程序。
定义子程序的语法如下:```subroutine_name:; 子程序代码ret```其中,subroutine_name是子程序的名称,可以根据实际需求自定义。
ret指令用于返回到调用子程序的指令处,继续执行程序的下一条指令。
调用子程序的语法如下:```call subroutine_name```其中,subroutine_name是要调用的子程序的名称。
二、传递参数和返回值子程序可以接收参数,并且可以有返回值。
在调用子程序时,可以通过寄存器或栈来传递参数。
在子程序内部,可以通过相应的寄存器或栈地址来获取参数的值。
例如,我们定义一个计算两个数之和的子程序add:```add:mov ax, [bp+4] ; 获取第一个参数的值add ax, [bp+6] ; 获取第二个参数的值ret```在主程序中调用add子程序:```mov ax, 5 ; 第一个参数mov bx, 10 ; 第二个参数call add ; 调用add子程序; 此时ax寄存器中的值为15,即5+10的结果```在子程序add中,我们通过寻址方式获取传递的参数,并将计算结果存入ax寄存器中,供主程序使用。
三、保存和恢复寄存器在汇编语言中,调用子程序时需要保存和恢复寄存器的值,以保证程序的正确执行。
在调用子程序前,我们可以使用push指令将需要保存的寄存器值压栈,然后在子程序的开头使用相应的pop指令将值弹出并恢复。
汇编语言各种指令的解释与用法
汇编语言各种指令的解释与用法汇编语言是一种低级语言,通过编写汇编程序可以直接操作计算机硬件。
在汇编语言中,各种指令起到了关键的作用。
本文将对常用的汇编语言指令进行解释,并说明其用法。
1. 数据传输指令数据传输指令用于在存储器和寄存器之间传输数据。
常用的数据传输指令包括MOV、PUSH和POP。
- MOV指令用于将数据从一个位置传送到另一个位置。
语法格式为:MOV 目的地,源。
- PUSH指令用于将数据压入栈中。
语法格式为:PUSH 寄存器/内存地址。
- POP指令用于从栈中弹出数据并存放到指定位置。
语法格式为:POP 寄存器/内存地址。
2. 算术运算指令算术运算指令用于进行各种算术运算,如加法、减法、乘法和除法。
常用的算术运算指令有ADD、SUB、MUL和DIV。
- ADD指令实现两个操作数的加法。
语法格式为:ADD 目的操作数,源操作数。
- SUB指令实现两个操作数的减法。
语法格式为:SUB 目的操作数,源操作数。
- MUL指令实现两个操作数的乘法。
语法格式为:MUL 操作数。
- DIV指令实现两个操作数的除法。
语法格式为:DIV 操作数。
3. 分支控制指令分支控制指令用于根据条件来选择不同的执行路径,包括条件跳转和无条件跳转。
常用的分支控制指令有JMP、JZ、JE和JNE。
- JMP指令用于无条件跳转到指定的地址。
语法格式为:JMP 标号/偏移量。
- JZ指令用于在零标志位为1时跳转到指定地址。
语法格式为:JZ标号/偏移量。
- JE指令用于在相等标志位为1时跳转到指定地址。
语法格式为:JE 标号/偏移量。
- JNE指令用于在不相等标志位为1时跳转到指定地址。
语法格式为:JNE 标号/偏移量。
4. 逻辑运算指令逻辑运算指令用于实现与、或、非、异或等逻辑运算。
常用的逻辑运算指令有AND、OR、NOT和XOR。
- AND指令用于执行按位与运算。
语法格式为:AND 目的操作数,源操作数。
- OR指令用于执行按位或运算。
木马免杀之汇编花指令技巧(精)
木马免杀之汇编花指令技巧作者:逆流风(发表于《黑客X档案》07.07,转载注明出处)相信很多朋友都做过木马免杀,早期的免杀都是加壳和改特征码,现在免杀技术已经发展到花指令免杀,改壳之类的,而这些需要一定的汇编知识,但是汇编却不是一块容易啃的骨头,所以我写了这篇菜鸟版的免杀汇编教程,帮助小菜们快速入门,掌握免杀必备的汇编知识,改花指令,改特征码的技巧和编写自己的花指令。
一、免杀必备的汇编知识push 压栈,栈是一种数据结构,记住四个字:先进后出。
压栈就是把数据放如栈中,从栈顶放如,出栈的时候也是从栈顶取出,所以会有先进后出的特点!先进后出我们可以这样理解,例如:一个乒乓球筒,我们放入乒乓球,然后取出乒乓球,取出的都是就后放进的球。
就如我们放入球的顺序是球1、2、3、4,取出的顺序是球4、3、2、1。
pop 出栈,与push相对应。
mov a,b 把b的值送给a,把它看作编程中的赋值语句就是b赋值给a,这时a的值就是b了。
nop 无作用,就是什么也没做。
retn 从堆栈取得返回地址并跳到该地址执行。
下面是一些算术运算指令:ADD 加法sub 减法inc 加1dec 减1最后是跳转指令:jmp 无条件跳je 或jz 若相等则跳jne或jnz 若不相等则跳jb 若小于则跳jl 若小于则跳ja 若大于则跳jg 若大于则跳jle 若小于等于则跳jge 若大于等于则跳这些就是我们需要掌握的,怎么样不多吧,一些指令可能看不明白,看了后面的就会清楚了。
对了,忘了讲寄存器了,寄存器是中央处理器内的其中组成部份。
寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和位址。
我们需要了解的是8个通用寄存器:EAX,EBX,ECX,EDX,ESI,EDI,EBP,ESP二、特征码和花指令的修改特征码我就不多说了,大家都知道的,现在杀毒软件查杀都用特征码查杀,改了木马的特征码,杀毒软件就查不出我们的木马,这样就达到免杀的效果。
花指令——精选推荐
花指令刚在52破解看了⼀篇花指令的⽂章,感觉挺好的。
第⼀种花指令是jmp+垃圾数据⽐如jmp label//这⾥存放垃圾指令或数据label://正常指令push ebpmov ebp,esp第⼆种是假分⽀跳转xor eax, eax;test eax, eax;jnz LABEL1;jz LABEL2;xor eax,eax这让eax为0,逻辑运算指令会影响ZF标志位的,所以会置ZF为1,那么永远会跳转到LABEL2处,这样LABEL1处的代码全部是垃圾指令,不管看起来多么正常,统统都是垃圾指令。
第三种是call和retn配合,看起来好像调⽤了⼀个函数,但实际上啥事也没做就返回了。
我写了⼀段测试代码。
int main(int argc, char* argv[]){printf("hello world");int a;__asm {call LABEL9;_emit 0x55;_emit 0x8b;_emit 0xec;_emit 0xff;_emit 0x83;_emit 0xec;_emit 0xc;LABEL9:add dword ptr ss : [esp], 0x0D;ret;__emit 0xF3;}a = 3;return 0;}_emit 0x55;_emit 0x8b;_emit 0xec;_emit 0xff;_emit 0x83;_emit 0xc;这中间有_emit的都是垃圾数据,⼲扰分析者的。
我们真正有效的代码就是int a;a=3;return 0;没了。
add dword ptr ss : [esp], 0x0D;这个改变函数返回地址的,调⽤完call Lable9之后,栈顶会存放函数的返回地址,也就是_emit 0x8b这个数据的地址。
由于是垃圾数据,我们必须不能让它返回到这个地址,要改⼀下改到下⼀句有效代码的地址处,也就是a=3;这句代码的地址,那么就需要让返回地址加⼀个值,加多少呢?这个我是反汇编之后⽤OLLYDBG调试之后算出来的。
★花指令编写手册★
花指令的变形技巧.
cmp a,b 比较a与b
mov a,b 把b的值送给a
ret 返回主程序
nop 无作用
call 调用子程序
=================
je 若相等则跳
jne 若不相等则跳
jz 若相等则跳
jnz 若不相等则跳
jb 若相等则跳
5. 上下代码互换.
6. 改相等含义的代码.
jnb 入口地址
mov eax,入口地址
jmp eax
手动编写例子
push ebp
mov ebp,esp
sub eax,-2
dec eax
dec eax
sub eax,5
add eax,3
add eax,2
add esp,0B
add esp,-0B
jb 原入口点
jnb 若不相等则跳
jmp 无条件跳
=================
jb 若小于则跳
ja 若大于则跳
jg 若大于则跳
jge 若大于等于则跳
jl 若小于则跳 jle 若小来自等于则跳 pop 出栈
push 压栈
加花方法
加花的方法:
1.去头加花,又分为直接去头.头前加花.头后加花。
注:编写花指令,可参考以下成双指令,可任意自由组合.达到免杀效果.
push ebp
pop ebp
push eax
pop eax
push esp
pop esp
push 0
push 0
push 10 -------其中数字可以任意,注意与下面对应
汇编语言常用指令大全
汇编语言常用指令大全汇编语言是一种计算机编程语言,使用指令来控制计算机硬件执行特定的操作。
在本文中,我们将介绍一些常用的汇编语言指令,以帮助读者更好地理解和学习汇编语言。
一、数据传输指令1. MOV:将数据从一个位置复制到另一个位置。
例子:MOV AX, BX 将寄存器BX中的值复制到寄存器AX中。
2. PUSH:将数据压入堆栈。
例子:PUSH AX 将寄存器AX中的值压入堆栈。
3. POP:从堆栈中弹出并获取数据。
例子:POP AX 从堆栈中弹出一个值,并将其存入寄存器AX中。
二、算术指令1. ADD:将两个操作数相加。
例子:ADD AX, BX 将寄存器AX和BX中的值相加,并将结果存入寄存器AX中。
2. SUB:将一个操作数从另一个操作数中减去。
例子:SUB AX, BX 将寄存器BX中的值从寄存器AX中减去,并将结果存入寄存器AX中。
3. MUL:将两个操作数相乘。
例子:MUL AX, BX 将寄存器AX和BX中的值相乘,并将结果存入寄存器AX中。
三、逻辑指令1. AND:进行逻辑与操作。
例子:AND AX, BX 对寄存器AX和BX中的值进行逻辑与操作,并将结果存入寄存器AX中。
2. OR:进行逻辑或操作。
例子:OR AX, BX 对寄存器AX和BX中的值进行逻辑或操作,并将结果存入寄存器AX中。
3. NOT:进行逻辑非操作。
例子:NOT AX 对寄存器AX中的值进行逻辑非操作。
四、条件分支指令1. JMP:无条件跳转到指定的地址。
例子:JMP label 跳转到标记为label的地址。
2. JZ:当操作数为零时跳转到指定的地址。
例子:JZ label 如果寄存器AX中的值为零,则跳转到标记为label 的地址。
3. JC:当进位标志为1时跳转到指定的地址。
例子:JC label 如果进位标志位为1,则跳转到标记为label的地址。
五、循环指令1. LOOP:当计数器不为零时,循环执行指定的代码块。
电脑常用花指令大全
常用花指令大全用花指令大全常用花指令大全╬┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅╬常用花指令大全╬┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅╬┇部分花指令内容相同只是改了一些跳转处的汇编代码换了名字┇┇大家在加花指令的时候可以在新入口处先NOP几行在开始加花┇┇在加花的同时你也可以在花指令中随便NOP几行在继续添加花┇╬┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅╬******************************************************************** ****1.伪装vc++5.0代码:PUSH EBPMOV EBP,ESPPUSH -1push 415448 -\___PUSH 4021A8 -/ 在这段代码中类似这样的操作数可以乱填MOV EAX,DWORD PTR FS:[0]PUSH EAXMOV DWORD PTR FS:[0],ESPADD ESP,-6CPUSH EBXPUSH ESIPUSH EDIADD BYTE PTR DS:[EAX],AL /这条指令可以不要!jmp 原入口地址******************************************************************** ****2.胡乱跳转代码:push ebpmov ebp,espinc ecxpush edxnoppop edxdec ecxpop ebpinc ecxloop somewhere /跳转到上面那段代码地址去!somewhere:nop /"胡乱"跳转的开始...jmp 下一个jmp的地址 /在附近随意跳jmp ... /...jmp 原入口地址 /跳到原始oep******************************************************************** ****3.伪装c++代码:push ebpmov ebp,esppush -1push 111111push 222222mov eax,fs:[0]push eaxmov fs:[0],esppop eaxmov fs:[0],eaxpop eaxpop eaxpop eaxpop eaxmov ebp,eaxjmp 原入口地址******************************************************************** ****4.伪装Microsoft Visual C++ 6.0代码:PUSH -1PUSH 0PUSH 0MOV EAX,DWORD PTR FS:[0]PUSH EAXMOV DWORD PTR FS:[0],ESPSUB ESP,68PUSH EBXPUSH ESIPUSH EDIPOP EAXPOP EAXPOP EAXADD ESP,68POP EAXMOV DWORD PTR FS:[0],EAXPOP EAXPOP EAXPOP EAXPOP EAXMOV EBP,EAXJMP 原入口地址******************************************************************** ****5.伪装防杀精灵一号防杀代码:push ebpmov ebp,esppush -1push 666666push 888888mov eax,dword ptr fs:[0]push eaxmov dword ptr fs:[0],esppop eaxmov dword ptr fs:[0],eaxpop eaxpop eaxpop eaxpop eaxmov ebp,eaxjmp 原入口地址******************************************************************** ****6.伪装防杀精灵二号防杀代码:push ebpmov ebp,esppush -1push 0push 0mov eax,dword ptr fs:[0]push eaxmov dword ptr fs:[0],espsub esp,68push ebxpush esipush edipop eaxpop eaxpop eaxadd esp,68pop eaxmov dword ptr fs:[0],eaxpop eaxpop eaxpop eaxpop eaxmov ebp,eaxjmp 原入口地址******************************************************************** ****7.伪装木马彩衣(无限复活袍)代码:PUSH EBPMOV EBP,ESPPUSH -1push 415448 -\___PUSH 4021A8 -/ 在这段代码中类似这样的操作数可以乱填MOV EAX,DWORD PTR FS:[0]PUSH EAXMOV DWORD PTR FS:[0],ESPADD ESP,-6CPUSH EBXPUSH ESIPUSH EDIADD BYTE PTR DS:[EAX],AL /这条指令可以不要!jo 原入口地址jno 原入口地址call 下一地址******************************************************************** ****8.伪装木马彩衣(虾米披风)代码:push ebpnopnopmov ebp,espinc ecxnoppush edxnopnoppop edxnoppop ebpinc ecxloop somewhere /跳转到下面那段代码地址去!someshere:nop /"胡乱"跳转的开始...jmp 下一个jmp的地址 /在附近随意跳jmp ... /...jmp 原入口的地址 /跳到原始oep******************************************************************** ****9.伪装花花添加器(神话)代码:-----------根据C++改nopnopnopmov ebp,esppush -1push 111111push 222222mov eax,dword ptr fs:[0]push eaxmov dword ptr fs:[0],esppop eaxmov dword ptr fs:[0],eaxpop eaxpop eaxpop eaxpop eaxmov ebp,eaxmov eax,原入口地址push eaxretn******************************************************************** ****10.伪装花花添加器(无极)代码:nopmov ebp, esppush -1push 0A2C2Apush 0D9038mov eax, fs:[0]push eaxmov fs:[0], esppop eaxmov fs:[0], eaxpop eaxpop eaxpop eaxpop eaxmov ebp, eaxmov eax, 原入口地址jmp eax******************************************************************** ****11.伪装花花添加器(金刚)代码:--------根据VC++5.0改nopnopmov ebp, esppush -1push 415448push 4021A8mov eax, fs:[0]push eaxmov fs:[0], espadd esp, -6Cpush ebxpush esipush ediadd [eax], almov eax,原入口地址jmp eax******************************************************************** ****12.伪装花花添加器(杀破浪)代码:nopmov ebp, esppush -1push 0push 0mov eax, fs:[0]push eaxmov fs:[0], espsub esp, 68push ebxpush esipush edipop eaxpop eaxpop eaxadd esp, 68pop eaxmov fs:[0], eaxpop eaxpop eaxpop eaxpop eaxmov ebp, eaxmov eax, 原入口地址jmp eax******************************************************************** ****12.伪装花花添加器(痴情大圣)代码:nop..........省略N行nopnoppush ebpmov ebp, espadd esp, -0Cadd esp, 0Cmov eax, 原入口地址push eaxretn******************************************************************** ****13.伪装花花添加器(如果*爱)代码:nop........省略N行nopnoppush ebpmov ebp, espinc ecxpush edxnoppop edxdec ecxpop ebpinc ecxmov eax, 原入口地址jmp eax******************************************************************** ****14.伪装PEtite 2.2 -> Ian Luck代码:mov eax,0040E000push 004153F3push dword ptr fs:[0]mov dword ptr fs:[0],esppushfwpushadpush eaxxor ebx,ebxpop eaxpopadpopfwpop dword ptr fs:[0]pop eaxjmp 原入口地址 '执行到程序的原有OEP******************************************************************** ****15.无效PE文件代码:push ebpmov ebp,espinc ecxpush edxnoppop edxdec ecxpop ebpinc ecxMOV DWORD PTR FS:[0],EAX \POP EAX |POP EAX \MOV DWORD PTR FS:[0],EAX |(注意了。
S7-200PLC子程序指令及应用实例
S7-200PLC子程序指令及应用实例S7-200 PLC把程序主要分为三大类:主程序、子程序和中断程序。
在实际应用中有些程序内容可能被反复使用,对那些需要经常执行的程序段,可设计成子程序的形式,并为每个子程序赋以不同的编号,在程序执行的过程中,可随时调用某个编号的子程序。
子程序的优点在于它可以用于对一个大的程序进行分段及分块,使其成为较小的更易管理的程序块。
程序调试、程序检查和程序维护时,可充分利用这项优势。
子程序只在需要时才被调用、执行。
这样就可以更有效地使用PLC,充分利用CPU的时间。
1)子程序的建立。
可以采用下列方法创建子程序:·在编辑环境的程序块中点击鼠标右键,选择“插入子程序SBR_n”(n的范围为:0~63)。
·从编辑菜单中,选择插入子程序SBR_n。
只要插入了子程序,程序编辑器底部就将出现一个新标签,标志新的子程序名。
此时,可以对新的子程序编程。
2)为子程序定义参数根据子程序有无参数,可以将子程序分为有参子程序和无参子程序,如果该子程序带有参数,就要使用该子程序的局部变量表来定义参数。
S7-200为每个程序都安排了局部变量表,必须利用选定该子程序后出现的局部变量表为该子程序的局部变量,S7-200对其局部变量参数有以下规定:·子程序在带参数调用时,最多可以带16个参数。
每个参数包含变量名、变量类型和数据类型。
这些参数在子程序的局部变量表中进行定义。
·变量名由不超过8个字符的字母和数字组成,但第一个字符必须是字母。
·变量类型:在子程序带参数调用时可以使用4种变量类型,根据数据传递的方向,依次安排这些变量类型在局部变量表中的位置,包含:①IN类型(传入子程序型)。
②IN/OUT类型(传入/传出子程序型,调用子程序时,将指定地址的参数传入子程序,子程序执行结束时,将得到的结果值返回达到同一个地址)。
③OUT类型(传出子程序型)。
④TEMP类型(暂时型,用于在子程序内部暂时存储数据,不能用来与主程序传递参数数据)。
花指令原理
花指令原理
花指令,也被称为花指令集或花指令片段,是一种干扰反汇编引擎正常工作的指令片段。
其原理是利用反汇编器静态分析算法的缺陷,使得代码在反编译解析时出错,从而干扰程序正常执行。
花指令内部如果涉及到寄存器的使用,一般会将其保存在栈中。
花指令可分为两大类:可执行花指令和不可执行花指令。
其中不可执行花指令是利用反汇编器静态分析算法的缺陷使得代码在反编译解析时出错。
其原理使反汇编分析执行流命中执行会出错的垃圾数据,就会造成解析错误,而实际执行过程中垃圾数据并不会执行。
此外,花指令还分为两类:一种是通过构造巧妙的代码,引导反汇编引擎解析一条错误的指令,扰乱指令的长度,使反汇编引擎无法按照正常的指令长度一次解析邻接未解析的指令,最终使反汇编引擎输出错误的反汇编结果;另一种是利用间接跳转形式的花指令(在定长指令集如arm中比较常见)。
总的来说,花指令的原理是利用反汇编器的缺陷和特性,通过干扰反汇编引擎的正常工作,增加程序静态分析的难度,从而达到保护程序代码、防止逆向工程等目的。
反调试入门篇(1)——花指令
反调试⼊门篇(1)——花指令花指令花指令是⼀种反静态调试的最基础⼿段(对于动态调试来说就没有⽤处),我们可以通过在程序的代码中添加⼀些不影响程序运⾏的垃圾机器码,进⽽影响反汇编结果的准确性,达到程序保护的⽬的花指令分类1、可执⾏花指令见字知其意,即花指令在程序正常运⾏的时候被执⾏,通⽤寄存器的值不发⽣改变,但不影响程序原有的功能执⾏2、不可执⾏花指令见字知其意,即花指令在程序正常运⾏的时候不会被执⾏,不影响程序原有的功能花指令编写原则:保持堆栈的平衡常⽤花指令汇编⼩知识:mov eax, 1 eax赋值为1pop 1 将1从栈顶弹出pop ebp 将栈顶的值弹出赋给寄存器ebppush 1 将1压⼊栈中push ebp 将ebp的值压⼊栈中sub eax, 1 eax的值减1add eax, 1 eax的值加1inc eax eax的值加1dec eax eax的值减1call [x] 调⽤地址为x的函数,call对应的硬编码码为0xE9nop 不做任何事情,相当于python中的pass,对应的硬编码为0x90_emit 相当于db,byte类型,1字节以下⽅式均通过内联汇编实现标签⽅式的花指令1、单节⽅式#include 'stdafx.h'void Test(){int a[3] = {1, 2, 3};_asm{jz Label;jnz Label;_emit 0xE8;}Label:a[0] = 2;a[1] = 5;a[2] = 6;printf('%d\n', a[2]);}int main(int argc, char* argv[]){Test();return 0;}使⽤IDA打开,可以看到标红的地⽅就是花指令,因为call指令的存在,使得后⾯的4字节数据被错误识别成函数地址,进⽽导致接下来的分析出错⼈⼯Patch花指令的⽅式很简单:选中call指令所在⾏,点击Edit选项>Patch program>Change byte将call的硬编码E8改为0x90(nop指令)2、多节⽅式#include 'stdafx.h'void Test(){int a[3] = {1, 2, 3};_asm{jz Label1;jnz Label1;_emit 0xE9;}Label1:a[0] = 5;a[1] = 6;a[2] = 7;_asm{jz Label2;jnz Label2;_emit 0xE8;}Label2:a[1] = a[0] a[2];a[2] = a[1] a[0];printf('%d\n', a[2]);}int main(int argc, char* argv[]){Test();3、多层乱序(疯狂套娃)#include 'stdafx.h'void Test(){int arr[3] = {1, 2, 3};_asm{jz Label3;jnz Label3;_emit 0xE8;}Label2:_asm{jz Label4;jnz Label4;_emit 0xE8;}Label3:_asm{jz Label1;jnz Label1;_emit 0xE9;}Label1:_asm{jz Label2;jnz Label2;_emit 0xE9;}Label4:int a = 10;printf('%d\n',a);4.开辟堆栈的花指令push 1push ebpmov ebp, espsub esp, 0x8push eaxpush ecxpop ecxpop eaxadd esp, 0x8pop ebpje xxxjne xxx花指令多的情况就需要⾃⼰写个IDA python脚本进⾏去除5.花指令免杀⼀些反病毒软件依靠特征码来判断⽂件是否有毒,其识别引擎在⽂件镜像(filebuffer)⼀定的偏移范围内进⾏扫描,⽐如在0x00001000~0x00006000之间,我们在其中加⼊⼀些花指令,使恶意代码偏离引擎识别的偏移范(OEP),就可以逃避这种⽅式的特征码识别end。
如何加花指令
花指令相信做过免杀的朋友都知道花指令吧。
加花指令是一种不错的文件免杀方法,而网上公布的花指令和花指令添加器因为里边的花指令被公布了,所以免杀效果不好。
有点汇编基础的人就写自己的花指令,但写花指令的过程比较烦,所以我萌生了写一个花指令生成器的想法,首创哦^_^一、写花指令生成器必备知识1、花指令原理花指令是程序中的无用代码,程序多它没影响,少了它也能正常运行。
加花指令后,杀毒软件对木马静态反汇编时,木马的代码就不会正常显示出来,加大杀毒软件的查杀难度。
2、如何写花指令下面我们先看看一段花指令,分析理解它的原理:PUSH EBPMOV EBP,ESPpush edxpop edxinc ecxdec ecxadd esp,21add esp,-21add esp,10sub esp,10JMP 附近空地址随便乱跳JMP 原入口点花指令一般有三部分,开头就是PUSH EBP和MOV EBP,ESP这两句在大部分程序开头可以经常看到。
PUSH EBP 是把EBP压入堆栈,MOV EBP,ESP是把ESP的值赋给EBP,不懂没关系,只要知道PUSH EBP和MOV EBP,ESP 这两句经常出现在文件开头就可以了,随便用OllyDbg打开一个不加壳的文件载入后经常停在PUSH EBP MOV EBP, ESP。
接下来就是花指令啦,push edx是把通用寄存器EDX压入堆栈,pop edx是把通用寄存器EDX弹出堆栈,这两句和起来就相当于什么也没做。
接下来的inc ecx,ecx用来保存计数值,也是寄存器,INC是加1;下面的dec ecx中的dec是减1,加1减1相抵消,又是什么也没做。
add esp,21这是寄存器esp加21,add是加上,下面一句ad d esp,-21是寄存器esp加-21,小学知识,+21+(-21)=0,还是什么也没做。
再下来add esp,10寄存器es p加21,sub esp,10寄存器esp减10,sub是减去。
12木马的加花指令
木马的加花指令
花指令:就是一段没有实际意义的、不影响程序正常运行的一段代码。
它的作用就是加大杀毒软件查杀病毒的难度。
(1)按照前面所讲述的方法配置一个不加壳的木马程序。
(2)用OD载入这个木马程序,如图1所示,同时记下入口点的内存地址。
图1:OD的程序界面
(3)向下拉滚动条,找到零区域(也就是可以插入代码的都是0的空白地方)。
并记下零区域的起始内存地址。
(4)从这个零区域的起始地址开始一句一句地写入我们准备好的花指令代码。
(5)花指令写完后,在花指令的结束位置加一句:JMP 刚才OD载入时的入口点内存地址。
(6)保存修改结果后,最后用PEditor这款工具打开这个改过后的木马程序。
如图2所示,在入口点处把原来的入口地址改成刚才记下的零区域的起始内存地址,并按应用更改,使更改生效。
图2:使用PEditor更改入口点
加花指令免杀技术的优缺点:
优点:通用性非常不错,一般一个木马程序加入花指令后,就可以躲避大部分的杀毒软件,不像改特征码,只能躲过某一种杀毒软件。
缺点:这种方法还是不能过具有内存查杀的杀毒软件,比如瑞星内存查杀等。
另外目前还有几款软件可以自动帮你加花,比如木马彩衣进行加花,如图3所示。
图3:利用“木马彩衣”加花
点击“浏览”选择需要加花的木马程序,选择一种加花方法,然后点击“穿上”,程序就被加入花指令了,也就是会让木马穿上一件彩衣伪装了。
新代系统子程序调用编程序例子
新代系统子程序调用编程序例子在计算机科学领域中,子程序是一种可重用的代码段,它可以被其他程序调用。
新代系统中,子程序调用是将程序分解成小块以便于维护和升级的一种方法。
本文将介绍新代系统子程序调用编程的一个例子。
我们假设我们需要编写一个简单的计算器程序,它可以执行加、减、乘、除四种基本算术运算。
我们可以将每个运算封装成一个子程序,并在程序中调用它们以执行相应的运算。
首先,我们编写一个加法子程序,代码如下:```PROCEDURE ADD(a, b: INTEGER): INTEGER;BEGINRETURN a + b;END;```这段代码定义了一个名为ADD的子程序,它接受两个整数类型参数a和b,并返回它们的和。
接下来,我们编写一个减法子程序,代码如下:```PROCEDURE SUBTRACT(a, b: INTEGER): INTEGER;BEGINRETURN a - b;```这段代码定义了一个名为SUBTRACT的子程序,它接受两个整数类型参数a和b,并返回它们的差。
类似地,我们编写乘法和除法子程序,分别如下:```PROCEDURE MULTIPLY(a, b: INTEGER): INTEGER;BEGINRETURN a * b;END;PROCEDURE DIVIDE(a, b: INTEGER): INTEGER;BEGINRETURN a DIV b;END;```现在我们已经编写了四个基本运算的子程序,接下来我们可以编写一个主程序,用于接收用户输入并调用相应的子程序以执行相应的运算。
代码如下:```VARa, b: INTEGER;op: CHAR;WRITE('Enter operation (+,-,*,/): ');READ(op);WRITE('Enter first number: ');READ(a);WRITE('Enter second number: ');READ(b);CASE op OF'+': WRITE(a, ' + ', b, ' = ', ADD(a, b));'-': WRITE(a, ' - ', b, ' = ', SUBTRACT(a, b));'*': WRITE(a, ' * ', b, ' = ', MULTIPLY(a, b));'/': WRITE(a, ' / ', b, ' = ', DIVIDE(a, b));END;END.```这段代码通过读取用户输入的操作符、第一个数和第二个数,并根据操作符调用相应的子程序,最后将运算结果输出给用户。
PIC单片机 加减法 子程序
PIC单片机加减法子程序16×16位定点数加、减法子程序以下子程序实现2个16×16位有符号数加、减运算,其和或差用一个16位数表示。
在子程序中,减法是通过对减数求补后再与被减数相加来实现的。
因此,当程序从D_sub进入子程序时为减法,当从D_add进入子程序时为加法。
子程序的入口条件和出口条件如下:入口条件:16位被加数/被减数存放在ACCBHI、ACCBLO中;16位加数/减数存放在ACCAHI、ACCALO中;出口条件:16位和/差存放在ACCBHI和ACCBLO中。
以下为16×16位有符号数加、减法子程序。
注意:在以下注释程序中均以ACCA代替ACCAHI、ACCALO两个字节,以ACCB代替ACCBHI、ACCBLO两个字节。
LIST p=16f877INCLUDE p16f877.incACCALO EQU 20 ;存放加数或减数低8位ACCAHI EQU 21 ;存放加数或减数高8位ACCBLO EQU 23 ;存放被加数或被减数低8位ACCBHI EQU 24 ;存放被加数或被减数高8位ORG 0X0000START GOTO MAIN;***双字节减法子程序,入口地址ACCB-ACCA,出口地址ACCB***D_sub CALL NEG_A ;求ACCA的补码;***双字节加法子程序,入口地址ACCB+ACCA,出口地址ACCB***D_add MOVF ACCALO,0 ;ACCB和ACCA低半字节相加ADDWF ACCBLOBTFSC STATUS,C ;有进位否?INCF ACCBHI ;有,ACCB高字节加1,再加ACCAHI MOVF ACCAHI,0 ;ACCA、ACCB高半字节相加ADDWF ACCBHIRETURN ;子程序返回;************** ACCA取补子程序*****************NEG_A COMF ACCALO ;ACCALO取反加1INCF ACCALOBTFSC STATUS,C ;低8位有进位吗?DECF ACCAHI ;有,ACCAHI减1,再取反COMF ACCAHI ;否则ACCAHI直接取反RETURN ;子程序返回【校验举例1】 19531+(-16594)=2937(十进制)化为十六进制数:4C46H+BF2EH结果:0B79H(十六进制)【校验举例2】 26222+3000=29222(十进制)化为十六进制数: 666EH+0BB8H结果:7226H(十六进制)【例程】MAIN MOVLW 0X6E ;被加数666EH送ACCB MOVWF ACCBLOMOVLW 0X66MOVWF ACCBHIMOVLW 0XB8 ;加数BB8H送ACCAMOVWF ACCALOMOVLW 0X0BMOVWF ACCAHICALL D_add ;调用双字节加法子程序,求和 END。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
子程序花指令加算法
————————————————————————————————作者:————————————————————————————————日期:
子程序花指令加密算法
根据反汇编器原理,分析现有的花指令加密算法存在的问题,我们提出了一种新的花指令加密算法——子程序花指令加密算法。
一、花指令加密基本原理及现状
1、花指令加密工作原理
软件破解者要想有效的破解软件,需要对程序代码进行静态分析和跟踪。
花指令加密可以有效地对抗静态分析,经过花指令变换后的程序代码具有一定的反跟踪能力,能够在很大程度上增加软件破解者对程序进行分析和跟踪的难度,从而有效地保护软件的知识产权。
花指令分为可执行花指令和不可执行花指令。
可执行花指令指的是能够正常运行但又不改变原始程序逻辑性的一组无用指令。
这类花指令常常用在病毒代码的变形引擎中,但反汇编器能够正常反汇编这些花指令。
不可执行花指令又称垃圾字节,是指被插入到原始代码中但又不改变原始程序逻辑性的一组无用字节。
被插入的字节不能被执行,否则会使程序的逻辑性遭到破坏,影响程序运行的结果。
根据反汇编的工作原理,当插入的最后一个或多个花指令与其后正常的指令被反汇编器识别成一条有效地指令时,就能有效地破坏反汇编器的反汇编结果。
花指令加密技术就充分利用了这一特点,通过在程序代码中插入一些随机的不完整指令来破坏反汇编器的结果,达到保护软件的目的。
2、花指令加密研究现状
目前花指令加密中采用较多的一种形式是无条件跳转指令JMP加花指令脚,这种方法具有简单、易实现的优点,但存在特征码,容易被工具自动去除。
另一种形式是直接在程序代码
中的JMP指令后添加花指令,这种方法的优点是不存在特征码,但受代码中JMP指令个数的影响,如果JMP指令数太少,则变换效果不明显。
从以上内容可以看出,目前花指令加密中采用的多是JMP及各种JMP变形后加花指令的变换方法,这种方法虽然能够在一定程度上破坏反汇编器的反汇编结果,但模糊度较低。
因此要想更好的对程序进行花指令加密,就必须应用多个方法,使得产生的花指令既无固定的特征码,又具有较高的模糊度。
二、反汇编器工作原理分析
目前,大多数反汇编器使用的反汇编方法分为两类:一是线性扫描法,反汇编器从程序代码的第一个可执行字节开始依次逐个的将程序中的二进制代码反汇编成相应的汇编指令;另一种方法是递归扫描法,反汇编器沿着程序的指令执行控制流来一步一步进行反汇编,将二进制代码反汇编成相应的汇编指令。
在递归扫描中,如果在目标程序的代码中出现了跳转分支,反汇编器就会把这个分支地址记录下来,并分头反汇编各个分支中的指令。
但反汇编器并不去判断分支代码正确与否,它们只是将跳转地址的代码进行反汇编。
因此,如果在程序代码中加入一些伪分支,使得这些伪分支永远也不可能达到圈,然后在这些伪分支的地方加上一些花指令,那么反汇编器就会将这些花指令作为代码进行反汇编,极有可能使得添加的花指令与其后的代码结合在一起,从而扰乱整个反汇编结果。
由于这种方法中,跳转伪分支的目的地址是正确的,因此这些花指令是必须要进行反汇编的,花指令也就更容易与其后的程序原代码结合在一起,扰乱反汇编器的反汇编结果。
三、子程序花指令加密算法
1、加密算法思想
在下面提出的子程序花指令加密算法中,采用了将可执行花指令与随机选择的不可执行花指令相结合的方法。
通过在程序的子程序中构造伪分支,并添加一些花指令,来迷惑反汇编器,达到代码保护的目的。
子程序中的伪分支使用XOR指令和CMP指令来进行构造o XOR指令是将两个操作数进行逻辑“异或”操作的指令,它具有一个明显的特点,即:某一个数A与同一个数B进行两次“异或”操作后数值A不变,即有:
在子程序花指令加密算法中就充分利用了这一特点。
通过随机插入一个数B,让B与寄存器AL数值中A进行“异或”,然后得到中间结果C,将这个C与B进行比较,如果相等就跳转到添加的花指令的位置,如果不等则跳转到添加的下一个“异或”指令,即,用C与召再进行一次“异或”操作,仍然得到原来的寄存器AL中的数值A。
伪分支就是在A与B进行了“异或”得到C之后,比较B与C的值,如果相等就跳转到labell 的位置,labell的位置是添加的随机花指令;如果不等就跳转到labe12的位置,labe12的位置是添加的第二条XOR指令。
只要寄存器AL中的值不为O,那么A和曰“异或”之后就永远也不可能等于日,所以labell就是一个伪分支,也就是说程序永远也不可能去执行labell处的指令,因此程序只能去执行labe12处的指令。
但是由于labell处的地址是合法的目的地址,而且添加的je labell是合法的跳转指令,所以反汇编器一定要反汇编labell 处的花指令,从而有可能将花指令与其后的代码结合在一起,使反汇编结果出错。
2、子程序花指令变换描述
子程序花指令加密算法变换前后:
基本加密算法概要描述如下:
(1)找到子程序调用候选块,得到子程序调用的指针p;
(2)进入子程序模块,找到MOV指令,产生一个随机数m;
(3)在MOV指令后面添加两条XOR AL,m指令;
(4)在添加的第一条XOR指令后添加CMP指令;
(5)在CMP指令后添加JE和JNE指令,并设置JNE的跳转;
(6)在JNE指令后添加上n条花指令;
(7)设置JE的跳转;
(8)变换完成,程序继续执行,扫描寻找下一个需要变换的子程序模块。
子程序花指令加密算法工作流程见图1。
3、迷惑度分析
子程序花指令加密算法最为关键的是添加的花指令反汇编器是一定要进行反汇编的,所以,当添加的不完整花指令是正确的跳转位置时,它们就更容易与其后的代码结合在一起,从而有效地扰乱程序代码。
而以前的各种JMP加花指令的形式,在反汇编器采用递归扫描方法反汇编代码时,由于花指令不在程序的控制流程内,所以反汇编器不用反汇编这些代码。
在本加密算法中,由于与寄存器做“异或”运算的数值m是随机产生的,添加的佗条花指令也是随机产生的,这保证了该加密算法具有一定的随机性。
两条XOR指令同时与AL中的值进行“异或”操作,保证了AL中的值在变换前后没有改变。
在比较指令CMP al,m 中,由于al中的值与m是不相等的,所以程序也不可能去执行JE labell指令,而只能去执行JNE labe12指令,因此程序在变换前后的逻辑一致性没有遭到破坏,仍然可以完成相同的功能。
四、子程序花指令加密算法实践
1、实验步骤与结果
(1)实验环境
硬件环境:AMD SempronlMProcessor 3200+1.79 GHz/768 MMemory/19.5 G HardDisk。
软件环境:操作系统Windows XP+SP2/JCEE变换器/OIIy-dbg反汇编调试器/实验用可执行程序0928.exe。
其中JCEE变换器是为实现变换而编制的测试程序,程序0928.exe是用来进行变换的实验用程序。
(2)实验步骤
a、对实验用原程序进行反汇编,得到汇编伪代码P;
b、用JCEE变换器对原程序进行变换,得到变换后的程序;
c、用反汇编器对汇编后的程序进行反汇编,得到汇编伪代码P’。
(3)实验结果
候选块的大小为58条指令,其中有4个子程序调用指令。
变换前后的程序代码分别如图2和图3所示(选定其中的一个子程序进行分析,这个子程序共有12条指令)。
2、实验分析
从图3可以看出,子程序在经过变换后,JE跳转位置处的不完整花指令确实与其后的若干个正常代码结合在一起,使得反汇编器的反汇编结果出错。
从以上的图2、图3中也可以分析出,原来的12条指令有2条指令和添加的花指令结合在一起,使得反汇编器出现了错误。
而且,添加XOR指令时是添加的两条XOR指令,但是第二条XOR指令也与花指令结合到一起。
因此,在这个子程序中共有3条指令出现了反汇编错误。
经验证,变换后的程序是可以运行的,而且和没有经过变换的程序具有一样的输出结果,也就是程序在经过变换后其逻辑一致性没有受到破坏。
对变换后的结果使用花指令自动去除工具,也不能将程序中的花指令自动去除。
这是由于JE指令是作为原始代码的一个组成部分是不能被去除的,否则程序逻辑性会遭到破坏,程序就无法正常运行了。