代碼還原的技術(shù): Unidbg調(diào)試浮點(diǎn)數(shù)運(yùn)算(一)

一、目標(biāo)

在做代碼還原的時(shí)候坛梁,經(jīng)常能看到一些奇怪的寄存器和奇怪的指令:

vldr s15, [r1]
vadd.f32 s15, s14, s15

很像某些流量明星而姐,看上去很眼熟,仔細(xì)看看又不認(rèn)識划咐。

它們就是傳說中的浮點(diǎn)數(shù)運(yùn)算拴念,今天我們來點(diǎn)亮一個(gè)很有用的技能樹: Unidbg調(diào)試浮點(diǎn)數(shù)運(yùn)算

二钧萍、步驟

先寫個(gè)floatdemo

有這么一個(gè)祖?zhèn)鞯乃惴ê瘮?shù)。

extern "C" JNIEXPORT jstring JNICALL
Java_com_fenfei_app_floatdemo_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject Obj, jdouble value) {
    std::string hello = "Hello from C++";

    double p=3.14159;
    double s,v,rc;

    v = 2*p*value;
    s = p*value*value;

    rc = v+s;

    hello = std::to_string(rc);

    return env->NewStringUTF(hello.c_str());
}

算出圓的周長和面積政鼠,然后再把它們相加风瘦。

高級語言就是好,一目了然公般。

IDA一把

floatone.png

可以看出兩個(gè)區(qū)別万搔, 一個(gè)是寄存器不一樣,普通運(yùn)算使用的寄存器是R0-Rx,浮點(diǎn)數(shù)運(yùn)算使用的是D0-Dx (其實(shí)還有 S0-Sx)官帘,另一個(gè)是指令不一樣瞬雹,普通運(yùn)算是MOV、MUL刽虹,而浮點(diǎn)數(shù)運(yùn)算使用的是VMOV酗捌,VMUL,感覺就是普通運(yùn)算的VIP版涌哲。

第一個(gè)知識點(diǎn)就出來了胖缤,V開頭的指令就是浮點(diǎn)數(shù)運(yùn)算指令,Dx Sx Qx 就是浮點(diǎn)數(shù)寄存器阀圾。

Unidbg亮相

按照 Unidbg模擬執(zhí)行某段子so實(shí)操教程(一) 先把框架搭起來 這個(gè)框架把我們剛才編譯的 floatdemo.apk 跑起來哪廓,然后增加一個(gè) stringFromJNI 函數(shù)的調(diào)用。

private String callfun(String methodSign, Object ...args) {
        DvmObject mainactivity = MainActivity_dvmclass.newObject(null);
        Object value = mainactivity.callJniMethodObject(emulator,methodSign,args).getValue();
        return value.toString();
}

由于 stringFromJNI 不是靜態(tài)(static)的類函數(shù),所以我們需要先創(chuàng)建個(gè)一個(gè) MainActivity 對象初烘,才可以調(diào)用它的方法撩独。

先跑一下看看結(jié)果

Find native function Java_com_fenfei_app_floatdemo_MainActivity_stringFromJNI(D)Ljava/lang/String; => RX@0x4000c6c9[libnative-lib.so]0xc6c9
JNIEnv->NewStringUTF("150.796320") was called from RX@0x4000c73d[libnative-lib.so]0xc73d
ret:150.796320
emulator destroy...

我們傳了個(gè)參數(shù)6,半徑是6的圓账月, 周長是 37.699综膀, 面積是113.097 ,它們之和是 150.796局齿。 結(jié)果沒毛病剧劝,那我們開始調(diào)試了。

Unidbg調(diào)試

從剛才運(yùn)行的結(jié)果里我們知道 stringFromJNI 函數(shù)的地址在 0xc6c9抓歼, 那么我們現(xiàn)在需要在這個(gè)地址下個(gè)斷點(diǎn)讥此,讓調(diào)試器停在這個(gè)地址。

Unidbg的調(diào)試功能依然很強(qiáng)大谣妻,它支持三種調(diào)試模式 CONSOLE萄喳、GDB和IDA,目前我用的順手的是 CONSOLE 模式蹋半,今天先介紹這個(gè)他巨。

開啟調(diào)試炒雞簡單,加上這兩行代碼就行

Debugger MyDbg = emulator.attach(DebuggerType.CONSOLE);
MyDbg.addBreakPoint(module.base + 0xc6c9);

運(yùn)行一下,就順利的進(jìn)入到調(diào)試器命令行了染突,直接回車捻爷,會顯示目前支持的調(diào)試命令。

debugone.png

我們是新手嘛份企,先掌握一個(gè)n和s兩個(gè)命令就行了也榄,n是單步步過,就是執(zhí)行一條指令司志,步過函數(shù)調(diào)用甜紫;s是單步步入,就是執(zhí)行一條指令骂远,進(jìn)入函數(shù)調(diào)用囚霸。

n命令跑幾下來到我們要分析的浮點(diǎn)數(shù)運(yùn)算的位置,發(fā)現(xiàn)尷尬了……

Unidbg調(diào)試器只顯示了Rx寄存器吧史,沒有顯示Dx系列的寄存器,這下怎么分析唠雕,不能盲摸呀贸营?

打開Unidbg浮點(diǎn)數(shù)寄存器顯示

Unidbg是支持浮點(diǎn)數(shù)運(yùn)算模擬的,那么一定是有地方去讀取浮點(diǎn)數(shù)寄存器的岩睁,只是沒有顯示出來而已钞脂。

我們先分析下Unidbg調(diào)試時(shí)寄存器顯示部分的代碼。

先搜索 r0= 在哪里處理的捕儒?

armjava.png

showRegs 就是顯示寄存器冰啃, 當(dāng)參數(shù)為null的時(shí)候,通過 ARM.getAllRegisters 來顯示所有的寄存器刘莹。但是為啥沒有顯示浮點(diǎn)寄存器呢阎毅?奇怪。

我們再往下翻点弯,發(fā)現(xiàn)在ARM64的模擬下顯示了Q0-Q31寄存器扇调,通過查閱資料,我們知道了原來它們都是一伙的抢肛。

d0.png

那ARM32先放一下狼钮,我們把模擬環(huán)境切換到ARM64

emulator = AndroidEmulatorBuilder.for64Bit().setProcessName("com.fenfei.runfloatdemo").build(); // 創(chuàng)建模擬器實(shí)例,要模擬32位或者64位捡絮,在這里區(qū)分

再跑一下熬芜,調(diào)試器沒有激活?

這是為什么福稳? 原來我們把模擬器從Arm32切換到了Arm64涎拉,那么載入的so就是64位的了,所以 stringFromJNI 函數(shù)的地址也變了,需要把斷點(diǎn)下在新的地址 0x12738 上面曼库。

qreg.png

這下不一樣了区岗,浮點(diǎn)寄存器都顯示出來了。

優(yōu)化一下浮點(diǎn)寄存器的顯示

李老板: 奮飛呀毁枯,這個(gè)0x400921f9f01b866e是啥意思呀慈缔,你是不是搞錯(cuò)了,浮點(diǎn)數(shù)寄存器顯示的咋不是 3.14159 ,而是這個(gè)亂七八糟的數(shù)據(jù)种玛?

奮飛: 老板藐鹤,程序員的母語就是16進(jìn)制,沒有一眼把 0x400921f9f01b866e 認(rèn)出是 3.14159的赂韵,晚飯是不配加雞腿的娱节,也不配變禿的。

有理想的同學(xué)請自行搜索 IEEE754 二進(jìn)制浮點(diǎn)數(shù)算術(shù)標(biāo)準(zhǔn)

其他的同學(xué)請和我一起優(yōu)化下浮點(diǎn)寄存器的顯示祭示。

由于飛哥目前為止還沒有變禿肄满,確實(shí)也看不出來這玩意就是 3.14159, 只好另辟蹊徑,給大家傳授一個(gè)神奇的函數(shù):

