反调试入门篇(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),就可以逃避这种方式的特征码识别


相关文章
|
7月前
|
安全 Java 数据安全/隐私保护
代码混淆技术探究与工具选择
代码混淆技术探究与工具选择
77 0
|
2月前
|
安全 API 数据安全/隐私保护
史上最全最完整,最详细,软件保护技术-程序脱壳篇-逆向工程学习记录(一)
欢迎访问我的原站!本文详细介绍了程序脱壳技术,包括壳的定义、作用、执行过程、OEP(原始入口点)的概念及查找方法。文章通过多个实例,逐步演示了如何使用OD(OllyDbg)等工具进行脱壳操作,涵盖了压缩壳、加密壳等多种类型的壳。内容详尽,适合逆向工程初学者深入学习。[点击查看原文](https://www.oisec.cn/index.php/archives/520/)
57 0
|
2月前
|
存储 监控 API
史上最全最完整,最详细,软件保护技术-程序脱壳篇-逆向工程学习记录(二)
本文详细介绍了软件保护技术中的程序脱壳过程,包括IAT(导入地址表)的重建、OD(OllyDbg)跟踪输入表、HOOK-API技术以及FSG、UPX和WinUpacx等常见压缩壳的加脱壳方法。文章通过具体实例和详细步骤,帮助读者理解并掌握逆向工程的基本技巧。[原文链接](https://developer.aliyun.com/article/1618653)
64 0
|
7月前
|
安全 NoSQL Linux
《ARM汇编与逆向工程 蓝狐卷 基础知识》
《ARM汇编与逆向工程 蓝狐卷 基础知识》
111 0
|
7月前
|
安全 API 数据安全/隐私保护
免杀开发基础(1)
本文是关于Windows恶意软件开发的技术介绍,主要包括动态函数加载和执行、Shellcode执行技术以及注入技术。动态函数加载避免了静态链接到特定库,增加了分析难度。Shellcode执行涉及通过指针、内存分配和回调函数等方式。注入技术如APC注入,包括枚举进程线程、分配内存、写入有效负载等步骤。此外,文章还提到了使用异或加密来隐藏Shellcode,以规避静态特征检测。总的来说,文章探讨了免杀技术的基础知识,强调了在恶意软件开发中灵活性和创意的重要性。
|
7月前
|
IDE 编译器 开发工具
学习STM32,该用哪款开发工具?
学习STM32,该用哪款开发工具?
144 1
|
安全 Android开发
[笔记]安卓逆向之动态调试
[笔记]安卓逆向之动态调试
112 0
|
前端开发 rax C语言
脱壳学习(二)- 反“反调试”篇
脱壳学习(二)- 反“反调试”篇
|
移动开发 JSON 小程序
【小程序开篇】小程序架构和配置
【小程序开篇】小程序架构和配置
292 0
【小程序开篇】小程序架构和配置
|
监控 NoSQL Unix
开源代码分析技巧之三——老外如是说
继续从深入分析开源代码说起,当然源码分析没有太多捷径可走。笔者只是探讨下,如何分析会更好些。特通过Samba技术邮件群组,向老外提问“如何更好的分析Samba源码”。
292 0