• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            elva

            扭曲變換加密

            作者:劉濤濤 me@liutaotao.com
            網址:http://liutaotao.com/nqby.txt

            一,一般來講,加密就是加殼

            我們經常考慮,一個可執行文件,怎么樣加密才能安全呢?

            一般用的手段,是加殼。加殼工具的工作原理,就是把可執行文件的代碼與
            數據都進行加密變換,作為數據存放。生成的目標文件入口代碼是加殼軟件
            準備好的防跟蹤代碼。經過漫長的防跟蹤代碼后,會把原始可執行文件的代碼
            與數據段恢復,然后跳轉到原來的入口處,繼續運行。這樣做的缺點是,不管
            你的加密多強,防跟蹤代碼多牛,只要一運行,在內存中就全部恢復了。只要
            把內存映象dump下來,反匯編一下,就清清楚楚了。甚至有工具可以直接把
            dump下來的內存映象存為可執行文件。這樣加密就徹底失敗了。

            簡單加殼是不安全的,這大家都知道了。我們一般把上述簡單的加殼方式叫“壓縮殼”。
            所以現在的加殼軟件都在上述“壓縮殼”的基礎上,多做了一些工作,比如:

            * 防止內存被 dump 。這實際上是不可能做到的。因為Windows操作系統就不是
            一個安全系統,你怎么可能做到內存不被dump呢?曾有一個殼,我用了多種方法
            dump都不成功。但最后還是找到了一個方法成功dump了。我這才驚嘆dump原來有
            這么多種方法,真是防不勝防。

            * 修改文件入口代碼。因為一般軟件都是用常用的幾種編譯器編譯生成的。如果
            加殼軟件知道你是用什么編譯器編的(這很容易),把入口代碼破壞掉,用另外一
            段功能類似的代碼替換它。這樣dump下來的代碼就比較難找到正確的入口,直接
            被存為一個EXE的可能性就小多了。但還是會被反匯編的。

            * 還有一些加殼軟件,支持對一個或幾個重點函數加密。甚至使用了虛擬機。但他們
            都只能重點加密少數幾個函數,不可能把所有函數都加密。而且對這個函數還有很多
            要求。這可以想象。如果用匯編寫一個函數,不加ret它可能連函數結束地址都找不到,
            怎么可能加密呢

            ******

            盡管加殼軟件可以使用以上多種技術防止被跟蹤,分析,還原,但我認為,它們仍然沒
            沒擺脫“殼”的這個中心思想。以上的這些技術不過是在“殼”的大前提下所做的一些
            小的插曲。它仍然是不安全的

            二,扭曲編譯的思想

            做個比喻。加殼保護就好比是你桌上有寶貝,為了保護它,你在屋外圍了一圈鐵絲網。只
            要有人突破了這道鐵絲網,進入你的屋子,一眼就看到了桌上的寶貝。這當然不安全。

            重點函數加密的思想,就好比是,我屋外圍了一圈鐵絲網,我還把寶貝放進了
            保險箱里。如果有人突破了鐵絲網,進入屋子,一眼就看到了保險箱。雖然保險箱不會被輕
            易打開,但他如果把保險箱搬走,慢慢分析呢?這也不夠安全。

            最安全的,就是進了屋子,卻什么也找不著。沒有目標,這才是最讓人頭疼的。

            現在的編譯器,都是追求生成高效率的運行代碼。這些代碼的模式基本一成不變。有經驗
            的程序員看反匯編代碼簡單跟看源碼一樣,毫無秘密可言。如果我們有一個編譯器,它的編譯
            目標不是為了高效,而是為了防止被讀懂,那該多好啊!我有C++源碼,我能看懂。一旦編譯,
            誰也別想通過反匯編看懂我想做什么,或者很難。遺憾的是,這樣的編譯器還沒有。

            如果我們自己編一個這樣的編譯器呢?不現實。工作量太大了。即使是找一個開源的C++編譯器
            來改工作量也不得了。

            直接做一個會加密的編譯器行不通。而一旦編譯連接生成EXE后,就只能加殼了。難道就沒有辦法
            了嗎?我想出一個主意,就是加密編譯的中間文件OBJ,輸出ASM文件,用ML編譯成OBJ,然后再link連接!

            這個方法有幾個好處:

            * OBJ文件格式相對簡單。不象處理C++源文件那么工作量大。
            * OBJ文件中保留了很多源文件的信息,比如符號名,代碼與數據,標號等等。方便加密。這些信
            息很多在LINK的過程中被丟掉了。所以LINK為EXE后再處理就極不方便了。
            * 這是一個全新的思想!對代碼的加密已經不限于加殼,而是加密每一個函數,每一條指令。再也
            沒有一目了然的匯編了。
            * 可以很容易設定加密的強度。可以根據需要,對一部分代碼輕量級加密,而對另一部分代碼重點
            加密。
            * 可以嵌套加密。重復使用幾種加密變換,無限制地使代碼膨脹
            * 因為是加密OBJ文件,所以不管DLL還是EXE都可順利加密,驅動程序也可以

            基于這個思想,我們的加密軟件就要出臺了!我們暫時叫它扭曲變換器 1.0

            三,扭曲變換器

            有了思想,就開始動手編碼。原以為OBJ文件格式是有文檔的,工程進度應該很快。沒想到其中還是
            有很多內容需要考慮。每每說這是最后一個問題,解決了就沒事了,卻總是后延。前前后后居然寫
            了差不多半年時間。

            主要遇到的技術問題:
            * 匯編器ML會把所有的代碼放到一個段中,這是不可以的。CL則通常是一個函數一個段。
            * 匯編器ML不能生成 COMDAT 段。盡管文檔中講它支持COMMON,但加了這個關鍵字無效果。
            * 匯編器ML不支持 WEAKEXTERN
            * 匯編器ML只支持 defaultlib 這一個 drectve 關鍵字,其它 export, include 等關鍵字不支持.

            總之,CL編譯的OBJ其中有很多屬性是ML無法生成的。微軟的masm真的該升級了。

            還有一些問題:
            * 分不清代碼與數據。數據段中肯定是數據,但代碼段中卻有可能不是代碼,是數據。這時如果你試圖
            反匯編它,就會出錯。
            * ?????

            不管怎樣,這些問題都一一解決了(別問我怎么做的)。

            采用的代碼扭曲方法:

            * 用 JMP 把代碼打亂。這已經不是什么新鮮的招數了,但它依然有效。

            * 用 JMP 把多個函數纏繞在一起。這樣可以讓分析者找不到函數從什么地方開始,到什么地方結束。

            * 把 call 改掉。破解者對 call 是極敏感的,這舉可以讓他找不到一個 call。比如,我可以把
            call sub1
                改為:
            mov eax, offset sub1 + 3
            push offset @1
            sub eax, 3
            jmp eax
                @1:
            * 把 ret 改掉。破解者對 ret 是極敏感的,這舉可以讓他找不到一個 ret。比如,我可以把ret寫作
            push ecx
            mov ecx, [esp+4]
            add esp,8
            jmp ecx
            * 改條件跳。條件跳也是極敏感的指令,比如我們可以把
                    cmp reg1, reg2
                    jge L_DST    
                L_NEXT:
            寫作:
                    push eax
                    mov eax, reg1
                    sub eax, reg2
                    shr eax, 1fh
                    neg eax
                    and eax, L2 - L1
                    add eax, L1
                    jmp eax
                L1:
                    pop eax
                    jmp L_DST
                L2:
                    pop eax
                L_NEXT:
            再看這個,你能看懂是什么意思嗎
            push offset @@L - offset L_3 + 23h
            jmp L_1
            L_2:
                    jz L_3
                    ret 4
            L_3:      
                    add dword ptr [esp+4], offset L_3 - 23h
                    add esp,4
                    ret

            L_1:
            call L_2
                    ...
            這里出現了call和ret,但又不是一般所期望的那種。這里的call不代表你發現了一個函數調用。
            這里的ret不代表是一個函數的結束。

            * 使用堆棧代替寄存器。比如:
            MOV     EAX, DWORD PTR [ECX+0AD8h]
            PUSH    EAX
            MOV     ECX, DWORD PTR [EAX]
            可以寫作:
            PUSH    EAX
            PUSH    ECX
            MOV     EAX, DWORD PTR [ESP]
            ADD     EAX, 0AD8h
            MOV     EAX, DWORD PTR [EAX]
            MOV     DWORD PTR [ESP+04h], EAX
            PUSH    DWORD PTR [ESP+04h]
            MOV     EAX, DWORD PTR [ESP]
            MOV     DWORD PTR [ESP+08h], EAX
            MOV     EAX, DWORD PTR [ESP]
            MOV     EAX, DWORD PTR [EAX]
            MOV     DWORD PTR [ESP+04h], EAX
            MOV     EAX, DWORD PTR [ESP]
            MOV     ECX, DWORD PTR [ESP+04h]
            ADD     ESP, 08h
            你能看懂嗎?很明顯,這個變換是不可逆變換。因為它本來使用了哪個寄存器,已經沒有辦法知道了。

            * ……還可以想出很多扭曲變換的方法。化繁為簡只有一種方法,化簡為繁可以有無窮多種方法。

            還有一些功能:
            * 在C語言中,使用 #pragma code_seg(".code$curve_NoChange") 來指示后面的代碼不做任何加密。因
            為有時候有些代碼含有大量的循環,加密它會嚴重影響效率。

            * 在C語言中,使用 #pragma code_seg(".code$curve_Max") 來指示后面的代碼重點加密。比如后面是
            與注冊算法相關。

            現在的扭曲變換器我叫它1.0版,已經非常穩定了。我用它把VC6的庫文件LIB都處理了一遍,再用LIB.exe工具
            寫回LIB文件中,我們就有了一套加密后的庫。如果用這套庫來LINK你的軟件,分析者就很難從匯編中找到哪
            個是printf哪個是strcpy,IDA也無法識別MFC靜態鏈接的庫函數了。能把VC6的庫都加密一遍不出錯,我
            相信它已經很強壯很穩定了。

            用它來加密我們做的一個共享軟件,就再也沒人寫出注冊機了。去讀懂大量的經過以上變換的代碼是不可
            想象的。但還是有人暴破了,真佩服他。我會不斷豐富加密方法,讓暴破者都放棄。

            現在的扭曲變換器還只支持VC6使用的COFF格式的OBJ,下一步,要分析一下VS2005的OBJ格式,盡快支持它。

            我經常喜歡反匯編一下,分析點什么東西。我有不少朋友也經常在做反匯編或破解的工作。我不希望扭曲變換
            器在網上一公布,被廣泛使用。有一天我想分析點什么卻無法下手。所以,這軟件暫時還不提供下載,也不出售。
            如果你有一段小程序想測試一下,可以把OBJ發給我,我加密一下給你。如果你有一個商業項目需要安全地加密,
            也可以談談。

            附上一個為CCG寫的crackme,用扭曲變換器加密,帶部分源碼,供參考。
            http://liutaotao.com/CrackMe.zip


            LiuTaoTao 2006.7.7

            posted on 2007-05-15 13:17 葉子 閱讀(469) 評論(0)  編輯 收藏 引用 所屬分類: 技術研究

            亚洲精品无码久久毛片| 99久久精品久久久久久清纯| 欧美精品丝袜久久久中文字幕| 国产精品美女久久久网AV| 久久天天躁狠狠躁夜夜av浪潮| 色播久久人人爽人人爽人人片aV | 亚洲精品美女久久久久99| 久久夜色精品国产噜噜麻豆| a级毛片无码兔费真人久久| 亚洲欧美久久久久9999| 久久香蕉国产线看观看99| 一级a性色生活片久久无少妇一级婬片免费放| 国内精品久久久久影院薰衣草| 国产精品久久精品| 久久无码专区国产精品发布| 久久综合九色综合欧美狠狠| 亚洲国产精品高清久久久| 久久精品国产精品亚洲人人| 国产美女久久久| 亚洲精品午夜国产VA久久成人 | 精品国产乱码久久久久软件| 狠狠色丁香婷综合久久| 伊人久久久AV老熟妇色| 思思久久99热免费精品6| 免费观看成人久久网免费观看| 久久精品国产亚洲AV不卡| 久久久综合香蕉尹人综合网| 久久精品国产亚洲沈樵| 91精品国产9l久久久久| 无码超乳爆乳中文字幕久久| 久久精品国产久精国产果冻传媒 | 亚洲va久久久噜噜噜久久狠狠| 国产三级观看久久| 国产精品久久久久久久久久免费| 99国产欧美久久久精品蜜芽| AAA级久久久精品无码片| 久久精品九九亚洲精品| 97久久国产亚洲精品超碰热| 91久久精一区二区三区大全| 久久精品国产亚洲一区二区| 蜜桃麻豆www久久|