android逆向奇技淫巧二十二:ida棧回溯加密算法跟蹤(未完待續)(七)


  1、上次通過hook registerNativeMethod找到了metasec種唯一注冊的jni函數,本想着通過trace call來看看到底這個函數層層調用了哪些函數,結果trace出來的結果完全是錯的(用hook到的地址調用findModuleByAddress確認哪個so,直接報異常!),stalker trace call的代碼:

function trace_entry(tatgetAddr){
    //var addr_1094d = targetSo.add(0x1094c+1);
    Interceptor.attach(tatgetAddr, {
        onEnter: function(args){
            console.log("enter tatgetAddr====================================================================");
            this.pid = Process.getCurrentThreadId();
            Stalker.follow(this.pid,{
                events:{
                    call:true,
                    ret:false,
                    exec:false,
                    block:false,
                    compile:false
                },
                onReceive:function(events){
                    var all_events = Stalker.parse(events);
                    console.log("on Received:",all_events.length);
                    for(var i=0;i<all_events.length;i++){
                        //console.log(all_events[i]);
                        var type=all_events[i][0];
                        if(type=="call"){
                            var addr1 = all_events[i][i];
                            try{
                                var module1=Process.findModuleByAddress(addr1);
                                if(module1!=null&&module1.name=="libmetasec_ml.so"){
                                    var addr2=all_events[i][2];
                                    var module2=Process.findModuleByAddress(addr2);
                                    console.log("call:",module1.name+"!"+addr1.sub(module1.base),module2.name+"!"+addr2.sub(module2.base));
                                }
                            }catch(error){
                                console.log("exception error:",error);   
                                console.log(all_events[i]);
                            }
                        }
                    }
                },
                onCallSummary:function(summary){
                    
                }
            });
        },onLeave: function(retval){
            Stalker.unfollow(this.pid);
            console.log("retval:"+retval);
            console.log("leave tatgetAddr====================================================================");
        }
    });
}

function main(){
    var targetSo = Module.findBaseAddress('libmetasec_ml.so');      
    //var targetSo = new NativePointer(0x4200000);   
    var tatgetAddr = targetSo.add(0x1096C+1);
    //var tatgetAddr = targetSo.add(0x6221c+1);
    trace_entry(tatgetAddr);
}

setImmediate(main);

  其他app的trace是ok的,這里不行,大概率有反frida的跟蹤;

