• <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>

            tqsheng

            go.....
            隨筆 - 366, 文章 - 18, 評論 - 101, 引用 - 0
            數(shù)據(jù)加載中……

            從IDA中提取代碼做匯編注冊機之C/C++篇

            標 題: 從IDA中提取代碼做匯編注冊機之C/C++篇
            作 者: laomms
            時 間: 2006-12-22 23:22
            鏈 接: http://bbs.pediy.com/showthread.php?threadid=36799
            詳細信息:

                繼上篇那個VB后,我也想做個C/C++類的例子,正好看到FreeSoul寫的FScrackme2,所以寫了這篇文章。
                FScrackme2應(yīng)該是在lunix下取了GNU中的 GCC.exe 和 G++.exe來編譯的一個C程序! 所以用PEID來看語言類型是MingWin32 GCC 3.x。也就是GCC編譯的C程序。

            先來分析程序,找到真正的注冊碼并不難,OD中的算法部分:
            00401AE7  |.  8945 9C       MOV [LOCAL.25],EAX                       ; |
            00401AEA  |.  837D A0 03    CMP [LOCAL.24],3                         ; |用戶名長度必須大于3位
            00401AEE  |.  0F8E C2000000 JLE <FScrackm.loc_401BB6>                ; |
            00401AF4  |.  837D 9C 1A    CMP [LOCAL.25],1A                        ; |注冊碼長度必須大于27位
            00401AF8  |.  0F8E B8000000 JLE <FScrackm.loc_401BB6>                ; |
            ...
            00401B62  |.  8B45 9C       MOV EAX,[LOCAL.25]
            00401B65  |.  894424 0C     MOV DWORD PTR SS:[ESP+C],EAX             ;  注冊碼長度
            00401B69  |.  8B45 A0       MOV EAX,[LOCAL.24]
            00401B6C  |.  894424 08     MOV DWORD PTR SS:[ESP+8],EAX             ;  用戶名長度
            00401B70  |.  8B45 A4       MOV EAX,[LOCAL.23]
            00401B73  |.  894424 04     MOV DWORD PTR SS:[ESP+4],EAX             ;  注冊碼ASCII
            00401B77  |.  8B45 EC       MOV EAX,[LOCAL.5]
            00401B7A  |.  890424        MOV DWORD PTR SS:[ESP],EAX               ;  用戶名ASCII
            00401B7D  |.  E8 1C010000   CALL <FScrackm.sub_401C9E>               ;  主要算法
            00401B82  |.  85C0          TEST EAX,EAX
            00401B84  |.  75 18         JNZ SHORT <FScrackm.loc_401B9E>          ;  判斷返回值是否為0


            ================================================================================================
            CALL <FScrackm.sub_401C9E>  主要算法:

            00401D33 > > \8B45 0C       MOV EAX,DWORD PTR SS:[EBP+C]            
            00401D36   .  8038 4E       CMP BYTE PTR DS:[EAX],4E                 ;  對比第一位注冊碼是否為“N”
            00401D39   .  74 0F         JE SHORT <FScrackm.loc_401D4A>
            00401D3B   .  C785 4CFFFFFF>MOV DWORD PTR SS:[EBP-B4],1
            00401D45   .  E9 7E070000   JMP <FScrackm.loc_4024C8>
            00401D4A > >  8B45 0C       MOV EAX,DWORD PTR SS:[EBP+C]            
            00401D4D   .  40            INC EAX
            00401D4E   .  8038 61       CMP BYTE PTR DS:[EAX],61                 ;  對比第二位注冊碼是否為“a”
            00401D51   .  74 07         JE SHORT <FScrackm.loc_401D5A>
            00401D53   .  C745 94 00000>MOV DWORD PTR SS:[EBP-6C],0
            00401D5A > >  8B45 0C       MOV EAX,DWORD PTR SS:[EBP+C]            
            00401D5D   .  83C0 02       ADD EAX,2
            00401D60   .  8038 52       CMP BYTE PTR DS:[EAX],52                 ;  對比第三位注冊碼是否為“R”
            00401D63   .  74 0F         JE SHORT <FScrackm.loc_401D74>
            00401D65   .  C785 4CFFFFFF>MOV DWORD PTR SS:[EBP-B4],1
            00401D6F   .  E9 54070000   JMP <FScrackm.loc_4024C8>
            00401D74 > >  8B45 0C       MOV EAX,DWORD PTR SS:[EBP+C]           
            00401D77   .  83C0 03       ADD EAX,3
            00401D7A   .  8038 46       CMP BYTE PTR DS:[EAX],46                 ;  對比第四位注冊碼是否為“F”
            00401D7D   .  74 0F         JE SHORT <FScrackm.loc_401D8E>
            00401D7F   .  C785 4CFFFFFF>MOV DWORD PTR SS:[EBP-B4],1
            00401D89   .  E9 3A070000   JMP <FScrackm.loc_4024C8>
            ...
            00401E8B   .  83C0 04       ADD EAX,4
            00401E8E   .  0FB600        MOVZX EAX,BYTE PTR DS:[EAX]
            00401E91   .  3A45 87       CMP AL,BYTE PTR SS:[EBP-79]              ;  對比第5位開始5位注冊碼
            00401E94   .  74 0F         JE SHORT <FScrackm.loc_401EA5>

            ...

            00401EEA   .  83C1 09       ADD ECX,9
            00401EF6   .  0FB601        MOVZX EAX,BYTE PTR DS:[ECX]
            00401EF9   .  3A02          CMP AL,BYTE PTR DS:[EDX]                 ;  對比第10位注冊碼
            00401EFB   .  74 0F         JE SHORT <FScrackm.loc_401F0C>
            ...
            00401F4A   .  83C2 0A       ADD EDX,0A
            00401F4D   .  8B85 70FFFFFF MOV EAX,DWORD PTR SS:[EBP-90]            ;  對比第11位注冊碼...
            00401F8B   .  E8 30420000   CALL <FScrackm.isalpha>                  ; 第12位后6位注冊碼,必須為字母
            ..
            00401FB5   .  E8 F6410000   CALL <FScrackm.isupper>                  ; 第12位后6位注冊碼,必須大寫
            ...
            0040205F   .  83C0 0A       ADD EAX,0A                               ;  第10位后
            00402075   .  0FBEC0        MOVSX EAX,AL
            00402078   .  39C1          CMP ECX,EAX                              ;  對比第11位開始3位的注冊碼
            0040207A   .  74 0F         JE SHORT <FScrackm.loc_40208B>
            ...
            004020B1   .  0FBEC0        MOVSX EAX,AL
            004020B4   .  39C1          CMP ECX,EAX                              ;  對比第17位開始倒數(shù)3位的注冊碼
            004020B6   .  74 44         JE SHORT <FScrackm.loc_4020FC>
            ...
            00402125   .  83C0 11       ADD EAX,11                               ; 第17位后
            00402128   .  0FBE00        MOVSX EAX,BYTE PTR DS:[EAX]              
            0040212B   .  890424        MOV DWORD PTR SS:[ESP],EAX               
            0040212E   .  E8 6D400000   CALL <FScrackm.isdigit>                  ; \第18位開始的6位必須為數(shù)字
            00402133   .  85C0          TEST EAX,EAX
            00402135   .  75 0F         JNZ SHORT <FScrackm.loc_402146>
            ...
            0040220D   .  0FB601        MOVZX EAX,BYTE PTR DS:[ECX]
            00402210   .  3A02          CMP AL,BYTE PTR DS:[EDX]                 ;  對比第18位后的6位注冊碼
            00402212   .  74 0F         JE SHORT <FScrackm.loc_402223>
            ...
            00402230   .  83C0 17       ADD EAX,17
            00402233   .  8038 2D       CMP BYTE PTR DS:[EAX],2D                 ;  對比第24位注冊碼,必須為“-”號
            00402236   .  74 07         JE SHORT <FScrackm.loc_40223F>
            ...
            004022C7   .  83C1 18       ADD ECX,18
            004022CA   .  8B85 58FFFFFF MOV EAX,DWORD PTR SS:[EBP-A8]
            004022D0   .  0FBE10        MOVSX EDX,BYTE PTR DS:[EAX]
            004022D3   .  0FB601        MOVZX EAX,BYTE PTR DS:[ECX]
            004022D6   .  3A842A 78FFFF>CMP AL,BYTE PTR DS:[EDX+EBP-88]          ;  對比第25位注冊碼
            004022DD   .  74 0F         JE SHORT <FScrackm.loc_4022EE>
            ...
            00402474   .  83C2 19       ADD EDX,19
            00402477   .  8B85 50FFFFFF MOV EAX,DWORD PTR SS:[EBP-B0]
            0040247D   .  3802          CMP BYTE PTR DS:[EDX],AL                 ;  對比第26位注冊碼
            0040247F   .  74 07         JE SHORT <FScrackm.loc_402488>
            00402481   .  C745 94 00000>MOV DWORD PTR SS:[EBP-6C],0
            00402488 > >  8B45 0C       MOV EAX,DWORD PTR SS:[EBP+C]             
            0040248B   .  83C0 1A       ADD EAX,1A
            0040248E   .  8038 44       CMP BYTE PTR DS:[EAX],44                 ;  對比第27位注冊碼是否為“D”
            00402491   .  74 07         JE SHORT <FScrackm.loc_40249A>
            ...
            0040249A > > \837D 14 1B    CMP DWORD PTR SS:[EBP+14],1B             ;  對比注冊碼長度是否為27位
            0040249E   .  74 0C         JE SHORT <FScrackm.loc_4024AC>

            ==================================================================================================


                我們主要是討論寫注冊機,所以算法具體不去討論。我們現(xiàn)在所知道的是,用戶名要大于三位,注冊碼必須為27位,而且我們知道了每個注冊碼比較的地方。CALL 00401C9E里面是具體的算法,里面還有很多子函數(shù),想提取這樣一個含有很多子程序的代碼到注冊機里在OD中好象沒有好的方法,只有手動提,而在IDA中就有辦法,這得益于最早由dreaman寫的提取函數(shù)的腳本,我稱它為GetCall.IDC(http://bbs.pediy.com/showthread.php?s=&threadid=23231),在IDA中,只要將光標定位于一個函數(shù)的起始代碼,運行腳本后,它會截取所有該函數(shù)的代碼,包括里面所有的子函數(shù)代碼,并在文件目錄保存匯編代碼為一個ASM文件。真是太方便了。讓我們行動。
            IDA反匯編FScrackme2,“G”到401C9E,菜單“文件”-“IDC文件”,運行腳本。FScrackme2目錄中已經(jīng)生成了FScrackme2Part.asm。但是在這之前,對于這個軟件,需要在IDA中動動手腳。因為軟件是GCC寫的,IDA的腳本gcc32rtf.sig自動把GCC的庫函數(shù)識別出來了:
            .text:00401DCF                 call    __Znaj

                這本來是個好事,我也想找GCC的運行庫,然后將它轉(zhuǎn)換成MASM的庫文件,這樣,這些CALL就可以直接在MASM中引用了,寫注冊機就非常方便了。但是找不到這樣的運行庫。而GetCall.IDC腳本只要碰到被IDA識別出來的函數(shù),它就不進去拷里面的子函數(shù),所以,解決方法只有一個,將IDA中的SIG文件夾下的gcc32rtf.sig文件刪除,再讓IDA反匯編FScrackme2,再拷CALL 401C9E里的代碼。這樣拷出來的的子函數(shù)就比較全了。(當然我也把所有的GCC的庫函數(shù)提取出來做個備份,誰需要的話跟我聯(lián)系。)
            現(xiàn)在就已經(jīng)把代碼全部拷出到FScrackme2Part.asm了,我們不管三七二十一先把這段匯編代碼拷到一個匯編注冊機模板里再說,就是上次那個模板,當然這樣在RADASM中運行,錯誤會非常多,有錯就改嘛,中國人的好作風。
            因為是C語言類的,所以不可避免的用到C運行庫msvcrt.dll。所以看到匯編代碼中很多對msvcrt的調(diào)用,比如:
            .text:00401F8B                 call    isalpha
            .text:00401D14                 call    isalnum

                先解決這個問題。有了上篇的文章,這已經(jīng)不是問題了,用Dll2inc將msvcrt.dll轉(zhuǎn)換為MASM的msvcrt.lib和msvcrt.inc文件,然后在匯編代碼中調(diào)用這兩個文件。這樣就可以直接在匯編中調(diào)用msvcrt的庫函數(shù)了。
            然后繼續(xù)讓RADASM找出錯誤,一步一步來解決,一般的方法是將RADASM中的錯誤提示地址復制出來,在IDA中G到該地址,看數(shù)據(jù)是屬于哪個段的,如果是.text可執(zhí)行代碼段的子函數(shù),就用GetCall腳本復制出來粘貼到匯編代碼區(qū),如果是.bss、.rdata、.data 等數(shù)據(jù)段,就拷貝到匯編代碼的.DATA區(qū),LINUX中還會出現(xiàn).stab .stabstr .comment .note .shstrtab .symtab .strtab,不過這些都沒用。我想在下篇結(jié)束篇專門寫如何從IDA中拷代碼,結(jié)合具體實例講的詳細些。在這里,拷好的代碼就看附件中的注冊機代碼。
            拷好并修改好后這儼然是用匯編代碼仿制FScrackme2,但是文件大小比原來小了N倍,執(zhí)行速度也快了不少。
            做成個仿制FScrackme2還不行,我們是要做它的注冊機。
            很多crackme都可以通過用戶名算出個結(jié)果,然后將注冊碼也通過運算得到這個結(jié)果,那就可以通過注冊碼算法的逆運算推出真實的注冊碼。
            但是這個crackme是個正向的,它就是通過運算得到一個個注冊碼,然后將輸入的注冊碼也一一對比。

            +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            對于這種crackme寫注冊機時我提供一種解決思路,就是制造一個“偽注冊碼”,然后將程序里算出的一個個真實的注冊碼重新存到一個地方,這個地方的字符串就是真的注冊碼了。
            +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                首先說偽注冊碼,只要符合條件的任何字符都行。我這里為了減少彎路,根據(jù)軟件的要求:第12到17位必須為大寫字母,第18位和第24位必須為數(shù)字,我提供個名稱為TEMP的偽注冊碼:12345678901ABCDEF123456789D:
            .data
            Temp            db '12345678901ABCDEF123456789D',0

            我將一個個真實的注冊碼存到SerialBuffer中:
            invoke SetDlgItemText,hDlg,IDC_SERIAL,addr SerialBuffer

            其次要將所有對比注冊碼的地方都改為移動真實的注冊碼到SerialBuffer,并且將那些對比發(fā)生錯誤跳轉(zhuǎn)到退出的地方都“爆掉”,相當于先爆破再復制代碼:
            cmp  byte ptr [eax],  4Eh                  ;對比第一位注冊碼是否為“N”
            mov      [SerialBuffer+0],4Eh                 ;將注冊碼第一位“N”寫回
            jmp  short loc_401D4A                     ;避免退出,原來是je  401D4A    

            再次要注意原來程序中循環(huán)取輸入的注冊碼進行對比的地方,我們要將它改為循環(huán)存儲到SerialBuffer中,這就需要個累計參數(shù),可以利用原程序中循環(huán)的時候?qū)Ρ仁欠裱h(huán)完的那個參數(shù),用那個非常爽:
            mov  [ebp+var_8C], 1

            cmp  [ebp+var_8C], 6                                                ;是否取完
            ….
            mov  al,  [edx]                              ;對比第18位后的6位注冊碼
            xor      ecxecx
            mov      cl,  byte ptr [ebp+var_8C]          ;循環(huán)中的對比參數(shù)
            mov      [SerialBuffer+ecx+10h],al               ;寫回第18位后的6位注冊碼
            jmp  short loc_402223                ;避免退出
            mov  [ebp+var_B4], 1
            jmp  loc_4024C8                      ;跳到退出

            lea  eax, [ebp+var_8C]
            inc  dword ptr [eax]                 ;累計

            最后還有一點,就是用前面已經(jīng)計算出來的正確注冊碼來推算后面部分的注冊碼,這時,不能偽注冊碼來推算了,因為它本身是錯誤的,所以推算出來的后面部分也是錯的,要替換成真實的注冊碼,如:
            mov  eax, [ebp+arg_4]  ;注意這里,這里是將已算出的注冊碼第23位拿來運算,所以要改成:
            mov eaxoffset SerialBuffer  ;將已經(jīng)算出的注冊碼放到EAX,當然也包括已算出的第23位
            mov  [esp+0C8h+var_C8], eax
            call  sub_4024FE

            然后我們來看看原來程序取用戶名和注冊碼的過程,我們可以替換成取用戶名和偽注冊碼:
            00401B65  |.  894424 0C     MOV DWORD PTR SS:[ESP+C],EAX             ;  注冊碼長度
            00401B69  |.  8B45 A0       MOV EAX,[LOCAL.24]
            00401B6C  |.  894424 08     MOV DWORD PTR SS:[ESP+8],EAX             ;  用戶名長度
            00401B70  |.  8B45 A4       MOV EAX,[LOCAL.23]
            00401B73  |.  894424 04     MOV DWORD PTR SS:[ESP+4],EAX             ;  注冊碼ASCII
            00401B77  |.  8B45 EC       MOV EAX,[LOCAL.5]
            00401B7A  |.  890424        MOV DWORD PTR SS:[ESP],EAX               ;  用戶名ASCII
            00401B7D  |.  E8 1C010000   CALL <FScrackm.sub_401C9E>               ;  主要算法
            00401B82  |.  85C0          TEST EAX,EAX
            00401B84  |.  75 18         JNZ SHORT <FScrackm.loc_401B9E>          ;  判斷返回值是否為0

            只要改為:
            invoke lstrlenaddr Temp                          ;取偽注冊碼長度
            mov  [esp+98h+var_8C], eax      
            invoke lstrlenaddr NameBuffer                    ;取用戶名長度
            mov  [esp+98h+var_90], eax             
            mov  [esp+98h+var_94], offset Temp              ;裝入偽注冊碼
            mov  [esp+98h+var_98], offset NameBuffer        ;裝入用戶名
            call  sub_401C9E                                 ;調(diào)用算法CALL
            test  eaxeax
            jnz  loc_401B9E

                我們還可以利用原來注冊碼錯誤的對話框的地方來提示對用戶名各種限制,比如要求第一位和最后一位必須是字母等。
                這樣弄好后,到最后一位注冊碼算好,所有的真實注冊碼也就已經(jīng)全部存到SerialBuffer中了。
                如果還有錯誤,最好的辦法就是在RADASM中用OD調(diào)試跟蹤錯誤。
                注冊機的源代碼我已經(jīng)放在附件里,最好結(jié)合原程序看看。注冊機里我已經(jīng)做了比較詳細的注釋了。
                注冊機中的全部代碼都拷自FScrackme2在IDA中反匯編后的代碼,也就是幾乎全部是算法函數(shù)CALL 401C9E里的代碼。我盡量保持“原汁原味”,雖然有些代碼完全可以刪除,但是直接拷貝比判斷該刪除哪些要好。
                主要就是加入了存儲真實注冊碼的過程,看看每個注冊碼的存儲方法,慢慢體會。

            附件:單擊下載

            【版權(quán)聲明】: 本文原創(chuàng)于看雪技術(shù)論壇, 轉(zhuǎn)載請注明作者并保持文章的完整, 謝謝!

                                                                   2006年12月24日
                                                                                                                                   


            ©2000-2007 PEdiy.com All rights reserved.
            By PEDIY

            posted on 2008-01-24 12:00 tqsheng 閱讀(1977) 評論(0)  編輯 收藏 引用

            国产欧美久久一区二区| 国内精品久久久久影院网站| 欧美日韩中文字幕久久伊人| 久久精品人人做人人爽电影蜜月| 久久人与动人物a级毛片| 久久中文精品无码中文字幕| 青青久久精品国产免费看| 午夜精品久久久久久久无码| 国产日韩久久久精品影院首页| 久久久久亚洲精品天堂久久久久久 | 无码AV中文字幕久久专区| 麻豆一区二区99久久久久| 国产精品久久网| 久久久久亚洲AV成人网| 狠狠色丁香久久婷婷综合蜜芽五月 | 狠狠色丁香婷婷久久综合五月| 亚洲欧美国产日韩综合久久| 亚洲成色www久久网站夜月| 亚洲欧美伊人久久综合一区二区 | 久久精品国产精品亚洲精品| 久久91精品国产91久久户| 国产精品99久久久久久猫咪| 午夜精品久久久久久影视777| 日韩欧美亚洲综合久久影院Ds| 日韩人妻无码一区二区三区久久99 | 久久香综合精品久久伊人| 国产精品久久久久jk制服| 精品国产乱码久久久久久浪潮| 午夜精品久久影院蜜桃| 一本色道久久99一综合| 精品久久国产一区二区三区香蕉| 精品国产综合区久久久久久| 亚洲国产精品无码久久一线| 久久亚洲高清观看| 久久精品国产男包| 91精品国产91久久| 精品久久一区二区| 国产成人综合久久精品红| 国产精品九九九久久九九| 欧美一级久久久久久久大片| 7777久久亚洲中文字幕|