在apk安全如今的时代,一切安全措施已经可以比肩pe级别的防护啦. 加壳,ollvm混淆,vmp
似乎各大厂商都在不惜用用户的流畅体验度,来换取更安全的防护力度. 也是2021了,谁还没有台晓龙855. CPU性能严重溢出,可能就是这些厂商的想法吧,反正不用白不用.这些算力也不是自己的.
但是碰到这么强的加固混淆,逆向人员应该如何是好呢?
ps :Unidbg跟010Editor更配哦!
今天作者就来带大家以自身使用的经验去了解一下Unidbg!
上面那张图片呢,用的就是小弟魔改的UnidbgTraceCode出来的文件,通过Trace方法可以快速定位某个函数在指令级别的作用,帮助逆向人员更快的分析出想要的算法.
当然Unidbg能做的远远不止这些,本文并不是一篇科普文,所以本文假定读者都是有一定基础的同学.
如果你仔细观摩过Uniidbg源码的话,你会发现所有callJniMethodObject最终都会并入一个叫callFunction的函数.
那么我们在分析So的过程中,发现了一个非JNI函数能不能主动调用呢?
答案是:必须能.
这种好处的体现在于,逆向人员不必使用Jni函数去分析大量的无用代码,而是能精确的定位一个小的Func的具体作用,以及算法逻辑.
通过该函数我们能得到这个小函数在内部到底做了什么操作,并且能Trace出更精确的指令文件
该函数的第一个参数毋庸置疑是当前的模拟器
第二个参数可以是导出函数名,或者是指定地址偏移
后面的参数就是个变长的参数列表,由逆向人员分析得到.
当然如果你是进行so内部函数调用的话,你大概率会填充一个指针,这里在给大家分享一段自己填充char* 类型的函数源码,别的类型参数同理,不在赘述.
当然Unidbg还内置了多种HOOK框架,今天讲一个分析So比较实用的一款HookZz
同理,此框架也支持导出函数HOOK以及InlineHOOK 有了这个方法,在你分析一些函数的时候,可以充当Log的效果 或者强行改变一些函数的返回值让你更容易的分析,比如本例中笔者改变了Lrand48的返回值,让函数每次都强行返回0x12345678,这样在逆向分析的时候能让一些不确定性变成可控性.
最后感谢Unidbg作者带来这么好的工具,并且希望大家能一起进步,在逆向的道路越走越远
public final Number[] callFunction(Emulator<?> emulator, String symbolName,
Object
... args) {
Symbol symbol
=
findSymbolByName(symbolName, false);
if
(symbol
=
=
null) {
throw new IllegalStateException(
"find symbol failed: "
+
symbolName);
}
if
(symbol.isUndef()) {
throw new IllegalStateException(symbolName
+
" is NOT defined"
);
}
return
symbol.call(emulator, args);
}
public final Number[] callFunction(Emulator<?> emulator, String symbolName,
Object
... args) {
Symbol symbol
=
findSymbolByName(symbolName, false);
if
(symbol
=
=
null) {
throw new IllegalStateException(
"find symbol failed: "
+
symbolName);
}
if
(symbol.isUndef()) {
throw new IllegalStateException(symbolName
+
" is NOT defined"
);
}
return
symbol.call(emulator, args);
}
emulator
=
createARMEmulator();
emulator
=
createARMEmulator();
private static void CallVMPFunc(Module module,AndroidEmulator emulator){
try
{
Symbol malloc
=
module.findSymbolByName(
"malloc"
);
Symbol free
=
module.findSymbolByName(
"free"
);
MemoryBlock block
=
MemoryAllocBlock.malloc(emulator,malloc,free,
0x1000
);
MemoryBlock namebyte
=
MemoryAllocBlock.malloc(emulator,malloc,free,
0x1000
);
UnidbgPointer blockpoint
=
block.getPointer();
UnidbgPointer namepoint
=
namebyte.getPointer();
String name
=
"magicillusion"
;
String data
=
"hello worid"
;
namepoint.write(name.getBytes());
blockpoint.write(data.getBytes());
Number[] ret
=
module.callFunction(emulator,
0x13B30
+
1
,namepoint,blockpoint,
2
);
UnidbgPointer ret1
=
new UnidbgPointer(emulator,ret[
0
].intValue(),
4
);
String string
=
ret1.getString(
0
);
System.out.println(
"Number => "
+
(string));
}
finally
{
}
}
private static void CallVMPFunc(Module module,AndroidEmulator emulator){
try
{
Symbol malloc
=
module.findSymbolByName(
"malloc"
);
Symbol free
=
module.findSymbolByName(
"free"
);
MemoryBlock block
=
MemoryAllocBlock.malloc(emulator,malloc,free,
0x1000
);
MemoryBlock namebyte
=
MemoryAllocBlock.malloc(emulator,malloc,free,
0x1000
);
UnidbgPointer blockpoint
=
block.getPointer();
UnidbgPointer namepoint
=
namebyte.getPointer();
String name
=
"magicillusion"
;
String data
=
"hello worid"
;
namepoint.write(name.getBytes());
blockpoint.write(data.getBytes());
Number[] ret
=
module.callFunction(emulator,
0x13B30
+
1
,namepoint,blockpoint,
2
);
UnidbgPointer ret1
=
new UnidbgPointer(emulator,ret[
0
].intValue(),
4
);
String string
=
ret1.getString(
0
);
System.out.println(
"Number => "
+
(string));
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2021-8-27 12:05
被至尊小仙侠编辑
,原因: