基础总结

Java

一、基础语法结构

1. 变量与数据类型

1
2
3
4
5
6
7
8
9
// 基本数据类型
int age = 25; // 整数(4字节)
double price = 9.99; // 双精度浮点
char grade = 'A'; // 单个字符
boolean isOpen = true; // 布尔值

// 引用数据类型
String name = "Android"; // 字符串
int[] numbers = {1,2,3}; // 数组

2. 控制流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 条件语句
if (score >= 60) {
System.out.println("及格");
} else if (score > 40) {
System.out.println("补考");
} else {
System.out.println("挂科");
}

// 循环结构
for (int i=0; i<5; i++) {
System.out.println(i); // 0,1,2,3,4
}

int j = 0;
while (j < 3) {
System.out.println(j++); // 0,1,2
}

二、面向对象核心

1. 类与对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 类定义
public class Person {
// 字段
private String name;

// 构造方法
public Person(String name) {
this.name = name;
}

// 方法
public void sayHello() {
System.out.println("Hello, I'm " + name);
}
}

// 对象使用
Person p = new Person("Alice");
p.sayHello(); // 输出: Hello, I'm Alice

2. 继承与多态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 父类
class Animal {
public void sound() {
System.out.println("动物叫");
}
}

// 子类
class Dog extends Animal {
@Override
public void sound() {
System.out.println("汪汪汪"); // 方法重写
}
}

// 多态示例
Animal myDog = new Dog();
myDog.sound(); // 输出: 汪汪汪

三、关键语法特性

1. 访问修饰符

修饰符 类内 同包 子类 其他包
private ✔️ ✖️ ✖️ ✖️
protected ✔️ ✔️ ✔️ ✖️
public ✔️ ✔️ ✔️ ✔️
默认 ✔️ ✔️ ✖️ ✖️

2. 接口与抽象类

1
2
3
4
5
6
7
8
9
10
// 接口(100%抽象)
interface USB {
void connect(); // 隐式 public abstract
}

// 抽象类(可包含实现)
abstract class Shape {
abstract void draw(); // 抽象方法
void move() { /* 具体实现 */ }
}

四、异常处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("除数不能为零");
} finally {
System.out.println("总会执行");
}

// 自定义异常
class MyException extends Exception {
public MyException(String message) {
super(message);
}
}

五、集合框架

1
2
3
4
5
6
7
8
9
// 常用集合类
List<String> list = new ArrayList<>(); // 有序可重复
Set<Integer> set = new HashSet<>(); // 无序唯一
Map<String, Integer> map = new HashMap<>(); // 键值对

// 集合操作
list.add("Java");
map.put("age", 20);
int value = map.get("age");

六、其他逆向重点

1. 反射机制(逆向关键)

1
2
3
Class<?> clazz = Class.forName("com.example.MyClass");
Method method = clazz.getMethod("secretMethod");
method.invoke(clazz.newInstance());

2. 泛型(反编译常见)

1
List<Map<String, Integer>> complexList = new ArrayList<>();

3. 多线程

1
2
3
new Thread(() -> {
System.out.println("异步执行");
}).start();

七、内存管理基础

  1. 栈内存:存储基本类型变量和方法调用
  2. 堆内存:存储对象实例
  3. 方法区:存储类信息、常量池
  4. 垃圾回收:自动回收无引用对象(System.gc()建议回收)

学习建议

  1. 重点掌握:类与对象、继承多态、集合框架
  2. 逆向关联:反射机制、异常处理、接口特性
  3. 实践方法:通过修改开源项目的代码观察运行结果

附:逆向工程中常见的Java代码特征

  • private static final 修饰的密钥字段
  • try-catch 包裹的核心逻辑
  • native 声明的JNI方法
  • synchronized 同步代码块

结合APK反编译后的实际代码进行对照学习,理解语法到字节码的转换逻辑。

Kotlin

