frida学习(process,module,memory) && android开发学习(结构,kotlin)(二)

FRIDA输出打印

console.log()
console.warn()
console.error()

console之hexdump

打印内存中的地址
target参数可以是ArrayBuffer或者NativePointer,而options参数则是自定义输出格式可以填这几个参数offset、lengt、header、ansi

var libc = Module.findBaseAddress('libc.so');
console.log(hexdump(libc, {
  offset: 0,
  length: 64,
  header: true,
  ansi: true
}));
           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
00000000  7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00  .ELF............
00000010  03 00 28 00 01 00 00 00 00 00 00 00 34 00 00 00  ..(.........4...
00000020  34 a8 04 00 00 00 00 05 34 00 20 00 08 00 28 00  4.......4. ...(.
00000030  1e 00 1d 00 06 00 00 00 34 00 00 00 34 00 00 00  ........4...4...

send(终于知道send是干什么的了)

nd是在python层定义的on_message回调函数,jscode内所有的信息都被监控script.on(‘message’, on_message),当输出信息的时候on_message函数会拿到其数据再通过format转换, 其最重要的功能也是最核心的是能够直接将数据以json格式输出,当然数据是二进制的时候也依然是可以使用send

process 对象

Process.id:返回附加目标进程的PID
Process.isDebuggerAttached():检测当前是否对目标程序已经附加
Process.enumerateModules()会枚举当前所有已加载的so模块,并且返回了数组Module对象

function frida_Process() {
    Java.perform(function () {
        var process_Obj_Module_Arr = Process.enumerateModules();
        for(var i = 0; i < process_Obj_Module_Arr.length; i++) {
            console.log("",process_Obj_Module_Arr[i].name);
        }
    });
}
setImmediate(frida_Process,0);

Process.enumerateThreads():枚举当前所有的线程,返回包含以下属性的对象数组:id.state,context
Process.getCurrentThreadId():获取此线程的操作系统特定 ID 作为数字(感觉没用)

module对象

Process.EnumererateModules()方法返回了就是一个Module对象
Module对象的属性
1 name 模块名称
2 base 模块地址,其变量类型为NativePointer
3 size 大小
4 path 完整文件系统路径

Module.load() //加载指定so文件,返回一个Module对象
function frida_module(){
Java.
  const hook = Module.load("libhello.so");
  console.log("模块名称:",hook.name);
  console.log("模块地址:",hook.base);
  console.log("模块大小:",hook.size);
  console.log("路径:",hook.path);
}	
Process.EnumererateModules() 
function frida_Module(){
   Java.perform(function(){
           var process_Obj_Module_Arr = Process.enumerateModules();
           for(var i = 0; i < process_Obj_Module_Arr.length; ++i)
           {
              if(process_Obj_Module_Arr[i].path.indexOf("hello") != -1)
              {
                         console.log("模块名称:",process_Obj_Module_Arr[i].name);
                         console.log("模块地址:",process_Obj_Module_Arr[i].base);
                         console.log("模块大小:",process_Obj_Module_Arr[i].size);
                         console.log("模块路径:",process_Obj_Module_Arr[i].path);
               }
           }

 });
}
setImmediate(frida_Module,0);
enumerateImports() //枚举模块中所有import函数
function frida_Module(){
     Java.perform(function(){
                const hooks = Module.load("libhello.so");
                var Imports = hooks.enumerateImports();
                for(var i =0 ; i < Imports.length ; ++i){
                       console.log("type:",Imports[i].type);
                       console.log("name:",Imports[i].name);
                       console.log("module:",Imports[i].module);
                       console.log("address:",Imports[i].address);
           }
    });
}
setImmediate(frida_Module,0);
enumerateExports() // 枚举模块中exports函数
function frida_Module(){
    Java.perform(function(){
              const hooks = Module.load("libhello.so");
              var Exports = hooks.enumerateExports();
              for(var i = 0 ; i < Exports.length ; ++i){
                     console.log("type:",Exports[i].type);
                     console.log("name:",Exports[i].name);
                     console.log("address:",Exports[i].address);
}

  });

}
setImmediate(frida_Module,0);
	enumerateSymbols() //枚举所有symbol库函数,返回Module数组对象
	function frida_Module() {
    Java.perform(function () {
        const hooks = Module.load('libc.so');
        var Symbol = hooks.enumerateSymbols();
        for(var i = 0; i < Symbol.length; i++) {
            console.log("isGlobal:",Symbol[i].isGlobal);
            console.log("type:",Symbol[i].type);
            console.log("section:",JSON.stringify(Symbol[i].section));
            console.log("name:",Symbol[i].name);
            console.log("address:",Symbol[i].address);
         }
    });
}
setImmediate(frida_Module,0);
Module.findExportByName(exportName), Module.getExportByName(exportName)
返回so文件中Export函数库中函数名称为exportName函数的绝对地址
function frida_Module() {
    Java.perform(function () {
        Module.getExportByName('libhello.so', 'c_getStr')
        console.log("Java_com_roysue_roysueapplication_hellojni_getStr address:",Module.findExportByName('libhello.so', 'Java_com_roysue_roysueapplication_hellojni_getStr'));
        console.log("Java_com_roysue_roysueapplication_hellojni_getStr address:",Module.getExportByName('libhello.so', 'Java_com_roysue_roysueapplication_hellojni_getStr'));
    });
}
setImmediate(frida_Module,0)
Module.findBaseAddress(name)、Module.getBaseAddress(name) // 返回name模块的基地址

function frida_Module() {
    Java.perform(function () {
        var name = "libhello.so";
        console.log("so address:",Module.findBaseAddress(name));
        console.log("so address:",Module.getBaseAddress(name));
    });
}
setImmediate(frida_Module,0);

Memory对象

Memory.scan
搜索内存中以address地址开始,搜索长度为size,需要搜是条件是pattern,callbacks搜索之后的回调函数;此函数相当于搜索内存的功能。

function frida_Memory() {
    Java.perform(function () {
        //先获取so的module对象
        var module = Process.findModuleByName("libhello.so"); 
        //??是通配符
        var pattern = "03 49 ?? 50 20 44";
        //基址
        console.log("base:"+module.base)
        //从so的基址开始搜索,搜索大小为so文件的大小,搜指定条件03 49 ?? 50 20 44的数据
        var res = Memory.scan(module.base, module.size, pattern, {
            onMatch: function(address, size){
                //搜索成功
                console.log('搜索到 ' +pattern +" 地址是:"+ address.toString());  
            }, 
            onError: function(reason){
                //搜索失败
                console.log('搜索失败');
            },
            onComplete: function()
            {
                //搜索完毕
                console.log("搜索完毕")
            }
          });
    });
}
setImmediate(frida_Memory,0);
function frida_Memory() {
    Java.perform(function () {
        const r = Memory.alloc(10);
        console.log(hexdump(r, {
            offset: 0,
            length: 10,
            header: true,
            ansi: false
        }));
    });
}
setImmediate(frida_Memory,0);
emory.allocUtf8String(str) 分配utf字符串
Memory.allocUtf16String 分配utf16字符串
Memory.allocAnsiString 分配ansi字符串
写入内存Memory.writeByteArray
function frida_Memory() {     
    Java.perform(function () {
        //定义需要写入的字节数组 这个字节数组是字符串"roysue"的十六进制
        var arr = [ 0x72, 0x6F, 0x79, 0x73, 0x75, 0x65];
        //申请一个新的内存空间 返回指针 大小是arr.length
        const r = Memory.alloc(arr.length);
        //将arr数组写入R地址中
        Memory.writeByteArray(r,arr);
        //输出
        console.log(hexdump(r, {
            offset: 0,
            length: arr.length,
            header: true,
            ansi: false
        }));  
    });
}
setImmediate(frida_Memory,0);

读取内存Memory.readByteArray
function frida_Memory() {     
    Java.perform(function () {
        //定义需要写入的字节数组 这个字节数组是字符串"roysue"的十六进制
        var arr = [ 0x72, 0x6F, 0x79, 0x73, 0x75, 0x65];
        //申请一个新的内存空间 返回指针 大小是arr.length
        const r = Memory.alloc(arr.length);
        //将arr数组写入R地址中
        Memory.writeByteArray(r,arr);
        //读取r指针,长度是arr.length 也就是会打印上面一样的值
        var buffer = Memory.readByteArray(r, arr.length);
        //输出
        console.log("Memory.readByteArray:");
        console.log(hexdump(buffer, {
            offset: 0,
            length: arr.length,
            header: true,
            ansi: false
        }));
      });  
    });
}
setImmediate(frida_Memory,0);

安卓开发

结算自第一行代码
自我认为的重点
在AndroidManifest.xml中

<intent-filter>
   <action android:name="android.intent.action.MAIN" />
   <category android:name="android.intent.category.LAUNCHER">
</intent-filter>

表面这个项目的主activity
AppcompatActivity是一种向下兼容的Activity,在不同系统版本功能保持一致
onCreate()是Activity被创建时必定要执行的方法
android讲究逻辑和视图布局分离
布局文件编写页面,activity引入进来
setContentView()引入布局
drawable放图片
mipmap放应用图标
values放字符串,样式,颜色…
layout放布局文件
定义了应用程序名的字符串

在代码中R.string.app_name获得该字符串的引用
在xml中通过@string/app_name获得该字符串的引用
最外层的build.gradle中
google() google自家的扩展依赖库
jcenter() 第三方开源库
Log.v()
Log.d()
Log.i()
Log.w()
Log.e()

kotlin学习

java 生成java.class由jvm执行
kotlin将kotlin编译成java.class交给jvm执行
有毛病啊,,语法糖这么多。。学习成本真高。。。
再次重申:kotlin就是个垃圾

//变量
val  //不可变 final
var //可变
va1 a:Int = 10 //类型声明
//函数
fun largenumber(a1:Int,a2:Int): Int{ return max(a1,a2)}
//函数语法糖
fun largenumber(a1:Int,a2:Int) = max(a1,a2)
//if 
和java差不多
但是可以将每个条件的最后一行代码为返回值
fun biggest(a1:Int,a2:Int) = if(a1>a2) a1 else a2
//when 和java switch差不多 但nb很多
匹配值 -> {执行逻辑}
fun getscore(name:String) = when(name)
    {
        "Tom" -> 67
        "alice" ->80
        "nmsl" -> 89
        else ->0
    }
  //when还可以类型匹配
  fun checknum(num:Number) = when(num)
{
    is Int -> println("is int")
    is Double -> println("is double")
    else -> println("fuck")
}
//循环 while差不多 for变得比较多
for(i in 0..10) [0,10]
for(i in 0 until 10) [0,10)
for(i in 0 until 10 step 2)// python for i in range(0,10,2)
for(i in 10 downTo 1 ) [10,1]
//面向对象
class Person {
    var age=0
    var name=""
    fun eat() = println(name + "eating,his age is" + age)

}
open 表示这个类可以继承
class Student(val sno: String, val grade: Int, ag: Int, na: String) : Person(na, ag) {}
后面两个不加val,是初始化超类得字段
init{}//构造函数内做的事
接口
interface Study{
fun readBoooks()
fun doHomework()
}
public private protected internal

