or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

apk-processing.mdbytecode-utilities.mdcli-tools.mddecompilation.mddex-analysis.mddynamic-analysis.mdindex.mdsession-management.mdstatic-analysis.mdutility-functions.mdxml-resources.md

bytecode-utilities.mddocs/

0

# Bytecode Utilities

1

2

Comprehensive bytecode analysis and formatting utilities for advanced Android reverse engineering. These functions provide visualization, export, and formatting capabilities for Android bytecode analysis.

3

4

## Capabilities

5

6

### Method Visualization

7

8

Generate visual representations of method control flow and structure.

9

10

```python { .api }

11

def method2dot(mx: MethodAnalysis, colors: dict = None) -> str:

12

"""

13

Generate DOT graph representation of method control flow.

14

15

Parameters:

16

- mx: MethodAnalysis object to visualize

17

- colors: Optional color mapping dictionary for nodes

18

19

Returns:

20

str: DOT format graph representation

21

"""

22

23

def method2format(filename: str, format: str, mx: MethodAnalysis, colors: dict = None) -> None:

24

"""

25

Export method visualization to various formats.

26

27

Parameters:

28

- filename: Output file name

29

- format: Output format ('png', 'svg', 'pdf', 'dot')

30

- mx: MethodAnalysis object to export

31

- colors: Optional color mapping for visualization

32

"""

33

34

def method2png(filename: str, mx: MethodAnalysis, colors: dict = None) -> None:

35

"""

36

Export method control flow as PNG image.

37

38

Parameters:

39

- filename: Output PNG file name

40

- mx: MethodAnalysis object to export

41

- colors: Optional color mapping for nodes

42

"""

43

```

44

45

### JSON Export

46

47

Convert bytecode analysis results to structured JSON format.

48

49

```python { .api }

50

def method2json(mx: MethodAnalysis, colors: dict = None) -> str:

51

"""

52

Convert method analysis to JSON representation.

53

54

Parameters:

55

- mx: MethodAnalysis object to convert

56

- colors: Optional color information to include

57

58

Returns:

59

str: JSON representation of method analysis

60

"""

61

62

def class2json(cx: ClassAnalysis) -> str:

63

"""

64

Convert class analysis to JSON representation.

65

66

Parameters:

67

- cx: ClassAnalysis object to convert

68

69

Returns:

70

str: JSON representation of class analysis

71

"""

72

73

def analysis2json(dx: Analysis) -> str:

74

"""

75

Convert complete analysis to JSON representation.

76

77

Parameters:

78

- dx: Analysis object to convert

79

80

Returns:

81

str: JSON representation of complete analysis

82

"""

83

```

84

85

### Class Name Formatting

86

87

Format Android class names for different target languages and conventions.

88

89

```python { .api }

90

def FormatClassToJava(class_name: str) -> str:

91

"""

92

Format Android class name to Java-style notation.

93

94

Parameters:

95

- class_name: Android internal class name (e.g., 'Lcom/example/App;')

96

97

Returns:

98

str: Java-style class name (e.g., 'com.example.App')

99

"""

100

101

def FormatClassToPython(class_name: str) -> str:

102

"""

103

Format Android class name to Python-style notation.

104

105

Parameters:

106

- class_name: Android internal class name

107

108

Returns:

109

str: Python-style class name with underscores

110

"""

111

112

def FormatClassToSmali(class_name: str) -> str:

113

"""

114

Format class name to Smali notation.

115

116

Parameters:

117

- class_name: Input class name

118

119

Returns:

120

str: Smali-format class name

121

"""

122

```

123

124

### Package and Class Analysis

125

126

Utilities for analyzing package structures and class relationships.

127

128

```python { .api }

129

def get_package_class_name(class_name: str) -> tuple[str, str]:

130

"""

131

Extract package and class name from full class name.

132

133

Parameters:

134

- class_name: Full Android class name

135

136

Returns:

137

tuple: (package_name, simple_class_name)

138

"""

139

140

def split_package_class(full_name: str) -> dict:

141

"""

142

Split full class name into components.

143

144

Parameters:

145

- full_name: Full class name to analyze

146

147

Returns:

148

dict: Dictionary with 'package', 'class', and 'inner_classes' keys

149

"""

150

151

def get_class_hierarchy(cx: ClassAnalysis) -> list[str]:

152

"""

153

Get inheritance hierarchy for a class.

154

155

Parameters:

156

- cx: ClassAnalysis object

157

158

Returns:

159

list: List of parent class names in hierarchy order

160

"""

161

```

162

163

### Bytecode Statistics

164

165

Generate statistical information about bytecode structure and complexity.

166

167

```python { .api }

168

def get_method_complexity(mx: MethodAnalysis) -> dict:

169

"""

170

Calculate complexity metrics for a method.

171

172

Parameters:

173

- mx: MethodAnalysis object

174

175

Returns:

176

dict: Complexity metrics including cyclomatic complexity, instruction count, etc.

177

"""

178

179

def get_class_statistics(cx: ClassAnalysis) -> dict:

180

"""

181

Generate statistics for a class.

182

183

Parameters:

184

- cx: ClassAnalysis object

185

186

Returns:

187

dict: Class statistics including method count, field count, complexity metrics

188

"""

189

190

def get_package_metrics(dx: Analysis, package_name: str) -> dict:

191

"""

192

Calculate metrics for an entire package.

193

194

Parameters:

195

- dx: Analysis object

196

- package_name: Target package name

197

198

Returns:

199

dict: Package-level metrics and statistics

200

"""

201

```

202

203

### Control Flow Utilities

204

205

Advanced control flow analysis and manipulation utilities.

206

207

```python { .api }

208

def get_basic_blocks(mx: MethodAnalysis) -> list:

209

"""

210

Extract basic blocks from method analysis.

211

212

Parameters:

213

- mx: MethodAnalysis object

214

215

Returns:

216

list: List of basic block objects

217

"""

218

219

def analyze_control_flow(mx: MethodAnalysis) -> dict:

220

"""

221

Perform detailed control flow analysis.

222

223

Parameters:

224

- mx: MethodAnalysis object

225

226

Returns:

227

dict: Control flow analysis results

228

"""

229

230

def detect_patterns(mx: MethodAnalysis) -> list[str]:

231

"""

232

Detect common code patterns in method.

233

234

Parameters:

235

- mx: MethodAnalysis object

236

237

Returns:

238

list: List of detected pattern names

239

"""

240

```

241

242

## Usage Examples

243

244

### Method Visualization

245

246

```python

247

from androguard.core.bytecode import method2dot, method2png, method2format

248

from androguard.misc import AnalyzeAPK

249

250

# Analyze APK

251

a, d, dx = AnalyzeAPK("app.apk")

252

253

# Find a specific method

254

target_method = None

255

for cls in dx.get_classes():

256

for method in cls.get_methods():

257

if method.name == "onCreate":

258

target_method = method

259

break

260

if target_method:

261

break

262

263

if target_method:

264

# Generate DOT graph

265

dot_graph = method2dot(target_method)

266

print("DOT Graph:")

267

print(dot_graph)

268

269

# Export as PNG

270

method2png("onCreate_flow.png", target_method)

271

272

# Export in multiple formats

273

method2format("onCreate_flow", "svg", target_method)

274

method2format("onCreate_flow", "pdf", target_method)

275

```

276

277

### JSON Export and Analysis

278

279

```python

280

from androguard.core.bytecode import method2json, class2json, analysis2json

281

import json

282

283

# Convert method to JSON

284

if target_method:

285

method_json = method2json(target_method)

286

method_data = json.loads(method_json)

287

288

print("Method Analysis JSON:")

289

print(json.dumps(method_data, indent=2))

290

291

# Convert entire class to JSON

292

target_class = target_method.get_class_analysis() if target_method else None

293

if target_class:

294

class_json = class2json(target_class)

295

class_data = json.loads(class_json)

296

297

print(f"Class '{target_class.name}' has {len(class_data['methods'])} methods")

298

299

# Export complete analysis

300

full_analysis = analysis2json(dx)

301

print(f"Full analysis size: {len(full_analysis)} characters")

302

```

303

304

### Class Name Formatting

305

306

```python

307

from androguard.core.bytecode import FormatClassToJava, FormatClassToPython, get_package_class_name

308

309

# Format class names

310

internal_name = "Lcom/example/myapp/MainActivity;"

311

java_name = FormatClassToJava(internal_name)

312

python_name = FormatClassToPython(internal_name)

313

314

print(f"Internal: {internal_name}")

315

print(f"Java: {java_name}") # com.example.myapp.MainActivity

316

print(f"Python: {python_name}") # com_example_myapp_MainActivity

317

318

# Extract package and class

319

package, class_name = get_package_class_name(internal_name)

320

print(f"Package: {package}") # com.example.myapp

321

print(f"Class: {class_name}") # MainActivity

322

```

323

324

### Bytecode Statistics

325

326

