• <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, 評(píng)論 - 101, 引用 - 0
            數(shù)據(jù)加載中……

            從IDA中提取代碼做匯編注冊(cè)機(jī)之C/C++篇

            標(biāo) 題: 從IDA中提取代碼做匯編注冊(cè)機(jī)之C/C++篇
            作 者: laomms
            時(shí) 間: 2006-12-22 23:22
            鏈 接: http://bbs.pediy.com/showthread.php?threadid=36799
            詳細(xì)信息:

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

            先來分析程序,找到真正的注冊(cè)碼并不難,OD中的算法部分:
            00401AE7  |.  8945 9C       MOV [LOCAL.25],EAX                       ; |
            00401AEA  |.  837D A0 03    CMP [LOCAL.24],3                         ; |用戶名長(zhǎng)度必須大于3位
            00401AEE  |.  0F8E C2000000 JLE <FScrackm.loc_401BB6>                ; |
            00401AF4  |.  837D 9C 1A    CMP [LOCAL.25],1A                        ; |注冊(cè)碼長(zhǎng)度必須大于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             ;  注冊(cè)碼長(zhǎng)度
            00401B69  |.  8B45 A0       MOV EAX,[LOCAL.24]
            00401B6C  |.  894424 08     MOV DWORD PTR SS:[ESP+8],EAX             ;  用戶名長(zhǎng)度
            00401B70  |.  8B45 A4       MOV EAX,[LOCAL.23]
            00401B73  |.  894424 04     MOV DWORD PTR SS:[ESP+4],EAX             ;  注冊(cè)碼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                 ;  對(duì)比第一位注冊(cè)碼是否為“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                 ;  對(duì)比第二位注冊(cè)碼是否為“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                 ;  對(duì)比第三位注冊(cè)碼是否為“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                 ;  對(duì)比第四位注冊(cè)碼是否為“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]              ;  對(duì)比第5位開始5位注冊(cè)碼
            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]                 ;  對(duì)比第10位注冊(cè)碼
            00401EFB   .  74 0F         JE SHORT <FScrackm.loc_401F0C>
            ...
            00401F4A   .  83C2 0A       ADD EDX,0A
            00401F4D   .  8B85 70FFFFFF MOV EAX,DWORD PTR SS:[EBP-90]            ;  對(duì)比第11位注冊(cè)碼...
            00401F8B   .  E8 30420000   CALL <FScrackm.isalpha>                  ; 第12位后6位注冊(cè)碼,必須為字母
            ..
            00401FB5   .  E8 F6410000   CALL <FScrackm.isupper>                  ; 第12位后6位注冊(cè)碼,必須大寫
            ...
            0040205F   .  83C0 0A       ADD EAX,0A                               ;  第10位后
            00402075   .  0FBEC0        MOVSX EAX,AL
            00402078   .  39C1          CMP ECX,EAX                              ;  對(duì)比第11位開始3位的注冊(cè)碼
            0040207A   .  74 0F         JE SHORT <FScrackm.loc_40208B>
            ...
            004020B1   .  0FBEC0        MOVSX EAX,AL
            004020B4   .  39C1          CMP ECX,EAX                              ;  對(duì)比第17位開始倒數(shù)3位的注冊(cè)碼
            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]                 ;  對(duì)比第18位后的6位注冊(cè)碼
            00402212   .  74 0F         JE SHORT <FScrackm.loc_402223>
            ...
            00402230   .  83C0 17       ADD EAX,17
            00402233   .  8038 2D       CMP BYTE PTR DS:[EAX],2D                 ;  對(duì)比第24位注冊(cè)碼,必須為“-”號(hào)
            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]          ;  對(duì)比第25位注冊(cè)碼
            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                 ;  對(duì)比第26位注冊(cè)碼
            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                 ;  對(duì)比第27位注冊(cè)碼是否為“D”
            00402491   .  74 07         JE SHORT <FScrackm.loc_40249A>
            ...
            0040249A > > \837D 14 1B    CMP DWORD PTR SS:[EBP+14],1B             ;  對(duì)比注冊(cè)碼長(zhǎng)度是否為27位
            0040249E   .  74 0C         JE SHORT <FScrackm.loc_4024AC>

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


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

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

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

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

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

            我將一個(gè)個(gè)真實(shí)的注冊(cè)碼存到SerialBuffer中:
            invoke SetDlgItemText,hDlg,IDC_SERIAL,addr SerialBuffer

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

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

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

            lea  eax, [ebp+var_8C]
            inc  dword ptr [eax]                 ;累計(jì)

            最后還有一點(diǎn),就是用前面已經(jīng)計(jì)算出來的正確注冊(cè)碼來推算后面部分的注冊(cè)碼,這時(shí),不能偽注冊(cè)碼來推算了,因?yàn)樗旧硎清e(cuò)誤的,所以推算出來的后面部分也是錯(cuò)的,要替換成真實(shí)的注冊(cè)碼,如:
            mov  eax, [ebp+arg_4]  ;注意這里,這里是將已算出的注冊(cè)碼第23位拿來運(yùn)算,所以要改成:
            mov eaxoffset SerialBuffer  ;將已經(jīng)算出的注冊(cè)碼放到EAX,當(dāng)然也包括已算出的第23位
            mov  [esp+0C8h+var_C8], eax
            call  sub_4024FE

            然后我們來看看原來程序取用戶名和注冊(cè)碼的過程,我們可以替換成取用戶名和偽注冊(cè)碼:
            00401B65  |.  894424 0C     MOV DWORD PTR SS:[ESP+C],EAX             ;  注冊(cè)碼長(zhǎng)度
            00401B69  |.  8B45 A0       MOV EAX,[LOCAL.24]
            00401B6C  |.  894424 08     MOV DWORD PTR SS:[ESP+8],EAX             ;  用戶名長(zhǎng)度
            00401B70  |.  8B45 A4       MOV EAX,[LOCAL.23]
            00401B73  |.  894424 04     MOV DWORD PTR SS:[ESP+4],EAX             ;  注冊(cè)碼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                          ;取偽注冊(cè)碼長(zhǎng)度
            mov  [esp+98h+var_8C], eax      
            invoke lstrlenaddr NameBuffer                    ;取用戶名長(zhǎng)度
            mov  [esp+98h+var_90], eax             
            mov  [esp+98h+var_94], offset Temp              ;裝入偽注冊(cè)碼
            mov  [esp+98h+var_98], offset NameBuffer        ;裝入用戶名
            call  sub_401C9E                                 ;調(diào)用算法CALL
            test  eaxeax
            jnz  loc_401B9E

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

            附件:單擊下載

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

                                                                   2006年12月24日
                                                                                                                                   


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

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


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            亚洲国产成人久久综合一| 国产成人综合久久综合| 大美女久久久久久j久久| 亚洲精品无码久久久久去q| 欧美成人免费观看久久| 久久久久国产精品麻豆AR影院| 久久精品国产69国产精品亚洲| 久久水蜜桃亚洲av无码精品麻豆| 无码精品久久久天天影视| 久久久久久久精品成人热色戒| 久久国内免费视频| 午夜精品久久久内射近拍高清| 久久午夜综合久久| 亚洲精品无码专区久久同性男| 久久久久婷婷| 亚洲日本久久久午夜精品| 久久天天婷婷五月俺也去| 国产精品99久久久久久宅男小说| 亚洲欧洲中文日韩久久AV乱码| 中文字幕精品久久| 精品久久久无码人妻中文字幕 | 久久精品黄AA片一区二区三区| 午夜久久久久久禁播电影| 久久亚洲国产成人精品性色| 成人资源影音先锋久久资源网| 99久久综合国产精品二区| 久久亚洲AV无码西西人体| 久久这里只精品99re66| 人妻精品久久久久中文字幕69| 99久久超碰中文字幕伊人| 国产午夜精品久久久久九九| 久久精品国产精品亚洲下载| 亚洲а∨天堂久久精品| 久久久久99精品成人片试看| 国产精品狼人久久久久影院| 中文字幕无码久久人妻| 久久午夜无码鲁丝片| 99久久精品免费看国产| 亚洲人成无码久久电影网站| 久久久久国产精品熟女影院| 久久精品二区|