跟着铁头干混淆4.1 ollvm控制流平坦化基本概念

ollvm 4.1 控制流平坦化基本概念

控制流平坦化基本概念

编译器参数:-mllvm -fla

英文全称 简称 编译参数
控制流平坦化 Control Flow Flattening fla -mllvm -fla

视频演示:https://space.bilibili.com/430241559

第1个例子 简单小程序:

c++源码
#include <cstdio>

int main(int n_argc, char** argv)
{
	int n_num = n_argc * 2;
	//scanf("%2d", &n_num);

	if (20 == n_num)
	{
		puts("20");
	}
	if(10 == n_num)
	{
	  	puts("10");
	}
	if(2 == n_num)
	{
	  	puts("2");
	}

	puts("error");

	return -1;
}
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := wtt
LOCAL_SRC_FILES := test.cpp
include $(BUILD_EXECUTABLE)
Application.mk

注意,这里加了 -mllvm -fla参数 表示开启控制流平坦化

APP_ABI := armeabi armeabi-v7a
APP_PIE:= true
APP_CPPFLAGS := -frtti  -std=c++11 -mllvm -fla
未混淆前流程图

没有被混淆的ida流程图

只用 控制流平坦化混淆后的流程图

源代码被 ollvm -fla混淆后的样子

混淆前后图解

混淆前:
ollvm fla混淆基本块之前

混淆后:ollvm fla混淆基本块之后

代码本来是依照逻辑顺序执行的,控制流平坦化是把,原来的代码的基本块拆分。

把本来顺序执行的代码块用 switch case打乱分发,用分发器和一个变量,把原本代码的逻辑连接起来。

让你不知 道代码块的原本顺序。让逆向的小老弟一眼看过去不知道所以然,不知道怎么去分析。

复杂的事变简单

c++源码编译器在编译你写的源码的时候

为了提升执行速度,做了大量的把复杂事情变简单的编译优化动作

比如你写了下面这一行代码

int n = 3 + 3 - 1  + x;

编译器会直接优化成:

int n = 5 + x;

在汇编层,你是看不到 3 3 1这三个中间数字的

你只能看到 5

这个流程有个专业的术语 叫 常量折叠


编译器 把复杂的事情变简单

混淆工具 把简单的事情变复杂

第2个例子 把妹小程序

就像下面的代码,这是一个把妹小程序的c++代码

程序写了一个肥宅拿钱去和妹子约会的场景

把妹小程序c++源码
#include <cstdio>

int ba_mei(int n_rmb);

//逛街小程序
int main(int n_argc, char** argv)
{
    //带了点钱出门
    int n_ret = ba_mei(n_argc);
    return n_ret;
}

//把妹函数 参数:软妹币数量
int ba_mei(int n_rmb)
{
    puts("和女票一起出门");
    puts("和女票走路去花店买花");
	n_rmb = n_rmb - 200;
    
    //如果手头的钱大于 800
	if(n_rmb >= 800)
	{
	  	puts("和女票去迪士尼");
        n_rmb = n_rmb - 500;
	}
    else
    {
        puts("和女票去博物馆");
        n_rmb = n_rmb - 50;
    }

    puts("逛累了 和女票打的去吃饭");
	n_rmb = n_rmb - 30;

    //如果手头的钱大于 500
    if(n_rmb >= 500)
	{
	  	puts("和女票去吃海底捞");
        n_rmb = n_rmb - 300;
	}
    else
    {
        puts("和女票去吃黄焖鸡米饭");
        n_rmb = n_rmb - 40;
    }

    puts("买了两瓶矿泉水");
    n_rmb = n_rmb - 3;

    //如果手头的钱大于 100
    if(n_rmb > 100)
    {
        puts("买包华子");
        n_rmb = n_rmb - 70;
    }
    else
    {
        puts("买包红双喜");
        n_rmb = n_rmb - 10;
    }

    puts("静静的抽了一根烟");
	puts("和女票一起回家");

	return n_rmb;
}

这个程序是一个把妹小程序

看源码能清晰的看懂逻辑 看懂程序大概做了些啥事,

通过ida进行反编译 ,也是可以清晰的看到逻辑的 基本上能看懂 程序干了啥

在有分支语句的时候,判断的依据是什么

把妹小程序反编译后的代码

控制流平坦化混淆之前反编译代码

这里 可以看到做了一些编译优化 v4这里是花掉的钱

-250这里是 先减去200 再减去50

-700 也是 先减去200 再减去500

在看看被混淆过的程序是啥样

把妹小程序 控制流平坦化混淆后的流程图

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值