其他
FartExt超进化之奇奇怪怪的新ROM工具MikRom
本文为看雪论坛优秀文章
看雪论坛作者ID:misskings
1
前言
感谢:看雪高研班课程、FART脱壳王课程、珍惜大佬的android进阶课程
2
FartExt
3
MikRom
内核修改过反调试
开启硬件断点
USB调试默认连接
脱壳(黑名单、白名单过滤、更深的主动调用链)
ROM打桩(ArtMethod调用、RegisterNative调用、JNI函数调用)
frida持久化(支持listen,wait,script三种模式)
支持自行切换frida-gadget版本
反调试(通过sleep目标函数,再附加进程来过掉起始的反调试)
trace java函数(smali指令的trace)
内置dobby注入
注入so
注入dex(实现对应的接口触发调用。目前还未测试)
4
MikManager
5
开发的始末
6
编译版本
bootstrap_go_package {
name: "blueprint-pathtools",
pkgPath: "github.com/google/blueprint/pathtools",
deps: [
"blueprint-deptools",
],
srcs: [
"pathtools/lists.go",
"pathtools/fs.go",
"pathtools/glob.go",
],
testSrcs: [
//修改处,这里的内容删掉
],
}
7
配置管理优化
8
添加系统服务
interface IMikRom
{
//读取文件
String readFile(String path);
//写入文件
void writeFile(String path,String data);
//执行shell命令
String shellExec(String cmd);
}
type untrusted_app, domain;
type untrusted_app_27, domain;
type untrusted_app_25, domain;
allow untrusted_app mikrom_service:service_manager find;
allow untrusted_app_27 mikrom_service:service_manager find;
allow untrusted_app_25 mikrom_service:service_manager find;
//获取服务
public class ServiceUtils {
private static IMikRom iMikRom = null;
public static IMikRom getiMikRom() {
if (iMikRom == null) {
try {
Class localClass = Class.forName("android.os.ServiceManager");
Method getService = localClass.getMethod("getService", new Class[] {String.class});
if(getService != null) {
Object objResult = getService.invoke(localClass, new Object[]{"mikrom"});
if (objResult != null) {
IBinder binder = (IBinder) objResult;
iMikRom = IMikRom.Stub.asInterface(binder);
}
}
} catch (Exception e) {
Log.d("MikManager",e.getMessage());
e.printStackTrace();
}
}
return iMikRom;
}
}
//将json数据保存到指定路径
public static void SaveMikromConfig(List<PackageItem> packageList){
Log.e(ConfigUtil.TAG,"SaveMikromConfig");
Gson gson = new Gson();
String savejson=gson.toJson(packageList);
try {
ServiceUtils.getiMikRom().writeFile(ConfigUtil.configPath,savejson);
} catch (RemoteException e) {
Log.e(ConfigUtil.TAG,"writeConfig err:"+e.getMessage());
}
}
private static IMikRom iMikRom=null;
public static IMikRom getiMikRom() {
if (iMikRom == null) {
try {
Class localClass = Class.forName("android.os.ServiceManager");
Method getService = localClass.getMethod("getService", new Class[] {String.class});
if(getService != null) {
Object objResult = getService.invoke(localClass, new Object[]{"mikrom"});
if (objResult != null) {
IBinder binder = (IBinder) objResult;
iMikRom = IMikRom.Stub.asInterface(binder);
}
}
} catch (Exception e) {
Log.d("MikManager",e.getMessage());
e.printStackTrace();
}
}
return iMikRom;
}
public static String getMikConfig(){
try {
IMikRom mikrom=getiMikRom();
if(mikrom==null){
return "";
}
return mikrom.readFile("/data/system/mik.conf");
} catch (RemoteException e) {
e.printStackTrace();
}
return "";
}
[{"appName":"crackme","breakClass":"","dexClassName":"","dexPath":"","enabled":true,"fridaJsPath":"","gadgetArm64Path":"","gadgetPath":"","isDeep":false,"isDobby":false,"isInvokePrint":false,"isJNIMethodPrint":true,"isRegisterNativePrint":false,"isTuoke":false,"packageName":"com.kanxue.crackme","port":0,"sleepNativeMethod":"","soPath":"","traceMethod":"","whiteClass":"","whitePath":""}]
9
脱壳相关优化
优化1方案:解决sdcard权限问题
//这里我判断如果非系统应用才增加这些权限
if((ai.flags&ApplicationInfo.FLAG_SYSTEM)!=1){
//试错中发现,开启这些权限的时候,有个google和message相关的进程会崩溃,所以过滤一下
if(!ai.packageName.contains("google") && !ai.packageName.contains("message")){
//下面是sdcard权限开启,以及debuggable权限开启。如果担心检测,可以关掉debuggable的默认开启
ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE;
ai.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
ai.flags |= ApplicationInfo.FLAG_DEBUGGABLE;
// Debuggable implies profileable
ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL;
}
}
优化2方案:解决抽取壳在脱壳完成后还需要手动修复
//存放dex的指针和长度
static std::map<void*,size_t> dex_map;
//主动调用函数的dump处理
extern "C" void dumpArtMethod(ArtMethod* artmethod) REQUIRES_SHARED(Locks::mutator_lock_) {
...
int dexfilefp=open(dexfilepath,O_RDONLY,0666);
///dex文件存在则不处理,避免主动调用每次都要重新保存dex
if(dexfilefp>0){
close(dexfilefp);
dexfilefp=0;
}else{
LOG(ERROR) << "mikrom ArtMethod::dumpdexfilebyArtMethod save dex_map";
//将这个地址给保存下来
dex_map.insert(std::pair<void*,size_t>((void*)begin_,size_));
int fp=open(dexfilepath,O_CREAT|O_APPEND|O_RDWR,0666);
...
}
}
//主动调用完成时,重新保存到文件名<dexSize>_dexfile_repair.dex中
extern "C" void dumpDexOver() REQUIRES_SHARED(Locks::mutator_lock_) {
if(dex_map.size()<=0){
LOG(ERROR) << "mikrom dumpDexOver dex_map.size()<=0";
return;
}
char *dexfilepath=(char*)malloc(sizeof(char)*1000);
LOG(ERROR) << "mikrom ArtMethod::dumpDexOver";
int result=0;
char* packageName=ArtMethod::GetPackageName();
std::map<void*, size_t>::iterator iter;
for(iter = dex_map.begin(); iter != dex_map.end(); iter++) {
void* begin_=iter->first;
size_t size_=iter->second;
int size_int_=(int)size_;
memset(dexfilepath,0,1000);
sprintf(dexfilepath,"/sdcard/Android/data/%s/files/dump",packageName);
mkdir(dexfilepath,0777);
memset(dexfilepath,0,1000);
sprintf(dexfilepath,"/sdcard/Android/data/%s/files/dump/%d_dexfile_repair.dex",packageName,size_int_);
int dexfilefp=open(dexfilepath,O_RDONLY,0666);
if(dexfilefp>0){
close(dexfilefp);
dexfilefp=0;
}else{
int fp=open(dexfilepath,O_CREAT|O_APPEND|O_RDWR,0666);
if(fp>0)
{
result=write(fp,(void*)begin_,size_);
if(result<0)
{
LOG(ERROR) << "mikrom ArtMethod::dumpDexOver,open dexfilepath error";
}
fsync(fp);
close(fp);
memset(dexfilepath,0,1000);
}
}
}
if(dexfilepath!=nullptr)
{
free(dexfilepath);
dexfilepath=nullptr;
}
}
10
新增功能
1、修改内核反调试
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"S (sleeping)", /* 4 */ //这里之前是 "T (stopped)",
"S (sleeping)", /* 8 */ //这里之前是 "t (tracing stop)"
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *p)
{
struct user_namespace *user_ns = seq_user_ns(m);
struct group_info *group_info;
int g;
struct fdtable *fdt = NULL;
const struct cred *cred;
pid_t ppid = 0, tpid = 0;
struct task_struct *leader = NULL;
rcu_read_lock();
if (pid_alive(p)) {
struct task_struct *tracer = ptrace_parent(p);
if (tracer)
tpid = task_pid_nr_ns(tracer, ns);
ppid = task_tgid_nr_ns(rcu_dereference(p->real_parent), ns);
leader = p->group_leader;
}
//这个直接强制改tpid为0。
tpid=0;
cred = get_task_cred(p);
...
}
Name: .kanxue.crackme
State: S (sleeping)
Tgid: 12142
Pid: 12142
PPid: 545
TracerPid: 0
Uid: 10027 10027 10027 10027
Gid: 10027 10027 10027 10027
Ngid: 0
FDSize: 128
Groups: 9997 20027 50027
VmPeak: 5657524 kB
VmSize: 5210040 kB
static int proc_pid_wchan(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
{
unsigned long wchan;
char symname[KSYM_NAME_LEN];
wchan = get_wchan(task);
if (lookup_symbol_name(wchan, symname) < 0)
if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
return 0;
else
return seq_printf(m, "%lu", wchan);
else
if(strstr(symname,"trace")){ //这里是新增的,如果符号名称包含trace,就固定改成sys_epoll_wait
return seq_printf(m,"%s","SyS_epoll_wait");
}
return seq_printf(m, "%s", symname);
}
2、sleep反调试
extern uint32_t JniMethodStart(Thread* self) {
JNIEnvExt* env = self->GetJniEnv();
DCHECK(env != nullptr);
uint32_t saved_local_ref_cookie = bit_cast<uint32_t>(env->GetLocalRefCookie());
env->SetLocalRefCookie(env->GetLocalsSegmentState());
ArtMethod* native_method = *self->GetManagedStack()->GetTopQuickFrame();
// TODO: Introduce special entrypoint for synchronized @FastNative methods?
// Or ban synchronized @FastNative outright to avoid the extra check here?
DCHECK(!native_method->IsFastNative() || native_method->IsSynchronized());
const char* methodname=native_method->PrettyMethod().c_str();
if(ArtMethod::GetDebugMethod()!=nullptr && strlen(ArtMethod::GetDebugMethod())>0){
if(strstr(methodname,ArtMethod::GetDebugMethod())!=nullptr){
std::ostringstream oss1;
oss1<< "fartext JniMethodStart methodname:"<<methodname<<" wait debug sleep 60...";
LOG(ERROR)<<oss1.str();
sleep(60);
}
}
if (!native_method->IsFastNative()) {
// When not fast JNI we transition out of runnable.
self->TransitionFromRunnableToSuspended(kNative);
}
return saved_local_ref_cookie;
}
3、ROM级打桩
void ShowVarArgs(const ScopedObjectAccessAlreadyRunnable& soa,
const char* jniMethod,
jmethodID mid,
va_list args){
if(ArtMethod::IsJNIMethodPrint()){
ArtMethod* method = jni::DecodeArtMethod(mid);
uint32_t shorty_len = 0;
const char* shorty =
method->GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetShorty(&shorty_len);
JValue result;
ArgArray arg_array(shorty, shorty_len);
arg_array.VarArgsShowArg(soa, args,jniMethod,method->PrettyMethod().c_str());
}
}
void ShowJValue(const ScopedObjectAccessAlreadyRunnable& soa,
const char* jniMethod,
jmethodID mid,
const jvalue* args){
if(ArtMethod::IsJNIMethodPrint()){
ArtMethod* method = jni::DecodeArtMethod(mid);
uint32_t shorty_len = 0;
const char* shorty =
method->GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetShorty(&shorty_len);
JValue result;
ArgArray arg_array(shorty, shorty_len);
arg_array.JValuesShowArg(soa, args,jniMethod,method->PrettyMethod().c_str());
}
}
void ShowJniField(const char* jniMethodName,jfieldID field) {
if(ArtMethod::IsJNIMethodPrint()){
ArtField* f = jni::DecodeArtField(field);
std::ostringstream oss;
oss << "mikrom jni "<<jniMethodName<<"\t"<<ArtField::PrettyField(f);
LOG(ERROR)<<oss.str();
}
}
void ShowArgStr(const char* jniMethod,const char* str1,const char* str2){
if(ArtMethod::IsJNIMethodPrint()){
std::ostringstream oss;
if(str1!=nullptr && str2!=nullptr){
oss << "mikrom jni "<<jniMethod<<"\t"<<str1<<"\t"<<str2;
}else if(str1!=nullptr ){
oss << "mikrom jni "<<jniMethod<<"\t"<<str1;
}else{
oss << "mikrom jni "<<jniMethod;
}
LOG(ERROR)<<oss.str();
}
}
void VarArgsShowArg(const ScopedObjectAccessAlreadyRunnable& soa,
va_list ap,const char* jniMethodName,const char* methodName)
REQUIRES_SHARED(Locks::mutator_lock_) {
std::stringstream ss;
ss << "mikrom jni "<<jniMethodName<<"\t"<<methodName<<"\t";
for (size_t i = 1; i < shorty_len_; ++i) {
switch (shorty_[i]) {
case 'Z':
case 'B':
case 'C':
case 'S':
case 'I':
ss<<"arg"<<i<<":"<<va_arg(ap, jint)<<"\t";
break;
case 'F':
ss<<"arg"<<i<<":"<<va_arg(ap, jdouble)<<"\t";
break;
case 'L':{
jobject obj=va_arg(ap, jobject);
ObjPtr<mirror::Object> receiver =soa.Decode<mirror::Object>(obj);
if(receiver==nullptr){
LOG(ERROR)<<"mikrom "<<jniMethodName<<" receiver =nullptr";
break;
}
ObjPtr<mirror::Class> cls=receiver->GetClass();
if (cls->DescriptorEquals("Ljava/lang/String;")){
ObjPtr<mirror::String> argStr =soa.Decode<mirror::String>(obj);
ss<<"arg"<<i<<":"<<(const char*)argStr->GetValue();
}else{
ss<<"arg"<<i<<":"<<receiver<<"\t";
}
break;
}
case 'D':
ss<<"arg"<<i<<":"<<va_arg(ap, jdouble)<<"\t";
break;
case 'J':
ss<<"arg"<<i<<":"<<va_arg(ap, jlong)<<"\t";
break;
}
}
LOG(ERROR) << ss.str();
}
void JValuesShowArg(const ScopedObjectAccessAlreadyRunnable& soa,
const jvalue* args,const char * jniMethodName,const char* methodName)
REQUIRES_SHARED(Locks::mutator_lock_) {
std::stringstream ss;
ss << "mikrom jni "<<jniMethodName<<"\t"<<methodName<<"\t";
for (size_t i = 1, args_offset = 0; i < shorty_len_; ++i, ++args_offset) {
switch (shorty_[i]) {
case 'Z':
ss<<"arg"<<i<<":"<<args[args_offset].z<<"\t";
break;
case 'B':
ss<<"arg"<<i<<":"<<args[args_offset].b<<"\t";
break;
case 'C':
ss<<"arg"<<i<<":"<<args[args_offset].c<<"\t";
break;
case 'S':
ss<<"arg"<<i<<":"<<args[args_offset].s<<"\t";
break;
case 'I':
FALLTHROUGH_INTENDED;
case 'F':
ss<<"arg"<<i<<":"<<args[args_offset].i<<"\t";
break;
case 'L':{
jobject obj=args[args_offset].l;
ObjPtr<mirror::Object> receiver =soa.Decode<mirror::Object>(obj);
if(receiver==nullptr){
LOG(ERROR)<<"mikrom "<<jniMethodName<<" receiver =nullptr";
break;
}
ObjPtr<mirror::Class> cls=receiver->GetClass();
if (cls->DescriptorEquals("Ljava/lang/String;")){
ObjPtr<mirror::String> argStr =soa.Decode<mirror::String>(obj);
ss<<"arg"<<i<<":"<<(const char*)argStr->GetValue();
}else{
ss<<"arg"<<i<<":"<<receiver<<"\t";
}
break;
}
case 'D':
FALLTHROUGH_INTENDED;
case 'J':
ss<<"arg"<<i<<":"<<args[args_offset].j<<"\t";
break;
}
}
LOG(ERROR) << ss.str();
}
static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, const jvalue* args) {
CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
ScopedObjectAccess soa(env);
//add
ShowJValue(soa,__FUNCTION__,mid,args);
//add end
return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
}
static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
va_list ap;
va_start(ap, mid);
ScopedVAArgs free_args_later(&ap);
CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
ScopedObjectAccess soa(env);
//add
ShowVarArgs(soa,__FUNCTION__,mid,ap);
//add end
JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
return result.GetF();
}
4、frida-gadget持久化
public static void loadGadget(){
String processName = ActivityThread.currentProcessName();
for(PackageItem item : mikConfigs){
if(item.packageName.equals(processName)){
try{
boolean flag=true;
if(item.fridaJsPath.length()<=0){
continue;
}
String configPath="/data/data/"+processName+"/libfdgg.config.so";
String configPath2="/data/data/"+processName+"/libfdgg32.config.so";
if(item.fridaJsPath.equals("listen")||item.fridaJsPath.equals("listen_wait")){
WriteConfig(configPath,item.fridaJsPath,item.port);
WriteConfig(configPath2,item.fridaJsPath,item.port);
}else{
File file = new File(item.fridaJsPath);
if(!file.exists()){
file = new File( "/data/data/" + processName +"/"+file.getName());
}
if(!file.exists()){
Log.e("mikrom", "initConfig package:" + processName+" frida js path:"+item.fridaJsPath+" not found");
continue;
}
WriteConfig(configPath,item.fridaJsPath,item.port);
WriteConfig(configPath2,item.fridaJsPath,item.port);
}
String tagPath = "/data/data/" + processName + "/libfdgg.so";//64位so的目录
String tagPath2 = "/data/data/" + processName + "/libfdgg32.so";//32位的so目录
//使用用户自己设置的gadget路径
if(item.gadgetPath!=null&&item.gadgetPath.length()>0){
mycopy(item.gadgetArm64Path, tagPath);//复制so到私有目录
mycopy(item.gadgetPath, tagPath2);
}else{
mycopy("/system/lib64/libfdgg.so", tagPath);//复制so到私有目录
mycopy("/system/lib/libfdgg.so", tagPath2);
}
int perm = FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO;
FileUtils.setPermissions(tagPath, perm, -1, -1);//将权限改为777
FileUtils.setPermissions(tagPath2, perm, -1, -1);
FileUtils.setPermissions(configPath, perm, -1, -1);
FileUtils.setPermissions(configPath2, perm, -1, -1);
File file1 = new File(tagPath);
File file2 = new File(tagPath2);
if (file1.exists()) {
Log.e("mikrom", "app: " +System.getProperty("os.arch"));//判断是64位还是32位
if (System.getProperty("os.arch").indexOf("64") >= 0) {
Log.e("mikrom", "initConfig package:" + processName+" frida js path:"+item.fridaJsPath+" load arch64");
System.load(tagPath);
file1.delete();//用完就删否则不会更新
} else {
Log.e("mikrom", "initConfig package:" + processName+" frida js path:"+item.fridaJsPath+" load 32");
System.load(tagPath2);
file2.delete();
}
}
Log.e("mikrom", "initConfig package:" + processName+" initConfig over");
}catch(Exception ex){
Log.e("mikrom", "initConfig package:" + processName+" frida js path:"+item.fridaJsPath+" load err:"+ex.getMessage());
}
break;
}
}
}
5、so注入以及dobby的内置
public static void loadSo(String path){
String processName = ActivityThread.currentProcessName();
String fName = path.trim();
String fileName = fName.substring(fName.lastIndexOf("/")+1);
String tagPath = "/data/data/" + processName + "/"+fileName;//64位so的目录
mycopy(path, tagPath);
int perm = FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO;
FileUtils.setPermissions(tagPath, perm, -1, -1);//将权限改为777
File file = new File(tagPath);
if (file.exists()){
Log.e("mikrom", "load so:"+tagPath);
System.load(tagPath);
file.delete();//用完就删否则不会更新
}
}
//注入so
public static void loadConfigSo(){
String processName = ActivityThread.currentProcessName();
for(PackageItem item : mikConfigs){
if(!item.packageName.equals(processName))
continue;
if(item.soPath.length()<=0)
continue;
if(item.isDobby){
if(System.getProperty("os.arch").indexOf("64") >= 0) {
loadSo("/system/lib64/libdby_64.so");
}else{
loadSo("/system/lib/libdby.so");
}
}
String[] soList=item.soPath.split("\n");
for(String sopath :soList){
loadSo(sopath);
}
}
}
6、smali trace
static inline void TraceExecution(const ShadowFrame& shadow_frame, const Instruction* inst,
const uint32_t dex_pc)
REQUIRES_SHARED(Locks::mutator_lock_) {
if(shadow_frame.GetMethod()!=nullptr && ArtMethod::GetTraceMethod()!=nullptr&&strlen(ArtMethod::GetTraceMethod())>0){
const char* methodName=shadow_frame.GetMethod()->PrettyMethod().c_str();
if(strstr(methodName,ArtMethod::GetTraceMethod())) {
std::ostringstream oss;
oss << android::base::StringPrintf("mikrom smaliTrace 0x%x: ", dex_pc)
<< inst->DumpString(shadow_frame.GetMethod()->GetDexFile()) << "\t//";
for (uint32_t i = 0; i < shadow_frame.NumberOfVRegs(); ++i) {
uint32_t raw_value = shadow_frame.GetVReg(i);
ObjPtr<mirror::Object> ref_value = shadow_frame.GetVRegReference(i);
oss << android::base::StringPrintf(" vreg%u=0x%08X", i, raw_value);
if (ref_value != nullptr) {
if (ref_value->GetClass()->IsStringClass() &&
!ref_value->AsString()->IsValueNull()) {
oss << "/java.lang.String \"" << ref_value->AsString()->ToModifiedUtf8() << "\"";
} else {
oss << "/" << ref_value->PrettyTypeOf();
}
}
}
LOG(ERROR)<<oss.str();
}
}
}
static inline JValue Execute(
Thread* self,
const CodeItemDataAccessor& accessor,
ShadowFrame& shadow_frame,
JValue result_register,
bool stay_in_interpreter = false,
bool from_deoptimize = false) REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK(!shadow_frame.GetMethod()->IsAbstract());
DCHECK(!shadow_frame.GetMethod()->IsNative());
...
if(ArtMethod::GetTraceMethod()!=nullptr && strlen(ArtMethod::GetTraceMethod())>0){
if(strstr(method->PrettyMethod().c_str(),ArtMethod::GetTraceMethod())){
std::ostringstream oss;
oss<< "mikrom Execute strstr:"<<method->PrettyMethod().c_str()<<"\t"<<ArtMethod::GetTraceMethod();
LOG(ERROR) <<oss.str();
return ExecuteSwitchImpl<false, false>(self, accessor, shadow_frame, result_register,false);
}
}
//add end
...
}
static void LinkCode(ClassLinker* class_linker,
ArtMethod* method,
const OatFile::OatClass* oat_class,
uint32_t class_def_method_index) REQUIRES_SHARED(Locks::mutator_lock_) {
...
const void* quick_code = method->GetEntryPointFromQuickCompiledCode();
bool enter_interpreter = class_linker->ShouldUseInterpreterEntrypoint(method, quick_code);
if(strlen(ArtMethod::GetTraceMethod())>0){
std::ostringstream oss;
oss<<"mikrom LinkCode method:"<<method->PrettyMethod().c_str();
LOG(ERROR)<<oss.str();
enter_interpreter=true;
}
...
}
7、dex注入(未完成)
11
MikManager展示
12
使用说明
2022-01-30 19:43:30.198 4105-4105/com.kanxue.crackme E/.kanxue.crackm: mikrom jni CallNonvirtualVoidMethodV void java.lang.ClassNotFoundException.<init>(java.lang.String, java.lang.Throwable) arg1:android.widget.ViewStubarg2:0x6fcc6f50
2022-01-30 19:43:30.198 4105-4105/com.kanxue.crackme E/.kanxue.crackm: mikrom jni GetArrayLength
2022-01-30 19:43:30.198 4105-4105/com.kanxue.crackme E/.kanxue.crackm: mikrom jni GetStringUTFChars android.widget.ViewStub
2022-01-30 19:43:30.199 4105-4105/com.kanxue.crackme E/.kanxue.crackm: mikrom jni CallNonvirtualVoidMethodV void java.lang.ClassNotFoundException.<init>(java.lang.String, java.lang.Throwable) arg1:android.widget.ViewStubarg2:0x12c2a5e8
2022-01-30 19:43:30.199 4105-4105/com.kanxue.crackme E/.kanxue.crackm: mikrom jni GetStringUTFChars android.webkit.ViewStub
2022-01-30 19:43:30.199 4105-4105/com.kanxue.crackme E/.kanxue.crackm: mikrom jni NewStringUTF android.webkit.ViewStub
2022-01-30 19:43:30.199 4105-4105/com.kanxue.crackme E/.kanxue.crackm: mikrom jni CallObjectMethodV java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String) arg1:android.webkit.ViewStub
2022-01-30 19:43:30.199 4105-4105/com.kanxue.crackme E/.kanxue.crackm: mikrom jni GetStringUTFChars android.webkit.ViewStub
2022-01-30 19:43:30.199 4105-4105/com.kanxue.crackme E/.kanxue.crackm: mikrom jni GetStringUTFChars android.webkit.ViewStub
2022-01-30 19:43:30.199 4105-4105/com.kanxue.crackme E/.kanxue.crackm: mikrom jni CallNonvirtualVoidMethodV void java.lang.ClassNotFoundException.<init>(java.lang.String, java.lang.Throwable) arg1:android.webkit.ViewStubarg2:0x6fcc6f50
2022-01-30 19:43:30.199 4105-4105/com.kanxue.crackme E/.kanxue.crackm: mikrom jni GetArrayLength
2022-01-30 19:48:43.219 4576-4576/com.kanxue.crackme E/.kanxue.crackm: mikrom RomPrint RegisterNative name:boolean com.kanxue.crackme.MainActivity.jnicheck(java.lang.String) native_ptr:0x75a5735904 method_idx:568
2022-01-30 19:48:43.219 4576-4576/com.kanxue.crackme E/.kanxue.crackm: mikrom RomPrint RegisterNative name:boolean com.kanxue.crackme.MainActivity.crypt2(java.lang.String) native_ptr:0x75a5739750 method_idx:2
2022-01-30 19:50:16.247 4686-4686/com.kanxue.crackme E/.kanxue.crackm: mikrom [PerformCall] caller:boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)---called:boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)
2022-01-30 19:50:16.247 4686-4686/com.kanxue.crackme E/.kanxue.crackm: mikrom [PerformCall] caller:void android.graphics.Paint.nSetFlags(long, int)---called:void android.graphics.Paint.nSetFlags(long, int)
2022-01-30 19:50:16.247 4686-4686/com.kanxue.crackme E/.kanxue.crackm: mikrom [PerformCall] caller:int java.lang.String.hashCode()---called:int java.lang.String.hashCode()
2022-01-30 19:50:16.247 4686-4686/com.kanxue.crackme E/.kanxue.crackm: mikrom [PerformCall] caller:void android.graphics.Paint.nSetTextLocalesByMinikinLocaleListId(long, int)---called:void android.graphics.Paint.nSetTextLocalesByMinikinLocaleListId(long, int)
2022-01-30 19:50:16.247 4686-4686/com.kanxue.crackme E/.kanxue.crackm: mikrom [PerformCall] caller:void android.graphics.Paint.nSetDither(long, boolean)---called:void android.graphics.Paint.nSetDither(long, boolean)
2022-01-30 19:50:16.247 4686-4686/com.kanxue.crackme E/.kanxue.crackm: mikrom [PerformCall] caller:void android.graphics.Paint.nSetDither(long, boolean)---called:void android.graphics.Paint.nSetDither(long, boolean)
2022-01-30 20:06:11.003 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x0: invoke-static {}, void com.mik.miktest.CommonTools.Test() // method@7 // vreg0=0x00000000 vreg1=0x00000000 vreg2=0x00000000 vreg3=0x00000000 vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.003 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x3: const-string v0, "MainActivity" // string@30 // vreg0=0x00000000 vreg1=0x00000000 vreg2=0x00000000 vreg3=0x00000000 vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.008 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x5: const-string v1, "TraceTest" // string@33 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000000 vreg2=0x00000000 vreg3=0x00000000 vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.008 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x7: invoke-static {v0, v1}, int android.util.Log.i(java.lang.String, java.lang.String) // method@0 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x12C896A8/java.lang.String "TraceTest" vreg2=0x00000000 vreg3=0x00000000 vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.008 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0xa: add-int v1, v5, v6 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x12C896A8/java.lang.String "TraceTest" vreg2=0x00000000 vreg3=0x00000000 vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.008 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0xc: new-instance v2, java.lang.StringBuilder // type@TypeIndex[16] // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x00000000 vreg3=0x00000000 vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.010 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0xe: invoke-direct {v2}, void java.lang.StringBuilder.<init>() // method@17 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x12C896C8/java.lang.StringBuilder vreg3=0x00000000 vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.010 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x11: const-string v3, "TraceTest," // string@34 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x12C896C8/java.lang.StringBuilder vreg3=0x00000000 vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.010 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x13: invoke-virtual {v2, v3}, java.lang.StringBuilder java.lang.StringBuilder.append(java.lang.String) // method@19 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x12C896C8/java.lang.StringBuilder vreg3=0x12C89708/java.lang.String "TraceTest," vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.010 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x16: move-result-object v2 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x12C896C8/java.lang.StringBuilder vreg3=0x12C89708/java.lang.String "TraceTest," vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.010 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x17: invoke-virtual {v2, v1}, java.lang.StringBuilder java.lang.StringBuilder.append(int) // method@18 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x12C896C8/java.lang.StringBuilder vreg3=0x12C89708/java.lang.String "TraceTest," vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.010 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x1a: move-result-object v2 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x12C896C8/java.lang.StringBuilder vreg3=0x12C89708/java.lang.String "TraceTest," vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.010 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x1b: invoke-virtual {v2}, java.lang.String java.lang.StringBuilder.toString() // method@20 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x12C896C8/java.lang.StringBuilder vreg3=0x12C89708/java.lang.String "TraceTest," vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.010 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x1e: move-result-object v2 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x12C896C8/java.lang.StringBuilder vreg3=0x12C89708/java.lang.String "TraceTest," vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.010 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x1f: invoke-static {v0, v2}, int android.util.Log.i(java.lang.String, java.lang.String) // method@0 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x12C89738/java.lang.String "TraceTest,16" vreg3=0x12C89708/java.lang.String "TraceTest," vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.010 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x22: mul-int v2, v5, v6 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x12C89738/java.lang.String "TraceTest,16" vreg3=0x12C89708/java.lang.String "TraceTest," vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.010 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x24: new-instance v4, java.lang.StringBuilder // type@TypeIndex[16] // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x0000000F vreg3=0x12C89708/java.lang.String "TraceTest," vreg4=0x00000000 vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.010 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x26: invoke-direct {v4}, void java.lang.StringBuilder.<init>() // method@17 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x0000000F vreg3=0x12C89708/java.lang.String "TraceTest," vreg4=0x12C89758/java.lang.StringBuilder vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.010 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x29: invoke-virtual {v4, v3}, java.lang.StringBuilder java.lang.StringBuilder.append(java.lang.String) // method@19 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x0000000F vreg3=0x12C89708/java.lang.String "TraceTest," vreg4=0x12C89758/java.lang.StringBuilder vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.010 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x2c: move-result-object v3 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x0000000F vreg3=0x12C89708/java.lang.String "TraceTest," vreg4=0x12C89758/java.lang.StringBuilder vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.010 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x2d: invoke-virtual {v3, v2}, java.lang.StringBuilder java.lang.StringBuilder.append(int) // method@18 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x0000000F vreg3=0x12C89758/java.lang.StringBuilder vreg4=0x12C89758/java.lang.StringBuilder vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.010 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x30: move-result-object v3 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x0000000F vreg3=0x12C89758/java.lang.StringBuilder vreg4=0x12C89758/java.lang.StringBuilder vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.011 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x31: invoke-virtual {v3}, java.lang.String java.lang.StringBuilder.toString() // method@20 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x0000000F vreg3=0x12C89758/java.lang.StringBuilder vreg4=0x12C89758/java.lang.StringBuilder vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.011 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x34: move-result-object v3 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x0000000F vreg3=0x12C89758/java.lang.StringBuilder vreg4=0x12C89758/java.lang.StringBuilder vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.011 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x35: invoke-static {v0, v3}, int android.util.Log.i(java.lang.String, java.lang.String) // method@0 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x0000000F vreg3=0x12C897A8/java.lang.String "TraceTest,15" vreg4=0x12C89758/java.lang.StringBuilder vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.011 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x38: add-int v0, v1, v2 // vreg0=0x12C89670/java.lang.String "MainActivity" vreg1=0x00000010 vreg2=0x0000000F vreg3=0x12C897A8/java.lang.String "TraceTest,15" vreg4=0x12C89758/java.lang.StringBuilder vreg5=0x00000001 vreg6=0x0000000F
2022-01-30 20:06:11.011 5157-5157/com.mik.miktest E/com.mik.miktes: mikrom smaliTrace 0x3a: return v0 // vreg0=0x0000001F vreg1=0x00000010 vreg2=0x0000000F vreg3=0x12C897A8/java.lang.String "TraceTest,15" vreg4=0x12C89758/java.lang.StringBuilder vreg5=0x00000001 vreg6=0x0000000F
13
完结撒花
看雪ID:misskings
https://bbs.pediy.com/user-home-659397.htm
# 往期推荐
2.栈与栈帧的调试
3.python_mmdt:ssdeep、tlsh、vhash、mmdthash对比
6.Windows本地代码执行漏洞(CVE-2012-1876)x86/x64平台分析
球分享
球点赞
球在看
点击“阅读原文”,了解更多!