美文网首页移动开发iOS逆向工程
追踪iOS某APP的验证签名过程

追踪iOS某APP的验证签名过程

作者: 逆行的虫子 | 来源:发表于2017-08-24 12:31 被阅读285次

    利用反汇编追踪iOS某APP的验证签名过程


    环境需求

    • 越狱iOS设备一台,

    • Openssh

    • Cycript

    • Hopper Disassembler v4*

    • iProxy

    对iOS APP进行砸壳

    首先用USB连接越狱手机,使用USB进行端口映射到本机

    iproxy 2222 22
    

    新开终端

    ssh root@127.0.0.1 -p 2222
    

    开始砸壳

    DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/Application/1999C8D2-58C1-43C0-A717-A44B55CC1FEA/***.app/***
    

    得到砸壳后的文件

    Testerde-iPhone:~/decrypted root# ls
    cf.decrypted
    Testerde-iPhone:~/decrypted root#
    

    使用Hopper载入砸壳后的文件同时使用class-dump导出头文件

    class-dump -H ./cf.decrypted -o ./header --arch arm64
    

    注意在砸壳手机上运行的是什么CPU架构的,我们这里是arm64

    在使用charles抓包时发现URL中使用auth_key参数传递了验证签名,所以在hopper 中搜索auth_key
    得到以下片段

    00000001011436a9         db         "WSOpenMemberViewController", 0             ; DATA XREF=cfstring_WSOpenMemberViewController
    00000001011436c4         db         "loadedTimeRanges", 0                       ; DATA XREF=cfstring_loadedTimeRanges
    00000001011436d5         db         "v32@?0{?=qiIq}8", 0
    00000001011436e5         db         "mm:ss", 0                                  ; DATA XREF=cfstring_mm_ss
    00000001011436eb         db         "%@-%.f-0-0-%@", 0                          ; DATA XREF=cfstring______f_0_0___
    00000001011436f9         db         "%@?auth_key=%.f-0-0-%@", 0                 ; DATA XREF=cfstring____auth_key___f_0_0___
    0000000101143710         db         "player", 0                                 ; DATA XREF=0x10138cc60, 0x1013d6b60, 0x1013e1218, 0x101484138, 0x1014e82c8, 0x1014f6400, 0x10155c500, 0x101592bb8, 0x101593f18
    0000000101143717         db         "T@\"AVPlayer\",&,N,V_player", 0            ; DATA XREF=0x10138cc60, 0x1013d6b60, 0x101484138, 0x1014f6400, 0x101592bb8, 0x101593f18
    0000000101143731         db         "playerItem", 0                             ; DATA XREF=0x10138cc70, 0x1013d6b70
    000000010114373c         db         "T@\"AVPlayerItem\",&,N,V_playerItem", 0    ; DATA XREF=0x10138cc70, 0x1013d6b70
    000000010114375e         db         "playerLayer", 0                            ; DATA XREF=0x10138cc80, 0x1013d6b80, 0x1013e1228, 0x1014f6410, 0x10155c510
    000000010114376a         db         "T@\"AVPlayerLayer\",&,N,V_playerLayer", 0  ; DATA XREF=0x10138cc80, 0x1013d6b80, 0x1014f6410
    

    双击

    00000001011436f9         db         "%@?auth_key=%.f-0-0-%@", 0                 ; DATA XREF=cfstring____auth_key___f_0_0___
    

    查看到

     cfstring____auth_key___f_0_0___:
    00000001012e7760         dq         ___CFConstantStringClassReference, 0x7c8, 0x1011436f9, 0x16 ; "%@?auth_key=%.f-0-0-%@", DATA XREF=-[WSAVPlayerView encryptionUrl:andVideoKey:]+368, -[WSSpecialColumPlayerView encryptionUrl:andVideoKey:]+368
    

    这可以可以得出auth_key这个字符串在

    • [WSAVPlayerView encryptionUrl:andVideoKey:]+368
    • [WSSpecialColumPlayerView encryptionUrl:andVideoKey:]+368

    这两个地方使用过,这查看使用class_dump导出的头文件
    WSAVPlayerView.h

    //
    //     Generated by class-dump 3.5 (64 bit).
    //
    //     class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
    //
    
    #import "UIView.h"
    
    @class AVPlayer, AVPlayerItem, AVPlayerLayer, NSString, NSTimer, UIButton, UIImageView, UILabel, UIProgressView, UISlider, UITapGestureRecognizer;
    
    @interface WSAVPlayerView : UIView
    {
        _Bool _isPortraitShow;
        _Bool _isVIP;
        _Bool _isNetWorkWiFi;
        _Bool _isSeeking;
        _Bool _isShowingTool;
        NSString *_currentUrlString;
        NSString *_videoKey;
        double _time;
        id <WSAVPlayerViewDelegate> _delegate;
        AVPlayer *_player;
        AVPlayerItem *_playerItem;
        AVPlayerLayer *_playerLayer;
        UISlider *_progressSlider;
        UIView *_topToolView;
        UIView *_bottomToolView;
        UIView *_vipView;
        UILabel *_vipLabel;
        UIButton *_vipButton;
        UIButton *_continueButton;
        UIImageView *_vipBgImageView;
        UIButton *_backButton;
        UIButton *_lockButton;
        UIButton *_playButton;
        UILabel *_progressTimeLabel;
        UILabel *_restTimeLabel;
        UIButton *_expandOrShrinkButton;
        AVPlayerItem *_currentPlayerItem;
        NSTimer *_progressTimer;
        UIProgressView *_progressView;
        UITapGestureRecognizer *_tapGesture;
        NSTimer *_toolControlTimer;
    }
    
    + (Class)layerClass;
    @property(nonatomic) _Bool isShowingTool; // @synthesize isShowingTool=_isShowingTool;
    @property(nonatomic) _Bool isSeeking; // @synthesize isSeeking=_isSeeking;
    @property(retain, nonatomic) NSTimer *toolControlTimer; // @synthesize toolControlTimer=_toolControlTimer;
    @property(retain, nonatomic) UITapGestureRecognizer *tapGesture; // @synthesize tapGesture=_tapGesture;
    @property(retain, nonatomic) UIProgressView *progressView; // @synthesize progressView=_progressView;
    @property(retain, nonatomic) NSTimer *progressTimer; // @synthesize progressTimer=_progressTimer;
    @property(retain, nonatomic) AVPlayerItem *currentPlayerItem; // @synthesize currentPlayerItem=_currentPlayerItem;
    @property(retain, nonatomic) UIButton *expandOrShrinkButton; // @synthesize expandOrShrinkButton=_expandOrShrinkButton;
    @property(retain, nonatomic) UILabel *restTimeLabel; // @synthesize restTimeLabel=_restTimeLabel;
    @property(retain, nonatomic) UILabel *progressTimeLabel; // @synthesize progressTimeLabel=_progressTimeLabel;
    @property(retain, nonatomic) UIButton *playButton; // @synthesize playButton=_playButton;
    @property(retain, nonatomic) UIButton *lockButton; // @synthesize lockButton=_lockButton;
    @property(retain, nonatomic) UIButton *backButton; // @synthesize backButton=_backButton;
    @property(retain, nonatomic) UIImageView *vipBgImageView; // @synthesize vipBgImageView=_vipBgImageView;
    @property(retain, nonatomic) UIButton *continueButton; // @synthesize continueButton=_continueButton;
    @property(retain, nonatomic) UIButton *vipButton; // @synthesize vipButton=_vipButton;
    @property(retain, nonatomic) UILabel *vipLabel; // @synthesize vipLabel=_vipLabel;
    @property(retain, nonatomic) UIView *vipView; // @synthesize vipView=_vipView;
    @property(retain, nonatomic) UIView *bottomToolView; // @synthesize bottomToolView=_bottomToolView;
    @property(retain, nonatomic) UIView *topToolView; // @synthesize topToolView=_topToolView;
    @property(retain, nonatomic) UISlider *progressSlider; // @synthesize progressSlider=_progressSlider;
    @property(retain, nonatomic) AVPlayerLayer *playerLayer; // @synthesize playerLayer=_playerLayer;
    @property(retain, nonatomic) AVPlayerItem *playerItem; // @synthesize playerItem=_playerItem;
    @property(retain, nonatomic) AVPlayer *player; // @synthesize player=_player;
    @property(nonatomic) _Bool isNetWorkWiFi; // @synthesize isNetWorkWiFi=_isNetWorkWiFi;
    @property(nonatomic) _Bool isVIP; // @synthesize isVIP=_isVIP;
    @property(nonatomic) _Bool isPortraitShow; // @synthesize isPortraitShow=_isPortraitShow;
    @property(nonatomic) __weak id <WSAVPlayerViewDelegate> delegate; // @synthesize delegate=_delegate;
    @property(readonly, nonatomic) double time; // @synthesize time=_time;
    @property(retain, nonatomic) NSString *videoKey; // @synthesize videoKey=_videoKey;
    @property(readonly, copy, nonatomic) NSString *currentUrlString; // @synthesize currentUrlString=_currentUrlString;
    - (void).cxx_destruct;
    - (void)layoutSubviews;
    - (void)dealloc;
    - (id)getPrivateKey:(id)arg1;
    - (id)encryptionUrl:(id)arg1 andVideoKey:(id)arg2;
    - (void)seekTime:(double)arg1;
    - (id)convertTime:(double)arg1;
    - (double)availableDuration;
    - (void)observeValueForKeyPath:(id)arg1 ofObject:(id)arg2 change:(id)arg3 context:(void *)arg4;
    - (void)playerDidFinishPlaying:(id)arg1;
    - (void)prepareToPlay;
    - (void)removeSystemNotifications;
    - (void)addSystemNotifications;
    - (void)removeTimeObserver;
    - (void)addTimeObserver;
    - (void)removePlayerItemStatusObserver;
    - (void)addPlayerItemStatusObserver;
    - (void)refreshProgessUI;
    - (void)showVIPView:(_Bool)arg1;
    - (void)hideVIPView;
    - (void)hideToolView;
    - (void)showToolView;
    - (void)continuePlayVideo;
    - (void)openVIPAction;
    - (void)expandOrShrinkAction:(id)arg1;
    - (void)playAction:(id)arg1;
    - (void)lockAction:(id)arg1;
    - (void)backAction:(id)arg1;
    - (void)resumeRefreshing;
    - (void)pauseRefreshing;
    - (void)seek:(id)arg1;
    - (void)addExternToolView;
    - (void)playWithUrlString:(id)arg1;
    - (void)clean;
    - (void)pause;
    - (void)play;
    @property(readonly, nonatomic) _Bool isPlaying;
    - (void)initializeAVPlayer;
    - (id)initWithFrame:(struct CGRect)arg1;
    - (id)initWithFrame:(struct CGRect)arg1 playUrl:(id)arg2;
    
    @end
    

    通过查看头文件可以看到
    [WSAVPlayerView encryptionUrl:andVideoKey:]
    方法中的VideoKey会保存在view的属性里面,我们来看看这个VideoKey是什么?

    在终端查看进程id

     ps -e
    
     5507 ??         0:14.64 /var/mobile/Containers/Bundle/Application/3912B0D8-705D-42E0-A087-D7A9711CB464/QQ.app/QQ
     5703 ??         0:05.17 /var/mobile/Containers/Bundle/Application/30C91D48-B9A6-4CA2-9669-A76073893084/WeChat.app/WeChat
     5830 ??         0:00.30 /usr/libexec/rtcreportingd
     5976 ??         0:00.64 /System/Library/Frameworks/SystemConfiguration.framework/SCHelper
     6030 ??         1:01.96 /var/mobile/Containers/Bundle/Application/1999C8D2-58C1-43C0-A717-A44B55CC1FEA/***.app/***
    

    这时使用cycript附加上去

    cycript -p 6030
    cy#
    

    我们先让这个播放器初始化完成并传入数据,这时需要在手机上进入到响应页面点击播放按钮

    查看当前的视图层次

    UIApp.keyWindow.recursiveDescription().toString()
    
    <WSAVPlayerView: 0x12688de50; frame = (0 0; 320 201); hidden = YES; gestureRecognizers = <NSArray: 0x170846180>; layer = <AVPlayerLayer: 0x1748221a0>>
    

    发现 WSAVPlayerView的内存地址为0x12688de50
    这时为了方便下次的调用我们声明一个变量

    cy# var pv = #0x12688de50
    #"<WSAVPlayerView: 0x12688de50; frame = (0 0; 320 201); hidden = YES; gestureRecognizers = <NSArray: 0x170846180>; layer = <AVPlayerLayer: 0x1748221a0>>"
    

    查看属性VideoKey

    cy# pv.videoKey
    @"NnVpU1VEc2drMTIzQVB4dDY="
    

    通过对比发现NnVpU1VEc2drMTIzQVB4dDY=的值是在请求视频资料中传入的

    我们把输入带入[WSAVPlayerView encryptionUrl:andVideoKey:]
    这个方法需要传入两个参数,第一个为url,第二个为key

    cy# [pv encryptionUrl:@"http://www.baidu.com/class/18007651/454eae93a1963d7c31b1076b7c5a6e58_18007651_480.mp4" andVideoKey:@"NnVpU1VEc2drMTIzQVB4dDY="]
    @"http://www.baidu.com/class/18007651/454eae93a1963d7c31b1076b7c5a6e58_18007651_480.mp4?auth_key=1503547268-0-0-077178daad75b10032af437b1d5d4cfb"
    

    这里返回了正确的auth_key说明我们找的函数对了

    那么我们来看看hopper这个函数大致做了一些什么

    00000001000ee4b4         mov        x23, x0
    00000001000ee4b8         adrp       x8, #0x101615000                            ; @selector(setStarImage:highlightedStarImage:)
    00000001000ee4bc         ldr        x1, [x8, #0x948]                            ; "timeIntervalSince1970",@selector(timeIntervalSince1970)
    00000001000ee4c0         bl         imp___stubs__objc_msgSend
    00000001000ee4c4         mov        v8, v0
    00000001000ee4c8         adrp       x28, #0x101643000                           ; @selector(wifiReachability)
    00000001000ee4cc         ldr        x0, [x28, #0x9d0]                           ; objc_cls_ref_WOWSUtils,__objc_class_WOWSUtils_class
    00000001000ee4d0         adrp       x8, #0x101617000                            ; @selector(defaultManager)
    00000001000ee4d4         ldr        x1, [x8, #0x660]                            ; "base64Decode:",@selector(base64Decode:)
    00000001000ee4d8         mov        x2, x20
    00000001000ee4dc         bl         imp___stubs__objc_msgSend
    00000001000ee4e0         mov        x29, x29
    00000001000ee4e4         bl         imp___stubs__objc_retainAutoreleasedReturnValue
    00000001000ee4e8         mov        x25, x0
    00000001000ee4ec         adrp       x8, #0x101617000                            ; @selector(defaultManager)
    00000001000ee4f0         ldr        x1, [x8, #0x668]                            ; "getPrivateKey:",@selector(getPrivateKey:)
    00000001000ee4f4         mov        x0, x24
    00000001000ee4f8         mov        x2, x25
    00000001000ee4fc         bl         imp___stubs__objc_msgSend
    00000001000ee500         mov        x29, x29
    00000001000ee504         bl         imp___stubs__objc_retainAutoreleasedReturnValue
    00000001000ee508         mov        x24, x0
    00000001000ee50c         adrp       x21, #0x101643000                           ; @selector(wifiReachability)
    00000001000ee510         ldr        x0, [x21, #0xab0]                           ; objc_cls_ref_NSString,_OBJC_CLASS_$_NSString
    00000001000ee514         adrp       x8, #0x101612000
    00000001000ee518         ldr        x26, [x8, #0xad0]                           ; "stringWithFormat:",@selector(stringWithFormat:)
    00000001000ee51c         str        x24, [sp, #0x10]
    00000001000ee520         str        d8, [sp, #0x8]
    00000001000ee524         str        x22, sp
    00000001000ee528         adrp       x2, #0x1012e7000
    00000001000ee52c         add        x2, x2, #0x740                              ; @"%@-%.f-0-0-%@"
    00000001000ee530         mov        x1, x26
    00000001000ee534         bl         imp___stubs__objc_msgSend
    00000001000ee538         mov        x29, x29
    00000001000ee53c         bl         imp___stubs__objc_retainAutoreleasedReturnValue
    00000001000ee540         mov        x27, x0
    00000001000ee544         ldr        x0, [x28, #0x9d0]                           ; objc_cls_ref_WOWSUtils,__objc_class_WOWSUtils_class
    00000001000ee548         adrp       x8, #0x101617000                            ; @selector(defaultManager)
    00000001000ee54c         ldr        x1, [x8, #0x670]                            ; "getMD5String:",@selector(getMD5String:)
    00000001000ee550         mov        x2, x27
    00000001000ee554         bl         imp___stubs__objc_msgSend
    00000001000ee558         mov        x29, x29
    00000001000ee55c         bl         imp___stubs__objc_retainAutoreleasedReturnValue
    00000001000ee560         mov        x28, x0
    00000001000ee564         ldr        x0, [x21, #0xab0]                           ; objc_cls_ref_NSString,_OBJC_CLASS_$_NSString
    00000001000ee568         str        x28, [sp, #0x10]
    00000001000ee56c         str        d8, [sp, #0x8]
    00000001000ee570         str        x19, sp
    00000001000ee574         adrp       x2, #0x1012e7000
    00000001000ee578         add        x2, x2, #0x760                              ; @"%@?auth_key=%.f-0-0-%@"
    00000001000ee57c         mov        x1, x26
    00000001000ee580         bl         imp___stubs__objc_msgSend
    00000001000ee584         mov        x29, x29
    00000001000ee588         bl         imp___stubs__objc_retainAutoreleasedReturnValue
    00000001000ee58c         mov        x26, x0
    00000001000ee590         mov        x0, x28
    00000001000ee594         bl         imp___stubs__objc_release
    00000001000ee598         mov        x0, x27
    00000001000ee59c         bl         imp___stubs__objc_release
    00000001000ee5a0         mov        x0, x24
    00000001000ee5a4         bl         imp___stubs__objc_release
    00000001000ee5a8         mov        x0, x25
    00000001000ee5ac         bl         imp___stubs__objc_release
    00000001000ee5b0         mov        x0, x23
    00000001000ee5b4         bl         imp___stubs__objc_release
    00000001000ee5b8         mov        x0, x22
    00000001000ee5bc         bl         imp___stubs__objc_release
    00000001000ee5c0         ldr        x0, [sp, #0x18]
    00000001000ee5c4         bl         imp___stubs__objc_release
    00000001000ee5c8         b          loc_1000ee5d8
    
                         loc_1000ee5cc:
    00000001000ee5cc         mov        x0, x19                                     ; CODE XREF=-[WSAVPlayerView encryptionUrl:andVideoKey:]+68, -[WSAVPlayerView encryptionUrl:andVideoKey:]+72
    00000001000ee5d0         bl         imp___stubs__objc_retain
    00000001000ee5d4         mov        x26, x0
    
                         loc_1000ee5d8:
    00000001000ee5d8         mov        x0, x20                                     ; CODE XREF=-[WSAVPlayerView encryptionUrl:andVideoKey:]+448
    00000001000ee5dc         bl         imp___stubs__objc_release
    00000001000ee5e0         mov        x0, x19
    00000001000ee5e4         bl         imp___stubs__objc_release
    00000001000ee5e8         mov        x0, x26
    00000001000ee5ec         ldp        x29, x30, [sp, #0x80]
    00000001000ee5f0         ldp        x20, x19, [sp, #0x70]
    00000001000ee5f4         ldp        x22, x21, [sp, #0x60]
    00000001000ee5f8         ldp        x24, x23, [sp, #0x50]
    00000001000ee5fc         ldp        x26, x25, [sp, #0x40]
    00000001000ee600         ldp        x28, x27, [sp, #0x30]
    00000001000ee604         ldp        d9, d8, [sp, #0x20]
    00000001000ee608         add        sp, sp, #0x90
    00000001000ee60c         b          imp___stubs__objc_autoreleaseReturnValue
                            ; endp
    

    用hopper查看得出大致流程

    • 解密base64的VideoKey
    • 格式化需要签名的字符串
    • 生成效验字符串MD5
    • 格式化成最终URL,也就是上面返回值

    解密base64的VideoKey


    那现在我们来看看怎么解密VideoKey的
    服务器传下来的
    VideoKey是NnVpU1VEc2drMTIzQVB4dDY=
    base64解码以后的字符为
    6uiSUDsgk123APxt6

    00000001000ee4cc         ldr        x0, [x28, #0x9d0]                           ; objc_cls_ref_WOWSUtils,__objc_class_WOWSUtils_class
    00000001000ee4d0         adrp       x8, #0x101617000                            ; @selector(defaultManager)
    00000001000ee4d4         ldr        x1, [x8, #0x660]                            ; "base64Decode:",@selector(base64Decode:)
    00000001000ee4d8         mov        x2, x20
    00000001000ee4dc         bl         imp___stubs__objc_msgSend
    00000001000ee4e0         mov        x29, x29
    00000001000ee4e4         bl         imp___stubs__objc_retainAutoreleasedReturnValue
    00000001000ee4e8         mov        x25, x0
    00000001000ee4ec         adrp       x8, #0x101617000                            ; @selector(defaultManager)
    00000001000ee4f0         ldr        x1, [x8, #0x668]                            ; "getPrivateKey:",@selector(getPrivateKey:)
    

    在反汇编中可以看到解码以后调用了getPrivateKey方法
    那么我们这里在cycript中带入看看

    cy# [pv getPrivateKey:@"6uiSUDsgk123APxt6"]
    @"sgk123"
    

    发现这个结果是正确的

    这是在hopper中查看[WSAVPlayerView getPrivateKey:]方法

    00000001000ee610         stp        x24, x23, [sp, #-0x40]!                     ; Objective C Implementation defined at 0x10138c348 (instance method), DATA XREF=0x10138c348
    00000001000ee614         stp        x22, x21, [sp, #0x10]
    00000001000ee618         stp        x20, x19, [sp, #0x20]
    00000001000ee61c         stp        x29, x30, [sp, #0x30]
    00000001000ee620         add        x29, sp, #0x30
    00000001000ee624         mov        x20, x2
    00000001000ee628         adrp       x8, #0x101615000                            ; @selector(setStarImage:highlightedStarImage:)
    00000001000ee62c         ldr        x21, [x8, #0x1c8]                           ; "substringToIndex:",@selector(substringToIndex:)
    00000001000ee630         mov        x0, x20
    00000001000ee634         bl         imp___stubs__objc_retain
    00000001000ee638         mov        x19, x0
    00000001000ee63c         orr        w2, wzr, #0x1
    00000001000ee640         mov        x0, x20
    00000001000ee644         mov        x1, x21
    00000001000ee648         bl         imp___stubs__objc_msgSend
    00000001000ee64c         mov        x29, x29
    00000001000ee650         bl         imp___stubs__objc_retainAutoreleasedReturnValue
    00000001000ee654         mov        x21, x0
    00000001000ee658         adrp       x8, #0x101612000
    00000001000ee65c         ldr        x22, [x8, #0x8c8]                           ; "integerValue",@selector(integerValue)
    00000001000ee660         mov        x1, x22
    00000001000ee664         bl         imp___stubs__objc_msgSend
    00000001000ee668         mov        x23, x0
    00000001000ee66c         mov        x0, x21
    00000001000ee670         bl         imp___stubs__objc_release
    00000001000ee674         adrp       x8, #0x101612000
    00000001000ee678         ldr        x1, [x8, #0xa98]                            ; "length",@selector(length)
    00000001000ee67c         mov        x0, x20
    00000001000ee680         bl         imp___stubs__objc_msgSend
    00000001000ee684         sub        x2, x0, #0x1
    00000001000ee688         adrp       x8, #0x101614000                            ; @selector(setReturnKeyType:)
    00000001000ee68c         ldr        x1, [x8, #0x460]                            ; "substringFromIndex:",@selector(substringFromIndex:)
    00000001000ee690         mov        x0, x20
    00000001000ee694         bl         imp___stubs__objc_msgSend
    00000001000ee698         mov        x29, x29
    00000001000ee69c         bl         imp___stubs__objc_retainAutoreleasedReturnValue
    00000001000ee6a0         mov        x21, x0
    00000001000ee6a4         mov        x1, x22
    00000001000ee6a8         bl         imp___stubs__objc_msgSend
    00000001000ee6ac         mov        x22, x0
    00000001000ee6b0         mov        x0, x21
    00000001000ee6b4         bl         imp___stubs__objc_release
    00000001000ee6b8         adrp       x8, #0x101617000                            ; @selector(defaultManager)
    00000001000ee6bc         ldr        x1, [x8, #0x678]                            ; "substringWithRange:",@selector(substringWithRange:)
    00000001000ee6c0         mov        x0, x20
    00000001000ee6c4         mov        x2, x23
    00000001000ee6c8         mov        x3, x22
    00000001000ee6cc         bl         imp___stubs__objc_msgSend
    00000001000ee6d0         mov        x20, x0
    00000001000ee6d4         mov        x0, x19
    00000001000ee6d8         bl         imp___stubs__objc_release
    00000001000ee6dc         mov        x0, x20
    00000001000ee6e0         bl         imp___stubs__objc_retainAutoreleasedReturnValue
    00000001000ee6e4         ldp        x29, x30, [sp, #0x30]
    00000001000ee6e8         ldp        x20, x19, [sp, #0x20]
    00000001000ee6ec         ldp        x22, x21, [sp, #0x10]
    00000001000ee6f0         ldp        x24, x23, [sp]!, #0x40
    00000001000ee6f4         b          imp___stubs__objc_autoreleaseReturnValue
                            ; endp
    

    字符串6uiSUDsgk123APxt6得出sgk123的过程为
    第一个字符和最后一个字符为字符串需要截取的开始和结尾
    比如

    6uiSUDsgk123APxt6 => 6uiSUD sgk123 APxt6
    9TFQUz4wN sgk123 7ltDvfB6 => 9TFQUz4wN sgk123 7ltDvfB6
    

    格式化需要签名的字符串

    00000001000ee508         mov        x24, x0
    00000001000ee50c         adrp       x21, #0x101643000                           ; @selector(wifiReachability)
    00000001000ee510         ldr        x0, [x21, #0xab0]                           ; objc_cls_ref_NSString,_OBJC_CLASS_$_NSString
    00000001000ee514         adrp       x8, #0x101612000
    00000001000ee518         ldr        x26, [x8, #0xad0]                           ; "stringWithFormat:",@selector(stringWithFormat:)
    00000001000ee51c         str        x24, [sp, #0x10]
    00000001000ee520         str        d8, [sp, #0x8]
    00000001000ee524         str        x22, sp
    00000001000ee528         adrp       x2, #0x1012e7000
    00000001000ee52c         add        x2, x2, #0x740                              ; @"%@-%.f-0-0-%@"
    00000001000ee530         mov        x1, x26
    00000001000ee534         bl         imp___stubs__objc_msgSend
    00000001000ee538         mov        x29, x29
    00000001000ee53c         bl         imp___stubs__objc_retainAutoreleasedReturnValue
    00000001000ee540         mov        x27, x0
    00000001000ee544         ldr        x0, [x28, #0x9d0]                           ; objc_cls_ref_WOWSUtils,__objc_class_WOWSUtils_class
    00000001000ee548         adrp       x8, #0x101617000                            ; @selector(defaultManager)
    00000001000ee54c         ldr        x1, [x8, #0x670]                            ; "getMD5String:",@selector(getMD5String:)
    

    [WSAVPlayerView encryptionUrl:andVideoKey:]方法反汇编中可以看到

    format的格式为%@-%.f-0-0-%@,这里有三个参数,怎么取获取这三个参数的值?

    格式化完成以后传入getMD5String:方法
    直接在getMD5String中查看传入的值就好了,这里使用lldb 的debugserver查看

    debugserver默认没有task_for_pid权限
    我们先把越狱手机/Developer/usr/bin/debugserver复制到mac

    先创建一个ent.xml
    然后保存一下内容

    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">  
    <plist version="1.0">  
    <dict>  
            <key>com.apple.springboard.debugapplications</key>  
            <true/>  
            <key>get-task-allow</key>  
            <true/>  
            <key>task_for_pid-allow</key>  
            <true/>  
            <key>run-unsigned-code</key>  
            <true/>  
    </dict>  
    </plist>  
    

    执行签名

    ldid -Sent.xml debugserver
    

    然后复制到越狱设备的/usr/bin/
    开启调试***为进程名称

    Testerde-iPhone:~/ root# debugserver *:1234 -a "***"
    debugserver-@(#)PROGRAM:debugserver  PROJECT:debugserver-320.2.89
     for arm64.
    Attaching to process ***...
    Listening to port 1234 for a connection from *..
    

    这时调试服务器已经监听开启了1234端口等候处理
    这里我们再使用iProxy映射一个端口

    iproxy 1234 1234
    

    新开一个终端
    启动lldb建立和debugserver的连接

    ➜  ~ lldb
    (lldb) process connect connect://127.0.0.1:1234
    Process 6254 stopped
    * thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
        frame #0: 0x00000001965d4e7c libsystem_kernel.dylib`mach_msg_trap + 8
    libsystem_kernel.dylib`mach_msg_trap:
    ->  0x1965d4e7c <+8>: ret
    
    libsystem_kernel.dylib`mach_msg_overwrite_trap:
        0x1965d4e80 <+0>: mov    x16, #-0x20
        0x1965d4e84 <+4>: svc    #0x80
        0x1965d4e88 <+8>: ret
    (lldb)
    

    查看基址

    (lldb) image list -o -f
    [  0] 0x0000000000084000 /private/var/mobile/Containers/Bundle/Application/1999C8D2-58C1-43C0-A717-A44B55CC1FEA/***.app/***(0x0000000100084000)
    [  1] 0x0000000000094000 /Users/charley/Library/Developer/Xcode/iOS DeviceSupport/8.1.3 (12B466)/Symbols/usr/lib/dyld
    [  2] 0x000000010182c000 /Library/MobileSubstrate/MobileSubstrate.dylib(0x000000010182c000)
    [  3] 0x0000000003aac000 /Users/charley/Library/Developer/Xcode/iOS DeviceSupport/8.1.3 (12B466)/Symbols/usr/lib/libc++.1.dylib
    [  4] 0x0000000003aac000 /Users/charley/Library/Developer/Xcode/iOS DeviceSupport/8.1.3 (12B466)/Symbols/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics
    [  5] 0x0000000003aac000 /Users/charley/Library/Developer/Xcode/iOS DeviceSupport/8.1.3 (12B466)/Symbols/System/Library/Frameworks/Foundation.framework/Foundation
    [  6] 0x0000000003aac000 /Users/charley/Library/Developer/Xcode/iOS DeviceSupport/8.1.3 (12B466)/Symbols/System/Library/Frameworks/ImageIO.framework/ImageIO
    [  7] 0x0000000003aac000 /Users/charley/Library/Developer/Xcode/iOS DeviceSupport/8.1.3 (12B466)/Symbols/System/Library/Frameworks/MobileCoreServices.framework/MobileCoreServices
    [  8] 0x0000000003aac000 /Users/charley/Library/Developer/Xcode/iOS DeviceSupport/8.1.3 (12B466)/Symbols/System/Library/Frameworks/QuartzCore.framework/QuartzCore
    [  9] 0x0000000003aac000 /Users/charley/Library/Developer/Xcode/iOS DeviceSupport/8.1.3 (12B466)/Symbols/System/Library/Frameworks/Security.framework/Security
    [ 10] 0x0000000003aac000 /Users/charley/Library/Developer/Xcode/iOS DeviceSupport/8.1.3 (12B466)/Symbols/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration
    

    这里可以看到基址为0x0000000000084000

    [  0] 0x0000000000084000 /private/var/mobile/Containers/Bundle/Application/1999C8D2-58C1-43C0-A717-A44B55CC1FEA/***.app/***(0x0000000100084000)
    

    lldb命令c让程序继续运行

    (lldb) c
    Process 6254 resuming
    (lldb)
    

    我们在getMD5String这个方法的第一行下断点,也就是
    下面的第一行

    0000000100493b48         sub        sp, sp, #0x60                               ; Objective C Implementation defined at 0x10143f320 (class method), DATA XREF=0x10143f320
    0000000100493b4c         stp        x24, x23, [sp, #0x20]
    0000000100493b50         stp        x22, x21, [sp, #0x30]
    0000000100493b54         stp        x20, x19, [sp, #0x40]
    0000000100493b58         stp        x29, x30, [sp, #0x50]
    0000000100493b5c         add        x29, sp, #0x50
    0000000100493b60         mov        x19, x2
    

    那么程序在手机内存中的地址怎么计算?
    其实就是上面查看到的基址0x0000000000084000 +第一行的偏移量0000000100493b48 = 0x100517B48
    那么我就在0x100517B48下断点

    (lldb) br s -a 0x100517B48
    Breakpoint 6: where = *** `_mh_execute_header + 4772212, address = 0x0000000100517b48
    

    手机点击界面进行播放,lldb会断下来执行po $x2查看传入的参数

    Process 6254 stopped
    * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 6.1
        frame #0: 0x0000000100517b48 ***`_mh_execute_header + 4799304
    ***`_mh_execute_header:
    ->  0x100517b48 <+4799304>: sub    sp, sp, #0x60             ; =0x60
        0x100517b4c <+4799308>: stp    x24, x23, [sp, #0x20]
        0x100517b50 <+4799312>: stp    x22, x21, [sp, #0x30]
        0x100517b54 <+4799316>: stp    x20, x19, [sp, #0x40]
    (lldb)po $x2
    /class/17426404/2dbe0a6c9077e5aa969196faf047be2b_17426404_480.mp4-1503551940-0-0-sgk123
    (lldb)
    

    是不是很清楚了
    %@-%.f-0-0-%@格式化的三个参数

    • url路径
    • 时间戳
    • PrivateKey

    后面的就比较容易了


    生成效验字符串MD5


    使用格式化的字符做MD5结果
    f62b7278787782d900497c498d7271b2

    格式化成最终URL

    格式

    @"%@?auth_key=%.f-0-0-%@"
    

    参数如下

    • url地址
    • 时间戳
    • md5签名

    格式化的结果

    http://www.baidu.com/class/18007651/454eae93a1963d7c31b1076b7c5a6e58_18007651_480.mp4?auth_key=1503552405-0-0-f62b7278787782d900497c498d7271b2
    

    参考文章


    相关文章

      网友评论

      本文标题:追踪iOS某APP的验证签名过程

      本文链接:https://www.haomeiwen.com/subject/czmsdxtx.html