一枚KeyGenMe分析

一枚KeyGenMe分析

前言

玩CM的人好像很少,大家都缺乏熱情,小弟在此分析一枚,錯誤之處望各位大俠不吝指正。

“元旦佳節,難得有閒情逸致。品一杯香茗,看IDA中的彙編代碼。”
雖說是遲到的祝福,但這裏還是先祝各位朋友元旦快樂,願大家的技術蒸蒸日上,身體棒,棒,棒!在逆向這條荊棘密佈的道路上,難免遇到各種各樣的困難,有的甚至是看似不可逾越的鴻溝。但話又說回來,其實逆向這個領域,很多技術是相通的,思維方式更是相通的。
網上的資料並不少,教程和文章都很多,少的就是大家對一些新問題的思考,對一些知識的靈活運用和融會貫通。

初探加殼so

一般來說,我們從java層入手,在跟蹤某一個關鍵函數或者一個關鍵變量的時候,會跟到一個native的函數裏,這個時候就需要進入深邃的so。或許很多人會害怕so加殼,覺得那麼遙不可及。我們來揭開加殼後so的神祕面紗,讓大家對so加殼不再畏懼。
打開IDA定位到關鍵函數後:
這裏寫圖片描述

如圖,指令都被抹掉了,關鍵的函數完完全全被“清空”。
其他函數也一併被清空:
這裏寫圖片描述

卸下加殼so的外衣

儘管IDA加載的so裏面的指令都被清空了,但是有一條不變的宗旨。那就是這些代碼在執行之前肯定要解密的,解密的時候那就肯定在內存中,既然在內存中,我們就可以把它拿出來。
在關鍵函數段首下好斷點:
這裏寫圖片描述

IDA附加程序,出現same則點擊same對話框。接下來需要讓程序斷在我們的斷點處,代碼已經解密出來了:
這裏寫圖片描述
接下來用Ctrl+S 來定位一下該so在內存中的位置,用以下IDC腳本dump出來即可:

auto fp, SoAddress;
fp = fopen("D:\\unpack.so", "wb");
for ( SoAddress=0x51F6546C; SoAddress< 0x51F6B7B8; SoAddress++ )
fputc(Byte(SoAddress), fp);

脫殼前後對比

這裏寫圖片描述

左邊爲加殼後的指令,都被抹去
右邊爲脫殼後的指令,全部恢復

細心的讀者,肯定會發現,這和脫dex很相似,是的,這就是脫dex的方法在脫so殼上的再利用。

So裏面遨遊

在check函數裏面:
這裏寫圖片描述

可以看到最後對比的字符串爲:XVccAwVbVQQE
我們從最後開始往前推到。
轉換成相對應的Hex如下:
0x58 0x56 0x63 0x63

0x41 0x77 0x56 0x62

0x56 0x51 0x51 0x45

這些Hex的值怎麼算出來的呢?繼續往前看:
在base64encode函數中:
這裏寫圖片描述

一共12個值,通過num2base64char函數,循環3次,每次4個值。
進入num2base64char函數裏看算法:
這裏寫圖片描述

貼一段轉換後的java代碼:
public static int NumToChar(int a1){
{
int v2 ;
if ( a1 <= 0x19 ) //65到90
return (a1 + 65);
if ( a1 <= 0x33 )//
return (a1 + 71);//71到122
if ( a1 <= 0x3D )//61-4
return (a1 - 4);
v2 = 43;
if ( a1 != 62 )
{
if ( a1 == 63 )
{
v2 = 47;
}
else if ( a1 == 64 )
{
v2 = 61;
}
}
return v2;
}
根據這段算法逆推出Numtochar之前的Hex爲:
0x17 0x15 0x1c 0x1c

0x00 0x30 0x15 0x1b

0x15 0x10 0x10 0x04

繼續向前看,找出這12個Hex的值是如何來的:
這裏寫圖片描述
圖中紅框的函數爲關鍵函數,進去看一下:
這裏寫圖片描述

傳入3個參數,生成了4個結果。所以之前的12個Hex的值應該是3組3位的Hex值生成的,根據算法,解密程序如下:

        int x ,y ,z ,four1,four2,four3,four4;
        for(x=0;x<=0xff;x++){
            for(y=0;y<=0xff;y++){
                for(z=0;z<=0xff;z++){
                    four1 = x>>2;
                    four2 = (16 * x & 0x30) + (y >> 4);
                    four3 = (4 * y & 0x3C) + (z >> 6);
                    four4 = z & 0x3F;
                    if(four1==0x15 && four2==0x10 &&  four3==0x10 && four4==0x04){
                        System.out.println("X:0x"+Integer.toHexString(x)+" Y:0x"+Integer.toHexString(y)+" Z:0x"+Integer.toHexString(z));
                    }
                }
            }
        }

得出3組3位的Hex值如下:
0x5d 0x57 0x1c
0x03 0x05 0x5b
0x55 0x04 0x04
再往前就是java層了:只要傳入的字符串爲以下Hex則成功:
16進制:5d 57 1c 03 05 5b 55 04 04

| |
| |

\ /
\/

JAVA層
JAVA層的加密函數爲:

 public static String Encrpt(String arg9, String arg10) {
            String v0_2;
            String v1 = null;
            if(arg9 != null && arg10 != null) {
                try {
                    char[] v2 = arg10.toCharArray();
                    char[] v3 = arg9.toCharArray();
                    int v4 = v3.length; //v4 =9
                    int v5 = v2.length;
                    char[] v6 = new char[v4];
                    int v0_1;
                    for(v0_1 = 0; v0_1 < v4; ++v0_1) {
                        System.out.println((int)(v3[v0_1])+" ^ "+(int)v2[v0_1 % v5]);
                        v6[v0_1] = ((char)(v3[v0_1] ^ v2[v0_1 % v5]));
                    }

                    v0_2 = new String(v6);
                }
                catch(Exception v0) {
                    v0.printStackTrace();
                    v0_2 = v1;
                }
            }
            else {
                v0_2 = v1;
            }
            return v0_2;
        }
        public static String toHexString(String s) {
            String str = "";
            for (int i = 0; i < s.length(); i++) {
                int ch = (int) s.charAt(i);
                String s4 = Integer.toHexString(ch);
                System.out.println((i+1)+": 0x"+s4);
                str = str + s4;
            }
            return str;
        }

運算都是異或加密,逆運算就是結果與key再異或回來,而key在Java層已經可以知道,爲”52pojie”,所以異或回來的答案如下:
Answer:104 101 108 108 111 50 48 49 54

最後再查一下ASCII碼錶得出答案爲:hello2016
驗證一下:

這裏寫圖片描述

總結
希望通過對這篇文章閱讀,你已經對so不再恐懼了。再次祝大家2016年有新的收穫!

2016年元旦

By Ericky

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章