目录

1.准备工作

2.编写smali文件

3.编译smali文件

4.检查并运行

5.遇到问题


1.准备工作

1.1下载好smali的jar这里使用smali-2.4.0.jar  (PS: 执行命令为 java -jar assemble xxx.smali -o xxx.dex)

1.2 root的真机或者模拟器

1.3 安装好JaDex方便自己看看大概写出来的东西是个什么样子,用其它工具也行,不过这个很方便。

2.编写smali文件

.class public Lcom/test/smali/Programmer;
.super Ljava/lang/Object;
.source "Programmer.java"#变量
.field private name:Ljava/lang/String;#名称
.field private age:I#年龄
.field private sex:I#性别 1男 0女
.field private partnerName:Ljava/lang/String;#构造函数 PS:如果只有一个无参构造函数不用自己写g构造函数,否则new的时候会死循环
.method public constructor <init>(Ljava/lang/String;)V
.locals 1invoke-direct {p0}, Lcom/test/smali/Programmer;-><init>()V.param p1,"name"
if-eqz p1,:cound_0
iput-object p1,p0,Lcom/test/smali/Programmer;->name:Ljava/lang/String;
:cound_0return-void
.end method#get\set函数#getName函数
.method public getName()Ljava/lang/String;
.locals 1
.prologue
iget-object v0,p0,Lcom/test/smali/Programmer;->name:Ljava/lang/String;
return-object v0
.end method#setName函数
.method public setName(Ljava/lang/String;)V
.locals 1
.prologue
.local p1, "name":Ljava/lang/String;
if-eqz p1,:cound_0
#move-object name,p1 #这么写是错的,操作field要用iput
iput-object p1,p0,Lcom/test/smali/Programmer;->name:Ljava/lang/String;
:cound_0
return-void
.end method#getAge函数
.method public getAge()I
.locals 1
.prologue
iget v0,p0,Lcom/test/smali/Programmer;->age:I
return v0
.end method#setAge函数
.method public setAge(I)V
.locals 1
.prologue
.local p1, "age":I
if-lez p1,:cound_0
iput p1,p0,Lcom/test/smali/Programmer;->age:I
:cound_0
return-void
.end method#getSex函数
.method public getSex()I
.locals 1
.prologue
iget v0,p0,Lcom/test/smali/Programmer;->sex:I
return v0
.end method#setSex函数
.method public setSex(I)V
.locals 1
.local p1,"sex":I
iput p1,p0,Lcom/test/smali/Programmer;->sex:I
return-void
.end method#getPartnerName函数
.method public getPartnerName()Ljava/lang/String;
.locals 1
.prologue
iget-object v0,p0,Lcom/test/smali/Programmer;->partnerName:Ljava/lang/String;
return-object v0
.end method#setPartnerName函数
.method public setPartnerName(Ljava/lang/String;)V
.locals 1
.local p1,"name":Ljava/lang/String;
if-eqz p1,:cound_0
iput-object p1,p0,Lcom/test/smali/Programmer;->partnerName:Ljava/lang/String;
:cound_0
return-void
.end method#toString函数
.method public toString()Ljava/lang/String;
.locals 14
.prologue#创建一个StringBuilder用来拼接字符串
new-instance v0,Ljava/lang/StringBuilder;
invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V
#给v0寄存器所持有的StringBuilder的实例一个为"sb"名称
.local v0,"sb":Ljava/lang/StringBuilder;iget-object v1,p0,Lcom/test/smali/Programmer;->name:Ljava/lang/String;
.local v1,"name":Ljava/lang/String;
iget v2,p0,Lcom/test/smali/Programmer;->age:I
.local v2,"age":I
iget v3,p0,Lcom/test/smali/Programmer;->sex:I
.local v3,"sex":I
iget-object v4,p0,Lcom/test/smali/Programmer;->partnerName:Ljava/lang/String;
.local v4,"partnerName":Ljava/lang/String;const-string v5,"这是一个默默无闻的程序员"
const-string v6,"年龄:"
const-string v7,"对象是"
const-string v8,"是条单身狗!"
const-string v9,"性别"
const-string v10,"男"
const-string v11,"女"#对属性的值进行判断if-eqz v1,:cound_0
#if(name!=null)
invoke-virtual {v0,v1},Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
:cound_0if-nez v1,:cound_1
#if(name==null)
invoke-virtual{v0,v5},Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
:cound_1invoke-virtual{v0,v6},Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invoke-virtual{v0,v2},Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
invoke-virtual{v0,v9},Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;if-eqz v3,:cound_2
#if(sex!=0)
invoke-virtual{v0,v10},Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
:cound_2if-nez v3,:cound_3
#if(sex == 0)
invoke-virtual{v0,v11},Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
:cound_3if-eqz v4,:cound_4
invoke-virtual{v0,v7},Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invoke-virtual{v0,v4},Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
:cound_4if-nez v4,:cound_5
invoke-virtual{v0,v8},Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
:cound_5invoke-virtual {v0},Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v12sget-object v13,Ljava/lang/System;->out:Ljava/io/PrintStream;
invoke-virtual {v13,v12},Ljava/io/PrintStream;->println(Ljava/lang/String;)V.end local v0
#调用父类的toString方法
invoke-super {p0}, Ljava/lang/Object;->toString()Ljava/lang/String;
move-result-object v0
return-object v0
.end method#main函数
.method public static main([Ljava/lang/String;)V
.locals 6
.local p0,"strs":[Ljava/lang/String;
.prologueconst-string v0,"张三"
.local v0,"name":Ljava/lang/String;
const/16 v1,0x12
.local v1,"age":I
const/16 v2,0x1
.local v2,"sex":I
const-string v3,"李四"
.local v3,"partnerName":Ljava/lang/String;new-instance v4,Lcom/test/smali/Programmer;invoke-direct {v4},Lcom/test/smali/Programmer;-><init>()Vinvoke-virtual {v4,v0},Lcom/test/smali/Programmer;->setName(Ljava/lang/String;)V
invoke-virtual {v4,v1},Lcom/test/smali/Programmer;->setAge(I)V
invoke-virtual {v4,v2},Lcom/test/smali/Programmer;->setSex(I)V
#注释之后打印出该程序猿/媛是个单生狗
#invoke-virtual {v4,v3},Lcom/test/smali/Programmer;->setPartnerName(Ljava/lang/String;)Vinvoke-virtual {v4},Lcom/test/smali/Programmer;->toString()Ljava/lang/String;return-void
.end method

3.编译smali文件

自己写的一个smali.bat,为了少打几个字!

开始编译

4.检查并运行

JaDex查看:

package com.test.smali;public class Programmer {private int age;private String name;private String partnerName;private int sex;public Programmer(String name) {if (name != null) {this.name = name;}}public static void main(String[] strArr) {String partnerName = "李四";Programmer programmer = new Programmer();programmer.setName("张三");programmer.setAge(18);programmer.setSex(1);programmer.toString();}public int getAge() {return this.age;}public String getName() {return this.name;}public String getPartnerName() {return this.partnerName;}public int getSex() {return this.sex;}public void setAge(int age) {if (age > 0) {this.age = age;}}public void setName(String name) {if (name != null) {this.name = name;}}public void setPartnerName(String name) {if (name != null) {this.partnerName = name;}}public void setSex(int sex) {this.sex = sex;}public String toString() {StringBuilder sb = new StringBuilder();String name = this.name;int age = this.age;int sex = this.sex;String partnerName = this.partnerName;String str = "这是一个默默无闻的程序员";String str2 = "年龄:";String str3 = "对象是";String str4 = "是条单身狗!";String str5 = "性别";String str6 = "男";String str7 = "女";if (name != null) {sb.append(name);}if (name == null) {sb.append(str);}sb.append(str2);sb.append(age);sb.append(str5);if (sex != 0) {sb.append(str6);}if (sex == 0) {sb.append(str7);}if (partnerName != null) {sb.append(str3);sb.append(partnerName);}if (partnerName == null) {sb.append(str4);}System.out.println(sb.toString());return super.toString();}
}

模拟器运行:

5.遇到问题

1.定义全局变量出现错误

错误写法:.field private name:Ljava/lang/String; = "",根据错误提示的字面意思理解,应该是"只有静态的域才能够指定初始值。"

正确写法:.field private name:Ljava/lang/String;

编译后Jadex查看如下:

2.创建setName方法时move指令与iput混淆

错误写法:move-object p1,p0,Lcom/test/smali/Programmer;->name:Ljava/lang/String;

正确写法:iput-object p1,p0,Lcom/test/smali/Programmer;->name:Ljava/lang/String;

编译后JaDex查看如下:

3.创建方法提示寄存器数量定义问题

创建方法时没有指明寄存器数量,加上.locals "函数用到的寄存器数量" 即可。如: .locals 5

4.new-instance 死循环

由于模仿反编译出来的smali文件写了无参构造函数,结果在编译时出现构造函数死循环。

正确方法:不写构造函数,或者写一个有参的的构造函数。如下:

.method public constructor<init>(Ljava/lang/String;)V
.locals 1
.prologue
.param p1,"name"invoke-direct {p0},Lcom/test/smali/Programmer;-><init>()Vif-eqz p1,:cound_0
iput-object p1,p0,Lcom/test/smali/Programmer;->name:Ljava/lang/String;
:cound_0return-void
.end method

Android逆向:smali编码实践(三)—— 实体类创建以及if判断相关推荐

  1. Intellij IDEA 通过数据库表逆向生成带注释的实体类文件超级详细步骤,附详细解决方案

    Intellij IDEA 通过数据库表逆向生成带注释的实体类文件超级详细步骤,附详细解决方案 参考文章: (1)Intellij IDEA 通过数据库表逆向生成带注释的实体类文件超级详细步骤,附详细 ...

  2. android开发学习 ------- json数据与实体类之间的相互转换

    在网络请求的时候,会返回给我们实体类,我们需要将实体类转化为json字符串,方便处理数据: 有时候也会将json数据转换为实体类. 在Android Studio中,json要互相转换,需要用到gso ...

  3. mysql表 c#实体类,创建基于MySQL表中的C#类

    Is there anything built into .Net or visual studio that will allow my to create classes based off of ...

  4. java实体类属性非空判断工具类

    import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Map.En ...

  5. 网络流量分析与Android逆向小结

    本章对之前的网络流量分析与Android逆向做个小结. 网络流量分析 原理解析 分析原理前之前先了解中间人攻击的概念:在中间人攻击中,攻击主机通常截断客户端和服务器的加密通信.攻击机以自己的证书替代服 ...

  6. 移动安全Android逆向系列:Dalvik概念破解实例

    本篇文章是Android逆向系列的第三篇,开始介绍Dalvik虚拟机的相关知识,认识dex和smali文件格式和熟悉Dalvik字节码及指令集,对Dalvik指令集有个大概的了解就可以开始简单的反编译 ...

  7. groovy逆向工程生成自定义实体类图文详解

    文章目录 前言 步骤 给idea安装database插件,然后用idea连接数据库 右击数据库名,再点script Exctension,再点go to scrip.... 自定义自己的逆向生成脚本如 ...

  8. java 实体类 临时注解_JPA:Java持久层API--配置流程

    一.JPA概述 1.1 JPA是什么 JPA (Java Persistence API) Java持久化API.是一套Sun公司 Java官方制定的ORM 方案,是规范,是标准 ,sun公司自己并没 ...

  9. 现代密码学—密码学基本编码实践 16进制向base64编码转换 等长16进制字符串异或 找出密钥并破解密文 python

    实验地点:E楼III区503 实验时间:11.17 一.实验室名称:攻防实验室 二.实验项目名称:密码学基本编码实践 三.实验学时:6学时 四.实验原理: Base64是网络上最常见的用于传输8Bit ...

最新文章

  1. firefox下的调试工具
  2. VTK:InfoVis之WordCloud
  3. Web框架——Flask系列之session机制(十六)
  4. 由PPPOE看Linux网络协议栈的实现
  5. 华为云PaaS梳理了客户可能上云的三类场景和七种解决方案
  6. Java队列Disruptor 的使用
  7. 51nod 1605:棋盘问题
  8. 计算机领域CCF推荐会议列表
  9. EtherCAT报文格式详解
  10. (4.4.1)使用storyboard实现页面跳转,简单的数据传递
  11. c语言判断100的倍数,显示100以内所有9的倍数及其和。急要,请大家帮帮忙~~还有一些题。...
  12. 佳能打印机imageRUNNER系列 2206AD驱动安装
  13. Python基础(Day 2)(数值 字符串 布尔 列表)
  14. speedoffice被隐藏的工作表如何取消隐藏
  15. 模糊测试中的动态符号执行
  16. 采集google搜索引擎的10个经典方法
  17. 一句话可以彻底改变一个人的命运
  18. 基于深度卷积神经网络分割的飞机类型识别
  19. 超级星饭团专访陆毅:化身“霸总”上演“沙漏”式爱情
  20. 服务器系统怎么重置path,DediPath独立服务器重置IPMI教程

热门文章

  1. 10张剪纸风格2021牛年祝福海报
  2. IOTA--帮你构建安全的边缘计算网络
  3. 冒泡排序--咕噜咕噜
  4. Unreal Engine 4 UE4 CAVE VR 立体 Stereo nDisplay 多通道
  5. 全差分运放阻抗匹配计算(三)
  6. Java中变量与常量
  7. 4、cas Server连接mysql
  8. python pip install fitter 失败解决方案
  9. 小米刷机OTA、 Recovery、 FASTBOOT三种方法直接的区别和联系
  10. C++11多线程 内存序(std::memory_order_consume)