反调试入门篇(1)——花指令

简介: 反调试入门篇(1)——花指令

花指令


花指令是一种反静态调试的最基础手段(对于动态调试来说就没有用处),我们可以通过在程序的代码中添加一些不影响程序运行的垃圾机器码,进而影响反汇编结果的准确性,达到程序保护的目的


花指令分类

1、可执行花指令


见字知其意,即花指令在程序正常运行的时候被执行,通用寄存器的值不发生改变,但不影响程序原有的功能执行


2、不可执行花指令


见字知其意,即花指令在程序正常运行的时候不会被执行,不影响程序原有的功能


花指令编写


原则:保持堆栈的平衡


常用花指令


汇编小知识:


mov eax, 1      eax赋值为1
pop 1                 将1从栈顶弹出
pop ebp             将栈顶的值弹出赋给寄存器ebp
push 1              将1压入栈中
push ebp            将ebp的值压入栈中
sub eax, 1      eax的值减1
add eax, 1      eax的值加1
inc eax             eax的值加1
dec eax             eax的值减1
call [x]            调用地址为x的函数,call对应的硬编码为0xE8
jmp x                   跳转到x地址处,jmp对应的硬编码为0xE9
nop                     不做任何事情,相当于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字节数据被错误识别成函数地址,进而导致接下来的分析出错


946c313bc999c25697f33d062926b86a_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


人工Patch花指令的方式很简单:

选中call指令所在行,点击Edit选项>Patch program>Change byte


70d79d3d644a8a17ef94d803b567851e_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


将call的硬编码E8改为0x90(nop指令)


628e50460bad3a12aa26202a39175898_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


3bef0a054f23ec1ed5fc4f584d527d07_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


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();
return 0;
}


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);
}
int main(int argc, char* argv[])
{
Test();
return 0;
}


4.开辟堆栈的花指令


push 1
push ebp
mov ebp, esp
sub esp, 0x8
push eax
push ecx
pop ecx
pop eax
add esp, 0x8
pop ebp
je xxx
jne xxx

花指令多的情况就需要自己写个IDA python脚本进行去除


5.花指令免杀


一些反病毒软件依靠特征码来判断文件是否有毒,其识别引擎在文件镜像(filebuffer)一定的偏移范围内进行扫描,比如在0x00001000~0x00006000之间,我们在其中加入一些花指令,使恶意代码偏离引擎识别的偏移范围,再使用工具修改程序入口(OEP),就可以逃避这种方式的特征码识别


相关文章
|
1月前
|
存储 监控 API
史上最全最完整,最详细,软件保护技术-程序脱壳篇-逆向工程学习记录(二)
史上最全最完整,最详细,软件保护技术-程序脱壳篇-逆向工程学习记录(二)
53 0
|
1月前
|
安全 API 数据安全/隐私保护
史上最全最完整,最详细,软件保护技术-程序脱壳篇-逆向工程学习记录(一)
史上最全最完整,最详细,软件保护技术-程序脱壳篇-逆向工程学习记(一)
29 0
|
6月前
|
安全 API 数据安全/隐私保护
免杀开发基础(1)
本文是关于Windows恶意软件开发的技术介绍,主要包括动态函数加载和执行、Shellcode执行技术以及注入技术。动态函数加载避免了静态链接到特定库,增加了分析难度。Shellcode执行涉及通过指针、内存分配和回调函数等方式。注入技术如APC注入,包括枚举进程线程、分配内存、写入有效负载等步骤。此外,文章还提到了使用异或加密来隐藏Shellcode,以规避静态特征检测。总的来说,文章探讨了免杀技术的基础知识,强调了在恶意软件开发中灵活性和创意的重要性。
|
Android开发 iOS开发
iOS 逆向编程(四)实操 Jailbreak 进阶必备软件
iOS 逆向编程(四)实操 Jailbreak 进阶必备软件
101 0
|
6月前
|
安全 前端开发 数据安全/隐私保护
【教程】 iOS混淆加固原理篇
本文介绍了iOS应用程序混淆加固的缘由,编译过程以及常见的加固类型和逆向工具。详细讨论了字符串混淆、类名、方法名混淆、程序结构混淆加密等加固类型,并介绍了常见的逆向工具和代码虚拟化技术。
|
6月前
|
安全 算法 前端开发
【完整版教程】iOS混淆加固原理篇
在iOS开发中,应用程序的安全性和保护显得尤为重要。由于iOS系统的开放性,一些逆向工具可以轻松地对应用程序进行反编译和分析,从而导致应用程序源代码、算法和敏感信息的泄露。为了保护应用程序的安全性,我们需要对应用程序进行混淆加固。本文将介绍iOS混淆加固的原理和常见的加固类型。
|
Linux 编译器 开发工具
Linux环境基础开发工具使用(一)万字讲解
Linux环境基础开发工具使用(一)万字讲解
105 0
|
Android开发 iOS开发
iOS 逆向编程(四)实操越狱进阶必备软件
iOS 逆向编程(四)实操越狱进阶必备软件
106 0
|
缓存 Swift iOS开发
iOS 逆向编程(二十二)Hopper Disassmbler 安装使用
iOS 逆向编程(二十二)Hopper Disassmbler 安装使用
272 0
|
小程序 JavaScript API
01-小程序:开发入门篇
01-小程序:开发入门篇
412 0
01-小程序:开发入门篇