```python

327

from androguard.core.bytecode import get_method_complexity, get_class_statistics, get_package_metrics

328

329

# Method complexity analysis

330

if target_method:

331

complexity = get_method_complexity(target_method)

332

print("Method Complexity:")

333

print(f" Cyclomatic complexity: {complexity['cyclomatic']}")

334

print(f" Instruction count: {complexity['instructions']}")

335

print(f" Basic blocks: {complexity['basic_blocks']}")

336

print(f" Branch points: {complexity['branches']}")

337

338

# Class statistics

339

if target_class:

340

stats = get_class_statistics(target_class)

341

print("Class Statistics:")

342

print(f" Methods: {stats['method_count']}")

343

print(f" Fields: {stats['field_count']}")

344

print(f" Inner classes: {stats['inner_classes']}")

345

print(f" Average method complexity: {stats['avg_complexity']}")

346

347

# Package-level metrics

348

package_metrics = get_package_metrics(dx, "com.example.myapp")

349

print("Package Metrics:")

350

print(f" Total classes: {package_metrics['class_count']}")

351

print(f" Total methods: {package_metrics['method_count']}")

352

print(f" Package complexity: {package_metrics['total_complexity']}")

353

```

354

355

### Control Flow Analysis

356

357

```python

358

from androguard.core.bytecode import get_basic_blocks, analyze_control_flow, detect_patterns

359

360

if target_method:

361

# Get basic blocks

362

blocks = get_basic_blocks(target_method)

363

print(f"Method has {len(blocks)} basic blocks")

364

365

# Detailed control flow analysis

366

flow_analysis = analyze_control_flow(target_method)

367

print("Control Flow Analysis:")

368

print(f" Entry points: {flow_analysis['entry_points']}")

369

print(f" Exit points: {flow_analysis['exit_points']}")

370

print(f" Loops detected: {flow_analysis['loop_count']}")

371

print(f" Conditional branches: {flow_analysis['conditional_branches']}")

372

373

# Pattern detection

374

patterns = detect_patterns(target_method)

375

if patterns:

376

print("Detected Patterns:")

377

for pattern in patterns:

378

print(f" - {pattern}")

379

```

380

381

### Batch Analysis

382

383

```python

384

from androguard.core.bytecode import method2format, get_method_complexity

385

import os

386

387

# Create output directory

388

os.makedirs("analysis_output", exist_ok=True)

389

390

# Analyze all methods in a class

391

complexity_report = []

392

for method in target_class.get_methods() if target_class else []:

393

# Export visualization

394

safe_name = method.name.replace('<', '').replace('>', '').replace('/', '_')

395

output_file = f"analysis_output/{safe_name}"

396

397

try:

398

method2format(output_file, "png", method)

399

400

# Collect complexity data

401

complexity = get_method_complexity(method)

402

complexity_report.append({

403

'method': method.name,

404

'complexity': complexity['cyclomatic'],

405

'instructions': complexity['instructions']

406

})

407

except Exception as e:

408

print(f"Error analyzing {method.name}: {e}")

409

410

# Sort by complexity

411

complexity_report.sort(key=lambda x: x['complexity'], reverse=True)

412

413

print("Top 5 most complex methods:")

414

for item in complexity_report[:5]:

415

print(f" {item['method']}: complexity={item['complexity']}, instructions={item['instructions']}")

416

```

417

418

## Integration with Other Modules

419

420

### Combined with Static Analysis

421

422

```python

423

from androguard.core.bytecode import method2json, get_method_complexity

424

from androguard.core.analysis.analysis import MethodAnalysis

425

import json

426

427

# Find methods with high complexity that call cryptographic APIs

428

crypto_apis = ["javax.crypto", "java.security", "android.security"]

429

complex_crypto_methods = []

430

431

for cls in dx.get_classes():

432

for method in cls.get_methods():

433

# Check complexity

434

complexity = get_method_complexity(method)

435

if complexity['cyclomatic'] > 10: # High complexity threshold

436

437

# Check for crypto API usage

438

method_json = method2json(method)

439

method_data = json.loads(method_json)

440

441

calls_crypto = any(

442

any(crypto_api in call.get('target', '') for crypto_api in crypto_apis)

443

for call in method_data.get('external_calls', [])

444

)

445

446

if calls_crypto:

447

complex_crypto_methods.append({

448

'class': cls.name,

449

'method': method.name,

450

'complexity': complexity['cyclomatic']

451

})

452

453

print("Complex methods using cryptographic APIs:")

454

for method_info in sorted(complex_crypto_methods, key=lambda x: x['complexity'], reverse=True):

455

print(f" {method_info['class']}.{method_info['method']} (complexity: {method_info['complexity']})")

456

```