console.log('called from:\n' +Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n')

  用上面這個hook sub_6221c(就是調用base64碼表的關鍵函數)的結果如下:

sub_6221c called from:
0xb4cc14a3 libmetasec_ml.so!0x6c4a3
0xb4cc14a3 libmetasec_ml.so!0x6c4a3
0xb4c8a0d3 libmetasec_ml.so!0x350d3
0xb4c8bcf0 libmetasec_ml.so!0x36cf0

       太少了,根本找不出啥!無奈只能老老實實繼續用ida在sub_6221c下斷點,自己在棧上和LR上回溯;這里也看出一點:frida的trace在x音這里失效了,估計是有反調試吧!

    自己用ida根據棧回溯時遇到的問題:(1)x86有ebp作為棧幀,ebp+4就是返回地址;但arm沒有,只能自己在棧上挨個找!如果棧上的地址在代碼中是BL或BLX的下一行,就可以確認是函數調用關系了!如果不是在BL或BLX后面,可能是個局部變量或參數,暫時就不管了!   (2)ida有些地址反編譯失敗,棧上有的地址在debug view時只能看到一堆“數據塊”,如下(這種塊太多了,這里只貼部分):

text:00034DE9 46 08 46        byte_34DE9      DCB 0x46, 8, 0x46       ; DATA XREF: sub_2F9A0+14↑o
.text:00034DE9                                                         ; sub_2F9A0+1E↑o ...
.text:00034DEC 10 47 D0 E9+                    DCD 3922741008, 1753362688, 4031727128, 3045112139, 553707984
.text:00034DEC 00 31 82 68+                    DCD 4158473744, 3179346797, 1174713616, 4158482464, 1616967697
.text:00034DEC 18 46 4F F0+                    DCD 3037773072, 1746945540, 4212848602, 3171967072, 1174713616
.text:00034DEC 4B B9 80 B5+                    DCD 4220842046, 3171967008, 3922769280, 1175462144, 4286904302
.text:00034DEC D0 E9 00 21+                    DCD 3037773184, 1746945540, 4267767802, 3171971360, 3922769280
.text:00034DEC 10 46 DD F7+                    DCD 1175462144, 4219009018, 3044064640, 1747338756, 4158397744
.text:00034DEC 6D FB 80 BD+                    DCD 1753284583, 2970100992, 3178262821, 4518150, 4292802524
.text:00034DEC 10 B5 04 46+                    DCD 671115392, 620871624, 3178262821, 536930768, 22343936

  剛開始沒太在意,覺得應該是ida解析出錯(有可能是故意加花指令“誤導”IDA的),直到有一次又遇到signal報錯:C18C31CC: got SIGSEGV signal (Segmentation violation) (exc.code b, tid 21480);我已經掛起了其他線程,這個signal是誰、怎么發出來的了?難道還有其他進程給主進程發signal?好在這里提示了報錯的地址,用這個地址減去metasec_ml的基址,得到0x351CC的偏移,剛好在上面這個數據塊內部;嘗試繼續用C或P,果然能正常識別成代碼!猜測這里是故意讓ida不識別,或則把這段內存設置成不可執行;一旦檢測到ida在調試,想辦法讓代碼跳轉到這里(代碼內部有很多間接跳轉,也就跳轉地址放在寄存器,這樣一來跳轉地址就不用寫死了,可根據實際情況決定跳轉位置,也能防止IDA的交叉引用功能查詢,絕啊!),產生異常報錯! 程序退出也是操作系統的行為,自生並未直接調用exit這類的函數,逆向人員不容易捕捉!

  2、這里繼續用ida棧回溯,我個人的一些心得和技巧:

  (1)棧上凡是標記了紅框框這種的建議去源碼看看,凡是在BL或BLX代碼下一行的都是函數調用,建議下斷點嘗試!

          

       (2)寄存器重點監控兩類:malloc和heap!原因很簡單:數據要么存在stack,要么存heap,要么存操作系統的數據段;stack存的都是參數、返回地址、局部變了,函數調用一旦結束,這部分空間就釋放了,沒法繼續使用操作系統數據段存的都是全局變量和static變量,所以這4個字段肯定存在heap上!所以建議重點關注執行heap內存的寄存器,和保存malloc分配地址的寄存器

          

   (3)根據上面的一些小技巧,不停地在棧上回溯,挨個查找、下斷點調試(這里純粹就是體力活了),找到幾個新的地址:

  •  R1指向的地址包含了X-Argus和X-Gorgon兩個字段,代碼偏移:0x14204

   

  有時還能一次性出4個字段:

         

  在這附近,有時候還能一次集齊5個字段:偏移0x1424C

   

  這里看代碼更清晰:R1來自棧上,很有可能是C1A5D24C這里函數執行后保存在棧上sp+0x5c的!

        

  •        R1指向的地址包含了X-Gorgon,代碼偏移:0xD20C

        

       這里也能找到X-Argus:

        

  X-Tyhon也出現了:

  

  •   R1指向的地址包含了X-Argus,代碼偏移:0xD022

   

     同樣的偏移,R1指向了X-Ladon;從代碼看,地址來自傳入的R1;

         

    執行完 BLX    unk_C1A50690后,R0也指向了X-Tyhon:

    

   繼續往上根據函數調用關系找R1:發現來自R0;偏移:0x35008;這里的代碼看起來是不是有點奇怪了:

  •   每段代碼都是push開頭、pop結尾,經過多次調試觀察,每段代碼都被執行過,這里感覺有點像VMP的handler
  •        R2指向的是函數代碼入口,很有可能是通過BLX R2跳轉到這里的!通過寄存器的間接調用,可以防止在IDA通過xrefs查找調用關系,這是一絕啊!這該怎么繼續回溯了?看棧上我標紅的地址,從這里開始繼續回溯!

       

            果然是通過BX R2跳轉的!這里的offset:C1A7DDE8-C1A49000=0x34DE8;IDA在這里還標注了引用關系,順着這個繼續回溯!

            這里有點像VMP的入口,根據不同的R2跳轉到不同的地址(就是上面0x35008附近的代碼,每段代碼除了BL跳轉的地址不同,其他完全一樣)

            

       下面就是通過BX R2跳轉到不同的地址:

           

    接着BX R2的代碼回溯(ida已經標注了):這里多出取了PC的值,R1和R2指向了比較奇怪的字符串,R4和R6指向了代碼地址,這么做的動機暫時不明! 先記下offset: C1A7DD56-C1A49000=0x34D56

            

       其他重要偏移:0xD20E, 函數執行完后R1指向了X-argus:

       

    偏移:0xD220,BL執行完R1就保存了X-argus的地址!

            

            同樣的地方R1保存了X-Ladon:

            

            這幾天通過棧回溯,找到了一些線索!但感覺還是沒找到直接生成這些字段的代碼;在目前找到的這些關鍵函數中,還是要想辦法trace一下,或用unidbg執行試試,看看完整的代碼是怎么執行的!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM