寫在前面:
這次逆向?qū)崙?zhàn)其實(shí)是15年進(jìn)入公司后不久,某個(gè)項(xiàng)目需求得來的操作,當(dāng)時(shí)在Github文章寫了一半沒寫完,今天補(bǔ)充完畢,重新發(fā)出來算是給大家一個(gè)學(xué)習(xí)逆向基礎(chǔ)的參考_。
前言
“你學(xué)習(xí)一門技術(shù)的最佳時(shí)機(jī)是三年前,其次是現(xiàn)在?!?/p>
背景/目的
項(xiàng)目需求,需要根據(jù)手機(jī)端接收到的某心電寶測(cè)量的心電數(shù)據(jù)繪制相應(yīng)的心電圖,無奈數(shù)據(jù)是接收了,
卻不知道如何對(duì)數(shù)據(jù)進(jìn)行相應(yīng)的處理,瞎搞一通還是繪制不出來,只能傻臉了~
我們的參照App是某德康A(chǔ)pp,使用的是同一款心電寶,卻發(fā)現(xiàn)人家竟然能繪制!,舞草,好專業(yè)??!
既然正面得不到繪制原理對(duì)應(yīng)的代碼,那我就只好逆向xxoo你了,順帶踐行心生已久的跨入移動(dòng)安全這一深坑的想法。
嗯,所以這篇文章的目的呢,也就是實(shí)戰(zhàn)總結(jié),回顧,加深理解,基本掌握由smali代碼逆向出Java代碼。
知識(shí)點(diǎn)準(zhǔn)備
理解本篇內(nèi)容,需要你通讀并理解《Android軟件安全與逆向分析》一書的第一章、第二章、第三章、以及第五章5.6小節(jié)之前的全部內(nèi)容。
以下,為該書2013年2月份第一次印刷第一版電子版的研讀過程中我自己的書簽筆記,希望有助于你的理解,當(dāng)然,有錯(cuò)請(qǐng)指正。
P32,最后一段中,“第二條指令iload_2取第二個(gè)參數(shù)”,應(yīng)該為,“第二條指令iload_2取第三個(gè)參數(shù)”,
依據(jù)之前從“第二部分為下劃線右邊的數(shù)字,表示要操作具體哪個(gè)局部變量,索引值從0開始計(jì)數(shù)...”開始的指令含義介紹;
P33,第一段接上一頁的最后一句,“壓入第一個(gè)參數(shù)與第二個(gè)參數(shù)”,應(yīng)該為,“壓入第二個(gè)參數(shù)與第三個(gè)參數(shù)”;
P45,“注意”上面的一段中,倒數(shù)第二行,“AAAA/BBBB/CCCC/DDDD/EEEE/FFFF/GGGG/HHHH代表一個(gè)8位的數(shù)值”,
應(yīng)該為,“AAAA/BBBB/CCCC/DDDD/EEEE/FFFF/GGGG/HHHH代表一個(gè)16位的數(shù)值”
P46,3.3.3小節(jié)第十二行,“源寄存器為8位,目的寄存器為16位?!?,應(yīng)該為,“目的寄存器為8位,源寄存器為16位?!?/p>
P46,3.3.5小節(jié)第二行,“‘const/4 vA,#+B’將數(shù)值符號(hào)擴(kuò)展為32位后賦給寄存器vA?!?,對(duì)于“#+B”,
個(gè)人理解為在全書中的含義應(yīng)該都是表示一個(gè)常量,每一個(gè)大寫的字母表示4個(gè)位數(shù)。
至于“將數(shù)值符號(hào)擴(kuò)展為32位后”,我還是有點(diǎn)不太理解~
P53,第一段代碼中,本人在實(shí)際操作過程中發(fā)現(xiàn),".parameter"指令在JDK1.8且smali.jar版本為2.1.0的環(huán)境下不被識(shí)別,去掉就能正確編譯=_=||
P54,3.4.2小節(jié)那一條命令中,“classes.dex”,應(yīng)該為,“HelloWorld.dex”;
3.4.3小節(jié)那兩條命令中的“HelloWorld.zip”,應(yīng)該為,“HelloWorld.dex”;
第五章中提到的諸如sparse-switch-payload字段的格式定義內(nèi)容都可以暫時(shí)略過不看,以后回過頭來再研究吧。
逆smali得Java
samli目標(biāo)文件核心函數(shù)代碼
.method protected onDraw(Landroid/graphics/Canvas;)V
.locals 27
.param p1, "canvas" # Landroid/graphics/Canvas;
.prologue
.line 50
invoke-super/range {p0 .. p1}, Landroid/view/View;->onDraw(Landroid/graphics/Canvas;)V
.line 51
const/4 v2, -0x1
move-object/from16 v0, p1
invoke-virtual {v0, v2}, Landroid/graphics/Canvas;->drawColor(I)V
.line 53
new-instance v7, Landroid/graphics/Paint;
invoke-direct {v7}, Landroid/graphics/Paint;-><init>()V
.line 54
.local v7, "paint":Landroid/graphics/Paint;
const/4 v2, 0x1
invoke-virtual {v7, v2}, Landroid/graphics/Paint;->setAntiAlias(Z)V
.line 55
sget-object v2, Landroid/graphics/Paint$Style;->FILL:Landroid/graphics/Paint$Style;
invoke-virtual {v7, v2}, Landroid/graphics/Paint;->setStyle(Landroid/graphics/Paint$Style;)V
.line 58
const/4 v9, 0x0
.line 59
.local v9, "actulWidth":I
const/4 v8, 0x0
.line 60
.local v8, "actulHeight":I
const/16 v20, 0x0
.line 61
.local v20, "perUnitNum":I
const/16 v19, 0x0
.line 63
.local v19, "perMiniNum":I
move-object/from16 v0, p0
iget v2, v0, Lcom/mprc/bdk/ecgMeasurement/bluz/DrawHeart;->screenHeight:I
move-object/from16 v0, p0
iget v0, v0, Lcom/mprc/bdk/ecgMeasurement/bluz/DrawHeart;->screenWidth:I
move/from16 v25, v0
move/from16 v0, v25
if-le v2, v0, :cond_0
.line 67
const/16 v15, 0xa
.local v15, "i":I
:goto_0
const/16 v2, 0x64
if-lt v15, v2, :cond_1
.line 87
:goto_1
mul-int/lit8 v2, v20, 0x21
add-int/lit8 v9, v2, 0x4
.line 90
mul-int/lit8 v2, v20, 0x26
add-int/lit8 v8, v2, 0x4
.line 94
.end local v15 # "i":I
:cond_0
const/16 v2, 0xff
const/16 v25, 0xb4
const/16 v26, 0xb4
move/from16 v0, v25
move/from16 v1, v26
invoke-static {v2, v0, v1}, Landroid/graphics/Color;->rgb(III)I
move-result v2
invoke-virtual {v7, v2}, Landroid/graphics/Paint;->setColor(I)V
.line 95
add-int/lit8 v16, v19, 0x4
.local v16, "j":I
:goto_2
move/from16 v0, v16
if-lt v0, v9, :cond_4
.line 102
add-int/lit8 v15, v19, 0x4
.restart local v15 # "i":I
:goto_3
if-lt v15, v8, :cond_6
.line 110
const/high16 v2, -0x10000
invoke-virtual {v7, v2}, Landroid/graphics/Paint;->setColor(I)V
.line 111
const/16 v16, 0x4
:goto_4
move/from16 v0, v16
if-le v0, v9, :cond_8
.line 115
const/4 v15, 0x4
:goto_5
if-le v15, v8, :cond_9
.line 120
move-object/from16 v0, p0
iget-object v2, v0, Lcom/mprc/bdk/ecgMeasurement/bluz/DrawHeart;->list:Ljava/util/List;
invoke-interface {v2}, Ljava/util/List;->size()I
move-result v17
.line 121
.local v17, "length":I
div-int/lit8 v12, v17, 0x4
.line 122
.local v12, "firstlength":I
move v13, v12
.line 123
.local v13, "firstpioint":I
mul-int/lit8 v21, v12, 0x2
.line 124
.local v21, "secondpiont":I
mul-int/lit8 v22, v12, 0x3
.line 125
.local v22, "thirdpoint":I
const/high16 v2, 0x42180000 # 38.0f
move/from16 v0, v20
int-to-float v0, v0
move/from16 v25, v0
mul-float v2, v2, v25
int-to-float v0, v12
move/from16 v25, v0
div-float v23, v2, v25
.line 128
.local v23, "unitlength":F
const/high16 v2, -0x1000000
invoke-virtual {v7, v2}, Landroid/graphics/Paint;->setColor(I)V
.line 129
const/16 v16, 0x0
:goto_6
move/from16 v0, v16
if-lt v0, v13, :cond_a
.line 146
move/from16 v16, v13
:goto_7
move/from16 v0, v16
move/from16 v1, v21
if-lt v0, v1, :cond_b
.line 163
move/from16 v16, v21
:goto_8
move/from16 v0, v16
move/from16 v1, v22
if-lt v0, v1, :cond_c
.line 180
move/from16 v16, v22
:goto_9
add-int/lit8 v2, v17, -0x1
move/from16 v0, v16
if-lt v0, v2, :cond_d
.line 195
return-void
.line 69
.end local v12 # "firstlength":I
.end local v13 # "firstpioint":I
.end local v16 # "j":I
.end local v17 # "length":I
.end local v21 # "secondpiont":I
.end local v22 # "thirdpoint":I
.end local v23 # "unitlength":F
:cond_1
mul-int/lit8 v2, v15, 0x26
add-int/lit8 v14, v2, 0x4
.line 70
.local v14, "height":I
mul-int/lit8 v2, v15, 0x1c
add-int/lit8 v24, v2, 0x4
.line 71
.local v24, "width":I
move-object/from16 v0, p0
iget v2, v0, Lcom/mprc/bdk/ecgMeasurement/bluz/DrawHeart;->screenHeight:I
if-gt v14, v2, :cond_2
.line 73
add-int/lit8 v15, v15, 0x1
.line 74
goto/16 :goto_0
.line 77
:cond_2
rem-int/lit8 v18, v15, 0x5
.line 78
.local v18, "mode":I
if-nez v18, :cond_3
.line 79
add-int/lit8 v2, v15, -0x1
add-int/lit8 v25, v15, -0x1
rem-int/lit8 v25, v25, 0x5
sub-int v20, v2, v25
.line 80
div-int/lit8 v19, v20, 0x5
.line 81
goto/16 :goto_1
.line 84
:cond_3
add-int/lit8 v15, v15, 0x1
goto/16 :goto_0
.line 98
.end local v14 # "height":I
.end local v15 # "i":I
.end local v18 # "mode":I
.end local v24 # "width":I
.restart local v16 # "j":I
:cond_4
add-int/lit8 v2, v16, -0x4
sub-int v2, v2, v19
div-int v2, v2, v19
add-int/lit8 v2, v2, 0x1
rem-int/lit8 v18, v2, 0x5
.line 99
.restart local v18 # "mode":I
if-eqz v18, :cond_5
.line 100
move/from16 v0, v16
int-to-float v3, v0
const/high16 v4, 0x40800000 # 4.0f
move/from16 v0, v16
int-to-float v5, v0
int-to-float v6, v8
move-object/from16 v2, p1
invoke-virtual/range {v2 .. v7}, Landroid/graphics/Canvas;->drawLine(FFFFLandroid/graphics/Paint;)V
.line 95
:cond_5
add-int v16, v16, v19
goto/16 :goto_2
.line 104
.end local v18 # "mode":I
.restart local v15 # "i":I
:cond_6
add-int/lit8 v2, v15, -0x4
sub-int v2, v2, v19
div-int v2, v2, v19
add-int/lit8 v2, v2, 0x1
rem-int/lit8 v18, v2, 0x5
.line 105
.restart local v18 # "mode":I
if-eqz v18, :cond_7
.line 106
const/high16 v3, 0x40800000 # 4.0f
int-to-float v4, v15
int-to-float v5, v9
int-to-float v6, v15
move-object/from16 v2, p1
invoke-virtual/range {v2 .. v7}, Landroid/graphics/Canvas;->drawLine(FFFFLandroid/graphics/Paint;)V
.line 102
:cond_7
add-int v15, v15, v19
goto/16 :goto_3
.line 113
.end local v18 # "mode":I
:cond_8
move/from16 v0, v16
int-to-float v3, v0
const/high16 v4, 0x40800000 # 4.0f
move/from16 v0, v16
int-to-float v5, v0
int-to-float v6, v8
move-object/from16 v2, p1
invoke-virtual/range {v2 .. v7}, Landroid/graphics/Canvas;->drawLine(FFFFLandroid/graphics/Paint;)V
.line 111
add-int v16, v16, v20
goto/16 :goto_4
.line 117
:cond_9
const/high16 v3, 0x40800000 # 4.0f
int-to-float v4, v15
int-to-float v5, v9
int-to-float v6, v15
move-object/from16 v2, p1
invoke-virtual/range {v2 .. v7}, Landroid/graphics/Canvas;->drawLine(FFFFLandroid/graphics/Paint;)V
.line 115
add-int v15, v15, v20
goto/16 :goto_5
.line 132
.restart local v12 # "firstlength":I
.restart local v13 # "firstpioint":I
.restart local v17 # "length":I
.restart local v21 # "secondpiont":I
.restart local v22 # "thirdpoint":I
.restart local v23 # "unitlength":F
:cond_a
int-to-float v2, v8
move/from16 v0, v16
int-to-float v0, v0
move/from16 v25, v0
mul-float v25, v25, v23
sub-float v4, v2, v25
.line 133
.local v4, "pointy":F
move-object/from16 v0, p0
iget-object v2, v0, Lcom/mprc/bdk/ecgMeasurement/bluz/DrawHeart;->list:Ljava/util/List;
move/from16 v0, v16
invoke-interface {v2, v0}, Ljava/util/List;->get(I)Ljava/lang/Object;
move-result-object v2
check-cast v2, Ljava/lang/Integer;
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
move-result-object v2
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
int-to-float v10, v2
.line 134
.local v10, "datamv":F
mul-int/lit8 v2, v20, 0x9
add-int/lit8 v2, v2, 0x4
int-to-float v2, v2
move/from16 v0, v19
int-to-float v0, v0
move/from16 v25, v0
mul-float v25, v25, v10
const/high16 v26, 0x40880000 # 4.25f
div-float v25, v25, v26
sub-float v3, v2, v25
.line 137
.local v3, "pointx":F
int-to-float v2, v8
add-int/lit8 v25, v16, 0x1
move/from16 v0, v25
int-to-float v0, v0
move/from16 v25, v0
mul-float v25, v25, v23
sub-float v6, v2, v25
.line 138
.local v6, "pointy2":F
move-object/from16 v0, p0
iget-object v2, v0, Lcom/mprc/bdk/ecgMeasurement/bluz/DrawHeart;->list:Ljava/util/List;
add-int/lit8 v25, v16, 0x1
move/from16 v0, v25
invoke-interface {v2, v0}, Ljava/util/List;->get(I)Ljava/lang/Object;
move-result-object v2
check-cast v2, Ljava/lang/Integer;
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
move-result-object v2
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
int-to-float v11, v2
.line 139
.local v11, "datamv2":F
mul-int/lit8 v2, v20, 0x9
add-int/lit8 v2, v2, 0x4
int-to-float v2, v2
move/from16 v0, v19
int-to-float v0, v0
move/from16 v25, v0
mul-float v25, v25, v11
const/high16 v26, 0x40880000 # 4.25f
div-float v25, v25, v26
sub-float v5, v2, v25
.local v5, "pointx2":F
move-object/from16 v2, p1
.line 142
invoke-virtual/range {v2 .. v7}, Landroid/graphics/Canvas;->drawLine(FFFFLandroid/graphics/Paint;)V
.line 129
add-int/lit8 v16, v16, 0x1
goto/16 :goto_6
.line 149
.end local v3 # "pointx":F
.end local v4 # "pointy":F
.end local v5 # "pointx2":F
.end local v6 # "pointy2":F
.end local v10 # "datamv":F
.end local v11 # "datamv2":F
:cond_b
int-to-float v2, v8
sub-int v25, v16, v13
move/from16 v0, v25
int-to-float v0, v0
move/from16 v25, v0
mul-float v25, v25, v23
sub-float v4, v2, v25
.line 150
.restart local v4 # "pointy":F
move-object/from16 v0, p0
iget-object v2, v0, Lcom/mprc/bdk/ecgMeasurement/bluz/DrawHeart;->list:Ljava/util/List;
move/from16 v0, v16
invoke-interface {v2, v0}, Ljava/util/List;->get(I)Ljava/lang/Object;
move-result-object v2
check-cast v2, Ljava/lang/Integer;
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
move-result-object v2
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
int-to-float v10, v2
.line 151
.restart local v10 # "datamv":F
mul-int/lit8 v2, v20, 0xf
add-int/lit8 v2, v2, 0x4
int-to-float v2, v2
move/from16 v0, v19
int-to-float v0, v0
move/from16 v25, v0
mul-float v25, v25, v10
const/high16 v26, 0x40880000 # 4.25f
div-float v25, v25, v26
sub-float v3, v2, v25
.line 154
.restart local v3 # "pointx":F
int-to-float v2, v8
sub-int v25, v16, v13
add-int/lit8 v25, v25, 0x1
move/from16 v0, v25
int-to-float v0, v0
move/from16 v25, v0
mul-float v25, v25, v23
sub-float v6, v2, v25
.line 155
.restart local v6 # "pointy2":F
move-object/from16 v0, p0
iget-object v2, v0, Lcom/mprc/bdk/ecgMeasurement/bluz/DrawHeart;->list:Ljava/util/List;
add-int/lit8 v25, v16, 0x1
move/from16 v0, v25
invoke-interface {v2, v0}, Ljava/util/List;->get(I)Ljava/lang/Object;
move-result-object v2
check-cast v2, Ljava/lang/Integer;
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
move-result-object v2
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
int-to-float v11, v2
.line 156
.restart local v11 # "datamv2":F
mul-int/lit8 v2, v20, 0xf
add-int/lit8 v2, v2, 0x4
int-to-float v2, v2
move/from16 v0, v19
int-to-float v0, v0
move/from16 v25, v0
mul-float v25, v25, v11
const/high16 v26, 0x40880000 # 4.25f
div-float v25, v25, v26
sub-float v5, v2, v25
.restart local v5 # "pointx2":F
move-object/from16 v2, p1
.line 159
invoke-virtual/range {v2 .. v7}, Landroid/graphics/Canvas;->drawLine(FFFFLandroid/graphics/Paint;)V
.line 146
add-int/lit8 v16, v16, 0x1
goto/16 :goto_7
.line 166
.end local v3 # "pointx":F
.end local v4 # "pointy":F
.end local v5 # "pointx2":F
.end local v6 # "pointy2":F
.end local v10 # "datamv":F
.end local v11 # "datamv2":F
:cond_c
int-to-float v2, v8
sub-int v25, v16, v21
move/from16 v0, v25
int-to-float v0, v0
move/from16 v25, v0
mul-float v25, v25, v23
sub-float v4, v2, v25
.line 167
.restart local v4 # "pointy":F
move-object/from16 v0, p0
iget-object v2, v0, Lcom/mprc/bdk/ecgMeasurement/bluz/DrawHeart;->list:Ljava/util/List;
move/from16 v0, v16
invoke-interface {v2, v0}, Ljava/util/List;->get(I)Ljava/lang/Object;
move-result-object v2
check-cast v2, Ljava/lang/Integer;
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
move-result-object v2
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
int-to-float v10, v2
.line 168
.restart local v10 # "datamv":F
mul-int/lit8 v2, v20, 0x15
add-int/lit8 v2, v2, 0x4
int-to-float v2, v2
move/from16 v0, v19
int-to-float v0, v0
move/from16 v25, v0
mul-float v25, v25, v10
const/high16 v26, 0x40880000 # 4.25f
div-float v25, v25, v26
sub-float v3, v2, v25
.line 171
.restart local v3 # "pointx":F
int-to-float v2, v8
sub-int v25, v16, v21
add-int/lit8 v25, v25, 0x1
move/from16 v0, v25
int-to-float v0, v0
move/from16 v25, v0
mul-float v25, v25, v23
sub-float v6, v2, v25
.line 172
.restart local v6 # "pointy2":F
move-object/from16 v0, p0
iget-object v2, v0, Lcom/mprc/bdk/ecgMeasurement/bluz/DrawHeart;->list:Ljava/util/List;
add-int/lit8 v25, v16, 0x1
move/from16 v0, v25
invoke-interface {v2, v0}, Ljava/util/List;->get(I)Ljava/lang/Object;
move-result-object v2
check-cast v2, Ljava/lang/Integer;
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
move-result-object v2
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
int-to-float v11, v2
.line 173
.restart local v11 # "datamv2":F
mul-int/lit8 v2, v20, 0x15
add-int/lit8 v2, v2, 0x4
int-to-float v2, v2
move/from16 v0, v19
int-to-float v0, v0
move/from16 v25, v0
mul-float v25, v25, v11
const/high16 v26, 0x40880000 # 4.25f
div-float v25, v25, v26
sub-float v5, v2, v25
.restart local v5 # "pointx2":F
move-object/from16 v2, p1
.line 176
invoke-virtual/range {v2 .. v7}, Landroid/graphics/Canvas;->drawLine(FFFFLandroid/graphics/Paint;)V
.line 163
add-int/lit8 v16, v16, 0x1
goto/16 :goto_8
.line 183
.end local v3 # "pointx":F
.end local v4 # "pointy":F
.end local v5 # "pointx2":F
.end local v6 # "pointy2":F
.end local v10 # "datamv":F
.end local v11 # "datamv2":F
:cond_d
int-to-float v2, v8
sub-int v25, v16, v22
move/from16 v0, v25
int-to-float v0, v0
move/from16 v25, v0
mul-float v25, v25, v23
sub-float v4, v2, v25
.line 184
.restart local v4 # "pointy":F
move-object/from16 v0, p0
iget-object v2, v0, Lcom/mprc/bdk/ecgMeasurement/bluz/DrawHeart;->list:Ljava/util/List;
move/from16 v0, v16
invoke-interface {v2, v0}, Ljava/util/List;->get(I)Ljava/lang/Object;
move-result-object v2
check-cast v2, Ljava/lang/Integer;
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
move-result-object v2
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
int-to-float v10, v2
.line 185
.restart local v10 # "datamv":F
mul-int/lit8 v2, v20, 0x1b
add-int/lit8 v2, v2, 0x4
int-to-float v2, v2
move/from16 v0, v19
int-to-float v0, v0
move/from16 v25, v0
mul-float v25, v25, v10
const/high16 v26, 0x40880000 # 4.25f
div-float v25, v25, v26
sub-float v3, v2, v25
.line 188
.restart local v3 # "pointx":F
int-to-float v2, v8
sub-int v25, v16, v22
add-int/lit8 v25, v25, 0x1
move/from16 v0, v25
int-to-float v0, v0
move/from16 v25, v0
mul-float v25, v25, v23
sub-float v6, v2, v25
.line 189
.restart local v6 # "pointy2":F
move-object/from16 v0, p0
iget-object v2, v0, Lcom/mprc/bdk/ecgMeasurement/bluz/DrawHeart;->list:Ljava/util/List;
add-int/lit8 v25, v16, 0x1
move/from16 v0, v25
invoke-interface {v2, v0}, Ljava/util/List;->get(I)Ljava/lang/Object;
move-result-object v2
check-cast v2, Ljava/lang/Integer;
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
move-result-object v2
invoke-virtual {v2}, Ljava/lang/Integer;->intValue()I
move-result v2
int-to-float v11, v2
.line 190
.restart local v11 # "datamv2":F
mul-int/lit8 v2, v20, 0x1b
add-int/lit8 v2, v2, 0x4
int-to-float v2, v2
move/from16 v0, v19
int-to-float v0, v0
move/from16 v25, v0
mul-float v25, v25, v11
const/high16 v26, 0x40880000 # 4.25f
div-float v25, v25, v26
sub-float v5, v2, v25
.restart local v5 # "pointx2":F
move-object/from16 v2, p1
.line 193
invoke-virtual/range {v2 .. v7}, Landroid/graphics/Canvas;->drawLine(FFFFLandroid/graphics/Paint;)V
.line 180
add-int/lit8 v16, v16, 0x1
goto/16 :goto_9
.end method
對(duì)應(yīng)的Java代碼
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(-1);
Paint paint = new Paint();//.local v7
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
int actulWidth = 0;//.locala v9
int actulHeight = 0;//.locala v8
//Java中的float是32位的,double是64位的
int perUnitNum = 0;//.local v20
int perMiniNum = 0;//.local v19
//還是有錯(cuò)誤
if(this.screenHeight>this.screenWidth){//否則跳轉(zhuǎn)到cond_0
int i=0xa;//.local v15
goto_0:
for(;i<0x64;i+=0x1){//.line 73 //.line 83 cond_3
//cond_1
int height = i*0x26+0x4;//.local v14
int width = i*0x1c+0x4;//.local v24
if(height>this.screenHeight){
//cond_2
int mode = i%0x5;//.line 78 //?貌似作用域不一樣
if(mode==0){
perUnitNum = (i-0x1)-(i-0x1)%0x5;
perMiniNum = perUnitNum/0x5;//.line 80
//goto/16 :goto_1
break;//.line 81
}
}
}
actulWidth=perUnitNum*0x21+0x4;//.line 87
actulHeight=perUnitNum*0x26+0x4;//.line 90
//.line 94 .end local v15 #"i":I
}/*else{*/
//cond_0
paint.setColor(Color.rgb(0xff, 0xb4, 0xb4));
/*}*/
int j = perMiniNum+0x4;//.line 95 .local v16
goto_2:
for(;j<actulWidth;j+=perMiniNum){
//cond_4
int mode = ((j - 0x4 - perMiniNum) / perMiniNum + 0x1) % 0x5;//.line 99 //.local v18
if (mode != 0) {
canvas.drawLine(j, 4.0f, j, actulHeight, paint);//.line 100
}
}
int i = perMiniNum+0x4;//.line 102
//.restart local v15
goto_3:
for(;i<actulHeight;i+=perMiniNum){
//cond_6
int mode = ((i - 0x4 - perMiniNum) / perMiniNum + 0x1) % 0x5;//.line 105 //.restart local v18
if(mode != 0){//否則cond_7
canvas.drawLine(4.0f, i, actulWidth, i, paint);//.line 106
}
}
//.line 110
paint.setColor(-0x10000);
j=0x4;
goto_4://.line 111
for(;j<=actulWidth;j+=perUnitNum){
//cond_8
canvas.drawLine(j, 4.0f, j, actulHeight, paint);//.line 114
}
i=+0x4;//.line 115
goto_5:
for(;i<=actulHeight;i+=perUnitNum){
//.line 117 //:cond_9
canvas.drawLine(4.0f, i, actulWidth, i, paint);
}
//.line 120
int length = this.list.size();//.local v17 //.line 121
int firstlength = length / 0x4;//.line 122 //.local v12
int firstpoint = firstlength;//.line 123 //.local v13
int secondpoint = firstlength * 0x2;//.line 124 //.local v21
int thirdpoint = firstlength * 0x3;//.line 125 //.local v22
float unitlength = perUnitNum * 38.0f / (firstlength * 1.0f);//.line 128 //.local v23
paint.setColor(-0X1000000);
j = 0x0;//.line 129
goto_6:
for(;j<firstpoint;j+=0x1){
//cond_a
float pointy = actulHeight - j * unitlength;// .local v4 //.line 133
float datamv = (float) Integer.valueOf(((Integer) this.list.get(j)).intValue()).intValue();//.local v10 //.line 134
float pointx = (perUnitNum * 0x9 + 0x4) - perMiniNum * datamv / 4.25f;//.line 137 //.local v3
float pointy2 = actulHeight - (j + 0x1) * unitlength;//.line 138 //.local v6
float datamv2 = Integer.valueOf(((Integer) this.list.get(j + 0x1)).intValue()).intValue();//.local v11 //.line 139
float pointx2 = (perUnitNum * 0x9 + 0x4) - perMiniNum * datamv2 / 4.25f;//.local v5
canvas.drawLine(pointx, pointy, pointx2, pointy2, paint);//.line 142
}
//.line 146
j=firstpoint;
goto_7:
for(;j<secondpoint;j+=0x1){
//cond_b
float pointy = actulHeight - (j - firstpoint) * unitlength;//.line 150 //.restart local v4
float datamv = (float) Integer.valueOf(((Integer) this.list.get(j)).intValue()).intValue();//.line 151 //.restart local v10
float pointx = perUnitNum * 0xf + 0x4 - perMiniNum * datamv / 4.25f;//.line 154 //.restart local v3
float pointy2 = actulHeight - (j - firstpoint + 0x1) * unitlength;//.line 155 //.restart local v6
float datamv2 = (float) Integer.valueOf((Integer) this.list.get(j + 0x1).intValue()).intValue();//.line 156 //.restart local v11
float pointx2 = perUnitNum * 0xf + 0x4 - perMiniNum * datamv2 / 4.25f;//.restart local v5
canvas.drawLine(pointx, pointy, pointx2, pointy2, paint);//.line 159
}
//.line 163
j=secondpoint;
goto_8:
for(;j<thirdpoint;j+=0x1){
//cond_c
float pointy = actulHeight - (j - secondpoint) * unitlength;
float datamv = Integer.valueOf((Integer) this.list.get(j).intValue()).intValue();
float pointx = (perUnitNum * 0x15 + 0x4) - perMiniNum * datamv / 4.25f;
float pointy2 = actulHeight - ((j - secondpoint) + 0x1) * unitlength;
float datamv2 = Integer.valueOf((Integer) this.list.get(j + 0x1).intValue()).intValue();
float pointx2 = (perUnitNum * 0x15 + 0x4) - perMiniNum * datamv2 / 4.25f;
canvas.drawLine(pointx, pointy, pointx2, pointy2, paint);//.line 176
}
//.line 180
j=thirdpoint;
goto_9:
for(;j<(length-1);j+=0x1){
//cond_d
float pointy = actulHeight - (j - thirdpoint) * unitlength;
float datamv = Integer.valueOf((Integer) this.list.get(j).intValue()).intValue();
float pointx = perUnitNum * 0x1b + 0x4 - perMiniNum * datamv / 4.25f;
float pointy2 = actulHeight - (j - thirdpoint + 0x1) * unitlength;
float datamv2 = Integer.valueOf((Integer) this.list.get(j + 0x1).intValue()).intValue();
float pointx2 = perUnitNum * 0x1b + 0x4 - perMiniNum * datamv2 / 4.25f;
canvas.drawLine(pointx, pointy, pointx2, pointy2, paint);//.line 193
}
}
Java代碼請(qǐng)自行對(duì)結(jié)構(gòu)邏輯進(jìn)行優(yōu)化吧,也就是去掉goto;標(biāo)識(shí)符的工作=
寫在后面:
相關(guān)資料工具
在你有可測(cè)試數(shù)據(jù)的基礎(chǔ)上,將我們根據(jù)語法逆向出來的.smali文件替換掉原APK對(duì)應(yīng)文件的.smali文件并重新編譯,根據(jù)測(cè)試結(jié)果對(duì)比來檢查我們操作結(jié)果的正確性,推薦工具APK改之理
當(dāng)時(shí)記錄的可用測(cè)試數(shù)據(jù):
[-127,-90]與[100,128]
這兩個(gè)區(qū)段隨機(jī)抽取整數(shù)64到100個(gè),在你自定義的View上通過如上方法繪制即可看到類似結(jié)果,如下圖所示:

自己加了標(biāo)記的《Android軟件安全與逆向分析》一書的PDF文件,僅供學(xué)習(xí)之用,有資金基礎(chǔ)的還是推薦買本實(shí)體書,支持下作者:
鏈接: http://pan.baidu.com/s/1eRCdEs6 密碼: wrqg
原APK文件:
鏈接: http://pan.baidu.com/s/1i5CTJil 密碼: vikw