Reverse花指令及反混淆

打印 上一主题 下一主题

主题 893|帖子 893|积分 2679

花指令及反混淆

1.花指令

  花指令是反调试的一种基本的方法。其存在是干扰选手静态分析,但不会影响步伐的运行。实质就是一串垃圾指令,它与步伐本身的功能无关,并不影响步伐本身的逻辑。在软件保护中,花指令被作为一种手段来增长静态分析的难度。IDA并不能正常辨认花指令,导致可看可分析代码被破坏,因此需要我们自己去分析一下。花指令主要分为两类:可执行花指令和不可执行花指令。

  • 可执行花指令:花指令在步伐正常运行的时间被执行,但不会影响步伐正常运行
  • 不可执行花指令:花指令在步伐正常运行的时间不会被执行
常见混淆的字节码:
机器码汇编语言9ACALL immed32E8CALL immed16E9JMP immed16EBJMP immed82.常见花指令分析

(1)单字节
  1. #include <stdio.h>
  2. int main()
  3. {
  4.     __asm {
  5.         jz start; //jz 和 jnz 同时出现,导致永恒跳转
  6.         jnz start;
  7.         _emit 0xE8; //这个地方就是故意插入的花指令 CALL + 地址
  8.     }
  9. start:
  10.     printf("ok!");
  11.     return 0;
  12. }
复制代码



例如:[NSSRound#3 Team]jump_by_jump
发现main函数编译不了 向下观察发现花指令

去除花指令 按D快捷键 先将call 转成硬编码 E8

再将光标放到 db 0E8上 将E8改成 nop(90) 再次按C键 点yes 将硬编码修复成代码

然后向下逐⼀修复 将光标放置在⻩⾊⾏上 按C修复 直到没有⻩⾊地址

将光标放置到函数开始的位置按 P键⽣成函数 最后tab转成伪代码



(2)永恒跳转
  1. int main()
  2. {
  3.     __asm {
  4.     xor eax, eax;// eax ^ eax = 0
  5.     jz s; // 必然成立跳转,一定会跳转
  6.     _emit 0x11; //填充垃圾指令 byte类型
  7.     _emit 0x22; //填充垃圾指令 byte类型
  8.     _emit 0x33; //填充垃圾指令 byte类型
  9.     s:
  10.     }
  11.         printf("test \n");
  12. }
复制代码
(3)更改ESP
  1. int main()
  2. {
  3.     __asm {
  4.         xor eax, eax;
  5.         jz s;
  6.         add esp, 0x11; // IDA 会把此指令识别对函数堆栈进行操作,导致识别函数失败
  7.     s:
  8.     }
  9.     printf("test \n");
  10. }
复制代码
(4)jmp跳转插入无效垃圾指令
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. int main()
  4. {
  5.     _asm {
  6.    
  7.         jmp $+5
  8.         _emit 0x71
  9.         _emit 2
  10.         _emit 0xE9
  11.         _emit 0xED
  12.    }
  13. lable:
  14.     printf("ok2");
  15.     return 0;
  16. }
复制代码
(5)嵌套永恒跳转
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. int main()
  4. {
  5.     _asm {
  6.         jz Label3;
  7.         jnz Label3;
  8.         _emit 0xE8;
  9.     }
  10. Label2:
  11.     _asm {
  12.         jz Label4;
  13.         jnz Label4;
  14.         _emit 0xE8;
  15.     }
  16. Label3:
  17.     _asm {
  18.         jz Label1;
  19.         jnz Label1;
  20.         _emit 0xE9;
  21.     }
  22. Label1:
  23.     _asm {
  24.         jz Label2;
  25.         jnz Label2;
  26.         _emit 0xE9;
  27.     }
  28. Label4:
  29.     printf("ok2");
  30.     return 0;
  31. }
复制代码





3.反混淆

方法一:手动规复

实用条件:混淆少且类型单一
  为了尽快解除题目,我们一般选择先手动去除混淆,迅速拿到flag
这里需要掌握IDA的基本快捷键:U、C、P

  • U: 在IDA Pro中,按“U”重新定义汇编,转换为字节码格式
  • C: 在IDA Pro中按“C”,转换字节码为汇编情势
  • P: 在IDA Pro中,按“P” 转换汇编语言为高级语言函数视图
方法二:IDA-Python脚本规复

实用条件:混淆大量,手工基本不可去除
  需要拿到混淆的字节码组成,利用脚本去除大量混淆。
例如:[GFCTF 2021]wordy

出现大量机器码为EBFF的花指令,如果手动nop很费,所以这里用idapython
  1. import idc
  2. import ida_bytes
  3. start_add=0x1144
  4. end_add=0x3100
  5. for address in range(start_add, end_add):
  6.   new_byte = ida_bytes.get_byte(address)
  7.   next = ida_bytes.get_byte(address + 1)
  8.   nnext = ida_bytes.get_byte(address + 2)
  9.   if new_byte == 0xeb and next == 0xff and nnext == 0xc0:  
  10.     ida_bytes.patch_byte(address, 0x90)
复制代码
  首先循环遍历从 0x1144 到 0x3100 的地址。在每个地址处,检查当前字节是否是 0xeb,下一个字节是否是 0xff,再下一个字节是否是 0xc0。如果匹配到 0xeb 0xff 0xc0 这个字节序列,就将当前地址处的字节 0xeb 修改为 0x90。0x90 在汇编语言中是 NOP 指令,表示“无操作”,即这个指令不会对步伐执行产生影响。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

络腮胡菲菲

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表