Iain D. Couzin

33 papers A* 1A 2Journal 27Unranked 3
YearRankTypeTitle / Venue / Authors
2025 J jnl
Sci. Robotics
Liang Li, Nagy Máté, Guy Amichay, Ruiheng Wu, Wei Wang, Oliver Deussen, Daniela Rus, Iain D. Couzin
2025 J jnl
CoRR
Mohammad Salahshour, Iain D. Couzin
2025 J jnl
CoRR
Alex Hoi Hang Chan, Otto Brookes, Urs Waldmann, Hemal Naik, Iain D. Couzin, Majid Mirmehdi, Noël Adiko Houa, Emmanuelle Normand, Christophe Boesch, Lukas Boesch, Mimi Arandjelovic, Hjalmar S. Kühl, Tilo Burghardt, Fumihiro Kano
2024 J jnl
Int. J. Comput. Vis.
Urs Waldmann, Alex Hoi Hang Chan, Hemal Naik, Nagy Máté, Iain D. Couzin, Oliver Deussen, Bastian Goldluecke, Fumihiro Kano
2024 J jnl
IEEE Robotics Autom. Mag.
Liang Li, Liming Chao, Siyuan Wang, Oliver Deussen, Iain D. Couzin
2023 J jnl
CoRR
Urs Waldmann, Alex Hoi Hang Chan, Hemal Naik, Nagy Máté, Iain D. Couzin, Oliver Deussen, Bastian Goldluecke, Fumihiro Kano
2023 A* conf
CVPR
Hemal Naik, Alex Hoi Hang Chan, Junran Yang, Mathilde Delacoux, Iain D. Couzin, Fumihiro Kano, Nagy Máté
2023 J jnl
CoRR
Hemal Naik, Alex Hoi Hang Chan, Junran Yang, Mathilde Delacoux, Iain D. Couzin, Fumihiro Kano, Nagy Máté
2023 J jnl
CoRR
Conor Heins, Beren Millidge, Lancelot Da Costa, Richard Mann, Karl J. Friston, Iain D. Couzin
2023 A conf
AAMAS
Iain D. Couzin
2022 conf
GCPR
Urs Waldmann, Hemal Naik, Nagy Máté, Fumihiro Kano, Iain D. Couzin, Oliver Deussen, Bastian Goldlücke
2022 J jnl
CoRR
Conor Heins, Beren Millidge, Daphne Demekas, Brennan Klein, Karl J. Friston, Iain D. Couzin, Alexander Tschantz
2022 J jnl
J. Open Source Softw.
Conor Heins, Beren Millidge, Daphne Demekas, Brennan Klein, Karl J. Friston, Iain D. Couzin, Alexander Tschantz
2021 J jnl
CoRR
Devis Tuia, Benjamin Kellenberger, Sara Beery, Blair R. Costelloe, Silvia Zuffi, Benjamin Risse, Alexander Mathis, Mackenzie W. Mathis, Frank van Langevelde, Tilo Burghardt, Roland Kays, Holger Klinck, Martin Wikelski, Iain D. Couzin, Grant Van Horn, Margaret C. Crofoot, Charles V. Stewart, Tanya Y. Berger-Wolf
2020 J jnl
IEEE Trans. Vis. Comput. Graph.
Hemal Naik, Renaud Bastien, Nassir Navab, Iain D. Couzin
2019 J jnl
CoRR
Hemal Naik, Renaud Bastien, Nassir Navab, Iain D. Couzin
2019 J jnl
Nat.
Iyad Rahwan, Manuel Cebrián, Nick Obradovich, Josh C. Bongard, Jean-François Bonnefon, Cynthia Breazeal, Jacob W. Crandall, Nicholas A. Christakis, Iain D. Couzin, Matthew O. Jackson, Nicholas R. Jennings, Ece Kamar, Isabel M. Kloumann, Hugo Larochelle, David Lazer, Richard McElreath, Alan Mislove, David C. Parkes, Alex 'Sandy' Pentland, Margaret E. Roberts, Azim Shariff, Joshua B. Tenenbaum, Michael P. Wellman
2017 J jnl
PLoS Comput. Biol.
Jaideep Joshi, Iain D. Couzin, Simon A. Levin, Vishwesha Guttal
2016 J jnl
IEEE Computer Graphics and Applications
Manuel Stein, Halldor Janetzko, Thorsten Breitkreutz, Daniel Seebacher, Tobias Schreck, Michael Grossniklaus, Iain D. Couzin, Daniel A. Keim
2015 J jnl
J. Nonlinear Sci.
Daniel T. Swain, Iain D. Couzin, Naomi Ehrich Leonard
2014 J jnl
PLoS Comput. Biol.
Albert B. Kao, Noam Miller, Colin J. Torney, Andrew Hartnett, Iain D. Couzin
2014 A conf
AAMAS
Iain D. Couzin
2013 J jnl
PLoS Comput. Biol.
Kolbjørn Tunstrøm, Yael Katz, Christos C. Ioannou, Cristián Huepe, Matthew J. Lutz, Iain D. Couzin
2013 J jnl
PLoS Comput. Biol.
Simon Garnier, Tucker Murphy, Matthew J. Lutz, Edward Hurme, Simon Leblanc, Iain D. Couzin
2012 J jnl
PLoS Comput. Biol.
Sepideh Bazazi, Frederic Bartumeus, Joseph J. Hale, Iain D. Couzin
2012 J jnl
Proc. IEEE
Daniel T. Swain, Iain D. Couzin, Naomi Ehrich Leonard
2011 J jnl
PLoS Comput. Biol.
Colin J. Torney, Andrew Berdahl, Iain D. Couzin
2010 J jnl
PLoS Comput. Biol.
Cédric Sueur, Jean-Louis Deneubourg, Odile Petit, Iain D. Couzin
2009 J jnl
J. Nonlinear Sci.
Benjamin Nabet, Naomi Ehrich Leonard, Iain D. Couzin, Simon A. Levin
2008 J jnl
Theory Biosci.
David J. T. Sumpter, Jérôme Buhl, Dora Biro, Iain D. Couzin
2007 conf
CDC
Daniel T. Swain, Naomi Ehrich Leonard, Iain D. Couzin, Albert B. Kao, Rodolphe Sepulchre
2007 conf
CDC
Derek A. Paley, Naomi Ehrich Leonard, Rodolphe Sepulchre, Iain D. Couzin
1998 J jnl
Adv. Complex Syst.
Andrew J. Spencer, Iain D. Couzin, Nigel R. Franks
redb/extractors/elf_extractors/elf_relocations.py
← Index redb/extractors/elf_extractors/elf_relocations.py python
import inspect
from datetime import datetime, timezone
from typing import Any, List, Dict

