这几天想学学加固,看到了大佬的帖子
https://bbs.kanxue.com/thread-280609.htm#msg_header_h1_11
复现分析的时候发现该加固更新了部分地方,故总结了一下我的复现过程
APK界面:
观察attachBaseContext类:
值得注意的是attachBaseContext与onCreate类都属于Application的回调方法,会进行一些初始化操作。
这里我们观察他在加载字符串的时候都使用了a.a方法,那么显然a.a方法就是就是一个解混淆的方法咯,我们还可以hook住看一下都做了些什么
在Stub最开始我们可以找到这个字符串:
private static String b = "libjiagu";
对他交叉引用看一看
可以发现加固保会判断手机的架构,针对不同的架构加载不同的Native文件。
显然我们可以发现该加固是通过Native层去释放Dex文件的,因此,我们主要分析的还是Native层的内容。
这里我们主要分析arm64:
可以发现该加固对于最外面的ELF做了处理,抹除了SO的导出表,如果没有导入导出表的话,这个ELF文件是如何运行的呢,那么不难发现其实加固保应该是使用了自己定义的链接器,在装载内存的时候才做相应的链接操作。
首先我们先hook dlopen来查看APK加载了哪些so文件:
正常来说,我们如果Hook dlopen的话,在安卓7.0之后我们需要hook的值则为"android_dlopen_ext":
我们可以发现加载了libjiagu_64.so,接下来就是想办法把它dump下来了,首先我们启动APP,使用frida -U -F -l Hook.js
参数注入如下脚本
这三个参数很重要,等下修复SO的时候需要使用。
SoFixer:https://github.com/F8LEFT/SoFixer
接下来我们需要使用SoFixer修复我们dump下来的So文件:
-m是刚刚我们脚本输出的偏移地址
接下来我们要做的就是分析ELF的逻辑了:
刚开始拿到这个ELF我们还无从下手,但是根据加固思路,我们可以先hook open函数,查看读取了哪些文件。
得到输出如下:
我们发现,非常奇怪,居然没有打开与我们程序相关的dex文件,我们取消对dex的过滤,查看一下都打开了一些什么内容。
多次的打开了maps文件,那么我们知道该文件包含了进程的内存映射信息,程序频繁读取是为了什么呢,其实猜测就是为了隐藏打开dex的操作,那么我们只需要重定向一下maps就可以了,hook open将打开open时如果存在扫描maps,就定向到自己的fakemaps。
那么我们能够发现确实使用了open去打开classes,并且实锤了是通过处理maps隐藏了内存映射,接下来我们就可以通过
来打印读取dex文件的Native地址。
获取到的输出如下:
可以发现每次打开dex的调用栈基本一致,我们在IDA中查看这个地址。
居然都未识别。
翻了一下这段数据,翻到头的时候可以发现
在这一段有被引用,我们跟过去看一看
后缀被加了.so,然后分段加载了一些东西。这个时候基本可以猜测是在linker另一个so了。
在自实现linker的时候,完成linker之后肯定是需要用dlopen去加载这个so的,那么我们hook一下dlopen验证一下我们的猜想。
流程说明了一切,直接实锤了自定义linker加固so,那接下来我们应该如何做呢,首先需要把另一个ELF给分离出来。
自定义linker SO加固的大部分思路其实就是分离出 program header 等内容进行单独加密,然后在link的时候补充soinfo。
我们使用010在之前Fix后的so里面查找ELF
在e8000处我们发现了ELF头,我们使用python脚本将其分离出来:
但是program header已经被加密了,那么接下来我们需要做的就是找到在哪儿解密的。
这里推荐oacia大佬的项目:https://github.com/oacia/stalker_trace_so
但是在使用大佬的项目的时候,我输出的js文件显示的内容都是乱码,所以对源码做了一些修改
改动点如下:
接下来利用stalker_trace_so来分析程序执行流:
注意此处需要改为libjiagu_64.so
接下来我们拿到如下执行流:
现在我们知道了控制流,然而还不够,因为自定义linker加固so,最后还是需要dlopen去手动加载的,那么我们对导入表中的dlopen进行交叉。
发现只有一次掉用,我们跟踪过去看一看。
全是Switch case:
http://androidxref.com/9.0.0_r3/xref/bionic/linker/linker.cpp
可以看看linker源码中的预链接部分,代码如出一折,那么此时我们就可以导入soinfo结构体了
在 ida 中依次点击 View->Open subviews->Local Types ,导入结构体(点击insert)
可以发现还是不完全,证明这个soinfo是被魔改过的
对其交叉,向上查看:
下方还调用了一个函数,我们进去看看。
发现这里的步长是0x38
好巧不巧,程序头就是0x38大小,那么这个方法肯定是在加载程序头了。
既然需要加载程序头,那么他肯定是需要解密之前被加密的程序头段的
加载在sub_5668调用于sub_4340又调用于sub_440C最后形成闭环
那我们只需要找sub_7BAC到sub_440C之间调用的函数就可以了。
这个uncompress就及其可疑了,这是个解压缩的方法,我们稍微向上找找:
就能发现我们的老熟人了
妥妥一RC4,但是找不到他的初始化算法,虽然就算没有初始化算法,我们也可以通过dump他的S盒,来解密,但是总感觉怪怪的,一筹莫展之际,我们向上交叉发现了loc_571c
未识别居然,我们识别看看
哟,这不是初始化算法么。
我们hook他看看密钥
在最开始找到的这个函数中,我们可以看到加载的地址和文件大小,那么我们直接使用python读取这个大小的段进行解密
最开始写一个python脚本解密的时候我们出现了如下问题
显然RC4解密出问题了,我们再回去看看rc4加密部分
对着其一顿还原,发现居然有魔改
但是解密出来依旧不对,我们看看S盒是否一致
显然Sbox是不一致的,那么反正有了Sbox,我们就不需要再去管init方法了,直接使用现成的Sbox就可以了。
还是没能解出来,有点难受了,还有一个细节就是i , j 来自于Sbox的第257和258位,他们会不会不是0呢?我们多dump两个看看
果然不是0!
解密成功
拿到的东西,似乎依旧不是正确的,继续查看调用链,最后在sub_5304找到了这样的一个函数
这里其实是一个向量运算,第一个字节为异或的值,后面的四个字节表示异或的大小。
接下来重新用脚本把他们都解密出来:
得到每个段的大小和偏移,还记不记得我们之前讲过程序头是6个大小0x38的字节组成的,那么计算一波这个a正好满足程序头的大小,那么我们使用010修补原本程序
然后我们继续观察,.rela.plt,.rela.dyn储存的内容是要远远大于dynamic的,所以我们可以锁定dynamic是d,那么我们根据program header table找到dynamic的偏移:
CTRL+G跳转过去
填入d的内容
接下来:
根据这个我们就能知道
0x7是dyn偏移,0x8是dyn大小
0x17是plt偏移,0x2是plt大小
对应的那么b就是plt了,c就是dyn了,依旧是填入修复:
至此,主so修复完成。
为了方便hook和分析,我们需要设置基地址为这个so的地址:这里是0xe8000
设置完了之后大家是否还记得最开始我们跟踪open的时候那几个函数呢,我们现在继续过去看看。
我们可以观察到在打开dex之后会调用0x136788,调用完他之后调用了artso里面的一些擀卷函数FindClass???显然在0x136788之后就解密完成了,那么我们跟过去看看
这附近肯定就存在解密解密点了,向下看:
我们可以找到该方法,通过之前hook的方式打印他的调用栈。
这
之后立马就是加载findclass这些,我们直接看看他的参数是什么样的,这里需要注意,之前我们hook的是Android_dlopen_ext,但是由于这个是主elf不是使用上面的加载的了,所以我们得改用对dlopen做hook。
hook一下0x193868,然后看一下内存
全体起立。
接下来就是把这个内存给dump下来了,那么要dump多大还不知道,我们看看别的参数。
发现aargs[2]就是dex的大小,那么我们根据这个写脚本就可以了。
至此,结束。
整个内容复现于https://oacia.dev/360-jiagu/
function
hook_dlopne() {
Interceptor.attach(Module.findExportByName(
"libdl.so"
,
"android_dlopen_ext"
), {
onEnter:
function
(args) {
console.log(
"Load -> "
, args[0].readCString());
}, onLeave:
function
() {
}
})
}
setImmediate(hook_dlopne);
function
hook_dlopne() {
Interceptor.attach(Module.findExportByName(
"libdl.so"
,
"android_dlopen_ext"
), {
onEnter:
function
(args) {
console.log(
"Load -> "
, args[0].readCString());
}, onLeave:
function
() {
}
})
}
setImmediate(hook_dlopne);
function
dump_so() {
var
soName =
"libjiagu_64.so"
;
var
libSo = Process.getModuleByName(soName);
var
save_path =
"/data/data/com.swdd.txjgtest/"
+ libSo.name +
"_Dump"
;
console.log(
"[Base]->"
, libSo.base);
console.log(
"[Size]->"
, ptr(libSo.size));
var
handle =
new
File(save_path,
"wb"
);
Memory.protect(ptr(libSo.base), libSo.size,
'rwx'
);
var
Buffer = libSo.base.readByteArray(libSo.size);
handle.write(Buffer);
handle.flush();
handle.close();
console.log(
"[DumpPath->]"
, save_path);
}
setImmediate(dump_so);
function
dump_so() {
var
soName =
"libjiagu_64.so"
;
var
libSo = Process.getModuleByName(soName);
var
save_path =
"/data/data/com.swdd.txjgtest/"
+ libSo.name +
"_Dump"
;
console.log(
"[Base]->"
, libSo.base);
console.log(
"[Size]->"
, ptr(libSo.size));
var
handle =
new
File(save_path,
"wb"
);
Memory.protect(ptr(libSo.base), libSo.size,
'rwx'
);
var
Buffer = libSo.base.readByteArray(libSo.size);
handle.write(Buffer);
handle.flush();
handle.close();
console.log(
"[DumpPath->]"
, save_path);
}
setImmediate(dump_so);
[Base]-> 0x78c1443000
[Size]-> 0x27d000
[DumpPath->] /data/data/com.swdd.txjgtest/libjiagu_64.so_Dump
[Base]-> 0x78c1443000
[Size]-> 0x27d000
[DumpPath->] /data/data/com.swdd.txjgtest/libjiagu_64.so_Dump
.\SoFixer-Windows-64.exe -s .\libjiagu_64.so_Dump -o .\libjiagu_64.so_Fix -m 0x78c1443000 -d
.\SoFixer-Windows-64.exe -s .\libjiagu_64.so_Dump -o .\libjiagu_64.so_Fix -m 0x78c1443000 -d
function
hookOpen() {
var
openPtr = Module.getExportByName(
null
,
'open'
);
const open =
new
NativeFunction(openPtr,
'int'
, [
'pointer'
,
'int'
]);
Interceptor.replace(openPtr,
new
NativeCallback(
function
(fileNamePtr, flag) {
var
fileName = fileNamePtr.readCString();
if
(fileName.indexOf(
'dex'
) != -1) {
console.log(
"[Open]-> "
, fileName);
}
return
open(fileNamePtr, flag);
},
'int'
, [
'pointer'
,
'int'
]))
}
function
hook_dlopne() {
Interceptor.attach(Module.findExportByName(
"libdl.so"
,
"android_dlopen_ext"
), {
onEnter:
function
(args) {
var
loadFileName = args[0].readCString();
if
(loadFileName.indexOf(
'libjiagu'
) != -1) {
this
.is_can_hook =
true
;
}
}, onLeave:
function
() {
if
(
this
.is_can_hook) {
hookOpen();
}
}
})
}
setImmediate(hook_dlopne);
function
hookOpen() {
var
openPtr = Module.getExportByName(
null
,
'open'
);
const open =
new
NativeFunction(openPtr,
'int'
, [
'pointer'
,
'int'
]);
Interceptor.replace(openPtr,
new
NativeCallback(
function
(fileNamePtr, flag) {
var
fileName = fileNamePtr.readCString();
if
(fileName.indexOf(
'dex'
) != -1) {
console.log(
"[Open]-> "
, fileName);
}
return
open(fileNamePtr, flag);
},
'int'
, [
'pointer'
,
'int'
]))
}
function
hook_dlopne() {
Interceptor.attach(Module.findExportByName(
"libdl.so"
,
"android_dlopen_ext"
), {
onEnter:
function
(args) {
var
loadFileName = args[0].readCString();
if
(loadFileName.indexOf(
'libjiagu'
) != -1) {
this
.is_can_hook =
true
;
}
}, onLeave:
function
() {
if
(
this
.is_can_hook) {
hookOpen();
}
}
})
}
setImmediate(hook_dlopne);
function
hookOpen() {
var
FakeMaps =
"/data/data/com.swdd.txjgtest/maps"
;
var
openPtr = Module.getExportByName(
null
,
'open'
);
const open =
new
NativeFunction(openPtr,
'int'
, [
'pointer'
,
'int'
]);
var
readPtr = Module.findExportByName(
"libc.so"
,
"read"
);
Interceptor.replace(openPtr,
new
NativeCallback(
function
(fileNamePtr, flag) {
var
FD = open(fileNamePtr, flag);
var
fileName = fileNamePtr.readCString();
if
(fileName.indexOf(
"maps"
) >= 0) {
console.warn(
"[Warning]->mapsRedirect Success"
);
var
filename = Memory.allocUtf8String(FakeMaps);
return
open(filename, flag);
}
if
(fileName.indexOf(
'dex'
) != -1) {
console.log(
"[OpenDex]-> "
, fileName);
}
return
FD;
},
'int'
, [
'pointer'
,
'int'
]))
}
function
hook_dlopne() {
Interceptor.attach(Module.findExportByName(
"libdl.so"
,
"android_dlopen_ext"
), {
onEnter:
function
(args) {
var
loadFileName = args[0].readCString();
if
(loadFileName.indexOf(
'libjiagu'
) != -1) {
this
.is_can_hook =
true
;
}
}, onLeave:
function
() {
if
(
this
.is_can_hook) {
hookOpen();
}
}
})
}
setImmediate(hook_dlopne);
function
hookOpen() {
var
FakeMaps =
"/data/data/com.swdd.txjgtest/maps"
;
var
openPtr = Module.getExportByName(
null
,
'open'
);
const open =
new
NativeFunction(openPtr,
'int'
, [
'pointer'
,
'int'
]);
var
readPtr = Module.findExportByName(
"libc.so"
,
"read"
);
Interceptor.replace(openPtr,
new
NativeCallback(
function
(fileNamePtr, flag) {
var
FD = open(fileNamePtr, flag);
var
fileName = fileNamePtr.readCString();
if
(fileName.indexOf(
"maps"
) >= 0) {
console.warn(
"[Warning]->mapsRedirect Success"
);
var
filename = Memory.allocUtf8String(FakeMaps);
return
open(filename, flag);
}
if
(fileName.indexOf(
'dex'
) != -1) {
console.log(
"[OpenDex]-> "
, fileName);
}
return
FD;
},
'int'
, [
'pointer'
,
'int'
]))
}
function
hook_dlopne() {
Interceptor.attach(Module.findExportByName(
"libdl.so"
,
"android_dlopen_ext"
), {
onEnter:
function
(args) {
var
loadFileName = args[0].readCString();
if
(loadFileName.indexOf(
'libjiagu'
) != -1) {
this
.is_can_hook =
true
;
}
}, onLeave:
function
() {
if
(
this
.is_can_hook) {
hookOpen();
}
}
})
}
setImmediate(hook_dlopne);
console.log(
'RegisterNatives called from:\n'
+ Thread.backtrace(
this
.context, Backtracer.FUZZY).map(DebugSymbol.fromAddress).join(
'\n'
) +
'\n'
);
console.log(
'RegisterNatives called from:\n'
+ Thread.backtrace(
this
.context, Backtracer.FUZZY).map(DebugSymbol.fromAddress).join(
'\n'
) +
'\n'
);
function
hookOpen() {
var
FakeMaps =
"/data/data/com.swdd.txjgtest/maps"
;
var
openPtr = Module.getExportByName(
null
,
'open'
);
const open =
new
NativeFunction(openPtr,
'int'
, [
'pointer'
,
'int'
]);
var
readPtr = Module.findExportByName(
"libc.so"
,
"read"
);
Interceptor.replace(openPtr,
new
NativeCallback(
function
(fileNamePtr, flag) {
var
FD = open(fileNamePtr, flag);
var
fileName = fileNamePtr.readCString();
if
(fileName.indexOf(
"maps"
) >= 0) {
console.warn(
"[Warning]->mapsRedirect Success"
);
var
filename = Memory.allocUtf8String(FakeMaps);
return
open(filename, flag);
}
if
(fileName.indexOf(
'dex'
) != -1) {
console.info(
"[OpenDex]-> "
, fileName);
console.log(
'RegisterNatives called from:\n'
+ Thread.backtrace(
this
.context, Backtracer.FUZZY).map(DebugSymbol.fromAddress).join(
'\n'
) +
'\n'
);
}
return
FD;
},
'int'
, [
'pointer'
,
'int'
]))
}
function
hook_dlopne() {
Interceptor.attach(Module.findExportByName(
"libdl.so"
,
"android_dlopen_ext"
), {
onEnter:
function
(args) {
var
loadFileName = args[0].readCString();
if
(loadFileName.indexOf(
'libjiagu'
) != -1) {
this
.is_can_hook =
true
;
}
}, onLeave:
function
() {
if
(
this
.is_can_hook) {
hookOpen();
}
}
})
}
setImmediate(hook_dlopne);
function
hookOpen() {
var
FakeMaps =
"/data/data/com.swdd.txjgtest/maps"
;
var
openPtr = Module.getExportByName(
null
,
'open'
);
const open =
new
NativeFunction(openPtr,
'int'
, [
'pointer'
,
'int'
]);
var
readPtr = Module.findExportByName(
"libc.so"
,
"read"
);
Interceptor.replace(openPtr,
new
NativeCallback(
function
(fileNamePtr, flag) {
var
FD = open(fileNamePtr, flag);
var
fileName = fileNamePtr.readCString();
if
(fileName.indexOf(
"maps"
) >= 0) {
console.warn(
"[Warning]->mapsRedirect Success"
);
var
filename = Memory.allocUtf8String(FakeMaps);
return
open(filename, flag);
}
if
(fileName.indexOf(
'dex'
) != -1) {
console.info(
"[OpenDex]-> "
, fileName);
console.log(
'RegisterNatives called from:\n'
+ Thread.backtrace(
this
.context, Backtracer.FUZZY).map(DebugSymbol.fromAddress).join(
'\n'
) +
'\n'
);
}
return
FD;
},
'int'
, [
'pointer'
,
'int'
]))
}
function
hook_dlopne() {
Interceptor.attach(Module.findExportByName(
"libdl.so"
,
"android_dlopen_ext"
), {
onEnter:
function
(args) {
var
loadFileName = args[0].readCString();
if
(loadFileName.indexOf(
'libjiagu'
) != -1) {
this
.is_can_hook =
true
;
}
}, onLeave:
function
() {
if
(
this
.is_can_hook) {
hookOpen();
}
}
})
}
setImmediate(hook_dlopne);
function
hook_dlopne() {
Interceptor.attach(Module.findExportByName(
"libdl.so"
,
"android_dlopen_ext"
), {
onEnter:
function
(args) {
console.warn(
"[android_dlopen_ext] -> "
, args[0].readCString());
}, onLeave:
function
() {
}
})
}
function
hook_dlopne2() {
Interceptor.attach(Module.findExportByName(
"libdl.so"
,
"dlopen"
), {
onEnter:
function
(args) {
console.log(
"[dlopen] -> "
, args[0].readCString());
}, onLeave:
function
() {
}
})
}
setImmediate(hook_dlopne2);
setImmediate(hook_dlopne);
function
hook_dlopne() {
Interceptor.attach(Module.findExportByName(
"libdl.so"
,
"android_dlopen_ext"
), {
onEnter:
function
(args) {
console.warn(
"[android_dlopen_ext] -> "
, args[0].readCString());
}, onLeave:
function
() {
}
})
}
function
hook_dlopne2() {
Interceptor.attach(Module.findExportByName(
"libdl.so"
,
"dlopen"
), {
onEnter:
function
(args) {
console.log(
"[dlopen] -> "
, args[0].readCString());
}, onLeave:
function
() {
}
})
}
setImmediate(hook_dlopne2);
setImmediate(hook_dlopne);
with
open
(
'libjiagu_64.so_Dump'
,
'rb'
) as f:
s
=
f.read()
with
open
(
'libjiagu_64.so'
,
'wb'
) as f:
f.write(s[
0xe8000
::])
with
open
(
'libjiagu_64.so_Dump'
,
'rb'
) as f:
s
=
f.read()
with
open
(
'libjiagu_64.so'
,
'wb'
) as f:
f.write(s[
0xe8000
::])
call1:JNI_OnLoad
call2:j_interpreter_wrap_int64_t
call3:interpreter_wrap_int64_t
call4:_Znwm
call5:sub_13364
call6:_Znam
call7:sub_10C8C
call8:memset
call9:sub_9988
call10:sub_DE4C
call11:calloc
call12:malloc
call13:free
call14:sub_E0B4
call15:_ZdaPv
call16:sub_C3B8
call17:sub_C870
call18:sub_9538
call19:sub_9514
call20:sub_C9E0
call21:sub_C5A4
call22:sub_9674
call23:sub_15654
call24:sub_15DCC
call25:sub_15E98
call26:sub_159CC
call27:sub_1668C
call28:sub_15A4C
call29:sub_15728
call30:sub_15694
call31:sub_94B0
call32:sub_C8C8
call33:sub_CAC4
call34:sub_C810
call35:sub_906C
call36:dladdr
call37:strstr
call38:setenv
call39:_Z9__arm_a_1P7_JavaVMP7_JNIEnvPvRi
call40:sub_9A08
call41:sub_954C
call42:sub_103D0
call43:j__ZdlPv_1
call44:_ZdlPv
call45:sub_9290
call46:sub_7BAC
call47:strncpy
call48:sub_5994
call49:sub_5DF8
call50:sub_4570
call51:sub_59DC
call52:_ZN9__arm_c_19__arm_c_0Ev
call53:sub_9F60
call54:sub_957C
call55:sub_94F4
call56:sub_CC5C
call57:sub_5D38
call58:sub_5E44
call59:memcpy
call60:sub_5F4C
call61:sub_583C
call62:j__ZdlPv_3
call63:j__ZdlPv_2
call64:j__ZdlPv_0
call65:sub_9F14
call66:sub_9640
call67:sub_5894
call68:sub_58EC
call69:sub_9B90
call70:sub_2F54
call71:uncompress
call72:sub_C92C
call73:sub_440C
call74:sub_4BFC
call75:sub_4C74
call76:sub_5304
call77:sub_4E4C
call78:sub_5008
call79:mprotect
call80:strlen
call81:sub_3674
call82:dlopen
call83:sub_4340
call84:sub_3A28
call85:sub_3BDC
call86:sub_2F8C
call87:dlsym
call88:strcmp
call89:sub_5668
call90:sub_4C40
call91:sub_5BF0
call92:sub_7CDC
call93:sub_468C
call94:sub_7E08
call95:sub_86FC
call96:sub_8A84
call97:sub_7FDC
call98:interpreter_wrap_int64_t_bridge
call99:sub_9910
call100:sub_15944
call101:puts
call1:JNI_OnLoad
call2:j_interpreter_wrap_int64_t
call3:interpreter_wrap_int64_t
call4:_Znwm
call5:sub_13364
call6:_Znam
call7:sub_10C8C
call8:memset
call9:sub_9988
call10:sub_DE4C
call11:calloc
call12:malloc
call13:free
call14:sub_E0B4
call15:_ZdaPv
call16:sub_C3B8
call17:sub_C870
call18:sub_9538
call19:sub_9514
call20:sub_C9E0
call21:sub_C5A4
call22:sub_9674
call23:sub_15654
call24:sub_15DCC
call25:sub_15E98
call26:sub_159CC
call27:sub_1668C
call28:sub_15A4C
call29:sub_15728
call30:sub_15694
call31:sub_94B0
call32:sub_C8C8
call33:sub_CAC4
call34:sub_C810
call35:sub_906C
call36:dladdr
call37:strstr
call38:setenv
call39:_Z9__arm_a_1P7_JavaVMP7_JNIEnvPvRi
call40:sub_9A08
call41:sub_954C
call42:sub_103D0
call43:j__ZdlPv_1
call44:_ZdlPv
call45:sub_9290
call46:sub_7BAC
call47:strncpy
call48:sub_5994
call49:sub_5DF8
call50:sub_4570
call51:sub_59DC
call52:_ZN9__arm_c_19__arm_c_0Ev
call53:sub_9F60
call54:sub_957C
call55:sub_94F4
call56:sub_CC5C
call57:sub_5D38
call58:sub_5E44
call59:memcpy
call60:sub_5F4C
call61:sub_583C
call62:j__ZdlPv_3
call63:j__ZdlPv_2
call64:j__ZdlPv_0
call65:sub_9F14
call66:sub_9640
call67:sub_5894
call68:sub_58EC
call69:sub_9B90
call70:sub_2F54
call71:uncompress
call72:sub_C92C
call73:sub_440C
call74:sub_4BFC
call75:sub_4C74
call76:sub_5304
call77:sub_4E4C
call78:sub_5008
call79:mprotect
call80:strlen
call81:sub_3674
call82:dlopen
call83:sub_4340
call84:sub_3A28
call85:sub_3BDC
call86:sub_2F8C
call87:dlsym
call88:strcmp
call89:sub_5668
call90:sub_4C40
call91:sub_5BF0
call92:sub_7CDC
call93:sub_468C
call94:sub_7E08
call95:sub_86FC
call96:sub_8A84
call97:sub_7FDC
call98:interpreter_wrap_int64_t_bridge
call99:sub_9910
call100:sub_15944
call101:puts
#define __LP64__ 1
#if defined(__LP64__)
#define ElfW(type) Elf64_ ## type
#else
#define ElfW(type) Elf32_ ## type
#endif
#if defined(__LP64__)
#define USE_RELA 1
#endif
typedef
signed
char
__s8;
typedef
unsigned
char
__u8;
typedef
signed
short
__s16;
typedef
unsigned
short
__u16;
typedef
signed
int
__s32;
typedef
unsigned
int
__u32;
typedef
signed
long
long
__s64;
typedef
unsigned
long
long
__u64;
typedef
__u32 Elf32_Addr;
typedef
__u16 Elf32_Half;
typedef
__u32 Elf32_Off;
typedef
__s32 Elf32_Sword;
typedef
__u32 Elf32_Word;
typedef
__u64 Elf64_Addr;
typedef
__u16 Elf64_Half;
typedef
__s16 Elf64_SHalf;
typedef
__u64 Elf64_Off;
typedef
__s32 Elf64_Sword;
typedef
__u32 Elf64_Word;
typedef
__u64 Elf64_Xword;
typedef
__s64 Elf64_Sxword;
typedef
struct
dynamic{
Elf32_Sword d_tag;
union
{
Elf32_Sword d_val;
Elf32_Addr d_ptr;
} d_un;
} Elf32_Dyn;
typedef
struct
{
Elf64_Sxword d_tag;
union
{
Elf64_Xword d_val;
Elf64_Addr d_ptr;
} d_un;
} Elf64_Dyn;
typedef
struct
elf32_rel {
Elf32_Addr r_offset;
Elf32_Word r_info;
} Elf32_Rel;
typedef
struct
elf64_rel {
Elf64_Addr r_offset;
Elf64_Xword r_info;
} Elf64_Rel;
typedef
struct
elf32_rela{
Elf32_Addr r_offset;
Elf32_Word r_info;
Elf32_Sword r_addend;
} Elf32_Rela;
typedef
struct
elf64_rela {
Elf64_Addr r_offset;
Elf64_Xword r_info;
Elf64_Sxword r_addend;
} Elf64_Rela;
typedef
struct
elf32_sym{
Elf32_Word st_name;
Elf32_Addr st_value;
Elf32_Word st_size;
unsigned
char
st_info;
unsigned
char
st_other;
Elf32_Half st_shndx;
} Elf32_Sym;
typedef
struct
elf64_sym {
Elf64_Word st_name;
unsigned
char
st_info;
unsigned
char
st_other;
Elf64_Half st_shndx;
Elf64_Addr st_value;
Elf64_Xword st_size;
} Elf64_Sym;
#define EI_NIDENT 16
typedef
struct
elf32_hdr{
unsigned
char
e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Ehdr;
typedef
struct
elf64_hdr {
unsigned
char
e_ident[EI_NIDENT];
Elf64_Half e_type;
Elf64_Half e_machine;
Elf64_Word e_version;
Elf64_Addr e_entry;
Elf64_Off e_phoff;
Elf64_Off e_shoff;
Elf64_Word e_flags;
Elf64_Half e_ehsize;
Elf64_Half e_phentsize;
Elf64_Half e_phnum;
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shstrndx;
} Elf64_Ehdr;
#define PF_R 0x4
#define PF_W 0x2
#define PF_X 0x1
typedef
struct
elf32_phdr{
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_Phdr;
typedef
struct
elf64_phdr {
Elf64_Word p_type;
Elf64_Word p_flags;
Elf64_Off p_offset;
Elf64_Addr p_vaddr;
Elf64_Addr p_paddr;
Elf64_Xword p_filesz;
Elf64_Xword p_memsz;
Elf64_Xword p_align;
} Elf64_Phdr;
typedef
struct
elf32_shdr {
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
} Elf32_Shdr;
typedef
struct
elf64_shdr {
Elf64_Word sh_name;
Elf64_Word sh_type;
Elf64_Xword sh_flags;
Elf64_Addr sh_addr;
Elf64_Off sh_offset;
Elf64_Xword sh_size;
Elf64_Word sh_link;
Elf64_Word sh_info;
Elf64_Xword sh_addralign;
Elf64_Xword sh_entsize;
} Elf64_Shdr;
typedef
void
(*linker_dtor_function_t)();
typedef
void
(*linker_ctor_function_t)(
int
,
char
**,
char
**);
#if defined(__work_around_b_24465209__)
#define SOINFO_NAME_LEN 128
#endif
struct
soinfo {
#if defined(__work_around_b_24465209__)
char
old_name_[SOINFO_NAME_LEN];
#endif
const
ElfW(Phdr)* phdr;
size_t
phnum;
#if defined(__work_around_b_24465209__)
ElfW(Addr) unused0;
#endif
ElfW(Addr) base;
size_t
size;
#if defined(__work_around_b_24465209__)
uint32_t unused1;
#endif
ElfW(Dyn)* dynamic;
#if defined(__work_around_b_24465209__)
uint32_t unused2;
uint32_t unused3;
#endif
soinfo* next;
uint32_t flags_;
const
char
* strtab_;
ElfW(Sym)* symtab_;
size_t
nbucket_;
size_t
nchain_;
uint32_t* bucket_;
uint32_t* chain_;
#if !defined(__LP64__)
ElfW(Addr)** unused4;
#endif
#if defined(USE_RELA)
ElfW(Rela)* plt_rela_;
size_t
plt_rela_count_;
ElfW(Rela)* rela_;
size_t
rela_count_;
#else
ElfW(Rel)* plt_rel_;
size_t
plt_rel_count_;
ElfW(Rel)* rel_;
size_t
rel_count_;
#endif
linker_ctor_function_t* preinit_array_;
size_t
preinit_array_count_;
linker_ctor_function_t* init_array_;
size_t
init_array_count_;
linker_dtor_function_t* fini_array_;
size_t
fini_array_count_;
linker_ctor_function_t init_func_;
linker_dtor_function_t fini_func_;
};
#define __LP64__ 1
#if defined(__LP64__)
#define ElfW(type) Elf64_ ## type
#else
#define ElfW(type) Elf32_ ## type
#endif
#if defined(__LP64__)
#define USE_RELA 1
#endif
typedef
signed
char
__s8;
typedef
unsigned
char
__u8;
typedef
signed
short
__s16;
typedef
unsigned
short
__u16;
typedef
signed
int
__s32;
typedef
unsigned
int
__u32;
typedef
signed
long
long
__s64;
typedef
unsigned
long
long
__u64;
typedef
__u32 Elf32_Addr;
typedef
__u16 Elf32_Half;
typedef
__u32 Elf32_Off;
typedef
__s32 Elf32_Sword;
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2024-8-12 10:11
被Shangwendada编辑
,原因: 上传附件