0%

概述

对于JNI,有些童鞋在没有接触过的时候,可能会觉得比较复杂,但是其实当你真正去了解、去使用的时候,就会发现JNI的使用还是比较简单的,JNI本身提供了一系列的API让我们可以在native方法中操作java。JNI的使用无非也就是使用这些接口和java交互。这几天在学习JNI接口的时候,发现网上搜索的JNI的中文虽然不少,但是很多都是零零碎碎的小例子,有一些官方文档的翻译,但要么是不全面,要么是资料比较旧了,干脆自己根据java native interface specification整理了一份技术资料。当然,很多时候看中文资料是词不达意的,如果文中有疑问的地方欢迎指出,或者翻阅原文

首先,JNI是一个本地编程接口。它允许运行在Java虚拟机的Java代码与用其他语言(如C,C++和汇编)编写的库交互
JNI最大的好处是JNI不受Java虚拟机实现方式的限制,因此,Java虚拟机厂商添加JNI的支持并不会影响虚拟机其它功能模块。native代码只需要编写一遍,就可以在所有支持JNI的虚拟机上工作。

通过JNI,你可以在native代码中:

  • 创建、检查或者更新java对象
  • 调用java方法
  • 捕捉和抛出异常
  • 加载class和获取class信息
  • 运行时类型检查
阅读全文 »

Android应用程序使用NDK的意义在这里就不说了,本文主要讲解如何在Android Studio 2.2下如何一步步搭建NDK开发环境。

下载NDK和工具

Android Studio2.2开始推荐开发者使用CMake去构建本地代码,在构建之前,我们需先安装下面三个依赖:

  • NDK: a set of tools that allows you to use C and C++ code with Android.
  • CMake: an external build tool that works alongside Gradle to build your native library. You do not need this component if you only plan to use ndk-build.
  • LLDB: the debugger Android Studio uses to debug native code.

2019-9-2-11-11-0.png

我们可以使用SDK Manager进行下载,菜单位置:Tools > Android > SDK Manager,勾选后安装即可

阅读全文 »

ProGuard简介和工作流程

ProGuard能够通过压缩、优化、混淆、预检等操作,检测并删除未使用的类,字段,方法和属性,分析和优化字节码,使用简短无意义的名称来重命名类,字段和方法。从而使代码更小、更高效、更难进行逆向工程。
2019-9-2-10-59-30.png

上图就是ProGuard的工作流程,分别会经过四个阶段:

  1. 压缩(Shrink):在压缩处理这一步中,用于检测和删除没有使用的类,字段,方法和属性
  2. 优化(Optimize):在优化处理这一步中,对字节码进行优化,并且移除无用指令
  3. 混淆(Obfuscate):在混淆处理这一步中,使用a,b,c等无意义的名称,对类,字段和方法进行重命名
  4. 预检(Preveirfy):在预检这一步中,主要是在Java平台上对处理后的代码进行预检

以上四个步骤都是可选的,我们可以通过配置脚本来决定其中的哪几个步骤。比如我们可以配置只压缩和混淆,不进行优化,不进行预检。
ProGuard的官网有使用指导:http://proguard.sourceforge.net/

阅读全文 »

Lua栈

要理解Lua和C++交互,首先要理解Lua堆栈。简单来说,Lua和C/C++语言通信的主要方法是一个无处不在的虚拟栈。栈的特点是先进后出

在Lua中,Lua堆栈就是一个struct,堆栈索引的方式可是是正数也可以是负数,区别是:正数索引1永远表示栈底,负数索引-1永远表示栈顶,如图:
2019-9-2-10-56-15.png

入栈的数据类型包括数值, 字符串, 指针, talbe, 闭包等, 下面是一个栈的例子:
2019-9-2-10-56-27.png

阅读全文 »

什么是Lua

Lua 是一门强大、快速、轻量的嵌入式脚本语言。它由巴西里约热内卢 Pontifical Catholic 大学的 PUC-Rio 团队 开发。 Lua 是一个 自由软件, 广泛应用于世界上无数产品和项目

应用场景:

  • 游戏开发
  • 独立应用脚本
  • Web 应用脚本
  • 扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench
  • 安全系统,如入侵检测系统
阅读全文 »

什么是64K限制和LinearAlloc限制

64K限制

随着Android应用功能的增加,代码量不断地增大,当应用方法数量超过了65536的时候,编译的时候便会提示:
2019-9-2-10-54-5.png