一、基本特性与优势

  • 简洁性:语法精简,减少模板代码(如省略分号、简化类定义)。
  • 空安全:编译期检查空指针,从语法层面避免 NullPointerException
  • 函数式编程:支持 Lambda 表达式、高阶函数、协程等。
  • 面向对象:保留类、继承、接口等 OOP 特性,同时更灵活。
  • 与 Java 互操作:可直接调用 Java 代码,Java 也可调用 Kotlin 代码,无缝兼容 Android 现有项目。

二、基础语法

1. 变量声明

Kotlin 变量分为可变var)和不可变val,类似 Java 的 final),无需显式声明类型(类型推断):

1
2
3
4
5
6
7
// 不可变变量(推荐优先使用)
val name: String = "Kotlin" // 显式声明类型
val age = 30 // 类型推断为 Int

// 可变变量
var score = 90 // 类型推断为 Int
score = 95 // 可修改

2. 基本数据类型

与 Java 类似,但无基本类型与包装类之分,全部是对象,支持直接调用方法:

  • 数值类型:ByteShortIntLongFloatDouble
  • 字符:Char(单引号,如 'A'
  • 布尔:Booleantrue/false
  • 字符串:String(双引号,支持模板语法 ${}
1
2
3
4
5
6
7
val a: Int = 100
val b = 10L // 加 L 表示 Long 类型
val c = 3.14f // 加 f 表示 Float 类型

// 字符串模板
val name = "Kotlin"
val info = "Language: $name, Version: ${1.9 + 0.1}" // 输出 "Language: Kotlin, Version: 2.0"

3. 函数定义

fun 关键字定义,语法:`fun 函数名(参数: 类型): 返回值类型 { … }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 普通函数
fun sum(a: Int, b: Int): Int {
return a + b
}

// 单表达式函数(简化写法,自动推断返回值)
fun multiply(a: Int, b: Int) = a * b // 等价于返回 a*b

// 无返回值(返回 Unit,类似 Java 的 void,可省略)
fun printHello(): Unit {
println("Hello")
}
fun printHi() { // 省略 Unit
println("Hi")
}

特色参数

  • 默认参数:给参数设置默认值,调用时可省略

    1
    2
    3
    4
    5
    fun greet(name: String = "Guest") {
    println("Hello, $name")
    }
    greet() // 输出 "Hello, Guest"
    greet("Alice") // 输出 "Hello, Alice"
  • 命名参数:调用时指定参数名,增强可读性

    1
    2
    fun add(a: Int, b: Int, c: Int) = a + b + c
    add(b = 2, a = 1, c = 3) // 按名称传参,结果 6

三、控制流

1. 条件语句

  • if可作为表达式(有返回值),替代 Java 的三元运算符

    1
    val max = if (a > b) a else b  // 等价于 Java 的 a > b ? a : b
  • 多分支用 if-else if-else,逻辑同 Java。

2. when 表达式(替代 Java 的 switch)

更灵活,支持任意类型匹配,且可作为表达式返回值:

1
2
3
4
5
6
7
8
9
fun getType(x: Any): String {
return when (x) {
1 -> "Int 类型,值为 1"
"hello" -> "String 类型"
is Boolean -> "Boolean 类型" // 类型匹配(is 类似 Java 的 instanceof)
in 10..20 -> "在 10-20 范围内" // 范围匹配
else -> "未知类型" // 必须包含 else(除非覆盖所有可能)
}
}

3. 循环

  • for 循环:遍历集合或范围(.. 表示闭区间)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 遍历范围
    for (i in 1..5) { // 1 到 5(包含 5)
    print(i) // 输出 12345
    }

    // 遍历集合
    val list = listOf("a", "b", "c")
    for (item in list) {
    println(item)
    }
  • whiledo-while:与 Java 语法完全一致。

四、类与对象

1. 类定义

默认是不可继承的final),需用 open 关键字标记才能被继承:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 普通类
class Person {
// 类成员变量
var name: String = ""
var age: Int = 0
}

// 可继承的类(open 修饰)
open class Animal {
fun eat() {
println("动物进食")
}
}

2. 构造函数

  • 主构造函数:类名后直接声明,简洁用于初始化参数

    1
    2
    3
    4
    5
    6
    7
    8
    class Student(val id: Int, var name: String) {  // 主构造函数参数
    // 初始化代码块(主构造函数执行时调用)
    init {
    println("Student 初始化:id=$id, name=$name")
    }
    }

    // 使用:val stu = Student(1, "Tom")
  • 次构造函数:用 constructor 关键字,需调用主构造函数(this

    1
    2
    3
    4
    5
    6
    7
    8
    class Teacher(val id: Int) {
    var name: String = ""

    // 次构造函数(必须调用主构造函数)
    constructor(id: Int, name: String) : this(id) {
    this.name = name
    }
    }

3. 数据类(data class)

专门用于存储数据的类,自动生成 equals()hashCode()toString() 等方法,简化实体类定义(Android 中常用于网络数据模型):

1
2
3
4
5
6
data class User(val id: Int, val name: String, val age: Int)

// 使用
val user = User(1, "Alice", 25)
println(user) // 自动生成 toString():User(id=1, name=Alice, age=25)
val user2 = user.copy(age = 26) // 复制对象并修改部分属性

4. 密封类(sealed class)

用于受限的类层次结构(子类固定),常用于状态管理(如 UI 状态:加载中、成功、失败):

1
2
3
4
5
6
7
8
9
10
11
12
13
sealed class Result
class Success(val data: String) : Result()
class Error(val message: String) : Result()
object Loading : Result() // 单例对象

// 使用时,when 语句可自动推断所有子类,无需 else
fun handleResult(result: Result) {
when (result) {
is Success -> println("成功:${result.data}")
is Error -> println("错误:${result.message}")
Loading -> println("加载中...")
}
}

五、继承与接口

1. 继承

: 表示继承,父类需用 open 修饰,重写方法需用 override

1
2
3
4
5
6
7
8
9
10
11
open class Animal {
open fun makeSound() { // 可重写的方法(open 修饰)
println("动物叫")
}
}

class Dog : Animal() {
override fun makeSound() { // 重写父类方法(override 修饰)
println("汪汪叫")
}
}

2. 接口

interface 定义,支持默认方法实现,类用 : 实现接口(可多实现):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
interface Swimable {
// 抽象方法(无实现)
fun swim()

// 默认方法(有实现)
fun breath() {
println("在水中呼吸")
}
}

class Fish : Swimable {
override fun swim() {
println("鱼游来游去")
}
}

六、空安全(核心特性)

Kotlin 区分可空类型(可能为 null)和非空类型(不可为 null),编译期避免空指针:

1. 可空类型标记

在类型后加 ? 表示可空:

1
2
3
4
5
var str: String = "abc"  // 非空类型,不能赋值 null
str = null // 编译报错

var nullableStr: String? = "xyz" // 可空类型
nullableStr = null // 合法

2. 安全操作符

  • **安全调用 ?.**:若对象为 null,则表达式返回 null(不崩溃)

    1
    val length = nullableStr?.length  // 若 nullableStr 为 null,length 为 null
  • **Elvis 操作符 ?:**:若左侧为 null,则返回右侧默认值

    1
    val len = nullableStr?.length ?: 0  // 若为 null,返回 0
  • **非空断言 !!**:强制认为对象非空,若为 null 则抛出 NullPointerException(谨慎使用)

    1
    val len = nullableStr!!.length  // 若 nullableStr 为 null,崩溃

七、集合框架

Kotlin 集合分为不可变(默认,只读)和可变(可读写),通过不同函数创建:

集合类型 不可变(只读) 可变(可读写)
列表 listOf() mutableListOf()
集合 setOf() mutableSetOf()
映射 mapOf() mutableMapOf()
1
2
3
4
5
6
7
8
9
10
// 不可变列表(无法添加/删除元素)
val list = listOf(1, 2, 3)

// 可变列表
val mutableList = mutableListOf(1, 2, 3)
mutableList.add(4) // 合法

// 映射(键值对)
val map = mapOf("name" to "Kotlin", "version" to 1.9)
println(map["name"]) // 输出 "Kotlin"

集合操作(函数式风格):

1
2
3
4
val numbers = listOf(1, 2, 3, 4, 5)
val evenNumbers = numbers.filter { it % 2 == 0 } // 过滤偶数:[2,4]
val squares = numbers.map { it * it } // 求平方:[1,4,9,16,25]
val sum = numbers.reduce { acc, num -> acc + num } // 累加:15

八、扩展函数

无需继承,直接给现有类添加新方法(如给 StringisEmail 方法):

1
2
3
4
5
6
7
8
// 给 String 扩展一个判断是否为邮箱的方法
fun String.isEmail(): Boolean {
return contains("@") && contains(".")
}

// 使用
val email = "test@example.com"
println(email.isEmail()) // 输出 true

Android 中常用:给 Context 扩展 toast 方法,简化弹窗:

1
2
3
4
5
6
fun Context.toast(message: String) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}

// 在 Activity 中直接调用
toast("Hello Kotlin")

九、Lambda 表达式与高阶函数

1. Lambda 表达式

匿名函数,语法:{ 参数 -> 函数体 },常用于简化回调:

1
2
3
4
5
6
7
8
9
// 定义一个接收 Lambda 的函数
fun doSomething(action: () -> Unit) {
action() // 执行 Lambda
}

// 调用:传递 Lambda
doSomething {
println("执行操作") // 输出 "执行操作"
}

2. 高阶函数

参数或返回值为函数的函数(如集合的 filtermap):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 高阶函数:参数为 (Int) -> Boolean 类型的函数
fun filterNumbers(numbers: List<Int>, predicate: (Int) -> Boolean): List<Int> {
val result = mutableListOf<Int>()
for (num in numbers) {
if (predicate(num)) { // 调用传入的函数
result.add(num)
}
}
return result
}

// 调用:传递 Lambda 作为参数
val nums = listOf(1, 2, 3, 4, 5)
val evenNums = filterNumbers(nums) { it % 2 == 0 } // 过滤偶数:[2,4]

十、协程(Coroutines)

Kotlin 用于异步编程的核心特性,解决回调地狱,让异步代码像同步代码一样直观(Android 中用于网络请求、数据库操作等耗时任务):

1. 基本用法

需添加依赖(kotlinx-coroutines-core),用 launch 启动协程,suspend 标记 suspend 函数:

1
2
3
4
5
6
7
8
9
10
11
12
import kotlinx.coroutines.*

fun main() {
// 启动协程(在主线程的协程作用域中)
runBlocking {
launch { // 启动一个新协程
delay(1000) // 暂停 1 秒(非阻塞,不阻塞主线程)
println("协程执行完成")
}
println("主线程继续执行")
}
}

2. 关键概念

  • 协程作用域(CoroutineScope):管理协程生命周期(如 Android 中的 lifecycleScope)。
  • suspend 函数:只能在协程或其他 suspend 函数中调用,可包含耗时操作。
  • 非阻塞:协程暂停时,线程可执行其他任务,提高效率。

十一、与 Java 互操作

  • 调用 Java 代码:直接使用,无需额外处理(如调用 java.util.ArrayList)。
  • Java 调用 Kotlin 代码:
    • Kotlin 类默认是 final,Java 需用 open 修饰才能继承。
    • 顶层函数(不在类中的函数)会被编译为 文件名Kt 类的静态方法。

Android四大组件的核心概念

一、Activity(活动)

核心定义

  • 用户交互界面单元,每个屏幕对应一个Activity
  • 通过Intent实现页面跳转(正向/逆向均需重点监控)

关键特性

  • 生命周期onCreate()onStart()onResume()onPause()onStop()onDestroy()
  • 启动模式:standard/singleTop/singleTask/singleInstance(逆向时关注任务栈管理)
  • 布局绑定:通过setContentView()关联XML布局

逆向关注点

  • 查找Launcher Activity(应用入口):
1
2
3
4
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
  • 分析startActivityForResult()跨组件通信
  • Hook onActivityResult()获取数据回传逻辑

二、Service(服务)

核心定义

  • 后台运行组件,无界面(常驻/耗时操作)
  • 两种启动方式:
    • **startService()**(长期运行,如音乐播放)
    • **bindService()**(IPC跨进程通信)

生命周期差异

  • 启动式onCreate()onStartCommand()onDestroy()
  • 绑定式onCreate()onBind()onUnbind()onDestroy()

逆向关注点

  • 识别Foreground Service(通知栏常驻,需反编译检查通知配置)
  • 分析IntentService的消息处理机制
  • 检测startForeground()防杀保活手段
  • 定位跨进程通信的AIDL接口

三、BroadcastReceiver(广播接收器)

核心定义

  • 系统/应用事件监听器(如网络变化、短信接收)
  • 两种注册方式:
    • 静态注册:AndroidManifest.xml声明(系统广播)
    • 动态注册:代码中registerReceiver()(应用内广播)

事件响应流程

  1. 发送广播:sendBroadcast(intent)
  2. 匹配接收器:通过IntentFilter筛选
  3. 执行onReceive()逻辑

逆向关注点

  • 监控敏感广播(如BOOT_COMPLETED开机自启)
  • 分析有序广播的优先级滥用:
1
2
3
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
  • Hook abortBroadcast()拦截广播传递链

四、ContentProvider(内容提供者)

核心定义

  • 跨应用数据共享的标准化接口(数据库/文件)
  • 通过URI标识数据源:
1
2
3
content://com.example.provider/user/1
↑ ↑ ↑ ↑
协议 包名 表名 记录ID

核心方法

  • query():查询数据
  • insert():插入数据
  • update():更新数据
  • delete():删除数据
  • getType():返回MIME类型

逆向关注点

  • 解析<provider>声明中的权限控制
1
2
3
4
<provider 
android:authorities="com.example.provider"
android:readPermission="READ_DATA"
android:writePermission="WRITE_DATA"/>
  • 追踪ContentResolver的CRUD操作路径
  • 检测URI注入漏洞(未校验外部输入)

五、四大组件共性特征

1. 清单文件声明

所有组件必须在AndroidManifest.xml注册:

1
2
3
4
<activity android:name=".MainActivity"/>
<service android:name=".MyService"/>
<receiver android:name=".MyReceiver"/>
<provider android:name=".MyProvider"/>

2. Intent通信机制

  • 显式Intent:明确指定组件类名(逆向易追踪)
  • 隐式Intent:通过Action/Category匹配(需反编译查看过滤条件)

3. 逆向工程切入点

  • 入口分析:定位Launcher Activity和开机广播接收器
  • 协议破解:监控ContentProvider的数据读写格式
  • Hook位置:选择组件生命周期方法注入代码(如Activity的onCreate()

逆向实战技巧

  1. 快速定位组件

    • 使用apktool反编译后,在AndroidManifest.xml搜索组件声明
    • 通过jadx-gui查看组件的Java/Kotlin实现类
  2. 动态行为监控

    • 使用logcat过滤组件生命周期日志:

    • adb logcat | grep -E "ActivityManager|BroadcastRecord"
      
    • Frida Hook android.app.ActivityonCreate()方法

3.安全漏洞挖掘

  • 检测exported=true的暴露组件(未授权访问风险)
  • 分析Intent传递的Bundle数据是否缺少校验
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2025 唐小唐
  • 访问人数: | 浏览次数: