m0bilesecurity / RMS-Runtime-Mobile-Security

Runtime Mobile Security (RMS) 📱🔥 - is a powerful web interface that helps you to manipulate Android and iOS Apps at Runtime
https://twitter.com/mobilesecurity_
GNU General Public License v3.0
2.58k stars 373 forks source link

Can not run #12

Closed CEV-Code closed 4 years ago

CEV-Code commented 4 years ago

Hi guys! I run the following js code every time I go to "step 4" of dumpdex function and I don't continue. Why? ///////////////////////////////////////////////////////////////////////////////////////////////////

// js code begin

function LogPrint(log) { var theDate = new Date(); var hour = theDate.getHours(); var minute = theDate.getMinutes(); var second = theDate.getSeconds(); var mSecond = theDate.getMilliseconds()

hour < 10 ? hour = "0" + hour : hour;
minute < 10 ? minute = "0" + minute : minute;
second < 10 ? second = "0" + second : second;
mSecond < 10 ? mSecond = "00" + mSecond : mSecond < 100 ? mSecond = "0" + mSecond : mSecond;

var time = hour + ":" + minute + ":" + second + ":" + mSecond;
send("[" + time + "] " + log);

}

function getAndroidVersion(){ var version = 0;

if(Java.available){
    var versionStr = Java.androidVersion;
    version = versionStr.slice(0,1);
}else{
    LogPrint("Error: cannot get android version");
}
LogPrint("Android Version: " + version);
return version;

}

function getFunctionName(){ var i = 0; var functionName = "";

// Android 4: hook dvmDexFileOpenPartial
// Android 5: hook OpenMemory
// after Android 5: hook OpenCommon
if(getAndroidVersion() > 4){ // android 5 and later version
    var artExports =  Module.enumerateExportsSync("libart.so");
    for(i = 0; i< artExports.length; i++){
        if(artExports[i].name.indexOf("OpenMemory") !== -1){
            functionName = artExports[i].name;
            LogPrint("index " + i + " function name: "+ functionName);
            break;
        }else if(artExports[i].name.indexOf("OpenCommon") !== -1){
            functionName = artExports[i].name;
            LogPrint("index " + i + " function name: "+ functionName);
            break;
        }
    }
}else{ //android 4
    var dvmExports =  Module.enumerateExportsSync("libdvm.so");
    if(dvmExports.length !== 0){  // check libdvm.so first
        for(i = 0; i< dvmExports.length; i++){
            if(dvmExports[i].name.indexOf("dexFileParse") !== -1){
                functionName = dvmExports[i].name;
                LogPrint("index " + i + " function name: "+ functionName);
                break;
            }
        }
    }else{ // if not load libdvm.so, check libart.so
        dvmExports = Module.enumerateExportsSync("libart.so");
        for(i = 0; i< dvmExports.length; i++){
            if(dvmExports[i].name.indexOf("OpenMemory") !== -1){
                functionName = dvmExports[i].name;
                LogPrint("index " + i + " function name: "+ functionName);
                break;
            }
        }
    }
}
return functionName;

}

function getProcessName(){ var processName = "";

var fopenPtr = Module.findExportByName("libc.so", "fopen");
var fopenFunc = new NativeFunction(fopenPtr, 'pointer', ['pointer', 'pointer']);
var fgetsPtr = Module.findExportByName("libc.so", "fgets");
var fgetsFunc = new NativeFunction(fgetsPtr, 'int', ['pointer', 'int', 'pointer']);
var fclosePtr = Module.findExportByName("libc.so", "fclose");
var fcloseFunc = new NativeFunction(fclosePtr, 'int', ['pointer']);

var pathPtr = Memory.allocUtf8String("/proc/self/cmdline");
var openFlagsPtr = Memory.allocUtf8String("r");

var fp = fopenFunc(pathPtr, openFlagsPtr);
if(fp.isNull() === false){
    var buffData = Memory.alloc(128);
    var ret = fgetsFunc(buffData, 128, fp);
    if(ret !== 0){
        processName = Memory.readCString(buffData);
        LogPrint("processName " + processName);
    }
    fcloseFunc(fp);
}
return processName;

}

function arraybuffer2hexstr(buffer) { var hexArr = Array.prototype.map.call( new Uint8Array(buffer), function (bit) { return ('00' + bit.toString(16)).slice(-2) } ); return hexArr.join(' '); }

