Hamish McWilliam

25 papers Journal 25
YearRankTypeTitle / Venue / Authors
2015 J jnl
Nucleic Acids Res.
Silvano Squizzato, Young Mi Park, Nicola Buso, Tamer Gur, Andrew Peter Cowley, Weizhong Li, Mahmut Uludag, Sangya Pundir, Jennifer A. Cham, Hamish McWilliam, Rodrigo Lopez
2015 J jnl
Nucleic Acids Res.
Weizhong Li, Andrew Peter Cowley, Mahmut Uludag, Tamer Gur, Hamish McWilliam, Silvano Squizzato, Young Mi Park, Nicola Buso, Rodrigo Lopez
2014 J jnl
Nucleic Acids Res.
Nima Pakseresht, Blaise T. F. Alako, Clara Amid, Ana Cerdeño-Tárraga, Iain Cleland, Richard Gibson, Neil Goodgame, Tamer Gur, Mikyung Jang, Simon Kay, Rasko Leinonen, Weizhong Li, Xin Liu, Rodrigo Lopez, Hamish McWilliam, Arnaud Oisel, Swapna Pallreddy, Sheila Plaister, Rajesh Radhakrishnan, Stéphane Rivière, Marc Rossello, Alexander Senf, Nicole Silvester, Dimitriy Smirnov, Silvano Squizzato, Petra ten Hoopen, Ana Luisa Toribio, Daniel Vaughan, Vadim Zalunin, Guy Cochrane
2014 J jnl
Bioinform.
Philip Jones, David Binns, Hsin-Yu Chang, Matthew Fraser, Weizhong Li, Craig McAnulla, Hamish McWilliam, John Maslen, Alex L. Mitchell, Gift Nuka, Sebastien Pesseat, Antony F. Quinn, Amaia Sangrador-Vegas, Maxim Scheremetjew, Siew-Yit Yong, Rodrigo Lopez, Sarah Hunter
2013 J jnl
Nucleic Acids Res.
Hamish McWilliam, Weizhong Li, Mahmut Uludag, Silvano Squizzato, Young Mi Park, Nicola Buso, Andrew Peter Cowley, Rodrigo Lopez
2013 J jnl
Bioinform.
Jon C. Ison, Matús Kalas, Inge Jonassen, Dan M. Bolser, Mahmut Uludag, Hamish McWilliam, James Malone, Rodrigo Lopez, Steve Pettifer, Peter M. Rice
2013 J jnl
Nucleic Acids Res.
Guy Cochrane, Blaise T. F. Alako, Clara Amid, Lawrence Bower, Ana Cerdeño-Tárraga, Iain Cleland, Richard Gibson, Neil Goodgame, Mikyung Jang, Simon Kay, Rasko Leinonen, Xiu Lin, Rodrigo Lopez, Hamish McWilliam, Arnaud Oisel, Nima Pakseresht, Swapna Pallreddy, Young Mi Park, Sheila Plaister, Rajesh Radhakrishnan, Stéphane Rivière, Marc Rossello, Alexander Senf, Nicole Silvester, Dimitriy Smirnov, Petra ten Hoopen, Ana Luisa Toribio, Daniel Vaughan, Vadim Zalunin
2013 J jnl
Nucleic Acids Res.
James Robinson, Jason A. Halliwell, Hamish McWilliam, Rodrigo Lopez, Steven G. E. Marsh
2013 J jnl
Database J. Biol. Databases Curation
Weizhong Li, Bartosz Kondratowicz, Hamish McWilliam, Stephane Nauche, Rodrigo Lopez
2013 J jnl
Nucleic Acids Res.
James Robinson, Jason A. Halliwell, Hamish McWilliam, Rodrigo Lopez, Peter Parham, Steven G. E. Marsh
2012 J jnl
Bioinform.
Weizhong Li, Hamish McWilliam, Mickael Goujon, Andrew Peter Cowley, Rodrigo Lopez, William R. Pearson
2011 J jnl
Nucleic Acids Res.
James Robinson, Kavita Mistry, Hamish McWilliam, Rodrigo Lopez, Peter Parham, Steven G. E. Marsh
2010 J jnl
Nucleic Acids Res.
Mickael Goujon, Hamish McWilliam, Weizhong Li, Franck Valentin, Silvano Squizzato, Juri Paern, Rodrigo Lopez
2010 J jnl
Briefings Bioinform.
Franck Valentin, Silvano Squizzato, Mickael Goujon, Hamish McWilliam, Juri Paern, Rodrigo Lopez
2010 J jnl
Nucleic Acids Res.
James Robinson, Kavita Mistry, Hamish McWilliam, Rodrigo Lopez, Steven G. E. Marsh
2010 J jnl
Nucleic Acids Res.
Rasko Leinonen, Ruth Akhtar, Ewan Birney, James K. Bonfield, Lawrence Bower, Matthew Corbett, Ying Cheng, Fehmi Demiralp, Nadeem Faruque, Neil Goodgame, Richard Gibson, Gemma Hoad, Christopher I. Hunter, Mikyung Jang, Steven Leonard, Quan Lin, Rodrigo Lopez, Michael Maguire, Hamish McWilliam, Sheila Plaister, Rajesh Radhakrishnan, Siamak Sobhany, Guy Slater, Petra ten Hoopen, Franck Valentin, Robert Vaughan, Vadim Zalunin, Daniel R. Zerbino, Guy Cochrane
2010 J jnl
Nucleic Acids Res.
Weizhong Li, Hamish McWilliam, Ana Richart de la Torre, Adam Grodowski, Irina Benediktovich, Mickael Goujon, Stephane Nauche, Rodrigo Lopez
2009 J jnl
Nucleic Acids Res.
Guy Cochrane, Ruth Akhtar, James K. Bonfield, Lawrence Bower, Fehmi Demiralp, Nadeem Faruque, Richard Gibson, Gemma Hoad, Tim J. P. Hubbard, Christopher I. Hunter, Mikyung Jang, Szilveszter Juhos, Rasko Leinonen, Steven Leonard, Quan Lin, Rodrigo Lopez, Dariusz Lorenc, Hamish McWilliam, Gaurab Mukherjee, Sheila Plaister, Rajesh Radhakrishnan, Stephen Robinson, Siamak Sobhany, Petra ten Hoopen, Robert Vaughan, Vadim Zalunin, Ewan Birney
2009 J jnl
Nucleic Acids Res.
James Robinson, Matthew J. Waller, Sylvie C. Fail, Hamish McWilliam, Rodrigo Lopez, Peter Parham, Steven G. E. Marsh
2009 J jnl
Nucleic Acids Res.
Hamish McWilliam, Franck Valentin, Mickael Goujon, Weizhong Li, Menaka Narayanasamy, Jenny Martin, Teresa Miyar, Rodrigo Lopez
2008 J jnl
Nucleic Acids Res.
Guy Cochrane, Ruth Akhtar, Philippe Aldebert, Nicola Althorpe, Alastair Baldwin, Kirsty Bates, Sumit Bhattacharyya, James K. Bonfield, Lawrence Bower, Paul Browne, Matias Castro, Tony Cox, Fehmi Demiralp, Ruth Y. Eberhardt, Nadeem Faruque, Gemma Hoad, Mikyung Jang, Tamara Kulikova, Alberto Labarga, Rasko Leinonen, Steven Leonard, Quan Lin, Rodrigo Lopez, Dariusz Lorenc, Hamish McWilliam, Gaurab Mukherjee, Francesco Nardone, Sheila Plaister, Stephen Robinson, Siamak Sobhany, Robert Vaughan, Dan Wu, Weimin Zhu, Rolf Apweiler, Tim J. P. Hubbard, Ewan Birney
2007 J jnl
Bioinform.
Mark A. Larkin, Gordon Blackshields, Nigel P. Brown, R. Chenna, Paul A. McGettigan, Hamish McWilliam, Franck Valentin, Iain M. Wallace, Andreas Wilm, Rodrigo Lopez, Julie Dawn Thompson, Toby J. Gibson, Desmond G. Higgins
2007 J jnl
Nucleic Acids Res.
Tamara Kulikova, Ruth Akhtar, Philippe Aldebert, Nicola Althorpe, Mikael Andersson, Alastair Baldwin, Kirsty Bates, Sumit Bhattacharyya, Lawrence Bower, Paul Browne, Matias Castro, Guy Cochrane, Karyn Duggan, Ruth Y. Eberhardt, Nadeem Faruque, Gemma Hoad, Carola Kanz, Charles Lee, Rasko Leinonen, Quan Lin, Vincent Lombard, Rodrigo Lopez, Dariusz Lorenc, Hamish McWilliam, Gaurab Mukherjee, Francesco Nardone, Maria Pilar Garcia Pastor, Sheila Plaister, Siamak Sobhany, Peter Stoehr, Robert Vaughan, Dan Wu, Weimin Zhu, Rolf Apweiler
2006 J jnl
Nucleic Acids Res.
Guy Cochrane, Philippe Aldebert, Nicola Althorpe, Mikael Andersson, Wendy Baker, Alastair Baldwin, Kirsty Bates, Sumit Bhattacharyya, Paul Browne, Alexandra van den Broek, Matias Castro, Karyn Duggan, Ruth Y. Eberhardt, Nadeem Faruque, John Gamble, Carola Kanz, Tamara Kulikova, Charles Lee, Rasko Leinonen, Quan Lin, Vincent Lombard, Rodrigo Lopez, Michelle McHale, Hamish McWilliam, Gaurab Mukherjee, Francesco Nardone, Maria Pilar Garcia Pastor, Siamak Sobhany, Peter Stoehr, Katerina Tzouvara, Robert Vaughan, Dan Wu, Weimin Zhu, Rolf Apweiler
2000 J jnl
Nucleic Acids Res.
Jo L. Dicks, Mary Anderson, Linda Cardle, Sam Cartinhour, Matthew Couchman, Guy Davenport, Jeremy Dickson, Mike Gale, David F. Marshall, Sean T. May, Hamish McWilliam, Andrew O'Malia, Helen Ougham, Martin Trick, Sean Walsh, Robbie Waugh
tests/unit/test_apk_method_extractor.py
← Index tests/unit/test_apk_method_extractor.py python
"""
Unit tests for APK method-level content extraction, hashing, and similarity.

Tests SHA-256 normalization, ssdeep/TLSH computation, obfuscation detection,
and Dalvik-to-Java type conversion.
"""
import pytest

