Android Learning experience (A)---DEX file structure Analysis (1)
Last Update:2015-08-27
Source: Internet
Author: User
<span id="Label3"></p><p><p>I am on the blog to publish some of my Android learning experience, I hope that everyone can help.<br>This article tells us about the structural parsing of the Android executable, Dex.</p></p><p><p>Reference Leb128 data type Android learning experience (5)---dex data type LEB128<br>Reference example analysis learn to understand Dex file Structure Android learning experience (1)---dex file structure analysis</p></p>1. Dex Background<pre><pre><code> Android应用开发和Dalvik虚拟机Android应用所使用的编程语言是Java语言,在编译时使用JDK将Java源程序编程成标准的Java字节码文件。 而后通过工具软件DX把所有的字节码文件转成Android DEX文件(classes.dex)。 最后使用Android打包工具(aapt)将DEX文件,资源文件以及AndroidManifest.xml文件(二进制格式)组合成一个应用程序包(APK)。 </code></pre></pre>2. Dex File Overall structure<p><p><br><br></p></p><pre><pre><code></code></pre></pre><p><p>First we look at the dexfile structure through/dalvik/libdex/dexfile.h</p></p><pre class="prettyprint"><code class=" hljs d"><span class="hljs-comment">/* <span class="hljs-comment">* Structure representing a DEX File. * Code should regard Dexfile as opaque, using the API calls provided here * To access specific Structures. */</span></span><span class="hljs-keyword"><span class="hljs-keyword">typedef</span></span> <span class="hljs-keyword"><span class="hljs-keyword">struct</span></span>Dexfile {<span class="hljs-comment">/ <span class="hljs-comment">* directly-mapped "opt" Header *</span> /</span> <span class="hljs-keyword"><span class="hljs-keyword">Const</span></span>dexoptheader* poptheader;<span class="hljs-comment">/ <span class="hljs-comment">* pointers to directly-mapped structs and arrays in base DEX *</span> /</span> <span class="hljs-keyword"><span class="hljs-keyword">Const</span></span>dexheader* pheader;<span class="hljs-keyword"><span class="hljs-keyword">Const</span></span>dexstringid* pstringids;<span class="hljs-keyword"><span class="hljs-keyword">Const</span></span>dextypeid* ptypeids;<span class="hljs-keyword"><span class="hljs-keyword">Const</span></span>dexfieldid* pfieldids;<span class="hljs-keyword"><span class="hljs-keyword">Const</span></span>dexmethodid* pmethodids;<span class="hljs-keyword"><span class="hljs-keyword">Const</span></span>dexprotoid* pprotoids;<span class="hljs-keyword"><span class="hljs-keyword">Const</span></span>dexclassdef* pclassdefs;<span class="hljs-keyword"><span class="hljs-keyword">Const</span></span>dexlink* plinkdata;<span class="hljs-comment">/ <span class="hljs-comment">* Mapped in ' auxillary ' section *</span> /</span> <span class="hljs-keyword"><span class="hljs-keyword">Const</span></span>dexclasslookup* pclasslookup;<span class="hljs-comment">/ <span class="hljs-comment">* points to start of DEX file data *</span> /</span> <span class="hljs-keyword"><span class="hljs-keyword">Const</span></span>U1* baseaddr;<span class="hljs-comment">/ <span class="hljs-comment">* Track memory overhead for auxillary structures *</span> /</span> <span class="hljs-keyword"><span class="hljs-keyword">int</span></span>Overhead<span class="hljs-comment">/ <span class="hljs-comment">* Additional APP-SPECIFIC data structures associated with the DEX *</span> /</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span>* auxdata;} dexfile;</code></pre>3. Dex Header parsing<p><p>We view Header_item through/dalvik/libdex/dexfile.h</p></p><pre class="prettyprint"><code class=" hljs d"><span class="hljs-comment">/ <span class="hljs-comment">* * direct-mapped "header_item" Struct. *</span> /</span><span class="hljs-keyword"><span class="hljs-keyword">typedef</span></span> <span class="hljs-keyword"><span class="hljs-keyword">struct</span></span>Dexheader {u1 magic[<span class="hljs-number"><span class="hljs-number">8</span></span>];<span class="hljs-comment">/ <span class="hljs-comment">* Includes version number *</span> /</span>U4 checksum;<span class="hljs-comment">/ <span class="hljs-comment">* Adler32 Checksum *</span> /</span>U1 signature[ksha1digestlen];<span class="hljs-comment">/ <span class="hljs-comment">* SHA-1 Hash *</span> /</span>U4 fileSize;<span class="hljs-comment">/ <span class="hljs-comment">* Length of entire file *</span> /</span>U4 headersize;<span class="hljs-comment">/ <span class="hljs-comment">* Offset to start of next section *</span> /</span>U4 endiantag;<span class="hljs-comment">/ <span class="hljs-comment">* byte order label *</span> /</span>U4 linksize; U4 linkoff; U4 mapoff; U4 stringidssize; U4 stringidsoff; U4 typeidssize; U4 typeidsoff; U4 protoidssize; U4 protoidsoff; U4 fieldidssize; U4 fieldidsoff; U4 methodidssize; U4 methodidsoff; U4 classdefssize; U4 classdefsoff; U4 datasize; U4 dataoff;} dexheader;</code></pre><p><p><br></p></p>4, Mapoff Point Maplist<p><p>Maplist data structures in Dexheader structures<br></p></p><pre class="prettyprint"><code class=" hljs haskell">/* *<span class="hljs-type"><span class="hljs-type">Direct</span></span>-mapped<span class="hljs-string"><span class="hljs-string">"map_item"</span></span>. */<span class="hljs-title"><span class="hljs-title">typedef</span></span>struct<span class="hljs-type"><span class="hljs-type">Dexmapitem</span></span>{u2<span class="hljs-typedef"><span class="hljs-typedef"> <span class="hljs-keyword">type</span>; /* <span class="hljs-keyword">type</span> code <span class="hljs-container">(see<span class="hljs-title"></span> <span class="hljs-title">kdextype</span>* <span class="hljs-title">above</span>) */</span> </span></span>U2 unused; U4 size; /* Count<span class="hljs-keyword"><span class="hljs-keyword"></span> of</span>Items<span class="hljs-keyword"><span class="hljs-keyword"></span> of</span>The indicated<span class="hljs-typedef"><span class="hljs-typedef"> <span class="hljs-keyword">Type</span> *</span> /</span>U4 offset; /* file offset to the start<span class="hljs-keyword"><span class="hljs-keyword"></span> of</span> <span class="hljs-typedef"><span class="hljs-typedef"> <span class="hljs-keyword">Data</span> *</span> /</span>}<span class="hljs-type"><span class="hljs-type">Dexmapitem</span></span>;/* *<span class="hljs-type"><span class="hljs-type">Direct</span></span>-mapped<span class="hljs-string"><span class="hljs-string">"map_list"</span></span>. */<span class="hljs-title"><span class="hljs-title">typedef</span></span>struct<span class="hljs-type"><span class="hljs-type">dexmaplist</span></span>{u4 size; /* #<span class="hljs-keyword"><span class="hljs-keyword"></span> of</span>Entries<span class="hljs-keyword"><span class="hljs-keyword">inch</span></span>List */<span class="hljs-type"><span class="hljs-type">Dexmapitem</span></span>list[<span class="hljs-number"><span class="hljs-number">1</span></span>]; /* Entries */}<span class="hljs-type"><span class="hljs-type">dexmaplist</span></span>;</code></pre><p><p>In the Dexmapitem structure, type is an enumeration constant</p></p><pre class="prettyprint"><code class=" hljs rust"><span class="hljs-comment">/ <span class="hljs-comment">* Map Item type codes *</span> /</span> <span class="hljs-keyword"><span class="hljs-keyword">enum</span></span>{kdextypeheaderitem =<span class="hljs-number"><span class="hljs-number">0x0000</span></span>, Kdextypestringiditem =<span class="hljs-number"><span class="hljs-number">0x0001</span></span>, Kdextypetypeiditem =<span class="hljs-number"><span class="hljs-number">0x0002</span></span>, Kdextypeprotoiditem =<span class="hljs-number"><span class="hljs-number">0x0003</span></span>, Kdextypefieldiditem =<span class="hljs-number"><span class="hljs-number">0x0004</span></span>, Kdextypemethodiditem =<span class="hljs-number"><span class="hljs-number">0x0005</span></span>, Kdextypeclassdefitem =<span class="hljs-number"><span class="hljs-number">0x0006</span></span>, kdextypemaplist =<span class="hljs-number"><span class="hljs-number">0x1000</span></span>, kdextypetypelist =<span class="hljs-number"><span class="hljs-number">0x1001</span></span>, kdextypeannotationsetreflist =<span class="hljs-number"><span class="hljs-number">0x1002</span></span>, Kdextypeannotationsetitem =<span class="hljs-number"><span class="hljs-number">0x1003</span></span>, Kdextypeclassdataitem =<span class="hljs-number"><span class="hljs-number">0x2000</span></span>, Kdextypecodeitem =<span class="hljs-number"><span class="hljs-number">0x2001</span></span>, Kdextypestringdataitem =<span class="hljs-number"><span class="hljs-number">0x2002</span></span>, Kdextypedebuginfoitem =<span class="hljs-number"><span class="hljs-number">0x2003</span></span>, Kdextypeannotationitem =<span class="hljs-number"><span class="hljs-number">0x2004</span></span>, Kdextypeencodedarrayitem =<span class="hljs-number"><span class="hljs-number">0x2005</span></span>, Kdextypeannotationsdirectoryitem =<span class="hljs-number"><span class="hljs-number">0x2006</span></span>, };</code></pre>5. Part Structure<p><p>Find the structure in the Dexmapitem by dexmaplist the table generated by the structure<br>Due to the complexity of the class_def_item, a separate narrative</p></p><pre class="prettyprint"><code class=" hljs applescript">/* * direct-mapped<span class="hljs-string"><span class="hljs-string">"string_id_item"</span></span>. */typedef struct Dexstringid {u4 stringdataoff; /*<span class="hljs-type"><span class="hljs-type">file</span></span> <span class="hljs-command"><span class="hljs-command">Offset</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> to</span>String_data_item */} dexstringid; /* * direct-mapped<span class="hljs-string"><span class="hljs-string">"type_id_item"</span></span>. */typedef struct Dextypeid {u4 descriptoridx; /* Index<span class="hljs-keyword"><span class="hljs-keyword"></span> into</span>Stringids<span class="hljs-type"><span class="hljs-type">List</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> for</span>Type descriptor */} dextypeid; /* * direct-mapped<span class="hljs-string"><span class="hljs-string">"field_id_item"</span></span>. */typedef struct Dexfieldid {u2 classidx; /* Index<span class="hljs-keyword"><span class="hljs-keyword"></span> into</span>Typeids<span class="hljs-type"><span class="hljs-type">List</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> for</span>Defining<span class="hljs-type"><span class="hljs-type">class</span></span>*/U2 typeidx; /* Index<span class="hljs-keyword"><span class="hljs-keyword"></span> into</span>Typeids<span class="hljs-keyword"><span class="hljs-keyword"></span> for</span>Field type */u4 nameidx; /* Index<span class="hljs-keyword"><span class="hljs-keyword"></span> into</span>Stringids<span class="hljs-keyword"><span class="hljs-keyword"></span> for</span>Field<span class="hljs-property"><span class="hljs-property">name</span></span>*/} dexfieldid; /* * direct-mapped<span class="hljs-string"><span class="hljs-string">"method_id_item"</span></span>. */typedef struct Dexmethodid {u2 classidx; /* Index<span class="hljs-keyword"><span class="hljs-keyword"></span> into</span>Typeids<span class="hljs-type"><span class="hljs-type">List</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> for</span>Defining<span class="hljs-type"><span class="hljs-type">class</span></span>*/U2 protoidx; /* Index<span class="hljs-keyword"><span class="hljs-keyword"></span> into</span>Protoids<span class="hljs-keyword"><span class="hljs-keyword"></span> for</span>Method prototype */u4 nameidx; /* Index<span class="hljs-keyword"><span class="hljs-keyword"></span> into</span>Stringids<span class="hljs-keyword"><span class="hljs-keyword"></span> for</span>Method<span class="hljs-property"><span class="hljs-property">name</span></span>*/} dexmethodid; /* * direct-mapped<span class="hljs-string"><span class="hljs-string">"proto_id_item"</span></span>. */typedef struct dexprotoid {u4 shortyidx; /* Index<span class="hljs-keyword"><span class="hljs-keyword"></span> into</span>Stringids<span class="hljs-keyword"><span class="hljs-keyword"></span> for</span>Shorty Descriptor */u4 returntypeidx; /* Index<span class="hljs-keyword"><span class="hljs-keyword"></span> into</span>Typeids<span class="hljs-type"><span class="hljs-type">List</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> for</span> <span class="hljs-constant"><span class="hljs-constant">return</span></span>Type */u4 parametersoff; /*<span class="hljs-type"><span class="hljs-type">file</span></span> <span class="hljs-command"><span class="hljs-command">Offset</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> to</span>Type_list<span class="hljs-keyword"><span class="hljs-keyword"></span> for</span>Parameter Types */} dexprotoid;</code></pre><p><p>In the Dexprotoid structure, Parameteroff is the offset of the type_list</p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs cpp"><span class="hljs-comment">/* * Direct-mapped "type_item". */</span><span class="hljs-keyword">typedef</span><span class="hljs-keyword">struct</span> DexTypeItem { u2 typeIdx; <span class="hljs-comment">/* index into typeIds */</span><span class="hljs-comment">/* * Direct-mapped "type_list". */</span><span class="hljs-keyword">typedef</span><span class="hljs-keyword">struct</span> DexTypeList { u4 size; <span class="hljs-comment">/* #of entries in list */</span> <span class="hljs-built_in">list</span>[<span class="hljs-number">1</span>]; <span class="hljs-comment">/* entries */</span> } DexTypeList;</code></pre></pre>6. DEXCLASSDEF Structure<pre class="prettyprint"><code class=" hljs applescript">/* * direct-mapped<span class="hljs-string"><span class="hljs-string">"class_def_item"</span></span>. */typedef struct Dexclassdef {u4 classidx; /* Index<span class="hljs-keyword"><span class="hljs-keyword"></span> into</span>Typeids<span class="hljs-keyword"><span class="hljs-keyword"></span> for</span>This<span class="hljs-type"><span class="hljs-type">class</span></span>*/u4 accessflags; U4 superclassidx; /* Index<span class="hljs-keyword"><span class="hljs-keyword"></span> into</span>Typeids<span class="hljs-keyword"><span class="hljs-keyword"></span> for</span>Superclass */u4 interfacesoff; /*<span class="hljs-type"><span class="hljs-type">file</span></span> <span class="hljs-command"><span class="hljs-command">Offset</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> to</span>Dextypelist */u4 sourcefileidx; /* Index<span class="hljs-keyword"><span class="hljs-keyword"></span> into</span>Stringids<span class="hljs-keyword"><span class="hljs-keyword"></span> for</span>Source<span class="hljs-type"><span class="hljs-type">file</span></span> <span class="hljs-property"><span class="hljs-property">name</span></span>*/u4 annotationsoff; /*<span class="hljs-type"><span class="hljs-type">file</span></span> <span class="hljs-command"><span class="hljs-command">Offset</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> to</span>Annotations_directory_item */u4 classdataoff; /*<span class="hljs-type"><span class="hljs-type">file</span></span> <span class="hljs-command"><span class="hljs-command">Offset</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> to</span>Class_data_item */u4 staticvaluesoff; /*<span class="hljs-type"><span class="hljs-type">file</span></span> <span class="hljs-command"><span class="hljs-command">Offset</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> to</span>Dexencodedarray */} dexclassdef;</code></pre><p><p>Annotationsoff is an annotation directory structure offset, which is not currently detailed, and has a value of 0 if there is no Annotation.</p></p><p><p>Classdataoff is a pointer to the Class_data_item offset, which describes its structure<br>Path Is/dalvik/libdex/dexclass.h</p></p><pre class="prettyprint"><pre class="prettyprint"><code class="hljs applescript">/* expanded form <span class="hljs-keyword">of </span> Class_data_item. Note:if a particular <span class="hljs-property">item </span> <span class="hljs-keyword">is </span> * Absent (e.g., no St atic fields), <span class="hljs-keyword">then </span> <span class="hljs-keyword">the </span> corresponding pointer * Span class= "hljs-keyword" >is <span class="hljs-keyword">set </span> <span class="hljs-keyword">to </span> Null. */typedef struct Dexclassdata {dexclassdataheader header; dexfield* staticfields; dexfield* instancefields; dexmethod* directmethods; dexmethod* virtualmethods; } dexclassdata;/* expanded form <span class="hljs-keyword">of </span> a class_data_item header */typedef struct DEXCLASSD Ataheader {u4 staticfieldssize; U4 instancefieldssize; U4 directmethodssize; U4 virtualmethodssize; } dexclassdataheader; </code> </pre></pre><p><p>Dexfield & Dexmethod</p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs d"><span class="hljs-comment">/* expanded form of encoded_field */</span><span class="hljs-keyword">typedef</span><span class="hljs-keyword">struct</span> DexField { u4 fieldIdx; <span class="hljs-comment">/* index to a field_id_item */</span> <span class="hljs-comment">/* expanded form of encoded_method */</span><span class="hljs-keyword">typedef</span><span class="hljs-keyword">struct</span> DexMethod { u4 methodIdx; <span class="hljs-comment">/* index to a method_id_item */</span> u4 accessFlags; u4 codeOff; <span class="hljs-comment">/* file offset to a code_item */</span> } DexMethod;</code></pre></pre><p><p>Code_item is defined In/dalvik/libdex/dexfile.h</p></p><pre class="prettyprint"><code class=" hljs applescript">/* * direct-mapped<span class="hljs-string"><span class="hljs-string">"code_item"</span></span>. * * the<span class="hljs-string"><span class="hljs-string">"catches"</span></span>Table<span class="hljs-keyword"><span class="hljs-keyword"></span> is</span>Used when throwing an exception, *<span class="hljs-string"><span class="hljs-string">"debuginfo"</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> is</span>used when displaying a exception stack trace<span class="hljs-keyword"><span class="hljs-keyword">or</span></span>* Debugging. An<span class="hljs-command"><span class="hljs-command">Offset</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> of</span>Zero indicates<span class="hljs-keyword"><span class="hljs-keyword"></span> that</span>There is no entries. */typedef struct Dexcode {u2 registerssize; U2 inssize; U2 outssize; U2 triessize; U4 debuginfooff; /*<span class="hljs-type"><span class="hljs-type">file</span></span> <span class="hljs-command"><span class="hljs-command">Offset</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> to</span>Debug Info Stream */u4 insnssize; /* size<span class="hljs-keyword"><span class="hljs-keyword"></span> of</span> <span class="hljs-keyword"><span class="hljs-keyword"></span> the</span>Insns array,<span class="hljs-keyword"><span class="hljs-keyword">inch</span></span>U2 units */u2 insns[<span class="hljs-number"><span class="hljs-number">1</span></span>]; /* followed<span class="hljs-keyword"><span class="hljs-keyword"></span> by</span>Optional U2 padding */* followed<span class="hljs-keyword"><span class="hljs-keyword"></span> by</span>try_item[triessize] *//* followed<span class="hljs-keyword"><span class="hljs-keyword"></span> by</span>uleb128 handlerssize */* followed<span class="hljs-keyword"><span class="hljs-keyword"></span> by</span>catch_handler_item[handlerssize] */} dexcode;</code></pre><p><p>So far, basically we have put the Dex file structure to show you.<br>The next thing to do is to analyze the Dex file instance with this Article.<br>Android Learning experience (+)---DEX file structure Analysis (2)</p></p> <p style="font-size:12px;"><p style="font-size:12px;">Copyright Notice: This article for Bo Master original article, without Bo Master permission not Reproduced.</p></p> <p><p>Android Learning experience (A)---DEX file structure Analysis (1)</p></p></span>