function checkDexMagic(dataAddr){ var magicMatch = true; var magicFlagHex = [0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x35, 0x00];

for(var i = 0; i < 8; i++){
    if(Memory.readU8(ptr(dataAddr).add(i)) !== magicFlagHex[i]){
        magicMatch = false;
        break;
    }
}

return magicMatch;

}

function checkOdexMagic(dataAddr){ var magicMatch = true; var magicFlagHex = [0x64, 0x65, 0x79, 0x0a, 0x30, 0x33, 0x36, 0x00];

for(var i = 0; i < 8; i++){
    if(Memory.readU8(ptr(dataAddr).add(i)) !== magicFlagHex[i]){
        magicMatch = false;
        break;
    }
}

return magicMatch;

}

function dumpDex(moduleFuncName, processName){ if(moduleFuncName !== ""){ var hookFunction; if(getAndroidVersion() > 4){ // android 5 and later version hookFunction = Module.findExportByName("libart.so", moduleFuncName); LogPrint("step 1" + hookFunction); }else{ // android 4 hookFunction = Module.findExportByName("libdvm.so", moduleFuncName); // check libdvm.so first LogPrint("step 2" + hookFunction); if(hookFunction == null) { hookFunction = Module.findExportByName("libart.so", moduleFuncName); //// if not load libdvm.so, check libart.so LogPrint("step 3" + hookFunction); } } Interceptor.attach(hookFunction,{ onEnter: function(args){ LogPrint("step 4");

            var begin = 0;
            var dexMagicMatch = false;
            var odexMagicMatch = false;

            dexMagicMatch = checkDexMagic(args[0]);
            if(dexMagicMatch === true){
                begin = args[0];
            }else{
                odexMagicMatch = checkOdexMagic(args[0]);
                if(odexMagicMatch === true){
                    begin = args[0];
                }
            }

            if(begin === 0){
                dexMagicMatch = checkDexMagic(args[1]);
                if(dexMagicMatch === true){
                    begin = args[1];
                }else{
                  odexMagicMatch = checkOdexMagic(args[1]);
                  if(odexMagicMatch === true){
                      begin = args[1];
                  }
                }
            }

            if(dexMagicMatch === true){
                LogPrint("magic : " + Memory.readUtf8String(begin));
                //console.log(hexdump(begin, { offset: 0, header: false, length: 64, ansi: false }));
                var address = parseInt(begin,16) + 0x20;
                var dex_size = Memory.readInt(ptr(address));
                LogPrint("dex_size :" + dex_size);
                var dex_path = "/data/data/" + processName + "/" + dex_size + ".dex";
                var dex_file = new File(dex_path, "wb");
                dex_file.write(Memory.readByteArray(begin, dex_size));
                dex_file.flush();
                dex_file.close();
                LogPrint("dump dex success, saved path: " + dex_path + "\n");
            }else if(odexMagicMatch === true){
                LogPrint("magic : " + Memory.readUtf8String(begin));
                //console.log(hexdump(begin, { offset: 0, header: false, length: 64, ansi: false }));
                var address = parseInt(begin,16) + 0x0C;
                var odex_size = Memory.readInt(ptr(address));
                LogPrint("odex_size :" + odex_size);
                var odex_path = "/data/data/" + processName + "/" + odex_size + ".odex";
                var odex_file = new File(odex_path, "wb");
                odex_file.write(Memory.readByteArray(begin, odex_size));
                odex_file.flush();
                odex_file.close();
                LogPrint("dump odex success, saved path: " + odex_path + "\n");
            }
        },
        onLeave: function(retval){
        }
    });
}else{
    LogPrint("Error: cannot find correct module function.");
}

}

//start dump dex file var moduleFucntionName = getFunctionName(); var processName = getProcessName(); if(moduleFucntionName !== "" && processName !== ""){ dumpDex(moduleFucntionName, processName); }

// js code end

CEV-Code commented 4 years ago

Modify the on message callback problem to resolve the thanks :)

CEV-Code commented 4 years ago

The js code of dump dex is unstable😢

m0bilesecurity commented 4 years ago

Is the script working via FRIDA cli?

CEV-Code commented 4 years ago

Is the script working via FRIDA cli?

https://github.com/FuzzySecurity/Fermion This tool works fine!Hope to improve it! 😘

m0bilesecurity commented 4 years ago

Hey @CEV-Code, I finally found the time to try your script. I confirm that it is working via FRIDA cli but it is not working if executed via RMS.

Did you find the issue? It breaks immediately after step 1. I have no time to work on this specific and not common case but please if you find the issue let me know!