@+id/id_name 是定义
中通过来注册activity
在中通过声明哪个是主activity
<intent-filter>
<action android:name = "android.intent.action.MAIN"/>
<category android:name ="android.intent.category.LAUNCHER" />
</intent-filter>
toast将一些消息通知给用户,后自动消失
findViewById()获取布局文件中控件得实例
kotlin-android-extensions自动创建了
setOnClickListener()注册了一个监听器
button1.setOnClickListener{
Toast.makeText(this, "you push buttons", Toast.LENGTH_SHORT).show()
}
menus控件
创建具体的菜单项
intent是android各组件交互的主要方式
显式intent
button1.setOnClickListener{
val intent = Intent(this,SecondActivity::class.java)
startActivity(intent)
}
隐式intent
在相应的activity下给予定义
<intent-filter>
<action android:name="com.example.activitytest.ACTION_START"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
在主activity中写 val intent = Intent("com.example.activitytest.ACTION_START")
startActivity(intent)
category可以写多个
更多隐式intent
说百了 就是在xml中自己定义action category就行
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("https://www.baidu.com")
startActivity(intent)
intent数据传递
activity1
super.onCreate(savedInstanceState)
setContentView(R.layout.first_layout)
button1.setOnClickListener{
val data = "hello activity2"
val intent = Intent(this,SecondActivity::class.java)
intent.putExtra("extra_data",data)
startActivity(intent)
}
activity2
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
val extrada = intent.getStringExtra("extra_data")
Toast.makeText(this,"success $extrada",Toast.LENGTH_SHORT).show()
返回数据给上一个activity
startActivityForResult()
val intent = Intent(this,SecondActivity::class.java)
startActivityForResult(intent,1)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when(requestCode)
{
1-> if(resultCode== Activity.RESULT_OK){
val returneddata = data?.getStringExtra("data_return")
Toast.makeText(this,"$returneddata",Toast.LENGTH_SHORT).show()
}
}
}
button2.setOnClickListener {
val intent = Intent()
intent.putExtra("data_return","hello firstactivity")
setResult(Activity.RESULT_OK,intent)
finish()
}
activity
activity状态
运行,暂停,停止,销毁
oncreate() 初始化
onStart() 不可见变为可见时调用
onResume() 在与用户交互时调用
onPause()启用别的activity 将数据保存
onRestart() 由停止变成运行状态时调用
onDestroy()app被摧毁
onstop() //不可见执行 dialog 不会执行 其他的activity覆盖时将当前stop doalog没有覆盖,所以不用
activity的启动模式
standard:每启动一个activity,就将当前的activity入栈
singleTop:在启动activity时发现返回栈的栈顶是activity,不会再创建新的activity实例
androidManifest.xml在activty中 加入 android:launchMode = “singleTop”
singleTask:在启动activity时,发现栈中有该activity,将它之上的全部弹出,重新启动她
singleInstance:单独自己一个栈
kotlin学习
val result = with(StringBuilder())
{
append("start eating fruits\n")
for(fruit in list)
append(fruit+"\n")
append("finish eating\n")
toString()
}
run obj.run{} //最后一行代码作为返回值
applt obj.apply{} //自动返回调用对象本身
object //单例类
companion object //静态函数
@JvmStatic 真正的静态函数
顶层方法 直接在包名下kt文件 静态方法
frida使用
java对象
Java.available() 判断当前进程是否加载了Javavm,dalvik,art虚拟机
Java.androidVersion() 显示android系统版本号
Java.enumerateLoadedClasses() 枚举当前加载的所有类信息,有回调函数onMatch(),onComplete()
function frida_Java(){
Java.perform(function(){
if(Java.available())
{
Java.enumerateLoadedClasses({
onMatch : function(classname){
console.log("",classname)
},
onComplete: function(){
console.log("输出完毕")
}
});
}
else{
console.log("error");
}
});
}
setImmediate(frida_Java,0)
Java.enumerateClassLoaders加载所有类的信息有回调函数,onMatch: function(loader) 与 onComplete: function()
function frida_Java(){
Java.perform(function(){
if(Java.available)
{
Java.enumerateClassLOaders({
onMatch : function(loader){
console.log("".loader)
}
onComplete: function(){
console.log("输出完毕")
}
});
}
else{
console.log("error")
}
});
}
setImmediate(frida_Java,0)
*Java.perform(fn)*主要用于当前线程附加到java vm并调用fn
Java.use(classname),动态获取classname的类定义,调用
n
e
w
(
)
来
调
用
构
造
函
数
,
实
例
化
对
象
,
当
想
要
回
收
类
时
可
以
嗲
用
new()来调用构造函数,实例化对象,当想要回收类时可以嗲用
new()来调用构造函数,实例化对象,当想要回收类时可以嗲用dispose()现性释放,当然也可以等待javascript的垃圾回收机制(那肯定用它啊。。)
Java.choose()在堆上查找实例化的对象
Java.perform(function(){
Java.choose("android.view.view",{
onMatch : function(instance){
console.log(instance)
},
onComplete: function(){
console.log("end")
}
});
});
Java.cast类型转换器
Java.array定义java数组 Java.array(‘type’,[value1,value2,…]);
Java.perform(function(){
var intarr = Java.arr('int',[1003,1005,1007]);
var bytearr = Java.arr('byte',[0x48,0x65,0x69]);
for(var i =0 ; i < bytearr.length ; ++i)
{
console.log(bytearr[i])
}
});
Java.registerClass(spec)感觉没用
Java.vm对象十分常用,拿到JNI层的JNIEnv对象,getEnv() 没理解,之后再看
interceptor对象
感觉之后就都是so的了
Interceptor.attach(target,callbacks),target是需要拦截的位置的函数地址,也是填某个so层函数的地址,对其拦截
target是一个NativePointer函数,用来指定你想要拦截的函数的地址,NativePointer我们也学过是一个指针
callback回调函数:onEnter(args) args那个函数的地址
onLeave(retval): retval是返回参数,retval.replace(1337),也可以是指针retval.replace(ptr(“0x1234”))
这里的args,retval都是NativePointer
Interceptor.attach(Module.getExportByName("libc.so","read",{
onEnter: function(args){
this.fileDescriptor = args[0].toInt32()
},
onLeave: function(retval){
}
});
interceptor
属性: 含义
returnAddress 返回地址(NativePointer)
context 上下文eip,esp,sp的
errno 当前errno值
lastError 当前操作系统错误值
threadid 线程id
depth 相对于其他调用的调用深度?
function frida_Interceptor(){
Java.perform(function(){
Interceptor.attach(Module.findExportByName("libhello.so","Java_com_roysue_roysueapplication_hellojni"),{
onEnter: function(args){
console.log("Context information:");
console.log("context : "+JSON.stringify(this.context));
console.log("address: " + this.returnAddress);
console.log("ThreadId: " + this.ThreadId);
console.log("Depth: " + this.depth);
console.log("errorno:" + this.err);
},
onLeave : function(retval){}
});
});
}
Interceptor.detachAll让之前所有的Interptor.attach附加拦截的回调函数失效
Interceptor.replace() 替换掉原本的函数
function frida_Interceptor(){
Java.perform(function(){
var add_method = new NativeFunction(Module.findExportByName("libhello.so","c_getSum"),'int',['int','int']);
console.log("result:",add_method(1,2));
Interceptor.replace(add_method,new NativeCallback(function(a,b){
return 123;
},'int',['int','int']));
console.log("result:",add_method(1,2));//123
});
}
NativePointer对象
c语言的指针
new NativePointer(s)
function frida_NativePointer() {
Java.perform(function () {
//第一种字符串定义方式 十进制的100 输出为十六进制0x64
const ptr1 = new NativePointer("100");
console.log("ptr1:",ptr1);
//第二种字符串定义方式 直接定义0x64 同等与定义十六进制的64
const ptr2 = new NativePointer("0x64");
console.log("ptr2:",ptr2);
//第三种定数值义方式 定义数字int类型 十进制的100 是0x64
const ptr3 = new NativePointer(100);
console.log("ptr3:",ptr3);
});
}
NativeFunction对象
创建新的NativeFunction以调用address处的函数(用NativePointer指定),其中rereturn Type指定返回类型,argTypes数组指定参数类型。如果不是系统默认值,还可以选择指定ABI。对于可变函数,添加一个‘.’固定参数和可变参数之间的argTypes条目,我们来看看官方的例子。
new NativeFunction(address, returnType, argTypes[, options]),
NativeCallback对象
new NativeCallback(func,rereturn Type,argTypes[,])