欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    最近,Denuvo加密技術的出現讓國內外的游戲破解者徹底崩潰了,多款在去年發售的采用了最新一代Denuvo加密的游戲,時至今日仍然沒有要被破解的跡象,這一次游戲廠商似乎在反盜版的對抗中真的要獲勝了。那么Denuvo到底是一種什么技術?它真的能徹底讓游戲免遭破解嗎?在回答這個問題之前,我們不如借此機會來回顧一下,我們曾經見過或體驗過的那些游戲反盜版技術吧。

    事實上,游戲反盜版和音樂、電影等在反盜版的主要核心上都沒有太大的區別,那就是DRM,全稱是Digital Rights Management,即數字版權管理。這是一種出版方用來控制被保護對象使用權的一些技術,這些技術保護的有數字化內容以及硬件,處理數字化產品的某個實例的使用限制。

    這么看上去有些復雜,其實簡單點說就是一套加密系統,它可以由版權方自行定制被保護產品的使用權限。就一我們的游戲來舉例,它可以規定游戲在什么條件下能被激活,可以同時授權幾臺電腦運行,或者在什么時段內可以運行等等。使用者需要取得相應的密鑰(也就是CDKey)來取得這些權限。

    但是DRM只是一個籠統的說法,因為光在游戲界里就產生過多種DRM方案,而我們今天最先來講的就是我們現在想起來就好遙遠的光盤加密。

    還記得在網絡并不發達的時代,游戲的主要存在形式就是那些實體包裝的游戲光碟,只要有了這些光碟就可以正常地運行游戲了。不過為了防止游戲光碟像音樂CD或是電影DVD一樣被盜版,所有的游戲光碟都采用了加密技術。

    防止盜版游戲光盤的技術并沒生效

    關于光盤的加密技術,實際上很多廠商都會有自己的一套標準,我們就以索尼的SecuROM來舉例。這項技術旨在阻止家庭媒體重復設備,專業復制機,和逆向工程技術的企圖。數利用據存儲密度測量來保護光盤的每一個特征,只有符合特征的光盤才被認為是合法的。

    不過最終的結果證明,這些所謂的光盤保護程序并不靠譜,大街上5塊錢一張的游戲光盤就是最好的證明。比如SecuROM的一個巨大漏洞就是,雖然數利用據存儲密度測量看上去很可靠,但實際上是可以被繞過的,很有點馬其諾防線的意思。

    而且最后,這些加密技術不僅沒能阻止盜版,反而讓正版玩家苦不堪言,各種BUG和類似于惡意程序的軟件行為紛至沓來,導致這些技術最后都被停用了。

    免DVD補丁出現了

    到了網絡下在時代,人們的盜版游戲來源從買光盤變成了直接從網上下載游戲文件運行,所以這就讓游戲廠商想到了另一個反盜版的路子,那就是要求游戲文件在運行時必須同時運行配套的游戲光碟進行驗證,才能正常游戲。這樣一來,從網上下載的游戲文件就變得無效了,加上這些玩家們又懶得去買游戲光碟,以此達到反盜版的目的。

    要求插入光盤才能進行游戲

    然而和前面的SecuROM一樣,光盤驗證的招數最終還是沒有奏效,因為網上出現了一種叫做免DVD補丁的東西同原版游戲文件一同放出來了。

    相信早些年下過盜版游戲的玩家都還記得,那時候并沒有什么“破解補丁”的說法,而都是“免DVD補丁”。免DVD補丁一般都是修改后的可執行程序,用其替換掉原正版的執行程序,就不再提示需要插入光盤了。

    所以光盤驗證的結局并沒有好打哪里去,甚至最終也被正版玩家所摒棄,因為這類技術通常會存在一些問題,比如讓玩家的光驅非正常運轉。而隨著不配備電腦光驅的玩家越來越多,這種一定要光盤驗證的技術方案也幾乎都被拋棄了。

    聯網驗證也防不住盜版

    上面提到的兩種反盜版技術都是在脫離互聯網環境下的驗證系統,即本地Key解鎖本地光盤來通過驗證,但結果都被無情破解。隨后游戲廠商就想到了互聯網,通過聯網驗證的方式來確定玩家是否有權使用游戲。

    一般來說這種技術的原理很單純,那就是游戲必須用CDKey激活,而這些CDKey必須至少有一次是聯網驗證過的,一旦驗證通過就會在服務器端留下備份。一般來說一個CDKey只能在一臺電腦上激活,想要在另一臺電腦激活就必須先執行反激活,這個過程也是要通過官方服務器的。這樣就防止了CDKey被無限復制使用。

    要求聯網驗證的游戲

    由于官方服務器是沒法被破解的,所以這種方法一開始的確起到了一些作用。但是結局真是驚人的相似,由于僅需經過一次聯網激活就可以徹底斷網,所以游戲破解者最終還是搞出了相應的破解補丁只需要繞過一次驗證即可保證游戲可以暢行無阻。

    另外一套方案則是“注冊機”技術的出現,這個東西并不是最早游戲圈里出現的,很多盜版軟件的序列號都可以通過“注冊機”來獲得,所以把這套現成的技術拿到游戲這來生成CDKey也并非難事。

    全程聯網惹毛正版玩家

    從這個方面來看,游戲廠商又一次敗了。但是在這次失敗中,他們吸取了教訓:僅僅一次聯網驗證不是夠的。所以我們就看到了全程聯網驗證的反盜版技術的出現。

    其實這個技術的原理非常簡單粗暴,那就是要求玩家在游戲時全程保持聯網,不定時與驗證服務器進行反饋,其中的典型代表就是《暗黑3》。這一招的確徹底把游戲破解者都將死了,因為破解技術再牛也不能攻破官方服務器啊,所以到現在我們也沒看到《暗黑3》的破解版。

    《暗黑3》要求全程聯網

    只是可惜,這套技術最終還是被絕大多數游戲商放棄了,原因不是破解大神,而是正版玩家首先不干了。要求一款游戲全程聯網,而且這玩意還不是網游,這是很多玩家不能接受的。加上一些驗證服務器水平有限,驗證數據處理緩慢,搞不好就要斷線GG,所以大量玩家開始投訴。影響比較大的事件就是《模擬城市5》那次。最終EA不得不取消了這個設定,然后破解版也隨之而出……

    Steam的出現也“然并卵”

    之后一個叫做Steam的游戲平臺出現了,這個平臺不單單是一個賣游戲的二道販子,同時也是一個新的游戲運行環境。玩家想要運行Steam上發售的游戲,必須擁有一個Steam帳號并進行激活,并且在Steam環境中運行。

    但是這對于反盜版來說并不能解決問題,因為Steam和之前的CDKey聯網驗證一樣,只要一次驗證就可以切換到離線模式運行游戲。所以破解者只要模擬一個Steam的運行環境(大家應該都看過那個替換的steam_api.dll文件),并替換掉原游戲的執行文件(.exe)就算是完成破解了。

    Steam也防不了盜版

    雖然我們不清楚Steam版游戲的詳細破解過程,但這顯然已經沒有任何技術壁壘,只要Steam上的游戲發行,馬上就能找到破解版,甚至破解版出得比正版還快(如《輻射4》)。

    同理的還有Origin和Uplay,在破解面前毫無招架之力。

    被逼走上聯機模式

    走到這一步,游戲廠商們幾乎已經放棄和破解者的正面對抗了,一代又一代的防破解技術最終都是一個下場。所以游戲廠商們開始轉入迂回作戰,即干脆改變游戲的性質。

    從前文我們可以知道,只有官方服務器本身才是破解者最大的壁壘,所以多人聯機模式開始出現,并且成為游戲內容的主體。在近兩年發行的3A大作中我們能明顯看出,多人聯機部分占到了越來越多的游戲比重,而單人部分的內容在逐漸縮水。

    這就是在Denuvo出現前廠商們的終極殺招,游戲被破解我也不管了,反正單機內容就那么一點點,完全沒有吸引力,主要的游戲全在線上部分,這個誰也破不了,想要玩到完整的游戲就乖乖買正版吧。《GTA V》、《全境封鎖》、《戰地4》幾乎都是這種模式,精華全在線上。

    《龍騰世紀:審判》聯機模式

    但那些幾乎沒法做線上內容的游戲怎么辦呢?所以這種模式終歸不是萬能的,而且為了防破解硬生生砍掉大量單機內容也與游戲精神相悖,這時候Denuvo像救星一樣出現了。

    Denuvo到底是一種什么技術?

    終于到了今天的正題了,這個已經把全世界游戲破解者難住了幾個月的Denuvo到底是個什么技術?它真的能夠徹底封死破解嗎?

    按照字面意思,Denuvo的全稱叫做Denuvo Anti-Tamper,即一種反篡改技術,它的作用是阻止對可執行文件進行調試、反向工程和修改。

    這個定義是不是有些籠統?我們用最通俗的話來解釋。首先Denuvo并不是一種DRM加密技術,這與之前介紹的所有DRM方案有本質區別。Denuvo完全不參與游戲的加密過程,所以也不會對游戲本身造成負面影響,那它的作用是什么呢?它的作用是讓游戲的DRM不被繞過。

    從前面的文章中我們會發現,絕大多數DRM方案慘遭失敗并不是方案技術本身有問題,而是這些方案都被繞過去了,壓根沒派上用場。而Denuvo的作用就是為這些DRM方案提供保護,使它們不能被繞過,即篡改。

    我們知道游戲文件最終要實現破解,一定要用破解后的原件替換掉原文件(也就是大家都懂的覆蓋),但是Denuvo的反篡改技術就是讓這些原文件無法被替換和篡改的。說白了就是費老半天勁破解了的文件派不上用場了,所以即使是再拙劣再經不住破解的DRM技術也不怕了,反正破了你也不能用。

    Denuvo

    那么有人會說,把Denuvo破了不就好了,但是這并不簡單。Denuvo采用的是一種64位加密技術,并且會一直更新和迭代,從而導致破解的難度也會越來越大。

    可能有人會記得Denuvo曾經被破解過一次,即《龍騰世紀:審判》和《墮落之王》、《FIFA2015》那一批采用Denuvo的游戲。不過最后證實那一次并非破解,而是Denuvo本身的漏洞被利用了,但即便如此,《龍騰世紀:審判》到破解的那一刻,已經花費了破解者200多天的時間,游戲的熱度已經完全降下去了。

    現在Denuvo已經修復了漏洞卷土重來,而采用了新一代Denuvo的游戲如《正當防衛3》、《古墓麗影:崛起》到現在仍沒有破解的跡象,那么是不是可以說Denuvo將會徹底封死破解呢?

    《正當防衛3》至今未被破解

    答案并沒有這么絕對,就如Denuvo自己說的:“游戲終究會被破解,但是Denuvo反篡改技術可被認為是成功的,因為它延長了游戲發售到被破解的時間。”Denuvo的目的并不是徹底封死破解,而是盡可能延長破解的時間,為游戲發售爭取更多的時間。

    如果一款游戲從發售到破解需要一年的時間,相信絕大多數人都會對此失去興趣,要知道現在幾乎每天都有新游戲發售,如果需要等待一年的時間才能免費玩上一款過氣的游戲,那不如去掏錢買正版了。

    同時,如果一個以破解吸引流量的網站在一年內都無法放出破解,自然會流失大量用戶,沒有了流量的收益,也就逐漸失去了破解的動力。

    所以,雖然不能說Denuvo是一個“絕對領域”,但至少從目前來看這是最佳的反盜版方案。簡言之就是,超長破解周期+年貨游戲=無敵。

    研究Fairplay DRM(Digital Rights Management,即數字版權保護)最關鍵的兩點是授權和加密。但長久以來,關于App DRM的研究卻很少,而就是在這樣的前提下,Fairplay DRM又為iOS App的安全研究疊加了一層“阻礙”。我們通過分析混淆系統的設計和實現過程中的問題,克服調試跟蹤的障礙,設計了多種靜態和動態的對抗方案;同時通過大量的逆向工程,填補了安全研究人員對macOS系統機制中,關于Fairplay這一部分的認知空白。

    什么是DRM?

    DRM全稱Digital Rights Management,即數字版權保護。蘋果為了保護App Store分發的音樂/視頻/書籍/App免于盜版,開發了Fairplay DRM技術,并申請了很多相關的專利,比較有代表性的如:

    • US8934624B2: Decoupling rights in a digital content unit from download
    • US8165286B2: Combination white box/black box cryptographic processes and apparatus
    • ES2373131T3: Safe distribution of content using descifrado keys

    長久以來,關于App DRM的研究很少,而DRM的關鍵是授權和加密。破解Fairplay DRM加密的方式俗稱“砸殼”,這是進行iOS App安全研究的必要前提。自從2013年蘋果引入App DRM機制以后,誕生了如Cluth、Bagbak、Flexdecrypt這樣的經典“砸殼工具”,而此類“砸殼工具”通常需要越獄設備的支持,因此具有一定的局限性。

    2020年發布的M1 Mac將Fairplay DRM機制引入了MacOS,由于Mac設備的權限沒有iOS嚴格,因此我們得以在MacOS上探索更多Fairplay DRM的原理,最終目標是使解密流程不受Apple平臺的限制。下面,我們先來聊聊Apple中是如何實現的?

    Apple上DRM的實現:Fairplay DRM

    LC_ENCRYPTION_INFO中的標記

    加密的MachO含有LC_ENCRYPTION_INFO字段,其中cryptoff標識了加密部分在文件中的起始偏移,cryptsize標識了加密部分的尺寸,cryptid則表明了加密的方法。Fairplay DRM保護下的App,其加密尺寸為4096的倍數,加密方式標識為1。

    圖1

    而負責解密Mach-O的組件主要包括:內核態的FairplayIOKit和用戶態的fairplayd

    Fairplay的Open

    MacOS的XNU Kernel中有text_crypter_create_hook這個導出符號,IOTextEncryptionFamily驅動則注冊了這個Hook,并作為橋梁,將調用轉發給了FairplayIOKit內核驅動。

    圖2

    最終負責處理的函數是:

    com_apple_driver_FairPlayIOKit::xhU6d1(
      char const* executable_path,
      long long cpu_type,
      long long cpu_subtype,
      rp6S0jzg** out_handle
    )
    

    此后,內核中的FairplayIOKit開始初始化,通過host_get_special_port中的unfreed port發送MIG調用到用戶態的fairplayd,fairplayd開始處理SC_Info目錄下的sinf和supp文件,并將處理的數據返回給內核中的FairplayIOKit。

    注:用戶態的fairplayd具體工作流程不在本文討論范圍內。

    其中MIG調用的結構如下:

    struct FPRequest{
        mach_msg_header_t header;
        mach_msg_body_t body;
        mach_msg_ool_descriptor_t ool;
        NDR_record_t ndr;
        uint32_t size;
        uint64_t cpu_type;
        uint64_t cpu_subtype;
    };
    
    struct FPResponse{
        mach_msg_header_t header;
        mach_msg_body_t body;
        mach_msg_ool_descriptor_t ool1; //supf文件映射
        mach_msg_ool_descriptor_t ool2; //unk,正比與加密內容的尺寸
        uint64_t unk1;
        uint8_t unk2[136];
        uint8_t unk3[84];
        uint32_t size1;
        uint32_t size2;
        uint64_t unk5;
    };
    

    完成所有調用后,返回的結構rp6S0jzg*實際是一個uint32_t類型的handle,接下來則可以用這個handle來完成解密操作。

    Fairplay的Decrypt Page

    前面提到的Fairplay Open操作最終返回了一個pager_crypt_info的結構體,其中page_decrypt的Hook由IOTextEncryptionFamily驅動接管,并最終轉發給FairplayIOKit。

    圖3

    最后,FairplayIOKit中負責解密的函數定義如下:

    com_apple_driver_FairPlayIOKit::bvqhJ(
      rp6S0jzg *hanlde,
      unsigned long long offset,
      unsigned char const* src,
      unsigned char * dst
    )
    

    至此,Fairplay的解密邏輯完成調用。值得注意的是,在Fairplay DRM中,page的概念為4096bytes。

    那么,用戶態fairplayd處理的sinf和supp文件又是什么樣子的呢?

    SINF和SUPF文件

    結構

    用戶態的fairplayd會讀取隨IPA攜帶的兩個重要文件:SINF和SUPF,存儲在App的SC_Info目錄下。

    圖4

    其中SUPF文件和IPA一起分發,每個用戶的IPA和SUPF文件都是一致的,其中SUPF文件中保存了加密Mach-O的密鑰,但是密鑰本身被另外的機制加密。而SINF文件則作為每個用戶的DRM許可,記錄了購買用戶的標識符和姓名,以及解密SUPF需要的信息,因此在Sandbox策略下,App無法讀取自身的SINF文件,以防止其被作為唯一ID追蹤用戶

    SINF

    SINF文件是一個LTV+KV結構的文件,它的字段如下所示:

    sinf.frma: game
    sinf.schm: itun
    sinf.schi.user: 0xdeadbeef
    sinf.schi.key : 0x00000005
    sinf.schi.iviv: 0x12345678901234567890123456789012
    sinf.schi.righ.veID: 0x000007d3
    sinf.schi.righ.plat: 0x00000000
    sinf.schi.righ.aver: 0x01010100
    sinf.schi.righ.tran: 0xdc64f80c
    sinf.schi.righ.sing: 0x00000000
    sinf.schi.righ.song: 0x59a73c58
    sinf.schi.righ.tool: P550
    sinf.schi.righ.medi: 0x00000080
    sinf.schi.righ.mode: 0x00002000
    sinf.schi.righ.hi32: 0x00000004
    sinf.schi.name: User Name
    sinf.schi.priv: (432 Bytes Private Key)
    sinf.sign: (128 Bytes Private)
    

    SUPF

    SUPF文件主要分為三個部分,我們將其命名為Key Segments、Fairplay Certificate、RSA Signature,其中Key Segments可以含有多個子Segment,用來保存多個架構的解密信息。

    KeyPair Segments:
     Segment 0x0: arm64, Keys: 0x36c/4k, sha1sum=e369546960d805dd1188d42e3350430c7e3a0025
    
    Fairplay Certificate:
        Data:
            Version: 3 (0x2)
            Serial Number:
                33:33:af:08:07:08:af:00:01:af:00:00:10
            Signature Algorithm: sha1WithRSAEncryption
            Issuer: C=US, O=Apple Inc., OU=Apple Certification Authority, CN=Apple FairPlay Certification Authority
            Validity
                Not Before: Jul  8 00:48:29 2008 GMT
                Not After : Jul  7 00:48:29 2013 GMT
            Subject: C=US, O=Apple Inc., OU=Apple FairPlay, CN=AP.3333AF080708AF0001AF000010
            Subject Public Key Info:
                Public Key Algorithm: rsaEncryption
                    RSA Public-Key: (1024 bit)
                    Modulus:
                        00:b0:01:16:4b:62:b2:37:8d:60:12:4f:02:15:15:
                        a0:32:1b:e8:ed:44:ed:e9:17:5b:ec:9e:5d:11:24:
                        5a:66:2f:dc:a3:25:aa:52:70:e1:09:22:09:4b:65:
                        0f:67:f5:82:dc:af:78:9b:4c:45:f3:b4:f4:77:aa:
                        fc:a3:b2:84:c3:8b:09:c6:2e:55:f5:14:85:07:ac:
                        ae:0d:ff:ff:ca:41:3b:44:cb:52:b6:28:60:55:23:
                        35:8d:26:71:c6:12:a5:e0:72:58:09:3c:4a:9e:b6:
                        63:df:2a:91:94:27:eb:65:0a:b2:36:45:11:c1:91:
                        43:58:12:d9:e5:18:a1:ad:db
                    Exponent: 65537 (0x10001)
            X509v3 extensions:
                X509v3 Key Usage: critical
                    Digital Signature, Key Encipherment, Data Encipherment, Key Agreement
                X509v3 Basic Constraints: critical
                    CA:FALSE
                X509v3 Subject Key Identifier: 
                    7B:07:34:81:A5:75:D0:F6:11:BB:D2:36:3F:79:93:4B:A1:70:EB:CF
                X509v3 Authority Key Identifier: 
                    keyid:FA:0D:D4:11:91:1B:E6:B2:4E:1E:06:49:94:11:DD:63:62:07:59:64
    
        Signature Algorithm: sha1WithRSAEncryption
             06:11:4e:87:ed:b1:08:70:c2:0d:e4:d2:94:bb:7f:ee:50:18:
             c0:2a:21:34:0e:99:1f:bf:60:a2:58:d0:0c:28:3d:03:5b:ab:
             4e:72:69:ba:41:52:45:b2:29:27:4a:c8:ba:7f:b5:9b:63:78:
             b1:68:41:40:59:3f:05:8a:57:74:c5:63:30:cc:f3:20:41:c0:
             3c:65:d4:0d:22:47:f3:97:76:e6:d6:3c:eb:e7:20:78:10:59:
             fd:96:09:82:c3:41:f0:5f:d0:3e:91:44:6d:77:3f:a5:d9:da:
             f0:f7:53:ad:94:61:28:1c:4c:40:3b:17:2b:dd:e3:00:df:77:
             71:22
    
    RSA Signature: 6aeb00124d62f75f5761f7c26ec866a061f0776be7e84bfad4b6a1941dbddfdb3bd1afdcc5ef305877fa5bee41caa37b1a9d4ce763cf7d2cb89efa60660a49dd5ddff0f46eee7cd916d382f727d912e82b6e0a62e8110c195e298481aa8c8162faac066ef017c6c2c508700d7adb57e0c988af437621e698946da1b09adf89e9
    

    下面,我們來聊聊Fairplay DRM的混淆原理和實現。

    混淆原理和一些實現

    LLVM Pass

    LLVM是一個優良的編譯器框架,其中,我們可以將其大略的分為前端、中端、后端:

    圖5

    配圖節選自CMU的CS 15-745課程:https://www.cs.cmu.edu/~15745。

    前端負責將高級語言轉化為LLVM IR;中端處理LLVM IR,完成一系列的分析、優化任務,我們稱之為Pass,再次輸出LLVM IR;后端則負責將LLVM IR轉化為機器碼。其中,中端的玩法特別豐富,基本的優化任務:如死代碼消除、常量折疊都在這一部分完成;Address Sanitizer、PC Sanitizer等編譯器插樁也是在這里進行的;其他的混淆框架如討論的較多的ollvm以及Hikari,甚至包括蘋果的混淆機制,也都是基于此完成。

    這一混淆方式可以基本的分為控制流混淆和數據流混淆,除此之外的一些混淆方式,比如VMP等,不在本文討論范圍內。

    makeOpaque

    在編譯器中,為了防止一些具體的表達式被優化,我們會將表達式進行等價變化,我們暫時將這樣的操作定義為makeOpaque(如Safari的JavascriptCore,其JIT組件B3就提供這樣的機制),C++偽代碼如下:

    Expression* makeOpaque(Expression *in);
    

    不透明謂詞(Opaque Predicate)

    謂詞(Predicate)在計算機中,指的是執行后為True或False的表達式。數論里面的一些結論可以作為我們生成不透明謂詞的基礎,這些不透明謂詞的結果恒為True或恒為False。比如下列表達式中,y執行的結果就恒為True:

    uint32_t x=0;
    bool y=((x * x % 4)==0 || (x * x % 4)==1);
    

    不透明謂詞應用到混淆中的一個例子就是bogus CFG。 如源語句如下:

    foo1();
    foo2();
    

    經過變換,我們添加了一個虛假的分支(即bogus CFG) :

    foo1();
    if ( false )
      junk_code();
    else
      foo2();
    

    但是如果沒有經過特別處理,編譯器、反編譯器的死代碼消除就會將虛假分支去除掉,因此我們需要makeOpaque的引入,假設我們引入了前面示例中的表達式:

    foo1();
    uint32_t x=rand();
    bool y=((x * x % 4)==0 || (x * x % 4)==1);
    if ( !y )
      junk_code();
    else
      foo2();
    

    那么如果編譯器、反編譯器沒有相應的識別機制的話,這一部分的死代碼就保留了下來,通過在死代碼里面插入大量干擾指令,可以為逆向的人員帶來極大的困擾。經測試在-O2優化下,Clang 11已經可以識別這個規則,但是GCC 5.4無法識別。

    可逆變換

    這里我們介紹一下目前混淆技術中常用的等價變換方式。

    異或

    異或規則是最常見的變換,這里不再贅述。

    x ^ c ^ c=x;
    

    仿射變換(Affine transformation)

    我們先來看一下仿射函數。

    下面我們來看一下實際應用。

    由于計算機中的運算屬于隱式的模運算,因此會具有一些有意思的性質。如對于一個uint32上的運算,模運算逆元定義如下:

    //對于
    uint32_t a, r_a;
    
    //如果滿足
    (a * r_a) % UINT32_MAX==1;
    
    //那么 a 和 r_a 互為模反元素
    

    對于互為模反元素的a和r_a(可通過擴展歐幾里得算法求得),有這樣的特性:

    uint32_t x=rand();
    uint32_t y1=a * x + c;
    //那么滿足
    x==ra * y1 +  (- ra * c)
    

    最后舉個例子來說明:

    //對于互為模反元素的4872655123 * 3980501275,取
    uint32_t x=0xdeadbeef;
    uint32_t c=0xbeefbeef;
    //則 -ra * c=0x57f38dcb,且
    ((x * 4872655123) + 0xbeefbeef) * 3980501275 + 0x57f38dcb==x
    /*
    可在lldb中驗證如下
    (lldb) p/x uint32_t x=0xdeadbeef; (uint32_t)(((x * 4872655123) + 0xbeefbeef) * 3980501275 + 0x57f38dcb)
    (uint32_t) $8=0xdeadbeef
    */
    

    MBA表達式(Mixed Boolean-Arithmetic Expression)

    MBA表達式是把算術運算(+,-,*,/)和位運算(&,|,~)混合在一起用以隱藏原本表達式的混淆方法。它基于不同的數學原理存在多種形式,這里主要介紹多項式MBA,這是目前混淆技術中最常遇到的形式。

    類似的,在Fairplay混淆中用到的MBA表達式為:

    //OperationSet(+, -, *, &, |, ~)
    x - c=(x ^ ~c) + ((2 * x) & ~(2 * c + 1)) + 1;
    

    而使用MBA進行混淆操作主要依靠以下兩個步驟:

    不透明常量(Opaque Constant)

    不透明常量是基于MBA混淆的方法,用于隱藏數據流中的常量。它使用了置換多項式,是一種在有限域上的可逆多項式。

    控制流平坦化

    這一部分是逆向工程中討論的最熱門的話題,即將正常的控制流轉換等價替換為一個狀態機,從而干擾靜態的控制流分析,業界也有較多的解決方案。同時因為Fairplay DRM中沒有明顯用到這種類型的混淆,不再多討論。

    非直接跳轉(Indirect Branch)

    將一些基本塊的起始地址保存在全局變量中,通過不透明常量的生成,使得反匯編工具和肉眼無法直接獲取到基本塊跳轉的目標,模型如下:

    //記錄基本塊地址到全局查找表LUT
    LUT[i]=PC;
    
    //執行跳轉
    jmp/call LUT[makeOpaque(i)]
    

    具體的實例:

    圖6

    這樣,逆向人員就無法直接獲取跳轉的目標函數、基本塊了。同理,通過將判斷語句的條件映射到跳轉表,也可以實現對條件跳轉的混淆。

    所以,在逆向被混淆的Fairplay代碼時,IDA Pro大多數時刻,只能識別出來函數的第一個基本塊,無法分析出函數的邊界

    跨函數混淆 + 調用約定混淆

    正常情況下,編程語言如C語言的參數傳遞遵循特定的調用約定,但是部分混淆工具會對一些內部函數的調用約定進行修改,以Fairplay DRM為例:

    圖7

    我們可以看到常規的以寄存器和棧傳遞參數的方式被替換成了以堆傳遞參數的方式了,在構造好了結構體的情況下,這個參數傳遞的特征可以被清晰的看出來。同時,這里面對一些傳遞的參數進行了異或混淆,在子函數里面再恢復出來,使得我們難以直接得到原始數據,而靜態分析的工具比如IDA Pro也不支持跨函數的數據流分析。

    更嚴重的是,一些影響子函數運行的重要依賴數據,被提升到了父函數內,導致在沒有恢復調用關系前,我們根本無法推測子函數的運行流程。

    那么,Fairplay DRM的破解之道就是要找到它的弱點。

    Fairplay混淆的弱點

    通過前邊的工作,我們已經能Fairplay正常的完成打開和解密工作了,通過一系列的靜態分析和追蹤調試,我們發現了這一套混淆系統的一些對抗方案。

    這些問題的本質原因是:混淆系統在IR層面設計,對機器相關的部分操作沒有混淆,因此在生成的機器碼里面,我們可以推斷得到混淆前的一些特征信息

    函數邊界識別

    前面提到,由于Fairplay用到了非直接跳轉的混淆技術,IDA Pro無法直接分析函數的邊界。通過跟蹤,我們發現在arm64e設備下,該內核驅動中,同一個函數的所有基本塊在運行到跳轉指令時,均使用了同一個PAC Context,或者稱之為PAC Modifier。

    圖8

    借由這個特性,我們可以將函數的邊界和基本塊分組,盡管目前為止這些基本塊之間并不是連通的。

    非直接跳轉

    對于無條件跳轉,我們通過設置斷點跟蹤執行流,就可以解決了。

    圖9

    再通過KeyPatch這樣的工具,我們可以將一些簡單的函數恢復到比較易于理解的地步。

    圖10

    但是這里的難點在于恢復混淆里面的非直接跳轉指令,如下圖所示:

    圖11

    對于這個跳轉指令,我們可以生成如下的表達式:

    //cmp x0, #0
    w10=qword[x12 + (EQ * 0xB + w19) << 3]
    //0xB代表兩個基本塊的在LUT中的下標差
    

    通過CSET指令的形式,我們已經可以推斷跳轉指令應該是J.NE或者J.EQ了,通過我們的調試器插件,我們可以得到其中一個分支的跳轉地址和原本的跳轉指令,再通過表達式的信息,我們可以很快推斷出另外一個分支的地址。

    圖12

    再通過Keypatch,我們可以得到混淆前的分支語句結構:

    圖13

    至此,我們已經可以完整地恢復Fairplay的大多數控制流了。

    數據流混淆

    這一部分在前面已經提及到了一些,目前我們已經找到了MBA表達式的模式,但還沒能找到Fairplay中生成不透明常量的完整規則。其中MBA表達式的重寫規則目前看起來僅有一個,即:

    x - c=(x ^ ~c) + ((2 * x) & ~(2 * c + 1)) + 1;
    

    一些基于模式匹配的工具,比如D810已經可以比較好的處理這樣的情況了。

    結束語

    目前,我們已經可以獲取到解密每一段Mach-O的AES密鑰了,通過大量的調試和反混淆,我們已經得出了這些密鑰生成的初步結論。我們希望最終的目的是不依賴Apple設備的前提下,完成Fairplay DRM加解密的研究。

    圖14

    最后,附上源碼,歡迎大家進行參考和研究。

    參考文獻

    • Eyrolles, N. (2017). Obfuscation with Mixed Boolean-Arithmetic Expressions: reconstruction, analysis and simplification tools (Doctoral dissertation, Université Paris-Saclay)
    • https://github.com/obfuscator-llvm/obfuscator
    • https://github.com/HikariObfuscator/Hikari
    • https://github.com/keystone-engine/keypatch
    • https://eshard.com/posts/d810_blog_post_1

    作者簡介

    吳聊、落落、朱米,均來自美團信息安全部。

    | 本文系美團技術團隊出品,著作權歸屬美團。歡迎出于分享和交流等非商業目的轉載或使用本文內容,敬請注明“內容轉載自美團技術團隊”。本文未經許可,不得進行商業性轉載或者使用。任何商用行為,請發送郵件至tech@meituan.com申請授權。

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有