- 基于数据的混淆:利用VS编写程序,输出hello world,通过字符串变换完成对字符串“hello world”的隐藏,完成代码修改1和代码修改2,并说明现象;
vs高版本的/Ox优化不可行,所以优化编译无法做到隐藏字符串。
cl /Fehello.exe xiugai1.cpp /Fa1.asm
回到ida,通过设置断点的方式来查看data数组里的内容:
Eax,ecx,edx,三个寄存器反过来就是hello world
汇编文件和x32dbg都能看见字符串,只有ida无法查看。
ida
这串为hello world
X32dbg:
汇编文件
- 基于控制流的混淆:利用不透明谓词,编写如下程序:
#include <iostream>
int main()
{
int a,b,c;
double x;
a = 5;
b = 6;
x = 100.2;
if ((int)(pow(x, 2.0) + x) % 2 == 0)
c= a + b;
else
c= a * b;
}
在IDA下进行逆向分析,说明程序如何实现混淆。
分开看
这是a = 5;b = 6
x = 100.2;
隐藏的2.0,将x的值和2.0作为参数,调用了子程序sub_404020
其中的xmm0是双精度浮点数寄存器。而对应的两个地址赋值是:
通过转换,qword_40F70存放的是100.2,qword_40F68存放的是2.0
这里分别对应了POW(x,2)以及后续的加x,然后进行强制转换int类型然后and eax,80000001h,就是将eax和80000001h进行按位与操作,作用是提取eax 寄存器中的符号位和最低位,并将其他的位清零,最低为如果为1,就是%2有余数,为奇数,为0就是偶数,这就是%2的运算。Jns则是跳转到if判断分支
第一段为偶数分支,第二段为奇数分支,第三段则是结尾,通过这段代码可知if判断永远是对的,及永远是偶数,但是通过多了分支来增加代码的阅读量和分析成本,从而造成代码混淆的作用,这个不透明谓词其实就是假分支。