实验过程:

这里0040105E指向转跳到401060+1,而401060又有转跳指令,说明这里指令存在错误,有花指令。并且是*jmp型花指令*

img

更改401060的前两个字符为90。

img

改完后可以按空格查看流程图。说明更改正确。

img

流程图中这里有一个add的单独指令,怀疑存在问题

img

检查原指令栈情况,发现后续栈有问题

img

将add esp,30 h Nop掉

img

在这里可以看出来将buffer数组每一位都异或1Dh(加密)

加密后将将command也就是下一层加密代码的地址压入栈

img

编辑解密脚本

#include <idc.idc>

static xor_setp1(){

auto addr = 0x00403054; //这里填入要解密字节串的起始地址

auto i = 0;

for(i=0;addr+i<0x004030DF;i++) //循环结束的条件为字节串的结束地址

{

​ PatchByte(addr+i,Byte(addr+i)^0x1D); //异或的数字根据情况修改

}

}

static main()

{

​ xor_setp1();

}

进行解密

img

按快捷键C将字符串转换为汇编语言

img

保存成新文件后打开,寻找加密模块

img

其中a1为输入字符串。

If语句中解出第三位为a,四、七位为i,第八位为n,十一位为o

img

while函数进行判断

“,VEJ”和a2^a1[x]做比对

img

找到a2内容

imgimg

追踪到a2就是1D,解出密钥a1[0]=1 a1[2]=K a1[6]=X a1[10]=W

img

在main函数中找到一个异常处理

img

在except中可以看到转跳函数

img

因此需要触发异常

异常为除零异常,当输入为12位时触发

进入异常后F5查看伪代码

img

得知byte_4031D5是输入的一部分

要求输入第二位、第六位、第十位为“_”

img

byte_4031E1 = ‘_’+‘_’+‘_’=1D(取低两位)

这也是之前用1D异或的原因

解得输入应为1_Kai_Xin_Wo

*问题-1**:程序中一共有2处花指令干扰,分别是哪一种类型的花指令?*

*– 提示:结合动态调试,查看出现异常处的实际执行流程/跳转情况;判断是不是为”永恒跳转“*

第一处是jmp型花指令

img第二处是栈干扰指令

img

*问题-2**:程序中一共有两处异常处理,分别是哪一种?*

*– 提示:x32dbg 动态调试除零异常时,可通过在寄存器窗口修改除数对应的寄存器的值为0,来无条件触发*

*– 提示:注意审视对 SEH 的潜在 “惯性思维”,认为 它一定是“除零”,以及程序核心功能就一定藏 exception 处理里*

第一处是除零异常

可以再try块中看到特征idiv语句

img

第二处是判断输入异常

img

*问题-3**:程序使用了何种加密算法?在程序中总共使用了几次?各自用于实现什么目的?*

使用了异或加密

  1. 在主函数中对buffer加密

img

实现对反编译的干扰,无法直接读取汇编代码内容

  1. 在处理输入flag时进行加密

img

*问题-4**:画出程序的算法流程图,给出输入正确f FLAG 时的 CMD 运行窗口截图*

img

img