M. S. Ramanujan

160 papers A* 23A 18B 23C 1Misc 2Journal 79Unranked 13
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
Fedor V. Fomin, Petr A. Golovach, M. S. Ramanujan, Saket Saurabh
2026 A* conf
SODA
Johannes Carmesin, M. S. Ramanujan
2026 J jnl
SIAM J. Discret. Math.
Eduard Eiben, Diptapriyo Majumdar, M. S. Ramanujan
2026 J jnl
ACM Trans. Algorithms
Matthias Bentert, Fedor V. Fomin, Petr A. Golovach, Tuukka Korhonen, William Lochet, Fahad Panolan, M. S. Ramanujan, Saket Saurabh, Kirill Simonov
2026 J jnl
J. Comput. Syst. Sci.
Argyrios Deligkas, Eduard Eiben, Robert Ganian, Iyad Kanj, Dominik Leko, M. S. Ramanujan
2026 J jnl
J. Comb. Theory B
Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh
2025 J jnl
J. Artif. Intell. Res.
Umberto Grandi, Lawqueen Kanesh, Grzegorz Lisowski, M. S. Ramanujan, Paolo Turrini
2025 A* conf
SoCG
Eduard Eiben, Robert Ganian, Iyad Kanj, M. S. Ramanujan
2025 B conf
IPEC
Václav Blazej, Satyabrata Jana, M. S. Ramanujan, Peter Strulo
2025 J jnl
Algorithmica
Václav Blazej, Satyabrata Jana, M. S. Ramanujan, Peter Strulo
2025 A* conf
SODA
Matthias Bentert, Fedor V. Fomin, Petr A. Golovach, Tuukka Korhonen, William Lochet, Fahad Panolan, M. S. Ramanujan, Saket Saurabh, Kirill Simonov
2025 A conf
AAMAS
Argyrios Deligkas, Eduard Eiben, Robert Ganian, Iyad Kanj, M. S. Ramanujan
2025 B conf
WADS
Argyrios Deligkas, Eduard Eiben, Robert Ganian, Iyad Kanj, Dominik Leko, M. S. Ramanujan
2025 B conf
SAGT
Václav Blazej, Sushmita Gupta, M. S. Ramanujan, Peter Strulo
2025 J jnl
CoRR
Václav Blazej, Sushmita Gupta, M. S. Ramanujan, Peter Strulo
2025 A* conf
SoCG
Matthias Bentert, Fedor V. Fomin, Petr A. Golovach, M. S. Ramanujan, Saket Saurabh
2025 J jnl
CoRR
Matthias Bentert, Fedor V. Fomin, Petr A. Golovach, M. S. Ramanujan, Saket Saurabh
2024 J jnl
CoRR
Sushmita Gupta, M. S. Ramanujan, Peter Strulo
2024 A conf
STACS
Lawqueen Kanesh, Fahad Panolan, M. S. Ramanujan, Peter Strulo
2024 A conf
ITCS
Tanmay Inamdar, Madhumita Kundu, Pekka Parviainen, M. S. Ramanujan, Saket Saurabh
2024 A* conf
SODA
Daniel Lokshtanov, Pranabendu Misra, Fahad Panolan, M. S. Ramanujan, Saket Saurabh, Meirav Zehavi
2024 B conf
IPEC
Václav Blazej, Sushmita Gupta, M. S. Ramanujan, Peter Strulo
2024 J jnl
CoRR
Václav Blazej, Sushmita Gupta, M. S. Ramanujan, Peter Strulo
2024 J jnl
SIAM J. Discret. Math.
Rian Neogi, M. S. Ramanujan, Saket Saurabh, Roohani Sharma
2024 B conf
IPEC
Václav Blazej, Satyabrata Jana, M. S. Ramanujan, Peter Strulo
2024 J jnl
CoRR
Václav Blazej, Satyabrata Jana, M. S. Ramanujan, Peter Strulo
2024 J jnl
CoRR
Matthias Bentert, Fedor V. Fomin, Petr A. Golovach, Tuukka Korhonen, William Lochet, Fahad Panolan, M. S. Ramanujan, Saket Saurabh, Kirill Simonov
2024 A* conf
ICALP
Argyrios Deligkas, Eduard Eiben, Robert Ganian, Iyad Kanj, M. S. Ramanujan
2024 J jnl
CoRR
Argyrios Deligkas, Eduard Eiben, Robert Ganian, Iyad Kanj, M. S. Ramanujan
2024 J jnl
CoRR
Patrick O'Hara, M. S. Ramanujan, Theodoros Damoulas
2023 conf
FSTTCS
Akanksha Agrawal, M. S. Ramanujan
2023 conf
FSTTCS
Tanmay Inamdar, Lawqueen Kanesh, Madhumita Kundu, M. S. Ramanujan, Saket Saurabh
2023 J jnl
CoRR
Tanmay Inamdar, Lawqueen Kanesh, Madhumita Kundu, M. S. Ramanujan, Saket Saurabh
2023 B conf
MFCS
Eduard Eiben, Diptapriyo Majumdar, M. S. Ramanujan
2023 J jnl
CoRR
Eduard Eiben, Diptapriyo Majumdar, M. S. Ramanujan
2023 J jnl
CoRR
Daniel Lokshtanov, Pranabendu Misra, Fahad Panolan, M. S. Ramanujan, Saket Saurabh, Meirav Zehavi
2023 J jnl
Math. Program.
Fedor V. Fomin, Fahad Panolan, M. S. Ramanujan, Saket Saurabh
2022 J jnl
SIAM J. Discret. Math.
Akanksha Agrawal, Lawqueen Kanesh, Fahad Panolan, M. S. Ramanujan, Saket Saurabh
2022 B conf
MFCS
M. S. Ramanujan, Abhishek Sahu, Saket Saurabh, Shaily Verma
2022 J jnl
CoRR
Eduard Eiben, Diptapriyo Majumdar, M. S. Ramanujan
2022 A* conf
ICALP
Daniel Lokshtanov, Fahad Panolan, M. S. Ramanujan
2022 A* conf
SODA
Akanksha Agrawal, Lawqueen Kanesh, Daniel Lokshtanov, Fahad Panolan, M. S. Ramanujan, Saket Saurabh, Meirav Zehavi
2022 C conf
IWOCA
Akanksha Agrawal, M. S. Ramanujan
2022 A conf
AAMAS
Grzegorz Lisowski, M. S. Ramanujan, Paolo Turrini
2022 J jnl
CoRR
Umberto Grandi, Grzegorz Lisowski, M. S. Ramanujan, Paolo Turrini
2022 B conf
WG
Eduard Eiben, Diptapriyo Majumdar, M. S. Ramanujan
2021 A conf
STACS
Akanksha Agrawal, Lawqueen Kanesh, Fahad Panolan, M. S. Ramanujan, Saket Saurabh
2021 J jnl
CoRR
Akanksha Agrawal, Lawqueen Kanesh, Daniel Lokshtanov, Fahad Panolan, M. S. Ramanujan, Saket Saurabh
2021 A* conf
SODA
Daniel Lokshtanov, Pranabendu Misra, M. S. Ramanujan, Saket Saurabh, Meirav Zehavi
2021 A conf
ESA
M. S. Ramanujan
2021 J jnl
Algorithmica
Robert Ganian, Sebastian Ordyniak, M. S. Ramanujan
2021 J jnl
Algorithmica
Benjamin Bergougnoux, Eduard Eiben, Robert Ganian, Sebastian Ordyniak, M. S. Ramanujan
2020 J jnl
ACM Trans. Comput. Log.
Jakub Gajarský, Petr Hlinený, Jan Obdrzálek, Daniel Lokshtanov, M. S. Ramanujan
2020 J jnl
Inf. Process. Lett.
Venkatesh Raman, M. S. Ramanujan, Saket Saurabh
2020 J jnl
Theor. Comput. Sci.
Gregory Z. Gutin, M. S. Ramanujan, Felix Reidl, Magnus Wahlström
2020 J jnl
J. Comput. Syst. Sci.
Sudeshna Kolay, Pranabendu Misra, M. S. Ramanujan, Saket Saurabh
2020 J jnl
Theor. Comput. Sci.
Pranabendu Misra, Fahad Panolan, M. S. Ramanujan, Saket Saurabh
2020 J jnl
Algorithmica
Diptapriyo Majumdar, M. S. Ramanujan, Saket Saurabh
2020 A conf
ESA
Fedor V. Fomin, Petr A. Golovach, Pranabendu Misra, M. S. Ramanujan
2020 B conf
IPEC
Akanksha Agrawal, M. S. Ramanujan
2020 J jnl
CoRR
Rian Neogi, M. S. Ramanujan, Saket Saurabh, Roohani Sharma
2020 B conf
MFCS
Rian Neogi, M. S. Ramanujan, Saket Saurabh, Roohani Sharma
2020 A* conf
SODA
Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh, Meirav Zehavi
2019 A conf
ESA
M. S. Ramanujan
2019 J jnl
Algorithmica
Arne Meier, Sebastian Ordyniak, M. S. Ramanujan, Irena Schindler
2019 J jnl
J. Comput. Syst. Sci.
Eduard Eiben, Danny Hermelin, M. S. Ramanujan
2019 J jnl
CoRR
Diptapriyo Majumdar, M. S. Ramanujan, Saket Saurabh
2019 J jnl
Algorithmica
Robert Ganian, N. S. Narayanaswamy, Sebastian Ordyniak, C. S. Rahul, M. S. Ramanujan
2019 J jnl
CoRR
Patrick O'Hara, M. S. Ramanujan, Theodoros Damoulas
2019 J jnl
J. Comput. Syst. Sci.
Gregory Z. Gutin, M. S. Ramanujan, Felix Reidl, Magnus Wahlström
2019 B conf
WADS
Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh, Roohani Sharma, Meirav Zehavi
2018 J jnl
CoRR
Jakub Gajarský, Petr Hlinený, Daniel Lokshtanov, Jan Obdrzálek, M. S. Ramanujan
2018 J jnl
CoRR
Gregory Z. Gutin, M. S. Ramanujan, Felix Reidl, Magnus Wahlström
2018 A* conf
ICALP
Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh, Roohani Sharma, Meirav Zehavi
2018 J jnl
ACM Trans. Algorithms
Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh
2018 J jnl
CoRR
Robert Ganian, N. S. Narayanaswamy, Sebastian Ordyniak, C. S. Rahul, M. S. Ramanujan
2018 A conf
ESA
Fedor V. Fomin, Fahad Panolan, M. S. Ramanujan, Saket Saurabh
2018 J jnl
Theor. Comput. Sci.
Manu Basavaraju, Fahad Panolan, Ashutosh Rai, M. S. Ramanujan, Saket Saurabh
2018 A* conf
SODA
Jørgen Bang-Jensen, Manu Basavaraju, Kristine Vitting Klinkby, Pranabendu Misra, M. S. Ramanujan, Saket Saurabh, Meirav Zehavi
2018 J jnl
J. Comput. Syst. Sci.
Daniel Lokshtanov, Amer E. Mouawad, Fahad Panolan, M. S. Ramanujan, Saket Saurabh
2018 A* conf
ICALP
Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh, Meirav Zehavi
2018 J jnl
CoRR
Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh, Meirav Zehavi
2018 A* conf
SODA
Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh
2017 A conf
ESA
Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh
2017 A conf
SAT
Robert Ganian, M. S. Ramanujan, Stefan Szeider
2017 A conf
STACS
Robert Ganian, M. S. Ramanujan, Stefan Szeider
2017 J jnl
ACM Trans. Algorithms
Robert Ganian, M. S. Ramanujan, Stefan Szeider
2017 J jnl
J. Comput. Syst. Sci.
Rajesh Chitnis, Fedor V. Fomin, Daniel Lokshtanov, Pranabendu Misra, M. S. Ramanujan, Saket Saurabh
2017 A* conf
AAAI
Robert Ganian, Sebastian Ordyniak, M. S. Ramanujan
2017 J jnl
SIAM J. Discret. Math.
Daniel Lokshtanov, Pranabendu Misra, M. S. Ramanujan, Saket Saurabh
2017 Misc conf
COCOON
Pranabendu Misra, Fahad Panolan, M. S. Ramanujan, Saket Saurabh
2017 J jnl
ACM Trans. Algorithms
M. S. Ramanujan, Saket Saurabh
2017 B conf
MFCS
Eduard Eiben, Danny Hermelin, M. S. Ramanujan
2017 A* conf
STOC
Daniel Lokshtanov, Fahad Panolan, M. S. Ramanujan, Saket Saurabh
2017 J jnl
SIAM J. Discret. Math.
Rémy Belmonte, Fedor V. Fomin, Petr A. Golovach, M. S. Ramanujan
2017 J jnl
CoRR
Robert Ganian, Sebastian Ordyniak, M. S. Ramanujan
2017 J jnl
CoRR
Manu Basavaraju, Pranabendu Misra, M. S. Ramanujan, Saket Saurabh
2017 conf
FSTTCS
Akanksha Agrawal, R. Krithika, Daniel Lokshtanov, Amer E. Mouawad, M. S. Ramanujan
2017 J jnl
CoRR
Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh, Meirav Zehavi
2017 J jnl
SIAM J. Discret. Math.
Mark Jones, Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh, Ondrej Suchý
2017 A conf
ESA
Gregory Z. Gutin, M. S. Ramanujan, Felix Reidl, Magnus Wahlström
2017 J jnl
CoRR
Gregory Z. Gutin, M. S. Ramanujan, Felix Reidl, Magnus Wahlström
2017 A* conf
AAAI
M. S. Ramanujan, Stefan Szeider
2017 A* conf
ICALP
Jayesh Choudhari, Anirban Dasgupta, Neeldhara Misra, M. S. Ramanujan
2017 J jnl
CoRR
Jayesh Choudhari, Anirban Dasgupta, Neeldhara Misra, M. S. Ramanujan
2017 J jnl
CoRR
Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh
2017 B conf
MFCS
Benjamin Bergougnoux, Eduard Eiben, Robert Ganian, Sebastian Ordyniak, M. S. Ramanujan
2016 B conf
WG
M. S. Ramanujan
2016 J jnl
CoRR
Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh
2016 J jnl
CoRR
Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh
2016 A* conf
LICS
Jakub Gajarský, Petr Hlinený, Jan Obdrzálek, Daniel Lokshtanov, M. S. Ramanujan
2016 B conf
LATIN
Ashutosh Rai, M. S. Ramanujan, Saket Saurabh
2016 A conf
CP
Robert Ganian, M. S. Ramanujan, Stefan Szeider
2016 J jnl
CoRR
Robert Ganian, M. S. Ramanujan, Stefan Szeider
2016 J jnl
Algorithmica
Serge Gaspers, Sebastian Ordyniak, M. S. Ramanujan, Saket Saurabh, Stefan Szeider
2016 J jnl
CoRR
Robert Ganian, M. S. Ramanujan, Stefan Szeider
2016 A* conf
SODA
Robert Ganian, M. S. Ramanujan, Stefan Szeider
2016 J jnl
CoRR
Fedor V. Fomin, Fahad Panolan, M. S. Ramanujan, Saket Saurabh
2016 ch.
Encyclopedia of Algorithms
M. S. Ramanujan
2016 J jnl
CoRR
Daniel Lokshtanov, Fahad Panolan, M. S. Ramanujan, Saket Saurabh
2016 J jnl
CoRR
Rémy Belmonte, Fedor V. Fomin, Petr A. Golovach, M. S. Ramanujan
2016 B conf
MFCS
Robert Ganian, N. S. Narayanaswamy, Sebastian Ordyniak, C. S. Rahul, M. S. Ramanujan
2016 J jnl
SIAM J. Discret. Math.
Manu Basavaraju, Mathew C. Francis, M. S. Ramanujan, Saket Saurabh
2016 J jnl
CoRR
Arne Meier, Sebastian Ordyniak, M. S. Ramanujan, Irena Schindler
2016 conf
FSTTCS
Ashutosh Rai, M. S. Ramanujan
2015 J jnl
CoRR
Ashutosh Rai, M. S. Ramanujan, Saket Saurabh
2015 J jnl
CoRR
Robert Ganian, M. S. Ramanujan, Stefan Szeider
2015 A* conf
FOCS
Jakub Gajarský, Petr Hlinený, Daniel Lokshtanov, Jan Obdrzálek, Sebastian Ordyniak, M. S. Ramanujan, Saket Saurabh
2015 J jnl
CoRR
Jakub Gajarský, Petr Hlinený, Daniel Lokshtanov, Jan Obdrzálek, Sebastian Ordyniak, M. S. Ramanujan, Saket Saurabh
2015 J jnl
Algorithmica
Esha Ghosh, Sudeshna Kolay, Mrinal Kumar, Pranabendu Misra, Fahad Panolan, Ashutosh Rai, M. S. Ramanujan
2015 conf
ICALP (1)
Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh
2015 conf
MFCS (2)
Rémy Belmonte, Fedor V. Fomin, Petr A. Golovach, M. S. Ramanujan
2015 B conf
WADS
Fahad Panolan, M. S. Ramanujan, Saket Saurabh
2015 B conf
WADS
Daniel Lokshtanov, Amer E. Mouawad, Fahad Panolan, M. S. Ramanujan, Saket Saurabh
2015 J jnl
CoRR
Daniel Lokshtanov, Amer E. Mouawad, Fahad Panolan, M. S. Ramanujan, Saket Saurabh
2015 A* conf
SODA
Fedor V. Fomin, Daniel Lokshtanov, Neeldhara Misra, M. S. Ramanujan, Saket Saurabh
2014 J jnl
ACM Trans. Algorithms
Daniel Lokshtanov, N. S. Narayanaswamy, Venkatesh Raman, M. S. Ramanujan, Saket Saurabh
2014 A* conf
SODA
M. S. Ramanujan, Saket Saurabh
2014 Misc conf
COCOON
Manu Basavaraju, Fahad Panolan, Ashutosh Rai, M. S. Ramanujan, Saket Saurabh
2014 conf
ICALP (1)
Manu Basavaraju, Fedor V. Fomin, Petr A. Golovach, Pranabendu Misra, M. S. Ramanujan, Saket Saurabh
2014 conf
MFCS (2)
Sudeshna Kolay, Pranabendu Misra, M. S. Ramanujan, Saket Saurabh
2014 conf
FSTTCS
Geevarghese Philip, M. S. Ramanujan
2013 J jnl
Theory Comput. Syst.
Pranabendu Misra, Venkatesh Raman, M. S. Ramanujan, Saket Saurabh
2013 A conf
STACS
Serge Gaspers, Sebastian Ordyniak, M. S. Ramanujan, Saket Saurabh, Stefan Szeider
2013 B conf
IPEC
Rajesh Hemant Chitnis, Fedor V. Fomin, Daniel Lokshtanov, Pranabendu Misra, M. S. Ramanujan, Saket Saurabh
2013 conf
FAW-AAIM
Jason Crampton, Robert Crowston, Gregory Z. Gutin, Mark Jones, M. S. Ramanujan
2013 B conf
IPEC
Daniel Lokshtanov, Neeldhara Misra, Geevarghese Philip, M. S. Ramanujan, Saket Saurabh
2013 J jnl
CoRR
M. S. Ramanujan, Saket Saurabh
2013 A conf
ESA
Mark Jones, Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh, Ondrej Suchý
2013 conf
FSTTCS
Manu Basavaraju, Mathew C. Francis, M. S. Ramanujan, Saket Saurabh
2012 conf
SWAT
Esha Ghosh, Sudeshna Kolay, Mrinal Kumar, Pranabendu Misra, Fahad Panolan, Ashutosh Rai, M. S. Ramanujan
2012 J jnl
CoRR
Daniel Lokshtanov, N. S. Narayanaswamy, Venkatesh Raman, M. S. Ramanujan, Saket Saurabh
2012 J jnl
CoRR
Jason Crampton, Robert Crowston, Gregory Z. Gutin, Mark Jones, M. S. Ramanujan
2012 A conf
STACS
N. S. Narayanaswamy, Venkatesh Raman, M. S. Ramanujan, Saket Saurabh
2012 B conf
WG
Pranabendu Misra, Venkatesh Raman, M. S. Ramanujan, Saket Saurabh
2012 J jnl
CoRR
Mark Jones, Daniel Lokshtanov, M. S. Ramanujan, Saket Saurabh, Ondrej Suchý
2012 conf
ICALP (1)
Daniel Lokshtanov, M. S. Ramanujan
2011 B conf
ISAAC
Pranabendu Misra, Venkatesh Raman, M. S. Ramanujan, Saket Saurabh
2011 A conf
ESA
Venkatesh Raman, M. S. Ramanujan, Saket Saurabh
2010 B conf
IPEC
Abhimanyu M. Ambalath, Radheshyam Balasundaram, Chintan Rao H., Venkata Koppula, Neeldhara Misra, Geevarghese Philip, M. S. Ramanujan
redb/extractors/apk_extractors/apk_dex.py
← Index redb/extractors/apk_extractors/apk_dex.py python
import hashlib
import inspect
import json
from collections import Counter
from datetime import datetime, timezone
from typing import Any