public static double bytes2Double(byte[] arr) {
    long value = 0;
    for (int i = 0; i < 8; i++) {
        value |= ((long) (arr[i] & 0xff)) << (8 * i);
    }
    return Double.longBitsToDouble(value);
}


// 在showRegs64函數(shù)里面加個(gè)顯示
case Arm64Const.UC_ARM64_REG_Q0:
    byte[] data = backend.reg_read_vector(reg);

    double bOut = bytes2Double(data);

    if (data != null) {
        builder.append("\n>>>");
        builder.append(String.format(Locale.US, " q0=0x%s(%.3f)", newBigInteger(data).toString(16),bOut));
    }
    break;

科學(xué)研究表明:在沒有變禿的前提下质涛,我們依然有機(jī)會變強(qiáng)稠歉。

floatshow.png

其實(shí)C/C++ 有個(gè)神奇的玩意叫指針,這種顯示一把梭就行

BYTE dPiByte[8] = {0x6e, 0x86, 0x1b, 0xf0, 0xf9, 0x21, 0x09, 0x40 };
double dPi = *(double*)dPiByte;

好了汇陆,后面的幾步運(yùn)算就是乘乘加加了怒炸,同學(xué)你自己n幾下就ok了。

(此處應(yīng)有掌聲)

三毡代、總結(jié)

為什么要去調(diào)試阅羹,直接F5大法不香嗎?

現(xiàn)在Ollvm肆虐教寂,掌握一些手撕匯編的良方可保你無憂捏鱼。

為什么要用Unidbg去調(diào)試,IDA不香嗎酪耕?

悟空穷躁,等你遇上內(nèi)存防修改,無法下軟件斷點(diǎn)和一些BT的反調(diào)試的時(shí)候因妇,你自會回來和為師唱這首歌的: Only You ......

預(yù)告一下问潭,下一篇是開啟Arm32下的浮點(diǎn)數(shù)寄存器顯示和TraceCode

ffshow.jpeg

知道為何自古紅顏多薄命嗎?因?yàn)闆]人在意丑的人活多久婚被。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末狡忙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子址芯,更是在濱河造成了極大的恐慌灾茁,老刑警劉巖窜觉,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異北专,居然都是意外死亡禀挫,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門拓颓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來语婴,“玉大人,你說我怎么就攤上這事驶睦∨樽螅” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵场航,是天一觀的道長缠导。 經(jīng)常有香客問我,道長溉痢,這世上最難降的妖魔是什么僻造? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮孩饼,結(jié)果婚禮上髓削,老公的妹妹穿的比我還像新娘。我一直安慰自己捣辆,他們只是感情好蔬螟,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布此迅。 她就那樣靜靜地躺著汽畴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪耸序。 梳的紋絲不亂的頭發(fā)上忍些,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機(jī)與錄音坎怪,去河邊找鬼罢坝。 笑死,一個(gè)胖子當(dāng)著我的面吹牛搅窿,可吹牛的內(nèi)容都是我干的嘁酿。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼男应,長吁一口氣:“原來是場噩夢啊……” “哼闹司!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起沐飘,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤游桩,失蹤者是張志新(化名)和其女友劉穎牲迫,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體借卧,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盹憎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了铐刘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陪每。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖滨达,靈堂內(nèi)的尸體忽然破棺而出奶稠,到底是詐尸還是另有隱情,我是刑警寧澤捡遍,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布锌订,位于F島的核電站,受9級特大地震影響画株,放射性物質(zhì)發(fā)生泄漏辆飘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一谓传、第九天 我趴在偏房一處隱蔽的房頂上張望蜈项。 院中可真熱鬧,春花似錦续挟、人聲如沸紧卒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽跑芳。三九已至,卻和暖如春直颅,著一層夾襖步出監(jiān)牢的瞬間博个,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工功偿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盆佣,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓械荷,卻偏偏與公主長得像共耍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子吨瞎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容