写在前面:
这次逆向实战其实是15年进入公司后不久,某个项目需求得来的操作,当时在Github文章写了一半没写完,今天补充完毕,重新发出来算是给大家一个学习逆向基础的参考_。
前言
“你学习一门技术的最佳时机是三年前,其次是现在。”
背景/目的
项目需求,需要根据手机端接收到的某心电宝测量的心电数据绘制相应的心电图,无奈数据是接收了,
却不知道如何对数据进行相应的处理,瞎搞一通还是绘制不出来,只能傻脸了~
我们的参照App是某德康App,使用的是同一款心电宝,却发现人家竟然能绘制!,舞草,好专业!!
既然正面得不到绘制原理对应的代码,那我就只好逆向xxoo你了,顺带践行心生已久的跨入移动安全这一深坑的想法。
嗯,所以这篇文章的目的呢,也就是实战总结,回顾,加深理解,基本掌握由smali代码逆向出Java代码。
知识点准备
理解本篇内容,需要你通读并理解《Android软件安全与逆向分析》一书的第一章、第二章、第三章、以及第五章5.6小节之前的全部内容。
以下,为该书2013年2月份第一次印刷第一版电子版的研读过程中我自己的书签笔记,希望有助于你的理解,当然,有错请指正。
P32,最后一段中,“第二条指令iload_2取第二个参数”,应该为,“第二条指令iload_2取第三个参数”,
依据之前从“第二部分为下划线右边的数字,表示要操作具体哪个局部变量,索引值从0开始计数...”开始的指令含义介绍;
P33,第一段接上一页的最后一句,“压入第一个参数与第二个参数”,应该为,“压入第二个参数与第三个参数”;
P45,“注意”上面的一段中,倒数第二行,“AAAA/BBBB/CCCC/DDDD/EEEE/FFFF/GGGG/HHHH代表一个8位的数值”,
应该为,“AAAA/BBBB/CCCC/DDDD/EEEE/FFFF/GGGG/HHHH代表一个16位的数值”
P46,3.3.3小节第十二行,“源寄存器为8位,目的寄存器为16位。”,应该为,“目的寄存器为8位,源寄存器为16位。”
P46,3.3.5小节第二行,“‘const/4 vA,#+B’将数值符号扩展为32位后赋给寄存器vA。”,对于“#+B”,
个人理解为在全书中的含义应该都是表示一个常量,每一个大写的字母表示4个位数。
至于“将数值符号扩展为32位后”,我还是有点不太理解~
P53,第一段代码中,本人在实际操作过程中发现,".parameter"指令在JDK1.8且smali.jar版本为2.1.0的环境下不被识别,去掉就能正确编译=_=||
P54,3.4.2小节那一条命令中,“classes.dex”,应该为,“HelloWorld.dex”;
3.4.3小节那两条命令中的“HelloWorld.zip”,应该为,“HelloWorld.dex”;
第五章中提到的诸如sparse-switch-payload字段的格式定义内容都可以暂时略过不看,以后回过头来再研究吧。
逆smali得Java
samli目标文件核心函数代码
.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
对应的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
//还是有错误
if(this.screenHeight>this.screenWidth){//否则跳转到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代码请自行对结构逻辑进行优化吧,也就是去掉goto;标识符的工作=
写在后面:
相关资料工具
在你有可测试数据的基础上,将我们根据语法逆向出来的.smali文件替换掉原APK对应文件的.smali文件并重新编译,根据测试结果对比来检查我们操作结果的正确性,推荐工具APK改之理
当时记录的可用测试数据:
[-127,-90]与[100,128]
这两个区段随机抽取整数64到100个,在你自定义的View上通过如上方法绘制即可看到类似结果,如下图所示:
自己加了标记的《Android软件安全与逆向分析》一书的PDF文件,仅供学习之用,有资金基础的还是推荐买本实体书,支持下作者:
链接: http://pan.baidu.com/s/1eRCdEs6 密码: wrqg
原APK文件:
链接: http://pan.baidu.com/s/1i5CTJil 密码: vikw