import tlsh

from redb.extractors.enum import Tag
from redb.extractors.apk_extractor import APKExtractor
from redb.models.dataclasses import APKDexFile

# Sensitive API patterns categorized for malware analysis
SENSITIVE_API_CATEGORIES = {
    "reflection": [
        "Ljava/lang/reflect/Method;->invoke",
        "Ljava/lang/reflect/Field;->get",
        "Ljava/lang/reflect/Field;->set",
        "Ljava/lang/reflect/Constructor;->newInstance",
        "Ljava/lang/Class;->forName",
        "Ljava/lang/Class;->getMethod",
        "Ljava/lang/Class;->getDeclaredMethod",
        "Ljava/lang/Class;->getDeclaredField",
        "Ljava/lang/ClassLoader;->loadClass",
    ],
    "crypto": [
        "Ljavax/crypto/Cipher;->getInstance",
        "Ljavax/crypto/Cipher;->init",
        "Ljavax/crypto/spec/SecretKeySpec;-><init>",
        "Ljavax/crypto/spec/IvParameterSpec;-><init>",
        "Ljava/security/MessageDigest;->getInstance",
        "Ljava/security/KeyStore;->getInstance",
        "Ljavax/crypto/Mac;->getInstance",
    ],
    "dynamic_loading": [
        "Ldalvik/system/DexClassLoader;-><init>",
        "Ldalvik/system/PathClassLoader;-><init>",
        "Ldalvik/system/InMemoryDexClassLoader;-><init>",
        "Ldalvik/system/BaseDexClassLoader;-><init>",
        "Ljava/lang/Runtime;->exec",
        "Ljava/lang/ProcessBuilder;->start",
    ],
    "telephony": [
        "Landroid/telephony/TelephonyManager;->getDeviceId",
        "Landroid/telephony/TelephonyManager;->getSubscriberId",
        "Landroid/telephony/TelephonyManager;->getLine1Number",
        "Landroid/telephony/TelephonyManager;->getSimSerialNumber",
        "Landroid/telephony/TelephonyManager;->getNetworkOperator",
        "Landroid/telephony/TelephonyManager;->getSimOperator",
    ],
    "sms": [
        "Landroid/telephony/SmsManager;->sendTextMessage",
        "Landroid/telephony/SmsManager;->sendMultipartTextMessage",
        "Landroid/telephony/SmsManager;->sendDataMessage",
    ],
    "network": [
        "Ljava/net/HttpURLConnection;->connect",
        "Ljava/net/URL;->openConnection",
        "Lokhttp3/OkHttpClient;-><init>",
        "Lokhttp3/Request$Builder;->build",
        "Lorg/apache/http/client/HttpClient;->execute",
        "Landroid/webkit/WebView;->loadUrl",
        "Landroid/webkit/WebView;->setWebViewClient",
    ],
    "native": [
        "Ljava/lang/System;->loadLibrary",
        "Ljava/lang/System;->load",
        "Ljava/lang/Runtime;->loadLibrary",
    ],
    "device_info": [
        "Landroid/os/Build;->FINGERPRINT",
        "Landroid/os/Build;->MODEL",
        "Landroid/os/Build;->MANUFACTURER",
        "Landroid/os/Build;->PRODUCT",
        "Landroid/os/Build;->BRAND",
        "Landroid/os/Build;->DEVICE",
        "Landroid/os/Build;->HARDWARE",
        "Landroid/os/Build;->SERIAL",
        "Landroid/os/Build$VERSION;->SDK_INT",
        "Landroid/provider/Settings$Secure;->getString",
    ],
    "file_io": [
        "Ljava/io/FileOutputStream;-><init>",
        "Ljava/io/FileInputStream;-><init>",
        "Landroid/content/SharedPreferences;->edit",
        "Landroid/database/sqlite/SQLiteDatabase;->execSQL",
        "Landroid/database/sqlite/SQLiteDatabase;->rawQuery",
    ],
    "ipc": [
        "Landroid/content/ContentResolver;->query",
        "Landroid/content/ContentResolver;->insert",
        "Landroid/content/ContentResolver;->delete",
        "Landroid/content/Intent;-><init>",
        "Landroid/content/Context;->sendBroadcast",
        "Landroid/content/Context;->startService",
        "Landroid/content/Context;->bindService",
    ],
}


class APKDexExtractor(APKExtractor):

    def __init__(
        self, filepath, log, exporters=None, index_prefix=None,
        known_benign=False, known_malicious=False,
        apk=None,
    ):
        super().__init__(
            filepath, log, exporters, index_prefix,
            known_benign, known_malicious, apk,
        )
        self.dex_files = []
        self.log.debug(inspect.currentframe().f_code.co_name)

    def tag(self):
        return Tag.APK_DEX.value

    def _analyze_api_usage(self, dex):
        """Categorize sensitive API calls found in DEX bytecode."""
        api_usage = {cat: set() for cat in SENSITIVE_API_CATEGORIES}

        try:
            for method in dex.get_encoded_methods():
                code = method.get_code()
                if not code:
                    continue
                try:
                    bytecode = code.get_bc()
                    if not bytecode:
                        continue
                    for instruction in bytecode.get_instructions():
                        op_name = instruction.get_name()
                        if not op_name or not op_name.startswith("invoke"):
                            continue
                        output = instruction.get_output()
                        if not output:
                            continue
                        for category, patterns in SENSITIVE_API_CATEGORIES.items():
                            for pattern in patterns:
                                if pattern in output:
                                    api_usage[category].add(output.strip())
                                    break
                except Exception:
                    continue
        except Exception as e:
            self.log.warning(f"Error analyzing API usage: {e}")

        # Convert sets to sorted lists
        return {cat: sorted(calls) for cat, calls in api_usage.items() if calls}

    def _compute_obfuscation_indicators(self, classes, methods):
        """Compute obfuscation indicators from class/method names."""
        class_names = []
        for cls in classes:
            try:
                name = cls.get_name()
                if name:
                    class_names.append(name)
            except Exception:
                continue

        method_names = []
        for m in methods:
            try:
                name = m.get_name()
                if name and name not in ("<init>", "<clinit>"):
                    method_names.append(name)
            except Exception:
                continue

        if not class_names:
            return None

        # Short class names: extract just the class part from Dalvik notation
        short_class = 0
        for n in class_names:
            simple = n.split("/")[-1].rstrip(";")
            if len(simple) <= 2:
                short_class += 1

        short_method = sum(1 for n in method_names if len(n) <= 2)

        return {
            "short_class_names_pct": round(short_class / max(len(class_names), 1), 4),
            "short_method_names_pct": round(short_method / max(len(method_names), 1), 4),
            "non_ascii_identifiers": sum(1 for n in class_names if not n.isascii()),
            "avg_class_name_length": round(
                sum(len(n) for n in class_names) / max(len(class_names), 1), 2
            ),
        }

    def _compute_top_packages(self, classes):
        """Compute top packages by class count."""
        package_counter = Counter()
        for cls in classes:
            try:
                name = cls.get_name()  # "Lcom/example/foo/Bar;"
                if not name:
                    continue
                parts = name[1:].replace("/", ".").rsplit(".", 1)
                if len(parts) > 1:
                    package = parts[0]
                else:
                    package = "(default)"
                package_counter[package] += 1
            except Exception:
                continue

        return [
            {"package": pkg, "class_count": count}
            for pkg, count in package_counter.most_common(20)
        ]

    def extract(self):
        if not self._is_valid_apk():
            self.log.error(f"Invalid APK for {self.hash.sha256}")
            return None

        from androguard.core.dex import DEX

        try:
            dex_names = list(self.apk.get_dex_names() or [])
        except Exception as e:
            self.log.warning(f"Error getting DEX names for {self.hash.sha256}: {e}")
            dex_names = []

        try:
            dex_buffers = list(self.apk.get_all_dex() or [])
        except Exception as e:
            self.log.error(f"Error getting DEX buffers for {self.hash.sha256}: {e}")
            return None

        if not dex_buffers:
            self.log.debug("No DEX files found in APK")
            return None

        self.dex_files = []
        for i, dex_data in enumerate(dex_buffers):
            dex_name = dex_names[i] if i < len(dex_names) else f"classes{i}.dex"

            dex_sha256 = hashlib.sha256(dex_data).hexdigest()
            dex_tlsh = None
            if len(dex_data) >= 50:
                try:
                    dex_tlsh = tlsh.hash(dex_data) or None
                except Exception:
                    pass

            try:
                d = DEX(dex_data)
            except Exception as e:
                self.log.warning(f"Failed to parse DEX {dex_name}: {e}")
                continue

            try:
                classes = list(d.get_classes() or [])
            except Exception as e:
                self.log.warning(f"Error getting classes from {dex_name}: {e}")
                classes = []
            try:
                methods = list(d.get_methods() or [])
            except Exception as e:
                self.log.warning(f"Error getting methods from {dex_name}: {e}")
                methods = []
            try:
                strings = list(d.get_strings() or [])
            except Exception as e:
                self.log.warning(f"Error getting strings from {dex_name}: {e}")
                strings = []

            try:
                top_packages = self._compute_top_packages(classes)
            except Exception as e:
                self.log.warning(f"Error computing top packages for {dex_name}: {e}")
                top_packages = []
            try:
                api_usage = self._analyze_api_usage(d)
            except Exception as e:
                self.log.warning(f"Error analyzing API usage for {dex_name}: {e}")
                api_usage = {}
            try:
                obfuscation_indicators = self._compute_obfuscation_indicators(classes, methods)
            except Exception as e:
                self.log.warning(f"Error computing obfuscation indicators for {dex_name}: {e}")
                obfuscation_indicators = None

            self.dex_files.append(APKDexFile(
                filename=dex_name,
                sha256=dex_sha256,
                class_count=len(classes),
                method_count=len(methods),
                string_count=len(strings),
                tlsh=dex_tlsh,
                top_packages=top_packages,
                api_usage=api_usage if api_usage else None,
                obfuscation_indicators=obfuscation_indicators,
            ))

        return self.dex_files if self.dex_files else None

    def prepare_export_data(self, exporter_type: str) -> Any:
        if exporter_type == "ClickHouseExporter":
            if not self.dex_files:
                return None

            current_time = datetime.now(timezone.utc)

            # DEX table: one row per DEX file
            dex_data = []
            for dex in self.dex_files:
                dex_data.append([
                    self.sha256,
                    dex.sha256,
                    dex.filename,
                    dex.tlsh,
                    dex.class_count,
                    dex.method_count,
                    dex.string_count,
                    json.dumps(dex.top_packages) if dex.top_packages else None,
                    json.dumps(dex.obfuscation_indicators) if dex.obfuscation_indicators else None,
                    current_time,
                ])

            # API usage table: one row per category per DEX
            api_data = []
            for dex in self.dex_files:
                if dex.api_usage:
                    for category, api_calls in dex.api_usage.items():
                        api_data.append([
                            self.sha256,
                            dex.sha256,
                            category,
                            api_calls,
                            current_time,
                        ])

            return {
                'multi_table': True,
                'dex': {
                    'table': 'redb_apk_dex',
                    'data': dex_data,
                    'column_names': [
                        'sha256', 'dex_sha256', 'dex_filename', 'dex_tlsh',
                        'dex_class_count', 'dex_method_count', 'dex_string_count',
                        'dex_top_packages', 'dex_obfuscation_indicators',
                        'analysis_date',
                    ],
                    'column_type_names': [
                        'FixedString(64)', 'FixedString(64)', 'String', 'Nullable(String)',
                        'UInt32', 'UInt32', 'UInt32',
                        'Nullable(String)', 'Nullable(String)',
                        "DateTime64(3, 'UTC')",
                    ],
                },
                'api_usage': {
                    'table': 'redb_apk_dex_api_usage',
                    'data': api_data,
                    'column_names': [
                        'sha256', 'dex_sha256', 'api_category',
                        'api_calls', 'analysis_date',
                    ],
                    'column_type_names': [
                        'FixedString(64)', 'FixedString(64)', 'LowCardinality(String)',
                        'Array(String)', "DateTime64(3, 'UTC')",
                    ],
                },
            }

    def get_clickhouse_table(self) -> str:
        return "redb_apk_dex"