from elftools.elf.elffile import ELFFile
from elftools.common.exceptions import ELFError

from redb.extractors.enum import Tag
from redb.extractors.elf_extractor import ELFExtractor
from redb.models.dataclasses import ELFRelocation


class ELFRelocationExtractor(ELFExtractor):

    def __init__(
        self,
        filepath,
        log,
        exporters=None,
        index_prefix=None,
        elastic_index=None,
        known_benign=False,
        known_malicious=False,
        elf=None,
    ):
        super().__init__(
            filepath,
            log,
            exporters,
            index_prefix,
            elastic_index,
            known_benign,
            known_malicious,
            elf,
        )
        self.elf_relocations = []
        self.elastic_index = self.index_prefix + "-elf_relocations"
        self.log.debug(inspect.currentframe().f_code.co_name)

    def _get_relocation_type_string(self, reloc_type: int, machine_arch: str) -> str:
        """Convert relocation type number to human-readable string based on architecture."""
        # This is a simplified mapping - real implementation would need comprehensive
        # architecture-specific relocation type mappings

        common_types = {
            0: "R_NONE",
            1: "R_DIRECT",
            2: "R_PC_RELATIVE",
            3: "R_GOT",
            4: "R_PLT",
            5: "R_COPY",
            6: "R_GLOB_DAT",
            7: "R_JMP_SLOT",
            8: "R_RELATIVE"
        }

        # Architecture-specific mappings could be added here
        if machine_arch == "x86_64":
            x86_64_types = {
                1: "R_X86_64_64",
                2: "R_X86_64_PC32",
                3: "R_X86_64_GOT32",
                4: "R_X86_64_PLT32",
                5: "R_X86_64_COPY",
                6: "R_X86_64_GLOB_DAT",
                7: "R_X86_64_JUMP_SLOT",
                8: "R_X86_64_RELATIVE"
            }
            return x86_64_types.get(reloc_type, f"R_X86_64_{reloc_type}")
        elif machine_arch == "x86":
            i386_types = {
                1: "R_386_32",
                2: "R_386_PC32",
                3: "R_386_GOT32",
                4: "R_386_PLT32",
                5: "R_386_COPY",
                6: "R_386_GLOB_DAT",
                7: "R_386_JMP_SLOT",
                8: "R_386_RELATIVE"
            }
            return i386_types.get(reloc_type, f"R_386_{reloc_type}")

        return common_types.get(reloc_type, f"R_UNKNOWN_{reloc_type}")

    def _extract_relocation_data(self, relocation, section_name: str, machine_arch: str) -> Dict:
        """Extract data from a single relocation entry."""
        try:
            # Get relocation offset
            relocation_offset = relocation.entry.get('r_offset', 0)

            # Get relocation type
            relocation_type = relocation.entry.get('r_info_type', 0)

            # Get symbol index
            relocation_symbol_index = relocation.entry.get('r_info_sym', 0)

            # Get addend (only present in RELA sections)
            relocation_addend = None
            if hasattr(relocation.entry, 'r_addend'):
                relocation_addend = relocation.entry.get('r_addend', 0)

            # Get symbol name if available
            relocation_symbol_name = ""
            if hasattr(relocation, 'symbol') and relocation.symbol:
                relocation_symbol_name = relocation.symbol.name or f"<symbol_{relocation_symbol_index}>"
            else:
                relocation_symbol_name = f"<symbol_{relocation_symbol_index}>"

            # Get type string mapping
            relocation_type_str = self._get_relocation_type_string(relocation_type, machine_arch)

            return ELFRelocation(
                relocation_offset=relocation_offset,
                relocation_type=relocation_type,
                relocation_type_str=relocation_type_str,
                relocation_symbol_index=relocation_symbol_index,
                relocation_symbol_name=relocation_symbol_name,
                relocation_section=section_name,
                relocation_addend=relocation_addend
            )

        except Exception as e:
            self.log.error(f"Error extracting relocation data: {e}")
            return None

    def _extract_relocations_from_section(self, section, machine_arch: str) -> List[Dict]:
        """Extract all relocations from a relocation section."""
        relocations = []

        try:
            if not hasattr(section, 'iter_relocations'):
                return relocations

            section_name = section.name or f"<unnamed_section>"

            for relocation in section.iter_relocations():
                reloc_data = self._extract_relocation_data(relocation, section_name, machine_arch)
                if reloc_data:
                    relocations.append(reloc_data)

        except Exception as e:
            self.log.error(f"Error extracting relocations from section {section.name}: {e}")

        return relocations

    def tag(self):
        return Tag.ELF_RELOCATIONS.value if hasattr(Tag, 'ELF_RELOCATIONS') else "elf_relocations"

    def extract(self):
        try:
            self.log.debug(inspect.currentframe().f_code.co_name)

            def extract_data(elf):
                # Get architecture for relocation type mapping
                machine_arch = self._get_architecture()
                all_relocations = []

                # Iterate through all sections looking for relocation sections with per-section error handling
                for section_index, section in enumerate(elf.iter_sections()):
                    try:
                        # Check if this is a relocation section (.rel or .rela)
                        if (section.name and
                            (section.name.startswith('.rel') or section.name.startswith('.rela')) and
                            hasattr(section, 'iter_relocations')):

                            section_relocations = self._extract_relocations_from_section(section, machine_arch)
                            all_relocations.extend(section_relocations)
                            self.log.debug(f"Extracted {len(section_relocations)} relocations from section {section.name}")
                    except Exception as e:
                        section_name = getattr(section, 'name', f'section_{section_index}')
                        self.log.warning(f"Error processing relocation section {section_name}: {e}")
                        # Continue processing other sections

                return all_relocations

            if not self._is_elf_file():
                return None

            result = self._with_elf_file(extract_data)
            if result is None:
                return None

            self.elf_relocations = result
            return self.elf_relocations

        except Exception as e:
            self.log.error(f"Error extracting ELF relocations {self.hash.sha256}: {e}")
            return None

    def prepare_export_data(self, exporter_type: str) -> Any:
        self.log.debug(inspect.currentframe().f_code.co_name)

        if exporter_type == "ElasticsearchExporter":
            return self.elf_relocations
        elif exporter_type == "ClickHouseExporter":
            try:
                # Return valid empty structure if no relocations (e.g., statically linked binary)
                # None is reserved for actual errors

                # Prepare data arrays for all relocations
                data = []
                current_time = datetime.now(timezone.utc)
                for reloc in self.elf_relocations:
                    row = [
                        self.sha256,
                        self.md5,
                        self.sha1,
                        reloc.relocation_offset,
                        reloc.relocation_type,
                        reloc.relocation_type_str,
                        reloc.relocation_symbol_index,
                        reloc.relocation_symbol_name,
                        reloc.relocation_addend,
                        reloc.relocation_section,
                        current_time
                    ]
                    data.append(row)

                column_names = [
                    'sha256', 'md5', 'sha1',
                    'relocation_offset', 'relocation_type', 'relocation_type_str',
                    'relocation_symbol_index', 'relocation_symbol_name',
                    'relocation_addend', 'relocation_section',
                    'analysis_date'
                ]

                if not data:
                    return None

                column_type_names = [
                    'FixedString(64)', 'FixedString(32)', 'FixedString(40)',
                    'UInt64', 'UInt32', 'LowCardinality(String)',
                    'UInt32', 'LowCardinality(String)',
                    'Nullable(Int64)', 'LowCardinality(String)',
                    'DateTime64(3, \'UTC\')'
                ]

                return (data, column_names, column_type_names)

            except Exception as e:
                self.log.error(f"Error preparing export data: {e}")
                raise

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