用c语言编写花的代码,c语言编程星号

  用c语言编写花的代码,c语言编程星号

  概念

  插花是隐藏不想逆向工程的代码块(或其他函数)的一种方式。它将垃圾代码插入到实际代码中,同时确保原始程序正确运行。但节目反编译不好,节目内容难懂,视听效果混乱。

  简单来说就是在代码中混入垃圾数据,阻碍静态分析。

  花卉说明书分类

  命令大致可以分为两种:可执行命令和不可执行命令。

  可执行花卉指令

  可执行flower指令是指在程序的正常运行中执行flower指令代码的一部分。

  然而,运行这些代码是没有意义的。

  寄存器的值在执行前后不会改变(当然eip之类的除外)。

  反汇编程序也能成功识别一些代码。

  目的

  首先,花指令的首要目的还是增加静态分析的难度,让代码的真实意图难以识别。

  然后,这个flower命令破坏了反编译分析,堆栈指针可以在反编译引擎中抛出异常。(当然我们知道栈指针其实没有问题,只是反编译引擎需要改进。)

  不可执行flower指令

  不可执行flower指令是指在程序正常执行时,不执行flower指令代码的一部分。

  不可执行的花指令利用了反汇编线性扫描算法的缺陷,静态分析可以看到错误码。

  最常见的花命令

  如图,这是ctf主题中最常见最简单的flower指令之一,是典型的不可执行flower指令。

  小路

  首先,将0x00401D92代码转换为数据。

  然后,将0x00401D94的数据转换为代码,并将0x00401D94和0x00401D94的数据进行nop处理。

  我们知道E9是jmp指令对应的机器码。反汇编器读取E9时,下一次作为跳转目标的偏移量读取4个字节的数据,所以我们会看到错误的汇编代码。

  写作方法

  如果写程序时嵌入了_asm _emit 0E9,反编译器会把下面的指令当作地址数据:下一条指令的实际4个字节与地址数据或操作指令无关。

  _ _组件{

  _emit 075h #jmp $ 4

  _发射2h

  _emit 0E9h

  _emit 0EDh

  }

  嵌入上述4个字节的数据会导致反编译和反编译错误。请注意,这里的75是jnz的机器码,所以执行到这里停止时,Zflag=0。

  具体例子

  无花指令源程序

  我在这里写了tea加密算法。用msvc编译生成pdb文件,在ida中易于分析和打开。

  #包括

  #包括

  voidencrypt(uint32_t*v,uint32_t* k ) }

  uint32_t v0=v[0],v1=v[1],sum=0,I;/*设置*/

  uint 32 _ t delta=0x9e 3779 b 9;/*关键规划常数*/

  uint32_t k0=k[0],k1=k[1],k2=k[2],k3=k[3];/*缓存键*/

  for(I=0;i 32I ()/*basiccyclestart ) /

  苏美三角洲;

  v 0=(v 14)k0)v1sum)^)v15)k1);

  v1=(v04)k2)v0sum)^)v05)k3);

  (/)结束循环)/

  v[0]=v 0;v[1]=v1;

  }

  int main()).

  int a=1;

  uint 32 _ tflag [ ]={ 1234,5678 };

  uint 32 _ tkey [ ]={ 9,9,9 };

  加密(标志、密钥);

  printf(%d,%d ,flag[0],flag[1]);

  0;

  }

  首先你可以看到主函数和源代码差不多。

  您可以看到加密函数与源代码大致相同。

  添加花朵命令

  接下来,添加两个花命令

  第一个flower命令是我们上面在main函数中提供的最简单的写flower命令的方法。

  第二个flower命令是可以在encrypt函数中执行flower的命令。这里详细分析一下flower命令及其对应的移除方法。

  #

  包括

  #包括

  #定义垃圾代码__asm{

  __asm jmp junk1

  __asm __emit0x12

  __asm junk2:

  __asm ret

  __asm __emit0x34

  __asm junk1:

  __asm调用junk2

  }

  void encrypt(uint32_t* v,uint32_t* k) {

  uint32_t v0=v[0],v1=v[1],sum=0,I;/*设置*/

  uint 32 _ t delta=0x9e 3779 b 9;/*一个关键调度常量*/

  uint32_t k0=k[0],k1=k[1],k2=k[2],k3=k[3];/*缓存键*/

  for(I=0;i 32i ) { /*基本循环开始*/

  垃圾代码

  总和=delta

  v0=((v1 4) k0) ^ (v1总和)^((v1 5)k1);

  v1=((v 0 4)k2)^(v 0 sum)^((v 0 5)k3);

  } /*结束循环*/

  v[0]=v 0;v[1]=v1;

  }

  int main() {

  int a=1;

  uint32_t flag[]={ 1234,5678 };

  uint32_t key[]={ 9,9,9,9 };

  _ _组件{

  _emit 075h

  _发射2h

  _emit 0E9h

  _emit 0EDh

  }

  加密(标志、密钥);

  printf(%d,%d ,flag[0],flag[1]);

  返回0;

  }

  第一部花卉说明书

  Ida首先打开查看主功能:

  虽然反编译成功了,但是我们可以看到内容是完全错误的。我们来看一下主函数的汇编代码,这是我们添加的第一个flower指令。

  你可以看到这里出现的红色是我们的第一个花指令,贴片方法同上。我们主要看二花指令。

  第二部花卉说明书

  F5反编译直接报告错误

  可以发现花指令的混淆效果还是比较明显的,所以还是继续跟进花指令的反汇编代码吧。

  这里框中的说明是我们添加的花说明。逻辑其实很清晰,就是先跳转到junk1,再调用junk2。调用junk2时,地址0x004118D3会被堆栈,然后进入Junk2执行retn指令,会将地址0x00418d3弹出到eip,然后程序继续正常执行。

  移除方法

  这种去掉连续可执行指令的方法很简单,把整个nop掉就行了。

  但是现实复杂的程序中存在大量这样的华丽指令,人工nop耗时且容易出错,所以我们真正要掌握的是自动化的方法,就是编写脚本匹配华丽指令模板来去除。

  花朵移除说明

  这是我们想要删除的flower指令模板。

  #定义垃圾代码__asm{

  __asm jmp junk1

  __asm __emit0x12

  __asm junk2:

  __asm ret

  __asm __emit0x34

  __asm junk1:

  __asm调用junk2

  }

  下面是idapython写的ida匹配模板移除指令脚本。

  def nop(addr,endaddr):

  while addr endaddr:

  PatchByte(地址,0x90)

  addr=1

  def undefine(addr,endaddr):

  while addr endaddr:

  MakeUnkn(地址,0)

  addr=1

  def dejunkcode(addr,endaddr):

  while addr endaddr:

  制造商代码(地址)

  #匹配模板

  如果GetMnem(addr)==jmp 且GetOperandValue(addr,0)==addr 5且Byte(addr 2)==0x12:

  next=地址10

  nop(地址,下一个)

  addr=下一个

  继续

  addr=ItemSize(addr)

  去抖动码(0x00411820、0x00411957)

  未定义(0x00411820、0x00411957)

  MakeFunction(0x00411820,-1)

  重要功能分析

  Make (ea) #分析代码区,相当于ida快捷键c。

  Itize (EA) #获取指令或数据长度

  GetMnem(ea) #获取地址的操作码

  GetOperandValue(ea,n) #返回指令操作数的解析值。

  PatchByte(ea,value) #修改程序字节

  Byte(ea) #将地址解释为字节

  MakeUnkn(ea,0) #MakeCode的逆过程相当于ida快捷键u。

  MakeFunction(ea,end) #将begin to end的指令转换成函数。如果end被指定为psdhb(-1),IDA将通过定位函数的返回指令来尝试自动确定函数的结束地址。

  python提供了很多函数。如果不太理解这里的函数,可以在ida的Python命令行中自己尝试一下。通过比较ida汇编窗口的变化和函数的返回值,可以快速掌握函数的用法。

  运行脚本

  我们在ida中运行脚本,然后可以发现flower指令已经成功的丢弃了nop。按f5键进行反编译:

  您可以看到encrypt函数已经被成功反编译。

  对于比较复杂的程序来说,编写模板匹配脚本去除花指令是非常重要的,既能准确,又能节省大量时间。

  特殊花卉说明

  还有一种特殊的花指令,不会影响反汇编和反编译,只是单纯的迷惑人。

  比如我们的程序需要推送某个值(这里假设是0x12),正常的操作应该是:

  按下0x12

  添加了flower指令后,这个操作可以变成这样:

  按下0x26

  xor双字指针ss:[esp],0x34

  我们很容易看出两种写法是等价的。当我们要堆叠的数据是一些明显的特征值时,这个flower指令可以保护我们的特征值,防止算法特征被快速识别。

  当然这只是一个简单的例子,这种花指令的复杂性会大大提高分析的难度。

  摘要

  还有一些其他的使用花卉说明书的方法,包括一些非常特殊和罕见的。本文介绍的是我在学习过程中经常遇到的比较常见的花指令。

  往后的路还很长…慢慢学。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • c语言调用退出函数 c语言退出整个程序怎么写
  • c语言中怎么给函数初始化 c语言的初始化语句
  • c语言编写函数计算平均值 c语言求平均函数
  • 详解c语言中的字符串数组是什么,详解c语言中的字符串数组结构,详解C语言中的字符串数组
  • 表达式求值c++实现,c语言实现表达式求值
  • 看懂c语言基本语法,C语言详解,C语言的基本语法详解
  • 用c语言实现快速排序算法,排序算法设计与实现快速排序C语言,C语言实现快速排序算法实例
  • 深入解析c语言中函数指针的定义与使用方法,深入解析c语言中函数指针的定义与使用情况,深入解析C语言中函数指针的定义与使用
  • 描述E-R图,E-R图举例,关于C语言中E-R图的详解
  • 折半查找法C语言,折半查找算法(算法设计题)
  • 折半查找法C语言,c语言折半法查找数据,C语言实现折半查找法(二分法)
  • 扫雷小游戏c++代码设计,c语言扫雷游戏源代码,C语言实现扫雷小游戏详细代码
  • 怎样统计程序代码行数,C语言统计行数,C#程序员统计自己的代码行数
  • 基于c语言的贪吃蛇游戏程序设计,用c语言编写贪吃蛇游戏程序,C语言实现简单的贪吃蛇游戏
  • 图的两种遍历算法,图的遍历算法代码c语言,Python算法之图的遍历
  • 留言与评论(共有 条评论)
       
    验证码: