rusty_dex/dex/
code_item.rs1use std::io::{Seek, SeekFrom};
9
10use crate::error::DexError;
11use crate::dex::{
12 reader::DexReader,
13 types::DexTypes,
14 instructions,
15 instructions::Instructions
16};
17
18#[derive(Clone, Debug)]
20pub struct TryItem {
21 start_addr : u32,
22 insn_count : u16,
23 handler_off: u16
24}
25
26#[derive(Clone, Debug)]
28pub struct EncodedCatchHandler {
29 size : i32,
30 handlers : Vec<EncodedTypeAddrPair>,
31 catch_all_addr: Option<u32>,
32}
33
34#[derive(Clone, Debug)]
36pub struct EncodedTypeAddrPair {
37 decoded_type: String,
38 addr : u32,
39}
40
41#[derive(Debug)]
43pub struct CodeItem {
44 registers_size: u16,
45 ins_size : u16,
46 outs_size : u16,
47 debug_info_off: u32,
48 pub insns : Option<Vec<Instructions>>,
49 tries : Option<Vec<TryItem>>,
50 handlers : Option<Vec<EncodedCatchHandler>>
51}
52
53impl CodeItem {
54 pub fn build(dex_reader: &mut DexReader,
58 offset: u32,
59 types_list: &DexTypes) -> Result<Self, DexError> {
60
61 dex_reader.bytes.seek(SeekFrom::Start(offset.into()))?;
63
64 let registers_size = dex_reader.read_u16()?;
66 let ins_size = dex_reader.read_u16()?;
67 let outs_size = dex_reader.read_u16()?;
68 let tries_size = dex_reader.read_u16()?;
69 let debug_info_off = dex_reader.read_u32()?;
70 let insns_size = dex_reader.read_u32()?;
71
72 let mut insns = Vec::with_capacity(insns_size as usize);
74 let end_offset = dex_reader.bytes.position() + (insns_size * 2) as u64;
75
76 while dex_reader.bytes.position() < end_offset {
79 let _ = instructions::parse_instruction(dex_reader, &mut insns)?;
80 }
81
82 if tries_size != 0 && insns_size % 2 == 1 {
84 _ = dex_reader.read_u16()?;
85 }
86
87 let mut tries = Vec::<TryItem>::new();
88 let mut handlers = Vec::<EncodedCatchHandler>::new();
89
90 if tries_size != 0 {
91 tries = Vec::with_capacity(tries_size as usize);
92 for _ in 0..tries_size {
93 let start_addr = dex_reader.read_u32()?;
94 let insn_count = dex_reader.read_u16()?;
95 let handler_off = dex_reader.read_u16()?;
96
97 tries.push(TryItem {
98 start_addr,
99 insn_count,
100 handler_off
101 });
102 }
103
104 let (handlers_list_size, _) = dex_reader.read_uleb128()?;
105 handlers = Vec::with_capacity(handlers_list_size as usize);
106
107 for _ in 0..handlers_list_size {
108 let (handler_size, _) = dex_reader.read_sleb128()?;
109 let mut type_add_pairs = Vec::with_capacity(handler_size.unsigned_abs() as usize);
110
111 for _ in 0..handler_size.abs() {
112 let (type_idx, _) = dex_reader.read_uleb128()?;
113 let decoded_type = types_list.items.get(type_idx as usize)
114 .ok_or(DexError::InvalidTypeIdx)?;
115 let (addr, _) = dex_reader.read_uleb128()?;
116
117 type_add_pairs.push(EncodedTypeAddrPair {
118 decoded_type: decoded_type.to_owned(),
119 addr
120 });
121
122 }
123
124 if handler_size <= 0 {
125 let (catch_all_addr, _) = dex_reader.read_uleb128()?;
126 handlers.push(EncodedCatchHandler {
127 size: handler_size,
128 handlers: type_add_pairs,
129 catch_all_addr: Some(catch_all_addr)
130 });
131 } else {
132 handlers.push(EncodedCatchHandler {
133 size: handler_size,
134 handlers: type_add_pairs,
135 catch_all_addr: None
136 });
137 }
138 }
139 }
140
141 if tries_size != 0 {
142 Ok(
143 CodeItem {
144 registers_size,
145 ins_size,
146 outs_size,
147 debug_info_off,
148 insns: Some(insns),
150 tries: Some(tries),
151 handlers: Some(handlers)
152 }
153 )
154 } else {
155 Ok(
156 CodeItem {
157 registers_size,
158 ins_size,
159 outs_size,
160 debug_info_off,
161 insns: Some(insns),
163 tries: None,
164 handlers: None
165 }
166 )
167 }
168 }
169}