Nathan R. Sturtevant

218 papers A* 65A 8B 42C 6Journal 43Unranked 50
YearRankTypeTitle / Venue / Authors
2026 A* conf
AAAI
Ehsan Futuhi, Nathan R. Sturtevant
2026 J jnl
Artif. Intell.
Nathan R. Sturtevant, Shahaf S. Shperberg, Ariel Felner
2025 J jnl
CoRR
Ehsan Futuhi, Nathan R. Sturtevant
2025 A* conf
AAAI
Sepehr Lavasani, Lior Siag, Shahaf S. Shperberg, Ariel Felner, Nathan R. Sturtevant
2025 J jnl
CoRR
David Sychrovský, Christopher Solinas, Revan MacQueen, Kevin Wang, James R. Wright, Nathan R. Sturtevant, Michael Bowling
2025 J jnl
CoRR
Ehsan Futuhi, Nathan R. Sturtevant
2025 J jnl
CoRR
Christopher Solinas, Radovan Haluska, David Sychrovsky, Finbarr Timbers, Nolan Bard, Michael Buro, Martin Schmid, Nathan R. Sturtevant, Michael Bowling
2025 J jnl
CoRR
Zhe Chen, Daniel Harabor, Ryan Hechenberger, Nathan R. Sturtevant
2025 J jnl
CoRR
Saman Ahmadi, Nathan R. Sturtevant, Andrea Raith, Daniel Harabor, Mahdi Jalili
2025 A* conf
IJCAI
Isaac Stone, Nathan R. Sturtevant, Jonathan Schaeffer
2025 A* conf
AAAI
Mohammadreza Hami, Nathan R. Sturtevant
2024 A conf
AAMAS
Thayne T. Walker, Nathan R. Sturtevant, Ariel Felner
2024 B conf
SOCS
Thayne T. Walker, Nathan R. Sturtevant, Ariel Felner
2024 B conf
SOCS
Sumedh Pendurkar, Levi H. S. Lelis, Nathan R. Sturtevant, Guni Sharon
2024 conf
AIIDE
Kristen K. Yu, Matthew Guzdial, Nathan R. Sturtevant
2024 J jnl
CoRR
Kristen K. Yu, Matthew Guzdial, Nathan R. Sturtevant
2024 A* conf
ICAPS
Saman Ahmadi, Nathan R. Sturtevant, Daniel Harabor, Mahdi Jalili
2024 conf
AIIDE
Junwen Shen, Nathan R. Sturtevant
2024 conf
AIIDE
Yazeed Mahmoud, Nathan R. Sturtevant
2024 B conf
SOCS
Lior Siag, Shahaf S. Shperberg, Ariel Felner, Nathan R. Sturtevant
2024 A conf
ECAI
Lior Siag, Shahaf S. Shperberg, Ariel Felner, Nathan R. Sturtevant
2024 J jnl
CoRR
Lior Siag, Shahaf S. Shperberg, Ariel Felner, Nathan R. Sturtevant
2024 J jnl
CoRR
Thayne T. Walker, Nathan R. Sturtevant
2024 B conf
SOCS
Shahaf S. Shperberg, Ariel Felner, Lior Siag, Nathan R. Sturtevant
2024 J jnl
CoRR
Isaac Stone, Nathan R. Sturtevant, Jonathan Schaeffer
2024 conf
AIIDE
Kristen K. Yu, Matthew Guzdial, Nathan R. Sturtevant
2024 J jnl
CoRR
Douglas Rebstock, Christopher Solinas, Nathan R. Sturtevant, Michael Buro
2024 conf
AIIDE
Yazeed Mahmoud, Nathan R. Sturtevant
2023 A* conf
AAAI
Reza Mashayekhi, Dor Atzmon, Nathan R. Sturtevant
2023 J jnl
CoRR
Thayne T. Walker, Nathan R. Sturtevant, Ariel Felner
2023 B conf
SOCS
Lior Siag, Shahaf S. Shperberg, Ariel Felner, Nathan R. Sturtevant
2023 J jnl
Artif. Intell.
Dor Atzmon, Ariel Felner, Jiaoyang Li, Shahaf S. Shperberg, Nathan R. Sturtevant, Sven Koenig
2023 conf
AIIDE
Eugene You Chen Chen, Adam White, Nathan R. Sturtevant
2023 A* conf
IJCAI
Lior Siag, Shahaf S. Shperberg, Ariel Felner, Nathan R. Sturtevant
2023 A* conf
NeurIPS
Christopher Solinas, Douglas Rebstock, Nathan R. Sturtevant, Michael Buro
2023 J jnl
CoRR
Christopher Solinas, Douglas Rebstock, Nathan R. Sturtevant, Michael Buro
2023 conf
AIIDE
Debraj Ray, Nathan R. Sturtevant
2023 conf
EXAG@AIIDE
Seth Cooper, Faisal Abutarab, Emily Halina, Nathan R. Sturtevant
2023 A* conf
ICAPS
Dor Atzmon, Shahaf S. Shperberg, Netanel Sabah, Ariel Felner, Nathan R. Sturtevant
2022 conf
AIIDE
Kristen K. Yu, Matthew Guzdial, Nathan R. Sturtevant, Morgan Cselinacz, Chris Corfe, Izzy Hubert Lyall, Chris Smith
2022 conf
CG
Nathan R. Sturtevant
2022 A* conf
IJCAI
Jasmeet Kaur, Nathan R. Sturtevant
2022 conf
AIIDE
Kristen K. Yu, Matthew Guzdial, Nathan R. Sturtevant
2022 A* conf
IJCAI
Levi H. S. Lelis, João Gabriel Gama Vila Nova, Eugene Chen, Nathan R. Sturtevant, Carrie Demmans Epp, Michael Bowling
2022 A* conf
ICAPS
Shuli Hu, Daniel Damir Harabor, Graeme Gange, Peter J. Stuckey, Nathan R. Sturtevant
2022 B conf
SOCS
Tianhua Li, Ruimin Chen, Borislav Mavrin, Nathan R. Sturtevant, Doron Nadav, Ariel Felner
2021 B conf
SOCS
Jingwei Chen, Nathan R. Sturtevant
2021 A* conf
ICAPS
Thayne T. Walker, Nathan R. Sturtevant, Ariel Felner, Han Zhang, Jiaoyang Li, T. K. Satish Kumar
2021 B conf
SOCS
Shahaf S. Shperberg, Steven Danishevski, Ariel Felner, Nathan R. Sturtevant
2021 A* conf
ICAPS
Shahaf S. Shperberg, Steven Danishevski, Ariel Felner, Nathan R. Sturtevant
2021 A* conf
ICAPS
Shuli Hu, Daniel Damir Harabor, Graeme Gange, Peter J. Stuckey, Nathan R. Sturtevant
2021 A* conf
AAAI
Jingwei Chen, Nathan R. Sturtevant
2021 J jnl
CoRR
Kristen K. Yu, Matthew Guzdial, Nathan R. Sturtevant
2021 conf
AIIDE
Kristen K. Yu, Matthew Guzdial, Nathan R. Sturtevant
2021 conf
AIIDE
Matthew Guzdial, Nathan R. Sturtevant, Carolyn Yang
2021 J jnl
CoRR
Matthew Guzdial, Nathan R. Sturtevant, Carolyn Yang
2021 C conf
FDG
Kristen K. Yu, Nathan R. Sturtevant, Matthew Guzdial
2020 conf
AIIDE
Nathan R. Sturtevant, Nicolas Decroocq, Aaron Tripodi, Carolyn Yang, Matthew Guzdial
2020 B conf
SOCS
Nathan R. Sturtevant, Malte Helmert
2020 A* conf
AAAI
Nathan R. Sturtevant, Devon Sigurdson, Bjorn Taylor, Tim Gibson
2020 A* conf
IJCAI
Shahaf S. Shperberg, Ariel Felner, Nathan R. Sturtevant, Solomon Eyal Shimony, Avi Hayoun
2020 A* conf
AAAI
Thayne T. Walker, Nathan R. Sturtevant, Ariel Felner
2020 A* conf
IJCAI
Dor Atzmon, Jiaoyang Li, Ariel Felner, Eliran Nachmani, Shahaf S. Shperberg, Nathan R. Sturtevant, Sven Koenig
2020 B conf
SOCS
Dor Atzmon, Jiaoyang Li, Ariel Felner, Eliran Nachmani, Shahaf S. Shperberg, Nathan R. Sturtevant, Sven Koenig
2020 A* conf
ICAPS
Nathan R. Sturtevant, Shahaf S. Shperberg, Ariel Felner, Jingwei Chen
2020 A* conf
ICAPS
Dor Atzmon, Roni Stern, Ariel Felner, Nathan R. Sturtevant, Sven Koenig
2020 conf
AIIDE
Nathan R. Sturtevant, Nicolas Decroocq, Aaron Tripodi, Matthew Guzdial
2020 conf
AIIDE Workshops
Kristen K. Yu, Nathan R. Sturtevant, Matthew Guzdial
2019 C conf
CoG
Kristen Yu, Nathan R. Sturtevant
2019 ed.
CGW@IJCAI
Tristan Cazenave, Abdallah Saffidine, Nathan R. Sturtevant
2019 J jnl
ICGA J.
Tristan Cazenave, Abdallah Saffidine, Nathan R. Sturtevant
2019 A* conf
IJCAI
Jingwei Chen, Nathan R. Sturtevant
2019 A* conf
IJCAI
Shuli Hu, Nathan R. Sturtevant
2019 B conf
SOCS
Shahaf S. Shperberg, Ariel Felner, Nathan R. Sturtevant, Solomon Eyal Shimony, Avi Hayoun
2019 A* conf
AAAI
Shahaf S. Shperberg, Ariel Felner, Nathan R. Sturtevant, Solomon Eyal Shimony, Avi Hayoun
2019 conf
KEG@AAAI
Nathan R. Sturtevant
2019 J jnl
CoRR
Nathan R. Sturtevant, Malte Helmert
2019 B conf
SOCS
Shahaf S. Shperberg, Ariel Felner, Solomon Eyal Shimony, Nathan R. Sturtevant, Avi Hayoun
2019 A* conf
IJCAI
Malte Helmert, Tor Lattimore, Levi H. S. Lelis, Laurent Orseau, Nathan R. Sturtevant
2019 J jnl
CoRR
Malte Helmert, Tor Lattimore, Levi H. S. Lelis, Laurent Orseau, Nathan R. Sturtevant
2019 B conf
SOCS
Roni Stern, Nathan R. Sturtevant, Ariel Felner, Sven Koenig, Hang Ma, Thayne T. Walker, Jiaoyang Li, Dor Atzmon, Liron Cohen, T. K. Satish Kumar, Roman Barták, Eli Boyarski
2019 J jnl
CoRR
Roni Stern, Nathan R. Sturtevant, Ariel Felner, Sven Koenig, Hang Ma, Thayne T. Walker, Jiaoyang Li, Dor Atzmon, Liron Cohen, T. K. Satish Kumar, Eli Boyarski, Roman Barták
2019 conf
ACG
Nathan R. Sturtevant
2019 A* conf
IJCAI
Eshed Shaham, Ariel Felner, Nathan R. Sturtevant, Jeffrey S. Rosenschein
2019 conf
AIIDE
Nathan R. Sturtevant, Devon Sigurdson, Bjorn Taylor, Tim Gibson
2019 C conf
CoG
Douglas Rebstock, Christopher Solinas, Michael Buro, Nathan R. Sturtevant
2019 J jnl
CoRR
Douglas Rebstock, Christopher Solinas, Michael Buro, Nathan R. Sturtevant
2019 B conf
SOCS
Jingwei Chen, Nathan R. Sturtevant, William J. Doyle, Wheeler Ruml
2019 B conf
SOCS
Thayne T. Walker, Nathan R. Sturtevant, Ariel Felner
2018 A* conf
AAAI
Nathan R. Sturtevant, Ariel Felner
2018 J jnl
AI Matters
Nathan R. Sturtevant
2018 B conf
SOCS
Daniel Brewer, Nathan R. Sturtevant
2018 conf
AIIDE
Nathan R. Sturtevant, Matheus Jun Ota
2018 A* conf
IJCAI
Thayne T. Walker, Nathan R. Sturtevant, Ariel Felner
2018 B conf
SOCS
Eshed Shaham, Ariel Felner, Nathan R. Sturtevant, Jeffrey S. Rosenschein
2018 B conf
SOCS
Liron Cohen, Glenn Wagner, David M. Chan, Howie Choset, Nathan R. Sturtevant, Sven Koenig, T. K. Satish Kumar
2018 A conf
AAMAS
Liron Cohen, Sven Koenig, T. K. Satish Kumar, Glenn Wagner, Howie Choset, David M. Chan, Nathan R. Sturtevant
2017 conf
CGW@IJCAI
Nathan R. Sturtevant, Abdallah Saffidine
2017 A* conf
IJCAI
Jingwei Chen, Robert C. Holte, Sandra Zilles, Nathan R. Sturtevant
2017 J jnl
CoRR
Jingwei Chen, Robert C. Holte, Sandra Zilles, Nathan R. Sturtevant
2017 J jnl
Artif. Intell.
Robert C. Holte, Ariel Felner, Guni Sharon, Nathan R. Sturtevant, Jingwei Chen
2017 B conf
SOCS
Malte Helmert, Nathan R. Sturtevant, Ariel Felner
2017 J jnl
AI Mag.
Monica Anderson, Roman Barták, John S. Brownstein, David L. Buckeridge, Hoda Eldardiry, Christopher W. Geib, Maria L. Gini, Aaron Isaksen, Sarah Keren, Robert Laddaga, Viliam Lisý, Rodney Martin, David R. Martinez, Martin Michalowski, Loizos Michael, Reuth Mirsky, Thanh Hai Nguyen, Michael J. Paul, Enrico Pontelli, Scott Sanner, Arash Shaban-Nejad, Arunesh Sinha, Shirin Sohrabi, Kumar Sricharan, Biplav Srivastava, Mark Stefik, William W. Streilein, Nathan R. Sturtevant, Kartik Talamadupula, Michael Thielscher, Julian Togelius, Tran Cao Son, Long Tran-Thanh, Neal Wagner, Byron C. Wallace, Szymon Wilk, Jichen Zhu
2017 B conf
SOCS
Ariel Felner, Roni Stern, Solomon Eyal Shimony, Eli Boyarski, Meir Goldenberg, Guni Sharon, Nathan R. Sturtevant, Glenn Wagner, Pavel Surynek
2017 A* conf
ICAPS
Jürgen Eckerle, Jingwei Chen, Nathan R. Sturtevant, Sandra Zilles, Robert C. Holte
2017 B conf
SOCS
Eshed Shaham, Ariel Felner, Jingwei Chen, Nathan R. Sturtevant
2017 A* conf
AAAI
Nathan R. Sturtevant, Brian Magerko
2017 J jnl
AI Commun.
Meir Goldenberg, Ariel Felner, Alon Palombo, Nathan R. Sturtevant, Jonathan Schaeffer
2017 A* conf
ICAPS
Thayne T. Walker, David M. Chan, Nathan R. Sturtevant
2017 A* conf
AAAI
Nathan R. Sturtevant, Ariel Felner, Malte Helmert
2016 A* conf
AAAI
Robert C. Holte, Ariel Felner, Guni Sharon, Nathan R. Sturtevant
2016 A* conf
IJCAI
Nathan R. Sturtevant, Steve Rabin
2016 A* conf
AAAI
Steve Rabin, Nathan R. Sturtevant
2016 B conf
SOCS
Guni Sharon, Robert C. Holte, Ariel Felner, Nathan R. Sturtevant
2016 A* conf
IJCAI
Nathan R. Sturtevant, Jingwei Chen
2016 B conf
SOCS
Nathan R. Sturtevant
2016 J jnl
IEEE Trans. Comput. Intell. AI Games
Jochen Renz, Risto Miikkulainen, Nathan R. Sturtevant, Mark H. M. Winands
2016 ed.
AIIDE
Nathan R. Sturtevant, Brian Magerko
2016 J jnl
J. Artif. Intell. Res.
Nathan R. Sturtevant, Vadim Bulitko
2015 J jnl
AI Mag.
Robert Morris, Blai Bonet, Marc Cavazza, Marie desJardins, Ariel Felner, Nick Hawes, Brad Knox, Sven Koenig, George Dimitri Konidaris, Jérôme Lang, Carlos Linares López, Daniele Magazzeni, Amy McGovern, Sriraam Natarajan, Nathan R. Sturtevant, Michael Thielscher, William Yeoh, Sebastian Sardiña, Kiri Wagstaff
2015 conf
CGW/GIGA@IJCAI
Nathan R. Sturtevant
2015 J jnl
Artif. Intell.
Guni Sharon, Roni Stern, Ariel Felner, Nathan R. Sturtevant
2015 ed.
AIIDE
Arnav Jhala, Nathan R. Sturtevant
2015 B conf
SOCS
Nathan R. Sturtevant, Jason M. Traish, James R. Tulip, Tansel Uras, Sven Koenig, Ben Strasser, Adi Botea, Daniel Harabor, Steve Rabin
2014 A* conf
ICAPS
Richard Anthony Valenzano, Nathan R. Sturtevant, Jonathan Schaeffer, Fan Xie
2014 J jnl
J. Artif. Intell. Res.
Meir Goldenberg, Ariel Felner, Roni Stern, Guni Sharon, Nathan R. Sturtevant, Robert C. Holte, Jonathan Schaeffer
2014 B conf
SOCS
Levi H. S. Lelis, Roni Stern, Nathan R. Sturtevant
2014 B conf
SOCS
Nathan R. Sturtevant, Ariel Felner, Malte Helmert
2014 A* conf
AAAI
Guni Sharon, Ariel Felner, Nathan R. Sturtevant
2014 B conf
SOCS
Guni Sharon, Ariel Felner, Nathan R. Sturtevant
2014 J jnl
IEEE Trans. Comput. Intell. AI Games
Cameron Browne, Julian Togelius, Nathan R. Sturtevant
2014 J jnl
CoRR
Marc Lanctot, Mark H. M. Winands, Tom Pepels, Nathan R. Sturtevant
2014 conf
CIG
Marc Lanctot, Mark H. M. Winands, Tom Pepels, Nathan R. Sturtevant
2014 conf
AIIDE
Nathan R. Sturtevant, Jeff Orkin, Robert Zubek, Michael Cook, Stephen G. Ware, Christian Stith, Robert Michael Young, Phillip Wright, Squirrel (Brian) Eiserloh, Alejandro Ramirez-Sanabria, Vadim Bulitko, Kieran Lord
2014 B conf
SOCS
Nathan R. Sturtevant, Vadim Bulitko
2014 J jnl
AI Commun.
Daniel Borrajo, Ariel Felner, Richard E. Korf, Maxim Likhachev, Carlos Linares López, Wheeler Ruml, Nathan R. Sturtevant
2014 J jnl
AI Mag.
Nathan R. Sturtevant
2014 A* conf
AAAI
Richard Anthony Valenzano, Nathan R. Sturtevant, Jonathan Schaeffer
2013 A conf
AAMAS
Duane Szafron, Richard G. Gibson, Nathan R. Sturtevant
2013 conf
AI in the Game Design Process @ AIIDE
Nathan R. Sturtevant
2013 conf
SARA
Nathan R. Sturtevant
2013 B conf
SOCS
Faten Aljalaud, Nathan R. Sturtevant
2013 conf
AIIDE
Nathan R. Sturtevant
2013 A* conf
IJCAI
Nathan R. Sturtevant, Matthew J. Rutherford
2013 C ed.
MIG
Rachel McDonnell, Nathan R. Sturtevant, Victor B. Zordan
2013 B conf
SOCS
Guni Sharon, Nathan R. Sturtevant, Ariel Felner
2013 B conf
SOCS
Meir Goldenberg, Ariel Felner, Nathan R. Sturtevant, Robert C. Holte, Jonathan Schaeffer
2013 conf
AAAI (Late-Breaking Developments)
Guni Sharon, Ariel Felner, Roni Stern, Nathan R. Sturtevant
2013 A* conf
IJCAI
D. Chris Rayner, Nathan R. Sturtevant, Michael Bowling
2013 conf
CGW@IJCAI
Max Roschke, Nathan R. Sturtevant
2013 A* conf
ICAPS
Richard Anthony Valenzano, Shahab Jabbari Arfaee, Jordan Tyler Thayer, Roni Stern, Nathan R. Sturtevant
2012 A conf
ECAI
Richard Anthony Valenzano, Hootan Nakhost, Martin Müller, Jonathan Schaeffer, Nathan R. Sturtevant
2012 J jnl
IEEE Trans. Comput. Intell. AI Games
Nathan R. Sturtevant
2012 A* conf
AAAI
Guni Sharon, Roni Stern, Ariel Felner, Nathan R. Sturtevant
2012 conf
MAPF@AAAI
Guni Sharon, Roni Stern, Ariel Felner, Nathan R. Sturtevant
2012 B conf
SOCS
Guni Sharon, Roni Stern, Ariel Felner, Nathan R. Sturtevant
2012 A* conf
AAAI
Nathan R. Sturtevant, Ariel Felner, Maxim Likhachev, Wheeler Ruml
2012 B conf
SOCS
Guni Sharon, Roni Stern, Ariel Felner, Nathan R. Sturtevant
2012 C conf
MIG
Nathan R. Sturtevant
2012 ed.
MAPF@AAAI
Ariel Felner, Nathan R. Sturtevant, Kostas E. Bekris, Roni Stern
2012 A* conf
AAAI
Ariel Felner, Meir Goldenberg, Guni Sharon, Roni Stern, Tal Beja, Nathan R. Sturtevant, Jonathan Schaeffer, Robert Holte
2012 B conf
SOCS
Ariel Felner, Meir Goldenberg, Guni Sharon, Roni Stern, Tal Beja, Nathan R. Sturtevant, Robert Holte, Jonathan Schaeffer
2012 B ed.
SOCS
Daniel Borrajo, Ariel Felner, Richard E. Korf, Maxim Likhachev, Carlos Linares López, Wheeler Ruml, Nathan R. Sturtevant
2012 J jnl
AI Mag.
Vadim Bulitko, Mark O. Riedl, Arnav Jhala, Michael Buro, Nathan R. Sturtevant
2012 J jnl
AI Mag.
Vikas Agrawal, Jorge A. Baier, Kostas E. Bekris, Yiling Chen, Artur S. d'Avila Garcez, Pascal Hitzler, Patrik Haslum, Dietmar Jannach, Edith Law, Freddy Lécué, Luís C. Lamb, Cynthia Matuszek, Héctor Palacios, Biplav Srivastava, Lokendra Shastri, Nathan R. Sturtevant, Roni Stern, Stefanie Tellex, Stavros Vassos
2011 conf
AIIDE
Matthew Church, Eric Graves, Jason Duncan, Adel Lari, Robin Miller, Neesha Desai, Richard Zhao, Mike Carbonaro, Jonathan Schaeffer, Nathan R. Sturtevant, Duane Szafron
2011 J jnl
Künstliche Intell.
Mesut Kirci, Nathan R. Sturtevant, Jonathan Schaeffer
2011 B conf
SOCS
Mokhtar M. Khorshid, Robert C. Holte, Nathan R. Sturtevant
2011 conf
AIIDE
Nathan R. Sturtevant
2011 B conf
SOCS
Nathan R. Sturtevant
2011 A* conf
AAAI
D. Chris Rayner, Michael H. Bowling, Nathan R. Sturtevant
2011 J jnl
Artif. Intell.
Ariel Felner, Uzi Zahavi, Robert Holte, Jonathan Schaeffer, Nathan R. Sturtevant, Zhifu Zhang
2011 conf
CIG
Greg Ashe, Nathan R. Sturtevant, Jong-Hwan Kim
2011 A* conf
IJCAI
Nathan R. Sturtevant, Vadim Bulitko
2011 A* conf
AAAI
Meir Goldenberg, Nathan R. Sturtevant, Ariel Felner, Jonathan Schaeffer
2011 B conf
SOCS
Meir Goldenberg, Nathan R. Sturtevant, Ariel Felner, Jonathan Schaeffer
2010 conf
AIIDE
Nathan R. Sturtevant, Robert Geisberger
2010 C conf
FDG
Daniel Wong, Darren Earl, Fred Zyda, Ryan Zink, Sven Koenig, Allen Pan, Selby Shlosberg, Jaspreet Singh, Nathan R. Sturtevant
2010 A conf
AAMAS
Nathan R. Sturtevant, Vadim Bulitko, Yngvi Björnsson
2010 B conf
SOCS
Meir Goldenberg, Ariel Felner, Nathan R. Sturtevant, Jonathan Schaeffer
2010 B ed.
SOCS
Ariel Felner, Nathan R. Sturtevant
2010 A* conf
ICAPS
Richard Anthony Valenzano, Nathan R. Sturtevant, Jonathan Schaeffer, Karen Buro, Akihiro Kishimoto
2010 B conf
SOCS
Richard Anthony Valenzano, Nathan R. Sturtevant, Jonathan Schaeffer, Karen Buro, Akihiro Kishimoto
2010 A* conf
AAAI
Ariel Felner, Carsten Moldenhauer, Nathan R. Sturtevant, Jonathan Schaeffer
2010 B conf
SOCS
Carsten Moldenhauer, Ariel Felner, Nathan R. Sturtevant, Jonathan Schaeffer
2010 A* conf
AAAI
Jeffrey Richard Long, Nathan R. Sturtevant, Michael Buro, Timothy Furtak
2009 A* conf
IJCAI
Zhifu Zhang, Nathan R. Sturtevant, Robert C. Holte, Jonathan Schaeffer, Ariel Felner
2009 conf
SARA
Ariel Felner, Nathan R. Sturtevant
2009 A* conf
IJCAI
Carsten Moldenhauer, Nathan R. Sturtevant
2009 A* conf
IJCAI
Michael Buro, Jeffrey Richard Long, Timothy Furtak, Nathan R. Sturtevant
2009 A* conf
ICML
Barnabás Póczos, Yasin Abbasi-Yadkori, Csaba Szepesvári, Russell Greiner, Nathan R. Sturtevant
2009 A* conf
IJCAI
Nathan R. Sturtevant, Ariel Felner, Max Barer, Jonathan Schaeffer, Neil Burch
2009 conf
AAMAS (2)
Carsten Moldenhauer, Nathan R. Sturtevant
2009 conf
AIIDE
Nathan R. Sturtevant
2009 A* conf
IJCAI
Yngvi Björnsson, Vadim Bulitko, Nathan R. Sturtevant
2008 conf
AAMAS (3)
M. Renee Jansen, Nathan R. Sturtevant
2008 J jnl
ICGA J.
Nathan R. Sturtevant
2008 conf
Computers and Games
Nathan R. Sturtevant
2008 conf
AIIDE
M. Renee Jansen, Nathan R. Sturtevant
2008 A conf
SIGCSE
Nathan R. Sturtevant, H. James Hoover, Jonathan Schaeffer, Sean Gouglas, Michael H. Bowling, Finnegan Southey, Matthew Bouchard, Ghassan Zabaneh
2008 conf
AAMAS (3)
Akihiro Kishimoto, Nathan R. Sturtevant
2007 conf
SARA
Nathan R. Sturtevant, M. Renee Jansen
2007 J jnl
J. Artif. Intell. Res.
Vadim Bulitko, Nathan R. Sturtevant, Jieshan Lu, Timothy Yau
2007 A* conf
AAAI
Uzi Zahavi, Ariel Felner, Jonathan Schaeffer, Nathan R. Sturtevant
2007 conf
AIIDE
Nathan R. Sturtevant
2006 conf
Computers and Games
Nathan R. Sturtevant, Adam M. White
2006 conf
AIIDE
Nathan R. Sturtevant, Michael Buro
2006 conf
ACG
Yngvi Björnsson, Jonathan Schaeffer, Nathan R. Sturtevant
2006 A* conf
AAAI
Nathan R. Sturtevant, Martin Zinkevich, Michael H. Bowling
2006 A conf
AAMAS
Nathan R. Sturtevant, Michael H. Bowling
2005 conf
SARA
Nathan R. Sturtevant, Vadim Bulitko, Michael Buro
2005 A* conf
IJCAI
Nathan R. Sturtevant
2005 A* conf
AAAI
Nathan R. Sturtevant, Michael Buro
2005 A* conf
AAAI
Vadim Bulitko, Nathan R. Sturtevant, Maryia Kazakevich
2004 conf
Computers and Games
Nathan R. Sturtevant
2003 A* conf
IJCAI
Nathan R. Sturtevant
2002 conf
Computers and Games
Nathan R. Sturtevant
2000 conf
AAAI/IAAI
Nathan R. Sturtevant, Richard E. Korf
redb/extractors/decompiler/bninja/analysis/low_level.py
← Index redb/extractors/decompiler/bninja/analysis/low_level.py python
import time

