在这篇
帖子 中遇到的难题终于解出来了
这壳子有检测ROOT 检测仿真器 自身APK文件较验 检测一堆东西 之后还开双进程保护 做完这些才真正解密自己
小弟小菜一个 没啥技术 IDA跟踪硬冲冲了三四个月 没头绪
期间不断爬文爬文
后来念头一转 想说可以用神器 Xposed 于 package load 时 load 我的 .so dump memory
由于此方法不会改动原本的 APP 于是乎 Dump 出明文了
此 app 于 maps 中建立四段区块 其中有一块包含 string table 参考前辈文章
ELF DIY For Anddroid
分析出 symbol table 找出 local function 之于 base 的偏移后 配合 IDA 找出相关函式分析
由于水平有限 静态分析是没什么成果 只能靠动态分析 但前面提过 此 APP 双进程保护了
山不转路转呗 他可以用 fork 进程来 pthread 自己 那我也行阿 在想分析的关键函式 hook 并 fork 一份进程
之后让原进程 sleep 去 在用 IDA 去调试新的进程
以上 fork 的方法我是突然想到的 不知道以前有没有这种方法
hook 是在 .so 用 inline hook ARM 的方法做 因为是 local function 直接改 Symbol table 好像没用
这边请问各位大牛有没有 arm thumb inline hook 的例子 我这个 hook 跳走就回不去啦
其中牵扯的流程最后整理一下
先附上流程图
撰写 libFKPAD.so 贴个大致的 code
elfHookLocal("libpad.so", "FUNCTION_TO_ANALYSIS",(void*)myReadStreamCB,(void**)&old_func);
XLOG("After hook");
FILE* fp = fopen("/proc/self/maps", "r");
if(!fp)
{
XLOG("fail to open maps");
return;
}
const char space[2] = " ";
const char minus[2] = "-";
char target[] = "libpad.so";
int dump_idx = 0;
bool target_exist = false;
while(!feof(fp))
{
char* buffer = malloc(1024);
if(fgets(buffer, 1024, fp) != NULL)
{
char* pos = strstr(buffer, target);
if(pos)
{
target_exist = true;
XLOG(buffer);
unsigned int start_addr = get_addr(buffer);
unsigned int end_addr = get_addr(buffer+9);
LOGD("0x%08x", start_addr);
LOGD("0x%08x", end_addr);
char* section_start = start_addr;
char* section_end = end_addr;
char filepath[255] = {0};
sprintf(filepath, "/data/data/PACKAGE_NAME/files/dump%d.dat", dump_idx++);
LOGD("writting %s", filepath);
FILE * output = fopen(filepath, "w");
if(!output)
{
XLOG("failed to write dump file");
return;
}
for(char* poi = section_start;poi<=section_end;poi++)
{
fputc(*poi, output);
}
fclose(output);
}
}
free(buffer);
}
fclose(fp);
libFKPAD.so 预先写入 /system/lib
方法是
cd /system/lib
rm libFKPAD.so
cat /data/data/com.example.fkpad/lib/libFKPAD.so > libFKPAD.so
chmod 755 libFKPAD.so
接着准备 Xposed Module
由 Xposed 加载 Module 此 Module 会在目标 Package 加载 Main Activity OnCreate 时 System.load 载入我自己的 .so
myHookMethod(lpparam, "PACKAGE_MAINACTIVITY", "onCreate", Bundle.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("Loading FKPAD.so...");
try
{
System.loadLibrary("FKPAD");
}catch(Exception e)
{
XposedBridge.log("error: "+e.getMessage());
}
}
});
//复写 HookMethod 原本不知怎 不能 find 正确的 Method
private void myHookMethod(final LoadPackageParam lpparam, String clazz, String method, Object... parameterTypesAndCallback) throws Throwable {
Method m = null;
Class<?>[] parameterClasses = null;
for (int i = parameterTypesAndCallback.length - 1; i >= 0; i--) {
Object type = parameterTypesAndCallback[i];
// ignore trailing callback
if (type instanceof XC_MethodHook)
continue;
if (type instanceof XC_MethodReplacement)
continue;
if (parameterClasses == null)
parameterClasses = new Class<?>[i+1];
parameterClasses[i] = (Class<?>) type;
}
if (parameterClasses == null)
parameterClasses = new Class<?>[0];
XC_MethodHook callback = (XC_MethodHook) parameterTypesAndCallback[parameterTypesAndCallback.length-1];
try {
m = XposedHelpers.findClass(clazz, lpparam.classLoader).getDeclaredMethod(
method, parameterClasses);
XposedBridge.log("found method");
XposedBridge.hookMethod(m, callback);
XposedBridge.log("hooked: " + clazz + " : " + method);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
XposedBridge.log("hook error");
XposedBridge.log(e.getMessage());
}
}
特别感谢这份 Hook 框架给我的灵感 我记得是某大牛作品
https://github.com/boyliang/AllHookInOne
Dump 出来后的分析过程就不是此篇的重点了
欢迎讨论指点 拍打喂食
谢谢
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)