ios手动代码混淆函数和变量名基本原理和注意事项教程(含demo)

47 篇文章 1 订阅
47 篇文章 4 订阅
本文详细介绍了iOS应用中代码混淆的原理,通过宏定义#define替换函数和变量名,提供了代码混淆的例子及注意事项。混淆过程中需要注意替换set方法、避免混淆系统方法和类名、处理xib和storyboard中的变量名,以及验证混淆效果。同时,文章提醒了混淆init方法会导致编译错误,并给出了混淆后class-dump导出的头文件作为验证。
摘要由CSDN通过智能技术生成

混淆函数名原理

代码混淆替换函数名的主要原理是用宏定义#define来替换代码里的函数名或者变量民

代码例子没混淆的函数名

ViewController.h文件

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (assign,nonatomic)int money;
-(void)showMoney;
@end
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *label1;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    _money = 100;
}
-(void)showMoney{
    NSLog(@"money=%d",self.money);
    NSString * strFuncName = [NSString stringWithFormat:@"%s",__func__];
    self.label1.text = strFuncName;

}
- (IBAction)btnShowClick:(id)sender {
    [self showMoney];
}

这个代码就是点击按钮以后再界面上显示函数名,显示结果,如下图
在这里插入图片描述
label1的文字被改成了函数名:-[ViewController showMoney]

把上面的代码进行函数名混淆
新建一个pch文件 PrefixHeader.pch ,然后在xcode->target->build settings 搜索prefix header,里面输入pch文件的路径

pch文件里面就加了一行代码: 把 showMoney 宏定义成 AFAdsaf123

#define showMoney AFAdsaf123

这样编译之后手机显示结果如下图:
在这里插入图片描述
显示的label1变成了 -[ViewController AFAdsaf123]
因为宏定义替换了函数名
使用class-dump查看导出的头文件ViewController.h ,因为只混淆了ViewController这个类,注意看函数 - (void)AFAdsaf123; 就是我们写的showMoney方法

@class UILabel;

@interface ViewController : UIViewController
{
    int _money;
    UILabel *_label1;
}

- (void).cxx_destruct;
@property(nonatomic) __weak UILabel *label1; // @synthesize label1=_label1;
@property(nonatomic) int money; // @synthesize money=_money;
- (void)btnShowClick:(id)arg1;
- (void)AFAdsaf123;
- (void)viewDidLoad;

@end

注意事项

替换变量名时要把set方法替换

下面代码是比上面多了一个setMoney方法,还有在viewDidLoad里面给money变量赋值,调用了 setMoney方法

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *label1;
@property (weak, nonatomic) IBOutlet UILabel *label2;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.money = 100;//这句会调用setMoney
}
- (void)setMoney:(int)money{
    _money = money + 1;
}
-(void)showMoney{
    NSLog(@"money=%d",self.money);
    NSString * strFuncName = [NSString stringWithFormat:@"%s",__func__];
    self.label1.text = strFuncName;

}
- (IBAction)btnShowClick:(id)sender {
    [self showMoney];
    self.label2.text = [NSString stringWithFormat:@"money = %d",_money];
}
@end

当点击按钮以后,结果是money = 101因为 set方法把money = 100+ 1了,执行结果如下图,label2显示money = 101:
在这里插入图片描述

现在我们给money变量进行代码混淆
pch文件中添加一行

#define money xadsf32

编译报错:

Use of undeclared identifier '_money'

在这里插入图片描述
因为_money这个变量已经没有了,现在有的是_xadsf32
代码改成这样才能编译过

_xadsf32 = money + 1;

在这里插入图片描述
下面的_money也要改成self.money:

self.label2.text = [NSString stringWithFormat:@"money = %d",self.money];

在这里插入图片描述

手机运行结果如下图,money = 100,因为没有调用setMoney方法:
变量已经变成了_xadsf32 ,对应的set方法应该是 setXadsf32这样才能配对,所以原来的setMoney方法每调用

在这里插入图片描述
正确的变量set方法也要跟着改,在pch中把变量名和 set方法一起改,如下

#define money xadsf32
#define setMoney setXadsf32

这样调用就能调用变量 xadsf32的set方法了

_下划线成员变量要一起define混淆

自定义的init开头方法代码混淆会会报错,不能混淆

pch文件中添加deine

#define _money _xadsf32

调用的时候可以直接写_money

- (void)setMoney:(int)money{
    _money = money + 1;
}

如下定义了一个CA类
CA.h

@interface CA : NSObject
@property (assign,nonatomic)int money;
-(instancetype)initWithMoney:(int) money;
@end

CA.m

#import "CA.h"

@implementation CA
-(instancetype)initWithMoney:(int) money{
    self = [super init];
    if (self) {
        self.money = money;
    }
    return self;
}
@end

调用代码:

    CA * ca1 = [[CA alloc]initWithMoney:50];
    NSLog(@"ca1.money=%d",ca1.money);

运行结果:ca1.money=50

但是如果我们把 initWithMoney 函数名混淆
在pch里添加一行:

#define initWithMoney adsf456

编译报错: 不能在init方法之外给self 赋值

Cannot assign to 'self' outside of a method in the init family

在这里插入图片描述
因为自定义的init必须调用super的init,并且给self成员变量赋值,混淆以后就不是init开头了,编译器不让用init之外的方法名给self赋值,所以无法混淆init开头的函数名

系统方法和类名不能混淆

例如下面把 UIViewController混淆就会编译报错:
pch中添加:

#define UIViewController asdfadfs123

编译报错如下图,报错,没有找到ViewController的父类asdfadfs123的声明 :

Cannot find interface declaration for 'asdfadfs123', superclass of 'ViewController'

在这里插入图片描述

xib和storyboard中的变量和方法名不能混淆

例如上面例子我把storyboard中的label1连线到代码中,编译通过,但是运行以后崩溃,报错如下,没有找到label1的连线
reason: ‘[<ViewController 0x10520a990> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key label1.’

说明xib 和 storyboard不会读取 pch文件,因为storyboard和xib是 xml格式,打开如下:

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
    <device id="retina6_1" orientation="portrait" appearance="light"/>
    //省略一部分
             <connections>
                        <outlet property="label1" destination="eRd-fS-lGp" id="lQU-Vc-xDf"/>
                        <outlet property="label2" destination="9ip-sX-hLa" id="R8d-B7-296"/>
                    </connections>

可以看到最后2行的label1 label2,而且xml没有读取pch文件,所以不会被#define替换

class-dump导出混淆后的头文件,验证函数和变量已经被混淆

最后我们看一下混淆之后用class-dump导出头文件里面的函数名变量名如下:
可以看到
money变成了xadsf32
showMoney变成了 AFAdsaf123

#import <UIKit/UIViewController.h>

@class UILabel;

@interface ViewController : UIViewController
{
    int _xadsf32;
    UILabel *_label1;
    UILabel *_label2;
}

- (void).cxx_destruct;
@property(nonatomic) __weak UILabel *label2; // @synthesize label2=_label2;
@property(nonatomic) __weak UILabel *label1; // @synthesize label1=_label1;
@property(nonatomic) int xadsf32; // @synthesize xadsf32=_xadsf32;
- (void)btnShowClick:(id)arg1;
- (void)AFAdsaf123;
- (void)viewDidLoad;

@end

demo下载地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值