// lambda 表达式
 val list = ArrayList<String>()
    list.add("apple")
    list.add("banana")
    list.add("orange")
    list.add("pear")
    list.add("grape")
    val list1 = listOf("apple","orange","banana","grape","pear")//固定列表
    val list2 = mutableListOf("apple","fuck","pear","grape") //可变列表
val set = setOf("apple","pear")//固定集合
val set1 = mutableSetOf("pear","sdsdjks")//可变集合
           mapOf()//不可变
 val map = mutableMapOf("apple" to 1,"banana" to 2,"grapw" to 3)//可变map
    map["fuck"] =34
    for((num,fruit) in map)
        println("num: " + num +" fruit: " + fruit)
        //map按照方式映射
     val list = listOf("banana","apple","grape","nmsl")
    val list1 = list.map{it.toUpperCase()} 
      any()//判断集合中是否由指定元素完成条件
      all()//是否所有元素都满足条件
      filter()//筛选满足条件得
     要空指针用?
fun doStudy(study : Study?)
{
   if(study != null)
   {
      study.readbooks()
      study.dohomework()
   }
     }
     a?.doSomething =={
                   if(a != null)
                   a.doSomething()
}
val c = a?:b =={
   if(a!=null)
   a
   else b
}
obj1.let(obj2-<  lambda表达式)
val num=1
val name = "nmsl"
print("$name is $num")//字符串内嵌表达式
参数初始化蛮简单得 和c++差不多
    a(old = 1000,name = "fdghgfhdhgdh")
    fun a(name :String = "nmsl",old : Int = 10) = println("$name is $old  old")
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值