这个Android著名的Dex 64k method数量上限。那么,是什么原因导致方法数不能超过64K呢?网上搜集了一下资料,原因一般有:

  1. DexOpt优化的限制:当Android系统启动一个应用的时候,有一步是对Dex进行优化,这个过程有一个专门的工具来处理,叫DexOpt。DexOpt的执行过程是在第一次加载Dex文件的时候执行的。这个过程会生成一个ODEX文件,即Optimised Dex。执行ODex的效率会比直接执行Dex文件的效率要高很多。但是在早期的Android系统中,DexOpt有一个问题,也就是这篇文章想要说明并解决的问题。DexOpt会把每一个类的方法id检索起来,存在一个链表结构里面。但是这个链表的长度是用一个short类型来保存的,导致了方法id的数目不能够超过65536个。当一个项目足够大的时候,显然这个方法数的上限是不够的。尽管在新版本的Android系统中,DexOpt修复了这个问题,但是我们仍然需要对老系统做兼容
  2. dalvik bytecode的限制:因为 Dalvik 的 invoke-kind 指令集中,method reference index 只留了 16 bits,最多能引用 65535 个方法,参考链接:http://stackoverflow.com/questions/21490382/does-the-android-art-runtime-have-the-same-method-limit-limitations-as-dalvik/21492160#21492160,http://source.android.com/devices/tech/dalvik/dalvik-bytecode.html

鉴于以上原因,在打包Android应用的时候,会对方法数做一个检测,当方法数超过了DexFormat.MAX_MEMBER_IDX(定义为0Xffff, 注意,这个不是Dex文件格式的限制,Dex文件中存储方法ID用的并不是short类型,无论最新的DexFile.h新定义的u4是uint32_t,还是老版本DexFile引用的vm/Common.h里定义的u4是uint32或者unsigned int,都不是short类型,特此说明)便报错

阅读全文 »

什么是Makefile

Makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,文件之间有哪些依赖等。Makefile有自己的书写格式、关键字、函数。像C 语言有自己的格式、关键字和函数一样。而且在Makefile中可以使用系统shell所提供的任何命令来完成想要的工作。
Makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率

makefile的文件名

默认的情况下,make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件,找到了解释这个文件。在这三个文件名中,最好不要用“GNUmakefile”,这个文件是GNU的make识别的。有另外一些make只对全小写的“makefile”文件名敏感,但是基本上来说,大多数的make都支持“makefile”和“Makefile”这两种默认文件名。

当然,你可以使用别的文件名来书写Makefile,比如:“Make.Linux”,“Make.Solaris”,“Make.AIX”等,如果要指定特定的Makefile,你可以使用make的“-f”和“–file”参数,如:

1
2
make -f Make.Linux
make --file Make.AIX
阅读全文 »

用openssl指令逐步生成各个文件

  1. 生成服务器密钥:openssl genrsa -out server_private.key 2048

  2. 从密钥生成公钥(非必须):openssl rsa -in server_private.key -pubout > server_public.key

  3. 生成证书请求文件,这里会让你输入一堆信息,比如组织名称、个人信息等:openssl req -new -key server_private.key -out server_req.csr

  4. 初始化CA环境

    1
    2
    3
    4
    5
    6
    mkdir demoCA
    cd demoCA
    mkdir certs crl newcerts
    touch index.txt serial
    echo 00 > serial
    cd ..
  5. 生成ca密钥:openssl genrsa -out ca.key 2048

  6. 生成ca证书:openssl req -new -x509 -key ca.key -out ca.crt

  7. 用ca对服务器证书请求文件进行签名:openssl ca -in server_req.csr -out server.crt -cert ca.crt -keyfile ca.key -config /usr/ssl/openssl.cnf

  8. 可以把服务端的私钥和已签名的证书合并到一个pkcs12格式的文件:openssl pkcs12 -export -out server.pfx -inkey server_private.key -in server.crt

  9. 也可以把pkcs12格式转化为java常用的jks格式:keytool -importkeystore -v -srckeystore server.pfx -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore server.jks -deststoretype jks -deststorepass 123456

阅读全文 »

参考文档:Pro Git(中文版)

git已经越来越常用了,但是很多用惯了svn的童鞋使用git的时候,一开始对git应该不太习惯,比如我~~,但是用习惯了之后,发现git还真是好用,哈哈。git的使用和介绍分为两篇,第一篇将一些基础的指令和概念,第二篇讲git分支。下面就整理了一些git常用的命令:

查看已有配置

1
git config --list
阅读全文 »

Https通信基本过程

在通信过程中,https是如何保证通信的安全的?如何加密信息,如何防止中间人攻击?
以下是客户端发起https请求的时候的流程:

2019-9-2-10-48-38.png

流程解析如下:

  1. 客户端发送随机数client_random和支持的加密方式列表
  2. 服务器返回随机数server_random,选择的加密方式和证书(经过ca颁发,或者自签名的证书,该证书包含公钥)
  3. 客户端验证证书,使用证书中的公钥加密premaster secret发送给服务端
  4. 服务端使用私钥解密得到premaster secret
  5. 两端分别通过client_random,server_random和premaster secret生成master secret,用于对称加密后续通信内容

整个过程主要的作用是让双方安全地协商出一个key,这个key会用于对称加密中。第三方即使截取了所有的通信数据,也是无法获取到这个key的。既然第三方无法获取这个key,自然也对加密过的数据无可奈何了。大家看到这里可能一脸懵逼,可能会有以下疑问:

  • 这个过程是如何保证key不会被中间人窃取呢?
  • 客户端/服务端如何确认对方就是“正确的人”,而不是其他中间人呢?
阅读全文 »