package com.taobao.wireless.security.adapter.JNICLibrary;
import
com.alibaba.fastjson.util.IOUtils;
import
com.github.unidbg.AndroidEmulator;
import
com.github.unidbg.Module;
import
com.github.unidbg.Emulator;
import
com.github.unidbg.
file
.FileResult;
import
com.github.unidbg.
file
.IOResolver;
import
com.github.unidbg.
file
.linux.AndroidFileIO;
import
com.github.unidbg.linux.android.AndroidARMEmulator;
import
com.github.unidbg.linux.android.AndroidResolver;
import
com.github.unidbg.linux.android.dvm.
*
;
import
com.github.unidbg.linux.android.dvm.array.ArrayObject;
import
com.github.unidbg.linux.android.dvm.array.ByteArray;
import
com.github.unidbg.linux.android.dvm.wrapper.DvmInteger;
import
com.github.unidbg.linux.android.dvm.wrapper.DvmLong;
import
com.github.unidbg.memory.Memory;
import
java.io.
File
;
import
java.util.HashMap;
import
java.util.
Set
;
public
class
MyAli extends AbstractJni implements IOResolver<AndroidFileIO> {
private final AndroidEmulator emulator;
private final VM vm;
Module module;
DalvikModule dm;
static public
long
slot;
private final DvmClass MYJNICLibrary;
private final boolean logging;
@Override
public FileResult<AndroidFileIO> resolve(Emulator<AndroidFileIO> emulator, String pathname,
int
oflags){
System.out.println(
"[files open]->"
+
pathname);
switch (pathname){
case
"/data/app/com.rytong.ceair.apk"
:
return
FileResult.success(emulator.getFileSystem().createSimpleFileIO(
new
File
(
"unidbg-android/src/test/java/com/taobao/wireless/security/adapter/JNICLibrary/rootfs"
, pathname), oflags, pathname));
}
return
null;
}
public MyAli(boolean logging) {
this.logging
=
logging;
emulator
=
new AndroidARMEmulator(
"com.rytong.ceair"
);
final Memory memory
=
emulator.getMemory();
/
/
模拟器的内存操作接口
emulator.getSyscallHandler().addIOResolver(this);
memory.setLibraryResolver(new AndroidResolver(
23
));
/
/
设置系统类库解析
vm
=
emulator.createDalvikVM(new
File
(
"unidbg-android/src/test/java/com/taobao/wireless/security/adapter/JNICLibrary/donghang9.3.0.apk"
));
vm.setVerbose(logging);
/
/
设置是否打印Jni调用细节
vm.setJni(this);
MYJNICLibrary
=
vm.resolveClass(
"com/taobao/wireless/security/adapter/JNICLibrary"
);
}
void destroy() {
IOUtils.close(emulator);
if
(logging) {
System.out.println(
"destroy"
);
}
}
public static void main(String[] args) throws Exception {
MyAli test
=
new MyAli(true);
test.Call_doCommandNative();
test.destroy();
}
void Call_doCommandNative(){
dm
=
vm.loadLibrary(new
File
(
"unidbg-android/src/test/java/com/taobao/wireless/security/adapter/JNICLibrary/libsgmainso-5.4.193.so"
), true);
/
/
加载libttEncrypt.so到unicorn虚拟内存,加载成功以后会默认调用init_array等函数
dm.callJNI_OnLoad(emulator);
/
/
手动执行JNI_OnLoad函数
module
=
dm.getModule();
System.out.println(
"TAG Vison ------------------- [1] -------------------"
);
/
/
【
1
】
-
10101
So初始化
ArrayObject initSo_arg
=
new ArrayObject(
vm.resolveClass(
"android/content/Context"
).newObject(null),
DvmInteger.valueOf(vm,
3
),
new StringObject(vm,""),
new StringObject(vm,
"/data/user/0/com.rytong.ceair/app_SGLib"
),
new StringObject(vm,"")
);
DvmObject<?> dvmObject_initSo
=
MYJNICLibrary.callStaticJniMethodObject(emulator,
"doCommandNative(I[Ljava/lang/Object;)Ljava/lang/Object;"
,
10101
,initSo_arg);
System.out.println(
"TAG Vison ----- 10101 initSo ----- [res]:"
+
dvmObject_initSo.getValue());
System.out.println(
"TAG Vison ------------------- [2] -------------------"
);
/
/
【
2
】
-
10102
libsgmainso插件初始化
ArrayObject initSosgmain_arg
=
new ArrayObject(
new StringObject(vm,
"main"
),
new StringObject(vm,
"5.4.193"
),
new StringObject(vm,
"/data/app/com.rytong.ceair-yoTJTWpoydDKBU49a55E_A==/lib/arm/libsgmainso-5.4.193.so"
)
);
DvmObject<?> dvmObject_initSosgmain
=
MYJNICLibrary.callStaticJniMethodObject(emulator,
"doCommandNative(I[Ljava/lang/Object;)Ljava/lang/Object;"
,
10102
,initSosgmain_arg);
System.out.println(
"TAG Vison ----- 10102 initSosgmain ----- [res]:"
+
dvmObject_initSosgmain.getValue());
System.out.println(
"TAG Vison ------------------- [2-3 load-so] -------------------"
);
DalvikModule dm1
=
vm.loadLibrary(new
File
(
"unidbg-android/src/test/java/com/taobao/wireless/security/adapter/JNICLibrary/libsgsecuritybodyso-5.4.112.so"
), true);
/
/
加载libttEncrypt.so到unicorn虚拟内存,加载成功以后会默认调用init_array等函数
dm1.callJNI_OnLoad(emulator);
System.out.println(
"TAG Vison ------------------- [3] -------------------"
);
/
/
【
3
】
-
10102
libsgsecuritybodyso插件初始化
ArrayObject initSosgsecuritybody_arg
=
new ArrayObject(
new StringObject(vm,
"securitybody"
),
new StringObject(vm,
"5.4.112"
),
new StringObject(vm,
"/data/app/com.rytong.ceair-yoTJTWpoydDKBU49a55E_A==/lib/arm/libsgsecuritybodyso-5.4.112.so"
)
);
DvmObject<?> dvmObject_initSosgsecuritybody
=
MYJNICLibrary.callStaticJniMethodObject(emulator,
"doCommandNative(I[Ljava/lang/Object;)Ljava/lang/Object;"
,
10102
,initSosgsecuritybody_arg);
System.out.println(
"TAG Vison ----- 10102 initSosgsecuritybody ----- [res]:"
+
dvmObject_initSosgsecuritybody.getValue());
System.out.println(
"TAG Vison ------------------- [3-4 load-so] -------------------"
);
DalvikModule dm2
=
vm.loadLibrary(new
File
(
"unidbg-android/src/test/java/com/taobao/wireless/security/adapter/JNICLibrary/libsgavmpso-5.4.1002.so"
), true);
/
/
加载libttEncrypt.so到unicorn虚拟内存,加载成功以后会默认调用init_array等函数
dm2.callJNI_OnLoad(emulator);
System.out.println(
"TAG Vison ------------------- [4] -------------------"
);
/
/
【
4
】
-
10102
libsgavmpso插件初始化
ArrayObject initSosgavmp_arg
=
new ArrayObject(
new StringObject(vm,
"avmp"
),
new StringObject(vm,
"5.4.1002"
),
new StringObject(vm,
"/data/user/0/com.rytong.ceair/app_SGLib/app_1682143210/main/libsgavmpso-5.4.1002.so"
)
);
DvmObject<?> dvmObject_initSosgavmp
=
MYJNICLibrary.callStaticJniMethodObject(emulator,
"doCommandNative(I[Ljava/lang/Object;)Ljava/lang/Object;"
,
10102
,initSosgavmp_arg);
System.out.println(
"TAG Vison ----- 10102 initSosgavmp ----- [res]:"
+
dvmObject_initSosgavmp.getValue());
System.out.println(
"TAG Vison ------------------- [5] -------------------"
);
/
/
【
5
】
-
60901
AVMP初始化
ArrayObject initVmp_arg
=
new ArrayObject(
new StringObject(vm,
"0335_mwua"
),
new StringObject(vm,
"sgcipher"
)
);
DvmObject<?> dvmObject_initVmp
=
MYJNICLibrary.callStaticJniMethodObject(emulator,
"doCommandNative(I[Ljava/lang/Object;)Ljava/lang/Object;"
,
60901
,initVmp_arg);
long
createAVMPInstance
=
Long
.valueOf(dvmObject_initVmp.getValue().toString());
createAVMPInstance
=
createAVMPInstance&
0xffffffffL
;
System.out.println(
"TAG Vison ----- 60901 initVmp ----- [res]:"
+
createAVMPInstance);
/
/
long
createAVMPInstance
=
2242459650L
;
System.out.println(
"TAG Vison ------------------- [6] -------------------"
);
/
/
【
6
】
-
60902
wToken加密调用
String strbody
=
"{\"req\":\"S6TVWfiiBE2ZEXY9ldOr4oz9JB6+/EaSHqY1/vILbUs/6L2Eqv3e8m2QToNujniIPYeDZRK4Gr6fVX+hRS4f9aWHsJaevbhzM+qiHoS2nsFagR+T3pTsKJmkNRObOuYk0POOaSRogMRZ+1tkiG7RuzxfZ8fVZ47CKz6dGB1jsC2z4KGQDRp8iGkKlhzP65+DqgbazzCBhv3nFhKXFL/GtBnmJnoVktVmCGVp/tCMLmybMF+EniB7nejy3nlCoJ512ZOeuYNCWnYgz2KjnYr913ksgfGfewxGXJtLr8A3KjbGHAEAs/IOohWkoR8k+2X1+q4myAypJ+jh5cRj8ghYuz149+lGJan68aaZgeMOBYL1jdtAL71E8zPHCJ66Ap33flyIfK/D2SxzIaGvVjWttsMvCBTsd5xkqUiGgDOXCHb0MPez3c+fzBtg+LTsFbdNWBWdEKV+uVw/xJByHUncxmT/cT7cgQHt55qNvdULzpCYOFxh5tqQgFAs3lM27Y1Z6WYm5noXLO24gUoehhxCC2Rw/duiowt+yw2iHhi3UpLbjvGSudkDUyDIYb7ij7xpkIt6HD2O5avNJIBh2aYuRmcpcHPUQItbf/PoQwlB8BEy+tce6Pp7ZeOFUudo3yBOuWo2yP5KyKjL8nkstRDwKwjcplZPZfKwJQJvz+osen1oGdfyhseJEuBLGzHcc1g3pJbf9OqIoQ3iniQcne3IY7IB0Y5hWfMfgvCv5BbZjYD8Ofw5OkuvBOY7WKS0TuahsnucIVKtqhcy/C9NzAM9Zx1Ge2q+aK4zKjQJckgs6R4EXB4V+6ZlJx4rwFMXRs/WeJFE2TtIX83XND+KilCLvnI3BUfbDLAyvZk3e6EXaSDZtTxWGAr+sRrlk66dRZydCVe8Eu00bHTP7fV3MBcldb5RXoW3JAg0DyXJaPRUh7VL7w091OoUoW/9Kb0pbXjlent4Tvg/VKb5HBQ/BmV+HUcScDLm4ra7aPmYFR1v5SmXxRw1snKXgoM6Cu/pd1Z2epLsm2dqiaHO99B5bq853tKdtYDwXcXLh8Fr9MtyftqGy25cxVGK4sfzwvEAt9wzGX1xHKFROq4bJXEcFSDB2zifdx9QUjDIezIBiMNzg2nSYeAMsf/aymk8HnEAwPL7DjrvmzooFKI0IbVF+wT8mjsbAXmFyRLeuBQyKm9HSvNuoz7E9Z6xN8ZSnZyYpJ0KAovs59k9/HpHWMvXxK+7mjVDeUhk/LErE1d36LAxK0rAp10iwHqeXCPdwZr3+y/0/YKNgkXGV0IYrljD8X2ue13+cu3bMtDgaxACee0l57qzGr/bTcbW6RDzlwtZf/R8kNrvjTybLs+gwFl6wFHZbNxwJ3ED8k0Nxt/RO0ZBXdFtGJSQ+uppc5yh2OJJKXB3aYy7IsmCY8f02jI1qM/UfkGy3WGbToWtV0bEVV1SHIApX1+G10+9Lqc84JABPbwB26Zd+TljMcBCIzB2ltL/68kiId7EGlcUK3Y0C02XjVFGxqCz1+6Z/P+2IhpxzJCRfRWIXWImq76MfAIu3Xacmw9lLscd/pR9Saaj1/DMPSTU=\"}"
;
ArrayObject aryobj1
=
new ArrayObject(
DvmInteger.valueOf(vm,
3
),
new ByteArray(vm,strbody.getBytes()),
DvmInteger.valueOf(vm,strbody.length()),
new StringObject(vm,""),
new ByteArray(vm,new byte[
4
]),
DvmInteger.valueOf(vm,
0
)
);
ArrayObject aryobj2
=
new ArrayObject(
DvmLong.valueOf(vm,createAVMPInstance),
new StringObject(vm,
"sign"
),
vm.resolveClass(
"[B"
),
aryobj1
);
DvmObject<?> dvmObject_entry
=
MYJNICLibrary.callStaticJniMethodObject(emulator,
"doCommandNative(I[Ljava/lang/Object;)Ljava/lang/Object;"
,
60902
,aryobj2);
/
/
执行Jni方法
System.out.println(
"TAG Vison ----- 60902 wToken ----- [res]:"
+
dvmObject_entry);
}
@Override
public DvmObject<?> callObjectMethod(BaseVM vm, DvmObject<?> dvmObject, String signature, VarArg varArg) {
switch (signature){
case
"android/content/Context->getPackageCodePath()Ljava/lang/String;"
:{
return
new StringObject(vm,
"/data/app/com.rytong.ceair.apk"
);
}
case
"android/content/Context->getFilesDir()Ljava/io/File;"
:{
return
vm.resolveClass(
"java/io/File"
).newObject(new
File
(
"/data/data/com.rytong.ceair/files"
));
}
/
/
固定写法
case
"java/io/File->getAbsolutePath()Ljava/lang/String;"
: {
return
new StringObject(vm, ((
File
) dvmObject.getValue()).getAbsolutePath());
}
case
"[B->getClass()Ljava/lang/Class;"
:{
return
vm.resolveClass(
"[B"
);
}
case
"android/app/ActivityThread->getSystemContext()Landroid/app/ContextImpl;"
:{
return
vm.resolveClass(
"android/app/ContextImpl"
).newObject(null);
}
case
"android/app/ContextImpl->getPackageManager()Landroid/content/pm/PackageManager;"
:{
return
vm.resolveClass(
"android/content/pm/PackageManager"
).newObject(null);
}
case
"android/app/ContextImpl->getSystemService(Ljava/lang/String;)Ljava/lang/Object;"
:{
String str1
=
(String) varArg.getObject(
0
).getValue();
System.out.println(
"[getSystemService str1]->"
+
str1);
return
vm.resolveClass(
"android/net/wifi/WifiManager"
).newObject(null);
}
case
"android/net/wifi/WifiManager->getConnectionInfo()Landroid/net/wifi/WifiInfo;"
:{
return
vm.resolveClass(
"android/net/wifi/WifiInfo"
).newObject(null);
}
case
"android/net/wifi/WifiInfo->getMacAddress()Ljava/lang/String;"
:{
return
new StringObject(vm,
"02:00:00:00:00:00"
);
}
case
"java/util/HashMap->keySet()Ljava/util/Set;"
:{
HashMap<?,?>
map
=
(HashMap<?, ?>) dvmObject.getValue();
return
vm.resolveClass(
"java/util/Set"
).newObject(
map
.keySet());
}
case
"java/util/Set->toArray()[Ljava/lang/Object;"
:{
Set
<?>
set
=
(
Set
<?>) dvmObject.getValue();
Object
[] array
=
set
.toArray();
DvmObject<?>[] objects
=
new DvmObject[array.length];
for
(
int
i
=
0
;i<array.length;i
+
+
){
if
(array[i] instanceof String){
objects[i]
=
new StringObject(vm, (String) array[i]);
}
else
{
/
/
throw new IllegalAccessException(
"array="
+
array[i]);
}
}
return
new ArrayObject(objects);
}
case
"java/util/HashMap->get(Ljava/lang/Object;)Ljava/lang/Object;"
:{
HashMap<?,?>
map
=
(HashMap<?, ?>) dvmObject.getValue();
Object
key
=
varArg.getObject(
0
).getValue();
Object
obj
=
map
.get(key);
if
(obj instanceof String){
return
new StringObject(vm, (String) obj);
}
else
{
/
/
throw new IllegalAccessException(
"array="
+
obj);
}
}
}
return
super
.callObjectMethod(vm, dvmObject, signature, varArg);
}
@Override
public DvmObject<?> getObjectField(BaseVM vm, DvmObject<?> dvmObject, String signature) {
switch (signature){
case
"android/content/pm/ApplicationInfo->nativeLibraryDir:Ljava/lang/String;"
: {
return
new StringObject(vm,
"/data/app/com.rytong.ceair-yoTJTWpoydDKBU49a55E_A==/lib/arm"
);
}
}
return
super
.getObjectField(vm, dvmObject, signature);
}
@Override
public void callStaticVoidMethod(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {
switch (signature){
case
"com/alibaba/wireless/security/open/edgecomputing/ECMiscInfo->registerAppLifeCyCleCallBack()V"
: {
return
;
}
}
super
.callStaticVoidMethod(vm, dvmClass, signature, varArg);
}
@Override
public
int
callStaticIntMethod(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {
switch (signature){
case
"com/alibaba/wireless/security/framework/utils/UserTrackMethodJniBridge->utAvaiable()I"
: {
return
1
;
}
}
return
super
.callStaticIntMethod(vm, dvmClass, signature, varArg);
}
@Override
public DvmObject<?> newObject(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {
switch (signature){
/
/
固定写法
case
"java/lang/Integer-><init>(I)V"
: {
int
value
=
varArg.getInt(
0
);
return
vm.resolveClass(
"java/lang/Integer"
).newObject(value);
}
case
"java/lang/Long-><init>(J)V"
: {
int
value
=
varArg.getInt(
0
);
return
vm.resolveClass(
"java/lang/Long"
).newObject(value);
}
case
"com/alibaba/wireless/security/open/SecException-><init>(Ljava/lang/String;I)V"
: {
int
value
=
varArg.getInt(
1
);
System.out.println(
"[TAG-SecException]->"
+
value);
return
vm.resolveClass(
"com/alibaba/wireless/security/open/SecException"
).newObject(value);
}
}
return
super
.newObject(vm, dvmClass, signature, varArg);
}
@Override
public
long
getStaticLongField(BaseVM vm, DvmClass dvmClass, String signature) {
switch (signature) {
case
"com/alibaba/wireless/security/framework/SGPluginExtras->slot:J"
: {
return
slot;
}
}
return
super
.getStaticLongField(vm, dvmClass, signature);
}
@Override
public void setStaticLongField(BaseVM vm, DvmClass dvmClass, String signature,
long
value) {
switch (signature) {
case
"com/alibaba/wireless/security/framework/SGPluginExtras->slot:J"
: {
slot
=
value;
return
;
}
}
super
.setStaticLongField(vm, dvmClass, signature, value);
}
@Override
public
int
getStaticIntField(BaseVM vm, DvmClass dvmClass, String signature) {
switch (signature){
case
"android/os/Build$VERSION->SDK_INT:I"
:{
return
23
;
}
}
return
super
.getStaticIntField(vm, dvmClass, signature);
}
@Override
public DvmObject<?> callStaticObjectMethod(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {
switch (signature){
case
"android/app/ActivityThread->currentPackageName()Ljava/lang/String;"
:{
return
new StringObject(vm,
"com.rytong.ceair"
);
}
case
"android/app/ActivityThread->currentActivityThread()Landroid/app/ActivityThread;"
:{
return
dvmClass.newObject(null);
}
case
"android/os/SystemProperties->get(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"
:{
String str1
=
(String) varArg.getObject(
0
).getValue();
String res
=
"";
System.out.println(
"[SystemProperties str1]->"
+
str1);
System.out.println(
"[SystemProperties str2]->"
+
varArg.getObject(
1
).getValue());
if
(str1.indexOf(
"ro.serialno"
)!
=
-
1
){
res
=
"94CX1Z56A"
;
}
return
new StringObject(vm,res);
}
}
return
super
.callStaticObjectMethod(vm, dvmClass, signature, varArg);
}
@Override
public DvmObject<?> getStaticObjectField(BaseVM vm, DvmClass dvmClass, String signature) {
switch (signature){
case
"android/os/Build->BRAND:Ljava/lang/String;"
:
return
new StringObject(vm,
"Ljava/lang/String;"
);
case
"android/os/Build->MODEL:Ljava/lang/String;"
:
return
new StringObject(vm,
"Ljava/lang/String;"
);
case
"android/os/Build$VERSION->RELEASE:Ljava/lang/String;"
:
return
new StringObject(vm,
"Ljava/lang/String;"
);
case
"android/os/Build->DEVICE:Ljava/lang/String;"
:
return
new StringObject(vm,
"Ljava/lang/String;"
);
}
return
super
.getStaticObjectField(vm,dvmClass,signature);
}
}