from binaryninja import (
    LowLevelILInstruction,
)
from binaryninja import (
    LowLevelILOperation as LLIL_OP,
)
from binaryninja.lowlevelil import (
    LowLevelILAdd,
    LowLevelILConst,
    LowLevelILConstPtr,
    LowLevelILLoad,
    LowLevelILLsl,
    LowLevelILMul,
    LowLevelILPop,
    LowLevelILPush,
    LowLevelILReg,
    LowLevelILStore,
    LowLevelILSub,
)

# Support both package and standalone imports
try:
    from ..function_type import FunctionTypeAnalysis
    from ..similarity.minhasher import MinHasher, TokenKind
    from ..utils.hashes import calculate_sha256, calculate_tlsh
    from .low_level_normalization import LowLevelNormalization

except ImportError:
    # Fallback to absolute imports (for multiprocessing spawned processes)
    from redb.extractors.decompiler.bninja.analysis.low_level_normalization import LowLevelNormalization
    from redb.extractors.decompiler.bninja.similarity.minhasher import MinHasher
    from redb.extractors.decompiler.bninja.function_type import FunctionTypeAnalysis
    from redb.extractors.decompiler.bninja.utils.hashes import calculate_sha256, calculate_tlsh

class LowLevelAnalysis:
    def __init__(self, function, bv, logger):
        self.function = function
        self.name = function.name
        self.start = function.start
        self.llil_func = function.llil
        self.bv = bv
        self.logger = logger
        self.errors = []

    def log_error(
        self, message, function_name, address, exception=None, error_location="unknown"
    ):
        """Log an error during processing."""
        error_msg = f"Error in function {function_name} at {address}: {message}"
        if exception:
            error_msg += f" - {str(exception)}"
        self.logger.error(error_msg)

        # Add to errors list
        error = {
            "function_name": function_name,
            "function_address": str(address),
            "error_location": error_location,
            "error_message": message,
            "error_details": str(exception) if exception else "",
            "error_type": type(exception).__name__ if exception else "Unknown",
            "timestamp": int(time.time() * 1000),
        }
        self.errors.append(error)

    def count_control_flow_instructions(self):
        if self.llil_func is None:
            return 0

        count = 0
        for basic_block in self.llil_func.basic_blocks:
            for ins in basic_block:
                op = ins.operation
                if op in (
                    LLIL_OP.LLIL_IF,
                    LLIL_OP.LLIL_GOTO,
                    LLIL_OP.LLIL_JUMP,
                    LLIL_OP.LLIL_JUMP_TO,
                    LLIL_OP.LLIL_CALL,
                    LLIL_OP.LLIL_CALL_SSA,
                ):
                    count += 1

        return count

    def collect_memory_patterns(self):
        """ """
        patterns = set()

        try:
            llil = self.llil_func
            arch = self.bv.arch
            sp_name = arch.stack_pointer if arch and arch.stack_pointer else "sp"

            def analyze_addr(addr_expr, might_be_direct):
                """
                Visit the expression for the address and understand whether it has a direct, scaled, base offset, etc.
                access to memory
                """
                found = {
                    "direct": False,
                    "scaled": False,
                    "base_off": False,
                    "stack": False,
                    "string": False,
                }

                def addr_cb(n):
                    # stack (SP/BP-like)
                    match n:
                        case LowLevelILReg(src=reg):
                            if reg == sp_name:
                                found["stack"] = True

                        case LowLevelILConst() | LowLevelILConstPtr():
                            if might_be_direct:
                                found["direct"] = True

                        # base +/- const
                        case (
                            LowLevelILAdd(left=l, right=r)
                            | LowLevelILSub(left=l, right=r)
                        ):
                            l_is_reg = isinstance(l, LowLevelILReg)
                            r_is_reg = isinstance(r, LowLevelILReg)
                            l_is_cst = isinstance(
                                l, (LowLevelILConst, LowLevelILConstPtr)
                            )
                            r_is_cst = isinstance(
                                r, (LowLevelILConst, LowLevelILConstPtr)
                            )
                            if (l_is_reg and r_is_cst) or (r_is_reg and l_is_cst):
                                found["base_off"] = True

                        # scaled index (index*scale) or shift (index << k)
                        case LowLevelILMul(left=l, right=r):
                            if (
                                isinstance(l, LowLevelILReg)
                                and isinstance(r, LowLevelILConst)
                            ) or (
                                isinstance(r, LowLevelILReg)
                                and isinstance(l, LowLevelILConst)
                            ):
                                found["scaled"] = True

                        case LowLevelILLsl(left, right):
                            if isinstance(left, LowLevelILReg) and isinstance(
                                right, LowLevelILConst
                            ):
                                found["scaled"] = True

                    return None

                _ = list(addr_expr.traverse(addr_cb))

                if found["direct"]:
                    patterns.add("MEM_DIRECT")
                if found["scaled"]:
                    patterns.add("MEM_SCALED_INDEX")
                if found["base_off"]:
                    patterns.add("MEM_BASE_OFFSET")
                if found["stack"]:
                    patterns.add("MEM_STACK")
                elif found["string"]:
                    patterns.add("MEM_STRING")

            def func_cb(i):
                match i:
                    case LowLevelILPush(src=addr):
                        analyze_addr(addr, False)
                    case LowLevelILPop(src=addr):
                        analyze_addr(addr, False)
                    case LowLevelILLoad(src=addr):
                        analyze_addr(addr, True)
                    case LowLevelILStore(dest=addr, src=_):
                        analyze_addr(addr, True)

                return None

            # complete visit for the single instruction
            _ = list(llil.traverse(func_cb))

            return sorted(patterns)

        except Exception as e:
            self.log_error(
                "Failed to collect memory patterns via LLIL.traverse",
                self.name,
                self.start,
                e,
                "collect_memory_patterns",
            )
            return []

    def collect_register_usage(self):
        """
        Collect frequencies for register usage
        """
        try:
            llil = self.llil_func

            register_usage = {}

            def inc(reg, kind):
                if reg is None:
                    return
                entry = register_usage.setdefault(reg, {"reads": 0, "writes": 0})
                entry[kind] += 1

            if not llil:
                return {}, 0, 0

            for top_il in llil.instructions:
                registers_read = self.function.get_regs_read_by(
                    top_il.address, self.bv.arch
                )
                registers_write = self.function.get_regs_written_by(
                    top_il.address, self.bv.arch
                )

                for reg_read in registers_read:
                    inc(reg_read, "reads")

                for reg_write in registers_write:
                    inc(reg_write, "writes")

            total_reads = sum(entry["reads"] for entry in register_usage.values())
            total_writes = sum(entry["writes"] for entry in register_usage.values())

            return register_usage, total_reads, total_writes

        except Exception as e:
            self.log_error(
                "Failed to collect register usage via LLIL.traverse",
                self.name,
                self.start,
                e,
                "collect_register_usage",
            )
            return {}, 0, 0

    def _classify_address(self, bv, addr):
        """
        Classification of the address
        """
        info = {
            "address": addr,
            "section": None,
            "segment_writable": None,
            "symbol": None,
            "kind": None,  # "string", "function_ptr", "data_var", "symbol", "unknown"
            "datatype": None,  # es. "char *", "int32_t", "my_struct", ...
            "note": None,
        }

        # section / segment
        sec = bv.get_section_at(addr)
        seg = bv.get_segment_at(addr)
        if sec:
            info["section"] = sec.name
        if seg:
            info["segment_writable"] = bool(seg.writable)

        sym = bv.get_symbol_at(addr)
        if sym:
            info["symbol"] = sym.full_name

        # function pointer
        try:
            fns = list(bv.get_functions_at(addr))
        except Exception:
            # some versions have get_function_at(addr) that returns a single object or None
            fns = [bv.get_function_at(addr)] if hasattr(bv, "get_function_at") else []
        fns = [f for f in fns if f]
        if fns:
            info["kind"] = "function_ptr"
            info["datatype"] = "func"
            info["note"] = f"points to function {fns[0].name}"
            return info

        # string
        sref = bv.get_string_at(addr)
        if sref:
            info["kind"] = "string"
            # sref.type:
            info["datatype"] = (
                getattr(sref, "type", None).__class__.__name__
                if hasattr(sref, "type")
                else "string"
            )
            return info

        # data typed variable
        dv = bv.get_data_var_at(addr)
        if dv:
            info["kind"] = "data_var"
            info["datatype"] = str(dv.type) if getattr(dv, "type", None) else None
            if getattr(dv, "name", None):
                info["symbol"] = dv.name if not info["symbol"] else info["symbol"]
            return info

        # only symbol (no data var)
        if sym and not info["kind"]:
            info["kind"] = "symbol"
            return info

        # unknown
        info["kind"] = "unknown"
        return info

    def count_data_references(self):
        """Count the number of data references in a function using LLIL."""
        count = 0

        if self.llil_func is None:
            return 0

        try:
            # Iterate LLIL basic blocks and instructions
            for instr in self.llil_func.instructions:
                instr_str = str(instr)
                logged = False
                src = None

                # Check for constant dereferencing or symbolic refs
                if hasattr(instr, "src"):
                    src = instr.src
                    if isinstance(src, (LowLevelILConstPtr, LowLevelILConst)):
                        count += 1
                        logged = True

                if not logged and "_" in instr_str:
                    count += 1

                # If src is a pointer constant, check if it lands in a writable data segment
                if src is not None and isinstance(src, LowLevelILConstPtr):
                    addr = src.constant
                    segment = self.bv.get_segment_at(addr)
                    if segment and segment.writable:
                        count += 1

        except Exception as e:
            self.logger.warning(
                f"Failed to use LLIL for counting data references in "
                f"{self.name} at {self.start}: {e}"
            )
        return count

    def compute_num_calls(self):
        c = 0

        if not self.llil_func:
            return 0

        for instr in self.llil_func.instructions:
            if instr.operation in (LLIL_OP.LLIL_CALL, LLIL_OP.LLIL_TAILCALL):
                c += 1
        return c

    def compute_max_block_size(self):
        """Compute the maximum basic block size in a function."""
        if self.llil_func is None:
            return 0

        max_size = 0
        for block in self.llil_func.basic_blocks:
            try:
                # Count instructions in this block using the direct length approach
                # This avoids UTF-8 decoding issues entirely
                block_size = block.instruction_count
                max_size = max(max_size, block_size)
            except Exception as e:
                self.log_error(
                    f"[HandledError] computing max block size: {e}",
                    self.name,
                    self.start,
                    e,
                    "compute_max_block_size",
                )
        return max_size

    def estimate_stack_size(self):
        """Estimate the stack size used by a function."""
        try:
            # Binary Ninja provides a stack adjustment value for functions
            # Need to convert OffsetWithConfidence to a plain integer
            stack_adjust = self.function.stack_adjustment
            if hasattr(stack_adjust, "value"):  # Handle OffsetWithConfidence objects
                return stack_adjust.value
            return stack_adjust
        except Exception as e:
            self.log_error(
                "Failed to estimate stack size",
                self.name,
                self.start,
                e,
                "estimate_stack_size",
            )
            return -1

    def collect_instruction_types(self):
        def iter_llil_tree(root_il):
            stack = [root_il]
            while stack:
                il_single_op = stack.pop()
                if not isinstance(il_single_op, LowLevelILInstruction):
                    continue
                yield il_single_op
                for il_operand in il_single_op.operands:
                    if isinstance(il_operand, LowLevelILInstruction):
                        stack.append(il_operand)
                    elif isinstance(il_operand, (list, tuple)):
                        for sub in il_operand:
                            if isinstance(sub, LowLevelILInstruction):
                                stack.append(sub)

        type_frequencies = {}
        try:
            if self.llil_func is None:
                return type_frequencies

            il_func = self.llil_func

            for top_il in il_func.instructions:
                for il in iter_llil_tree(top_il):
                    op = getattr(il, "operation", None)
                    if op is None:
                        continue

                    category = str(op)

                    if category in type_frequencies:
                        type_frequencies[category] += 1
                    else:
                        type_frequencies[category] = 1

        except Exception as e:
            self.log_error(
                "Failed to collect LLIL instruction types",
               self.name,
                self.start,
                e,
                "collect_instruction_types_llil",
            )

        return type_frequencies

    def _collect_low_level_with_type(self):
        llil = self.llil_func
        if not llil:
            return [], []

        start = self.start

        low_level = LowLevelNormalization()

        instrs_with_addr = []

        for il in llil.instructions:
            norm = low_level.normalize_instr_with_operands(il)

            # Clamp negative offsets to 0 for UInt32 compatibility.
            # Negative offsets (instruction before function start) may occur with
            # overlapping functions or tail-calls in obfuscated/malware binaries.
            # Multiple instructions at offset 0 indicates this anomaly and can be
            # queried to identify such samples easily than by checking logs.
            # Triggered by 590ecad54cd9e1c8681509420ad56edde8b064ffbf884ce6cd8dd28eebb95ae1
            offset = il.address - start
            if offset < 0:
                offset = 0

            instrs_with_addr.append((offset, norm))

        return instrs_with_addr

    def _collect_low_level_and_with_addr(self):
        llil = self.llil_func
        if not llil:
            return [], []

        start = self.start

        low_level = LowLevelNormalization()

        instrs = []
        instrs_with_addr = []

        for il in llil.instructions:
            norm = low_level.normalize_instruction_all_levels(il)

            instrs.append(norm)

            # Clamp negative offsets to 0 for UInt32 compatibility.
            # Negative offsets (instruction before function start) may occur with
            # overlapping functions or tail-calls in obfuscated/malware binaries.
            # Multiple instructions at offset 0 indicates this anomaly and can be
            # queried to identify such samples easily than by checking logs.
            # Triggered by 590ecad54cd9e1c8681509420ad56edde8b064ffbf884ce6cd8dd28eebb95ae1
            offset = il.address - start
            if offset < 0:
                offset = 0

            instrs_with_addr.append((offset, norm))

        return instrs, instrs_with_addr


    def analyze(self):
        registers_uses, total_reads, total_written = self.collect_register_usage()
        instr_low_level, body_llil_vector = self._collect_low_level_and_with_addr()
        instr_low_level_str = str(instr_low_level)
        instructions_low_level = calculate_sha256(instr_low_level_str)
        instructions_low_level_tlsh = calculate_tlsh(instr_low_level_str)

        instr_typed_llil = self._collect_low_level_with_type()
        instr_typed_low_level_str = str(instr_typed_llil)
        instructions_typed_low_level = calculate_sha256(instr_typed_low_level_str)
        instructions_typed_low_level_tlsh = calculate_tlsh(instr_typed_low_level_str)

        seed = 0xdeadbeef
        minhash_llil_skeleton = MinHasher(seed, self.llil_func, TokenKind.LLIL).calculateMinHash()
        minhash_llil_typed = MinHasher(seed, self.llil_func, TokenKind.TYPED_LLIL).calculateMinHash()

        low_level_json = {
            "function_address": self.start,
            "function_type": FunctionTypeAnalysis(self.function)
            .get_function_type()
            .name,
            "body_llil_vector": body_llil_vector,
            "sha256_llil": instructions_low_level,
            "tlsh_llil": instructions_low_level_tlsh,
            "minhash_llil_skeleton": minhash_llil_skeleton,
            "instructions_types_llil": list(self.collect_instruction_types()),
            "instruction_typed_llil": instructions_typed_low_level,
            "tlsh_instruction_typed_llil": instructions_typed_low_level_tlsh,
            "minhash_llil_typed": minhash_llil_typed,
            "control_flow_count_llil": self.count_control_flow_instructions(),
            "memory_access_pattern_llil": self.collect_memory_patterns(),
            "register_usage": registers_uses,
            "total_reg_reads": total_reads,
            "total_reg_written": total_written,
            "data_references_count": self.count_data_references(),
            "max_block_size": self.compute_max_block_size(),
            "num_calls": self.compute_num_calls(),
            "stack_size": self.estimate_stack_size(),
        }

        return low_level_json, self.errors