pytestmark = [pytest.mark.unit, pytest.mark.apk, pytest.mark.decompile]


class TestHashingFunctions:
    """Tests for hashing utility functions."""

    def test_sha256_deterministic(self):
        from redb.extractors.decompiler.apk.method_extractor import compute_sha256
        h1 = compute_sha256("invoke-virtual {p0}, Lcom/Foo;->bar()V")
        h2 = compute_sha256("invoke-virtual {p0}, Lcom/Foo;->bar()V")
        assert h1 == h2

    def test_sha256_hex_length(self):
        from redb.extractors.decompiler.apk.method_extractor import compute_sha256
        assert len(compute_sha256("test")) == 64

    def test_sha256_different_inputs(self):
        from redb.extractors.decompiler.apk.method_extractor import compute_sha256
        assert compute_sha256("aaa") != compute_sha256("bbb")

    def test_ssdeep_none_for_short(self):
        from redb.extractors.decompiler.apk.method_extractor import compute_ssdeep
        assert compute_ssdeep("short") is None

    def test_tlsh_none_for_short(self):
        from redb.extractors.decompiler.apk.method_extractor import compute_tlsh
        assert compute_tlsh("x") is None


class TestObfuscationDetection:
    """Tests for obfuscation indicator detection."""

    def test_short_method_name_single_char(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        r = detect_obfuscation_indicators("a", "Lcom/Foo;", "", 10)
        assert r["short_method_name"] is True

    def test_short_method_name_two_chars(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        r = detect_obfuscation_indicators("ab", "Lcom/Foo;", "", 10)
        assert r["short_method_name"] is True

    def test_normal_method_name(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        r = detect_obfuscation_indicators("onCreate", "Lcom/Foo;", "", 10)
        assert r["short_method_name"] is False

    def test_short_class_name(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        r = detect_obfuscation_indicators("foo", "Lcom/a;", "", 10)
        assert r["short_class_name"] is True

    def test_normal_class_name(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        r = detect_obfuscation_indicators("foo", "Lcom/example/MainActivity;", "", 10)
        assert r["short_class_name"] is False

    def test_string_encryption_detected(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        smali = (
            'const-string v0, "xyz"\n'
            'invoke-static {v0}, Lcom/Enc;->decrypt(Ljava/lang/String;)Ljava/lang/String;\n'
        )
        r = detect_obfuscation_indicators("m", "Lcom/Foo;", smali, 10)
        assert r["has_string_encryption"] is True

    def test_no_string_encryption(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        smali = 'const-string v0, "hello"\ninvoke-virtual {v0}, Ljava/lang/String;->length()I'
        r = detect_obfuscation_indicators("m", "Lcom/Foo;", smali, 10)
        assert r["has_string_encryption"] is False

    def test_reflection_detected(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        smali = 'invoke-virtual {v0, v1}, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;'
        r = detect_obfuscation_indicators("m", "Lcom/Foo;", smali, 10)
        assert r["has_reflection_calls"] is True

    def test_no_reflection(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        smali = 'invoke-virtual {p0}, Lcom/Foo;->bar()V'
        r = detect_obfuscation_indicators("m", "Lcom/Foo;", smali, 10)
        assert r["has_reflection_calls"] is False

    def test_excessive_goto_detected(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        smali = "\n".join(["goto :label"] * 10)
        # threshold = max(5, 20*0.15=3) = 5, 10 > 5
        r = detect_obfuscation_indicators("m", "Lcom/Foo;", smali, 20)
        assert r["excessive_goto_count"] is True

    def test_no_excessive_goto(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        smali = "goto :label\nreturn-void"
        r = detect_obfuscation_indicators("m", "Lcom/Foo;", smali, 100)
        assert r["excessive_goto_count"] is False

    def test_goto_16_counted(self):
        from redb.extractors.decompiler.apk.method_extractor import detect_obfuscation_indicators
        smali = "\n".join(["goto/16 :label"] * 10)
        r = detect_obfuscation_indicators("m", "Lcom/Foo;", smali, 20)
        assert r["excessive_goto_count"] is True


class TestDalvikTypeConversion:
    """Tests for Dalvik-to-Java type conversion."""

    def test_void(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_type_to_java
        assert dalvik_type_to_java("V") == "void"

    def test_primitives(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_type_to_java
        assert dalvik_type_to_java("I") == "int"
        assert dalvik_type_to_java("Z") == "boolean"
        assert dalvik_type_to_java("J") == "long"
        assert dalvik_type_to_java("F") == "float"
        assert dalvik_type_to_java("D") == "double"
        assert dalvik_type_to_java("B") == "byte"
        assert dalvik_type_to_java("S") == "short"
        assert dalvik_type_to_java("C") == "char"

    def test_object_type(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_type_to_java
        assert dalvik_type_to_java("Ljava/lang/String;") == "String"
        assert dalvik_type_to_java("Lcom/example/Foo;") == "Foo"

    def test_array_type(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_type_to_java
        assert dalvik_type_to_java("[I") == "int[]"
        assert dalvik_type_to_java("[Ljava/lang/String;") == "String[]"

    def test_empty_returns_void(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_type_to_java
        assert dalvik_type_to_java("") == "void"


class TestJavaPrototypeConversion:
    """Tests for method signature to Java prototype conversion."""

    def test_simple_method(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_to_java_prototype
        assert dalvik_to_java_prototype("foo", "()V") == "void foo()"

    def test_method_with_params(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_to_java_prototype
        result = dalvik_to_java_prototype("bar", "(ILjava/lang/String;)Z")
        assert result == "boolean bar(int, String)"

    def test_method_returning_object(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_to_java_prototype
        result = dalvik_to_java_prototype("create", "()Lcom/example/Foo;")
        assert result == "Foo create()"

    def test_empty_signature(self):
        from redb.extractors.decompiler.apk.method_extractor import dalvik_to_java_prototype
        result = dalvik_to_java_prototype("m", "")
        assert "m()" in result


class TestDalvikParamParsing:
    """Tests for parsing Dalvik parameter descriptors."""

    def test_empty(self):
        from redb.extractors.decompiler.apk.method_extractor import _parse_dalvik_params
        assert _parse_dalvik_params("") == []

    def test_single_primitive(self):
        from redb.extractors.decompiler.apk.method_extractor import _parse_dalvik_params
        assert _parse_dalvik_params("I") == ["I"]

    def test_multiple_primitives(self):
        from redb.extractors.decompiler.apk.method_extractor import _parse_dalvik_params
        assert _parse_dalvik_params("IZJ") == ["I", "Z", "J"]

    def test_single_object(self):
        from redb.extractors.decompiler.apk.method_extractor import _parse_dalvik_params
        assert _parse_dalvik_params("Ljava/lang/String;") == ["Ljava/lang/String;"]

    def test_mixed(self):
        from redb.extractors.decompiler.apk.method_extractor import _parse_dalvik_params
        result = _parse_dalvik_params("ILjava/lang/String;Z")
        assert result == ["I", "Ljava/lang/String;", "Z"]

    def test_arrays(self):
        from redb.extractors.decompiler.apk.method_extractor import _parse_dalvik_params
        result = _parse_dalvik_params("[I[Ljava/lang/String;")
        assert result == ["[I", "[Ljava/lang/String;"]

    def test_two_objects(self):
        from redb.extractors.decompiler.apk.method_extractor import _parse_dalvik_params
        result = _parse_dalvik_params("Landroid/os/Bundle;Ljava/lang/String;")
        assert len(result) == 2