安卓 dex 通用脱壳技术研究(三)

Android脱壳之整体脱壳原理与实践 我最近从朋友那里收集到了2020-2021BAT 面试真题解析Android 基础、Java 基础、Android 源码相关分析、常见的一些原理性问题等等,可以很好地帮助大家深刻理解Android相关知识点的原理以及面试相关知识。这份资料把大厂面试中常被问到的技术点整理成了PDF,包知识脉络 + 诸多细节;还有 高级架构技术进阶脑图 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。这里也分享给广大面试同胞们,希望每位程序猿们都能面试成功~ 阅读详情

http://my.oschina.net/cve2015/blog/508918


摘要  本文剖析安卓 Dalvik 解释器 Portable 的原理与实现,并通过修改 Dalvik 虚拟机实现 dex 文件的通用脱壳方案;本方法同样适应于 ART 虚拟机;

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
/*
     此为DexHunter实现的主要功能,进行内存dump,将class_def_items中dump出classdef和extra部分
*/
void * DumpClass( void  *parament)
{
   while  (timer_flag) {
       sleep(5);
   }
 
   DvmDex* pDvmDex=(( struct  arg*)parament)->pDvmDex;  //pDvmDex代表一个dex文件
   Object *loader=(( struct  arg*)parament)->loader;
   DexFile* pDexFile=pDvmDex->pDexFile;
   MemMapping * mem=&pDvmDex->memMap;
 
   u4  time =dvmGetRelativeTimeMsec();
   ALOGI( "GOT IT begin: %d ms" , time );
 
   char  *path =  new  char [100];
   strcpy (path,dumppath);
   strcat (path, "classdef" );   //构造classdef文件路径 
   FILE  *fp =  fopen (path,  "wb+" );
 
   strcpy (path,dumppath);
   strcat (path, "extra" );  //构造extra文件路径 
   FILE  *fp1 =  fopen (path, "wb+" );
 
   uint32_t mask=0x3ffff;
   char  padding=0;
   const  char * header= "Landroid" ;
   unsigned  int  num_class_defs=pDexFile->pHeader->classDefsSize;  //dex文件的Header域,class_defs_size,标示了class_def域有几个class_def_item
   uint32_t total_pointer = mem->length-uint32_t(pDexFile->baseAddr-( const  u1*)mem->addr);
   uint32_t rec=total_pointer;
 
   while  (total_pointer&3) {
       total_pointer++;
   }
 
   int  inc=total_pointer-rec;
   uint32_t start = pDexFile->pHeader->classDefsOff+ sizeof (DexClassDef)*num_class_defs;
   uint32_t end = (uint32_t)(( const  u1*)mem->addr+mem->length-pDexFile->baseAddr);
 
   for  ( size_t  i=0;i<num_class_defs;i++)  //遍历所有class_def_item
   {
       bool  need_extra= false ;
       ClassObject * clazz=NULL;
       const  u1* data=NULL;
       DexClassData* pData = NULL;
       bool  pass= false ;
       const  DexClassDef *pClassDef = dexGetClassDef(pDvmDex->pDexFile, i);
       const  char  *descriptor = dexGetClassDescriptor(pDvmDex->pDexFile,pClassDef);
 
       if (! strncmp (header,descriptor,8)||!pClassDef->classDataOff)
       {
           pass= true ;
           goto  classdef;
       }
 
       clazz = dvmDefineClass(pDvmDex, descriptor, loader);   //First Step:class加载
 
       if  (!clazz) {
          continue ;
       }
 
       ALOGI( "GOT IT class: %s" ,descriptor);
 
       if  (!dvmIsClassInitialized(clazz)) {   //Second Step:class初始化,遍历所有类进行初始化
           if (dvmInitClass(clazz)){   //与dvmIsClassInitialized()函数共同完成初始化
               ALOGI( "GOT IT init: %s" ,descriptor);
           }
       }
            
       if (pClassDef->classDataOff<start || pClassDef->classDataOff>end)
       {
           need_extra= true ;   //是不是需要extra这一块,当存在class_data_off不在dex范围内时,就需要
       }
 
       data=dexGetClassData(pDexFile, pClassDef);
       pData = ReadClassData(&data);
 
       if  (!pData) {
           continue ;
       }
 
       if  (pData->directMethods) {
           for  (uint32_t i=0; i<pData->header.directMethodsSize; i++) {
               Method *method = &(clazz->directMethods[i]);
               uint32_t ac = (method->accessFlags) & mask;
 
               ALOGI( "GOT IT direct method name %s.%s" ,descriptor,method->name);
 
               if  (!method->insns||ac&ACC_NATIVE) {
                   if  (pData->directMethods[i].codeOff) {
                       need_extra =  true ;
                       pData->directMethods[i].accessFlags=ac;
                       pData->directMethods[i].codeOff=0;
                   }
                   continue ;
               }
 
               u4 codeitem_off = u4(( const  u1*)method->insns-16-pDexFile->baseAddr);
 
               if  (ac != pData->directMethods[i].accessFlags)
               {
                   ALOGI( "GOT IT method ac" );
                   need_extra= true ;
                   pData->directMethods[i].accessFlags=ac;
               }
 
               if  (codeitem_off!=pData->directMethods[i].codeOff&&((codeitem_off>=start&&codeitem_off<=end)||codeitem_off==0)) {
                   ALOGI( "GOT IT method code" );
                   need_extra= true ;
                   pData->directMethods[i].codeOff=codeitem_off;
               }
 
               if  ((codeitem_off<start || codeitem_off>end) && codeitem_off!=0) {
                   //如果code_item_off不在dex文件范围内,则写入extra; fp1为extra的句柄
                   //这里使用的是slider.pptx,中的第二种方案,见p42
                   need_extra= true ;
                   pData->directMethods[i].codeOff = total_pointer;
                   DexCode *code = (DexCode*)(( const  u1*)method->insns-16);
                   uint8_t *item=(uint8_t *) code;
                   int  code_item_len = 0;
                   if  (code->triesSize) {
                       const  u1 * handler_data = dexGetCatchHandlerData(code);
                       const  u1** phandler=( const  u1**)&handler_data;
                       uint8_t * tail=codeitem_end(phandler);
                       code_item_len = ( int )(tail-item);
                   } else {
                       code_item_len = 16+code->insnsSize*2;
                   }
 
                   ALOGI( "GOT IT method code changed" );
 
                   fwrite (item,1,code_item_len,fp1);
                   fflush (fp1);
                   total_pointer+=code_item_len;
                   while  (total_pointer&3) {
                       fwrite (&padding,1,1,fp1);
                       fflush (fp1);
                       total_pointer++;
                   }
               }
           }
       }
 
       if  (pData->virtualMethods) {
           for  (uint32_t i=0; i<pData->header.virtualMethodsSize; i++) {
               Method *method = &(clazz->virtualMethods[i]);
               uint32_t ac = (method->accessFlags) & mask;
 
               ALOGI( "GOT IT virtual method name %s.%s" ,descriptor,method->name);
 
               if  (!method->insns||ac&ACC_NATIVE) {
                   if  (pData->virtualMethods[i].codeOff) {
                       need_extra =  true ;
                       pData->virtualMethods[i].accessFlags=ac;
                       pData->virtualMethods[i].codeOff=0;
                   }
                   continue ;
               }
 
               u4 codeitem_off = u4(( const  u1 *)method->insns - 16 - pDexFile->baseAddr);
 
               if  (ac != pData->virtualMethods[i].accessFlags)
               {
                   ALOGI( "GOT IT method ac" );
                   need_extra= true ;
                   pData->virtualMethods[i].accessFlags=ac;
               }
 
               if  (codeitem_off!=pData->virtualMethods[i].codeOff&&((codeitem_off>=start&&codeitem_off<=end)||codeitem_off==0)) {
                   ALOGI( "GOT IT method code" );
                   need_extra= true ;
                   pData->virtualMethods[i].codeOff=codeitem_off;
               }
 
               if  ((codeitem_off<start || codeitem_off>end)&&codeitem_off!=0) {
                   need_extra= true ;
                   pData->virtualMethods[i].codeOff = total_pointer;
                   DexCode *code = (DexCode*)(( const  u1*)method->insns-16);
                   uint8_t *item=(uint8_t *) code;
                   int  code_item_len = 0;
                   if  (code->triesSize) {
                       const  u1 *handler_data = dexGetCatchHandlerData(code);
                       const  u1** phandler=( const  u1**)&handler_data;
                       uint8_t * tail=codeitem_end(phandler);
                       code_item_len = ( int )(tail-item);
                   } else {
                       code_item_len = 16+code->insnsSize*2;
                   }
 
                   ALOGI( "GOT IT method code changed" );
 
                   fwrite (item,1,code_item_len,fp1);
                   fflush (fp1);
                   total_pointer+=code_item_len;
                   while  (total_pointer&3) {
                       fwrite (&padding,1,1,fp1);
                       fflush (fp1);
                       total_pointer++;
                   }
               }
           }
       }
 
classdef:
        DexClassDef temp=*pClassDef;
        uint8_t *p = (uint8_t *)&temp;
 
        if  (need_extra) {
            ALOGI( "GOT IT classdata before" );
            int  class_data_len = 0;
            uint8_t *out = EncodeClassData(pData,class_data_len);
            if  (!out) {
                continue ;
            }
            temp.classDataOff = total_pointer;
            fwrite (out,1,class_data_len,fp1);
            fflush (fp1);
            total_pointer+=class_data_len;
            while  (total_pointer&3) {
                fwrite (&padding,1,1,fp1);
                fflush (fp1);
                total_pointer++;
            }
            free (out);
            ALOGI( "GOT IT classdata written" );
        } else {
            if  (pData) {
                free (pData);
            }
        }
 
        if  (pass) {
            temp.classDataOff=0;
            temp.annotationsOff=0;
        }
 
        ALOGI( "GOT IT classdef" );
        fwrite (p,  sizeof (DexClassDef), 1, fp);
        fflush (fp);
   }
 
   fclose (fp1);
   fclose (fp);
     //目前已经准备好了part1,classdef,data和extra 4部分文件
   strcpy (path,dumppath);
   strcat (path, "whole.dex" );  //组合4部分,并写入whole.dex
   fp =  fopen (path, "wb+" );
   rewind (fp);
 
   int  fd=-1;
   int  r=-1;
   int  len=0;  
   char  *addr=NULL;
   struct  stat st;
 
   strcpy (path,dumppath);
   strcat (path, "part1" );
 
   fd=open(path,O_RDONLY,0666);
   if  (fd==-1) {
       return  NULL;
   }
 
   r=fstat(fd,&st);  
   if (r==-1){  
       close(fd);  
       return  NULL;
   }
 
   len=st.st_size;
   addr=( char *)mmap(NULL,len,PROT_READ,MAP_PRIVATE,fd,0);
   fwrite (addr,1,len,fp);
   fflush (fp);
   munmap(addr,len);
   close(fd);
 
   strcpy (path,dumppath);
   strcat (path, "classdef" );
 
   fd=open(path,O_RDONLY,0666);
   if  (fd==-1) {
       return  NULL;
   }
 
   r=fstat(fd,&st);  
   if (r==-1){  
       close(fd);  
       return  NULL;
   }
 
   len=st.st_size;
   addr=( char *)mmap(NULL,len,PROT_READ,MAP_PRIVATE,fd,0);
   fwrite (addr,1,len,fp);
   fflush (fp);
   munmap(addr,len);
   close(fd);
 
   strcpy (path,dumppath);
   strcat (path, "data" );
 
   fd=open(path,O_RDONLY,0666);
   if  (fd==-1) {
       return  NULL;
   }
 
   r=fstat(fd,&st);  
   if (r==-1){  
       close(fd);  
       return  NULL;
   }
 
   len=st.st_size;
   addr=( char *)mmap(NULL,len,PROT_READ,MAP_PRIVATE,fd,0);
   fwrite (addr,1,len,fp);
   fflush (fp);
   munmap(addr,len);
   close(fd);
 
   while  (inc>0) {
       fwrite (&padding,1,1,fp);
       fflush (fp);
       inc--;
   }
 
   strcpy (path,dumppath);
   strcat (path, "extra" );
 
   fd=open(path,O_RDONLY,0666);
   if  (fd==-1) {
       return  NULL;
   }
 
   r=fstat(fd,&st);  
   if (r==-1){  
       close(fd);  
       return  NULL;
   }
 
   len=st.st_size;
   addr=( char *)mmap(NULL,len,PROT_READ,MAP_PRIVATE,fd,0);
   fwrite (addr,1,len,fp);
   fflush (fp);
   munmap(addr,len);
   close(fd);
 
   fclose (fp);
   delete  path;
 
   time =dvmGetRelativeTimeMsec();
   ALOGI( "GOT IT end: %d ms" , time );
 
   return  NULL;
}
//------------------------added end----------------------//

Android 逆向之脱壳实战篇 这篇文章比较干,比较偏实战,看之前建议先喝足水,慎入。在学脱壳之前,我们先来复习一下,什么时候是加固?加固本质上就是对 dex 文件进行加壳处理,让一些反编译工具反编译到的是 dex 壳,而不是 dex 文件本身。具体的实现方式是,将原 dex 文件进行加密,再合成到 dex 壳中,而系统运行应用的时候,会加载 dex 壳文件,而 dex 壳里面有一个自定义的 ClassLoader 类,它会将原有 dex 文件进行解密,然后再加载到 dex 数组中。学完了加固,那么什么是脱壳呢? 阅读详情

相关推荐

【frida逆向开发】frida脱壳原理及脱壳工具使用

目录一、知识补充二、操作流程演示 一、知识补充 1、加固后的APP运行流程 1. -->APP启动 2. -->壳dex先加载起来 3. -->壳负责把源dex文件读出来 4. -->壳把源dex文件解密 5. -->把解密后的dex加载进内存 源dex运行起来 2、脱壳原理 加固后的APP启动后最终源dex文件会被

ssrf 6098

ART 下 Dex 加载流程源码分析 和 通用脱壳点

进入 dex2oat.cc 的 main(),在 dex2oat::ReturnCode Setup() 方法中 将 dex 注册到 VerificationResults 时候可以拿到 dex_file 对象,这里也是一个很好的脱壳点。重新执行 frida 脚本 dump dex,从输出可以看到 dump 下来的 dex 魔数都是 dex 039 / dex 035 (标准 Dex 文件的魔数)不是 cdex001,可以直接用 jadx 去反编译了。

1141

360加固保的dex脱壳方法

完全测试了看雪论坛的方法,发现并没有脱壳,依然无法反编译 http://bbs.pediy.com/thread-213377.htm 使用上面方法的结果是会得到16个dex文件,只有一个是与程序相关的,用jadx打开发现还是360加固的dex,所以依然没什么用。 就看下面这个方法了,我也没弄出来

六桥风月IT随笔 6380

分享一个自己做的函数抽取壳

一、概述 项目中慢慢开始,写一些简单的 kotlin类了,挺方便的一个语言,借鉴了不少脚本语言的特点。刚开始用,有些点经常要翻越,特别记录下。 二、常用的几个复合符号 《Kotlin 实战》小人系列,的这本书里 画的图很清晰了,我又重画了一遍。 2.1、 ?.安全调用符 !这里写图片描述 if (foo != null){ return foo.bar() }else{ return null } 1 2 3 4 5 6 2.2、 ?: 2.3、 as? 2.4、 !! ...

zhangmiaoping23的专栏 1329

FART 脱壳某大厂 App + CodeItem 修复 dex + 反编译还原源码

主动调用时 dump 得到的 dex (*_dex_file.dex)和此时 dex 中的所有类列表,以及该 dex 中所有函数的 CodeItem( bin 文件)Execute 脱壳点得到的 dex (*_dex_file_execute.dex)和 dex 中的所有类列表( txt 文件)是一个将 Android 的 .dex 文件转换为 Java 的 .jar 文件的工具,方便反编译和分析 APK。修复组件就是通过读取 bin 文件的 method_idx 和 ins 进行 dex 的修复的。

1668

APP脱壳-安卓逆向

记录一下脱壳的过程。

weixin_41259961的博客 3004

Android Dex文件详解

前言 相信大家都熟悉dex文件,把一个apk给解压缩,就会得到一堆dex文件,但是这些dex文件是怎么来的,又有什么用,为什么这样设计,有进行思考过吗 俗话说知其然,知其所以然,本篇文章开始探究一下这些底层实现细节。 正文 不同的虚拟机 JVM JVM是Java Virtual Machine的简称,即Java虚拟机,它本质是一层软件抽象,在这之上才可以运行Java程序。Java文件经过编译后会生成JVM字节码,和C语言编译后生成的汇编语言不同,C编译成的汇编语言可以直接在硬件上跑,但是Java编译生成的字

Misdirection_XG的博客 8286

【愚公系列】2023年06月 移动安全之安卓逆向(DEX文件格式)

DEX文件格式是Android操作系统中的一种二进制文件格式,用于存储编译后的Java字节码和相关元数据。DEX文件是为了解决在Android系统中运行Java应用程序的效率问题而产生的,它采用了一种优化的方法来减小二进制代码的大小和内存占用。在Android系统中,所有的应用程序都被编译成DEX格式,然后通过Dalvik虚拟机进行解释执行。DEX文件格式是Android应用程序的核心组成部分,它的优化和压缩对于应用程序的性能和响应速度有重要影响。

愚公智库 4881

浅谈 Android Dex 文件

概述 为什么要了解 Dex 文件 了解了 Dex 文件以后,对日常开发中遇到一些问题能有更深的理解。如:APK 的瘦身、热修复、插件化、应用加固、Android 逆向工程、64 K 《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》开源 方法数限制。 什么是 Dex 文件 在明白什么是 Dex 文件之前,要先了解一下 JVM,Dalvik 和 ART。JVM 是 JAVA 虚拟机,用来运行 JAVA 字节码程序。Dalvik 是 Google 设计的用于 Android平

m0_54851114的博客 2653

【HarmonyOS 5】鸿蒙APP使用【团结引擎Unity】开发的案例教程

以下是基于团结引擎开发鸿蒙Unity应用的详细案例教程,整合环境配置、工程适配、跨语言通信等核心环节。

2201_75709314的博客 2483

jason-2卫星介绍及其数据下载

两台仪器发射脉冲宽度均为105.6μs,带宽320MHz(C频段)和320/100MHz(Ku频段),脉冲重复频率1800Hz(Ku频段)和300Hz(C频段),功率78W,数据传输速率22.5kbit/s。共发射了3颗卫星(Jason - 1/2/3),星上有效载荷均主要为雷达高度计和微波辐射计。Jason - 1卫星主要有效载荷为波塞冬 - 2和“贾森微波辐射计”,Jason - 2卫星进行了改进,主要携带了波塞冬 - 3和先进微波辐射计,此外,Jason - 2卫星还携带了“多里斯”系统。

beautyaaaa的博客 1606

Android Dex 文件解析

Android Dex 文件解析 文章目录Android Dex 文件解析前言基本数据类型LEB128 类型uleb128leb128uleb128p1Dex 文件结构图Dex 结构说明hedaer_itemstring_idstype_idsproto_idsfield_idsmethod_idsclass_defscall_site_idsmap_listtype_listclass_data_itemcode_itemdebug_info_itemDex 文件解析构建 Dex 文件执行 Dex 文件解

l0neman 的博客 5286

告别偏移地址!用C# S7PLUS驱动读写西门子S7-1500符号地址(TIA Portal V17+环境配置)

本文详细介绍了如何在TIA Portal V17+环境中使用C# S7PLUS驱动读写西门子S7-1500 PLC的符号地址,告别传统的偏移地址方式。通过配置OpenSSL、集成S7PLUS驱动库,以及实战案例展示符号地址的读写方法,显著提升代码可读性和维护效率。文章还涵盖了环境准备、高级配置及常见问题解决方案,助力工业自动化开发者实现更高效的PLC通讯。

weixin_28720767的博客 317

APP加壳原理及常用脱壳方法介绍

APP加壳原理及常用脱壳方法介绍 文章目录APP加壳原理及常用脱壳方法介绍前言1 加壳1.1 什么是加壳1.2 加壳作用1.3 加壳原理1.4 加壳后的利与弊1.5 如何辨别是否加壳2 脱壳2.1 脱壳原理2.2 常用脱壳软件2.2.1 反射大师2.3 脱壳后分析2.3.1 Dex2Java2.3.2 Dex2Smali3 总结 前言 目前针对移动应用市场上安卓APP被破解、反编译、盗版丛生的现象,很多APP开发人员已经意识到保护APP的重要性。而对于移动应用APP加密保护的问题,如何对DEX文件加密尤为重

weixin_43900244的博客 2万+

数字摄影与摄像中的图像信号处理器(ISP):流程与经典算法详解

图像信号处理器(Image Signal Processor, ISP)是现代数字成像系统(如智能手机、数码相机、网络摄像头等)中的核心组件,扮演着将图像传感器(如CMOS或CCD)捕获的原始光电信号转换为高质量、可供观看或进一步处理的数字图像的关键角色。在数字摄影和摄像的整个链路中,光线首先通过镜头(Lens)聚焦到图像传感器上,传感器将光信号转换为模拟电信号,随后经过模数转换(A/D转换)变为原始的数字图像信号。

qq_44682523的博客 3724

利用HipSTR从二代测序数据中精准解析短串联重复序列(STR)的遗传多态性

本文详细介绍了如何利用HipSTR工具从二代测序(NGS)数据中精准解析短串联重复序列(STR)的遗传多态性。通过三步走策略,HipSTR能够高效识别STR区域、估算重复次数并判定基因型,适用于法医鉴定、疾病研究和细胞系鉴定等多个领域。文章还提供了实战操作指南和常见问题解决方案,帮助研究者充分利用NGS数据开展STR分析。

weixin_28702105的博客 483

Android APK脱壳

概述 众所周知,Android应用开发完成后,除了使用Google官方的混淆外,还需要使用一些第三方的安全软件的加壳处理,比较出名的有腾讯乐固、360加固和爱加密等。我之前所在的公司,就是使用爱加密进行加壳处理的。 虽然加密后,让软件的安全性更高了,但并不是无懈可击,一些反加固技术和脱壳技术应运而生。今天要说的就是腾讯乐固、360加固一键脱壳。 工程,经过加固后的apk,通过dex2jar反编译效...

xiangzhihong8的专栏 2万+

IBIS模型中的Pullup和Pulldown曲线详解:如何避免信号完整性设计中的常见错误

本文深入解析IBIS模型中Pullup和Pulldown曲线的关键作用,揭示其在信号完整性设计中的黄金法则。通过详细分析曲线特性、常见误区及验证方法,帮助工程师避免设计错误,优化高速PCB设计。文章还展示了曲线数据在动态终端匹配、串扰预测和电源完整性分析中的高级应用,提升设计效率和可靠性。

weixin_30275415的博客 451

安卓逆向之脱壳-认识一下动态加载 双亲委派(一)

Android 使用多种来加载不同类型的类。默认情况下,Android 使用的是来加载应用程序的dex文件。系统 ClassLoader (:它负责加载 Android 系统核心库(如android.*和java.*等)。应用 ClassLoader (:负责加载应用程序的主dex文件。用户 ClassLoader (:在一些高级应用中,允许动态加载外部的dex文件(例如插件化框架)。每个都有自己的类加载路径,它们通过层层委托的方式来加载类。委托模式意味着一个会请求父加载类,直到找到该类为止。如果父。

SXXYNHHXX的博客 2074

Linux LT8912b调试记录(MIPI转LVDS/HDMI)

本文记录了在RK3588平台上使用LT8912B芯片实现MIPI转LVDS/HDMI的调试过程。主要包含设备树配置、驱动代码实现及常见问题解决。调试重点包括:1)正确配置1280x800分辨率的LVDS屏幕参数;2)确保I2C总线正常通信;3)解决花屏、图像抖动、黑屏等问题,涉及lane-rate计算、同步信号极性调整及MIPI模式选择。文中提供了详细的寄存器配置代码和故障排查方法,特别强调了I2C通信验证和电压匹配的重要性。通过参数优化和多种模式测试,最终实现了稳定的视频输出转换。

qq_45147279的博客 1088

《点云进阶》专栏文章目录

点云进阶》专栏文章目录

点云侠的博客 4905

基于frida的几种安卓脱壳工具

frida在Android脱壳的应用 在上篇文章中,提供了frida安装教程,本篇内容是利用frida对安卓应用进行脱壳,提供了几种方法。

T_NTRCE的博客 9125

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

安卓 dex 通用脱壳技术研究(一)

http://my.oschina.net/cve2015/blog/508604 摘要 本文剖析安卓 Dalvik 解释器 Portable 的原理与实现,并通过修改 Dalvik 虚拟机实现 dex 文件的通用脱壳方案;本方法同样适应于 ART 虚拟机; 目录[-] 0x01 背景介绍 0x02 Dalvik 解释器原理分析 0

四楼没电梯的专栏 1万+

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

阿里第一代 android dex加固的脱壳方法

测试程序 链接:http://pan.baidu.com/s/1cMGmF8 密码:8xgn脱壳环境: Android 4.2、dalvik模式、 root…使用到的工具: IDA 6.8 Android Device Monitor Android Killer V1.3.1.0 Android逆向助手V2.2 将程序拖入Android killer 工具中 ,弹出如下窗口在清单文件中看到a

coc_k的博客 9922

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Android通用脱壳机FUPK3

这次要发的作品是我以前写的一个脱壳机FUPK3,这个脱壳机的思路应该是以前没人放过的,这里我不私藏了,放出来给大家来评评。 Android代码是开源的,那么通过直接修改Android源码,把运行时的所有dex数据dump出来,不就可以实现一个通用的脱壳机了吗?FUPk3就是基于上面的思路来实现的。FUPK3需要修改Android源码,导出数据接口.不过,最为核心的脱壳操作是在一个so中执行的,...

weilailu001的博客 1727
上一篇: 安卓 dex 通用脱壳技术研究(二)
下一篇: 安卓 dex 通用脱壳技术研究(四)
@井九
博客等级 码龄19年 2615粉丝 348原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值