Ranga Vemuri

284 papers A* 14A 44B 15C 33Misc 42Journal 36Unranked 98
YearRankTypeTitle / Venue / Authors
2025 conf
ISQED
Suriya Srinivasan, Andrew Jones, Cameron Hingson, Gannon Darrach, Ranga Vemuri
2024 conf
MWSCAS
Juneet Kumar Meka, Ranga Vemuri
2024 conf
MWSCAS
Haimanti Chakraborty, Ranga Vemuri
2024 Misc conf
VLSID
Nikhil Saxena, Ranga Vemuri
2024 conf
MWSCAS
Padmaja Bhamidipati, Ranga Vemuri
2024 Misc conf
VLSID
Juneet Kumar Meka, Satya AmarKant Marupureddy, Ranga Vemuri
2024 conf
ISVLSI
Padmaja Bhamidipati, Ranga Vemuri
2024 Misc conf
VLSID
Haimanti Chakraborty, Ranga Vemuri
2024 conf
ISQED
Haimanti Chakraborty, Ranga Vemuri
2024 J jnl
CoRR
Haimanti Chakraborty, Ranga Vemuri
2024 Misc conf
VLSID
Suriya Srinivasan, Ranga Vemuri
2023 Misc conf
VLSID
Padmaja Bhamidipati, Ranga Vemuri
2023 conf
ISQED
Juneet Kumar Meka, Ranga Vemuri
2023 conf
MWSCAS
Nikhil Saxena, Ranga Vemuri
2023 J jnl
IEEE Access
Nikhil Saxena, Ranga Vemuri
2023 Misc conf
VLSID
Suriya Srinivasan, Ranga Vemuri
2023 conf
MWSCAS
Kishore Pula, Aparajithan Nathamuni Venkatesan, Ram Venkat Narayanan, Sundarakumar Muthukumaran, Ranga Vemuri, John Marty Emmert
2023 conf
ISQED
Ram Venkat Narayanan, Aparajithan Nathamuni Venkatesan, Kishore Pula, Sundarakumar Muthukumaran, Ranga Vemuri
2023 J jnl
CoRR
Ram Venkat Narayanan, Aparajithan Nathamuni Venkatesan, Kishore Pula, Sundarakumar Muthukumaran, Ranga Vemuri
2023 conf
ISVLSI
Sundarakumar Muthukumaran, Aparajithan Nathamuni Venkatesan, Kishore Pula, Ram Venkat Narayanan, Ranga Vemuri, John Marty Emmert
2023 conf
MWSCAS
Haimanti Chakraborty, Ranga Vemuri
2023 Misc conf
VLSID
Aparajithan Nathamuni Venkatesan, Ram Venkat Narayanan, Kishore Pula, Sundarakumar Muthukumaran, Ranga Vemuri
2023 J jnl
CoRR
Aparajithan Nathamuni Venkatesan, Ram Venkat Narayanan, Kishore Pula, Sundarakumar Muthukumaran, Ranga Vemuri
2022 conf
iSES
Juneet Kumar Meka, Shrinidhi Venkatesh, Ranga Vemuri
2022 conf
ACM Great Lakes Symposium on VLSI
Khitam M. Alatoun, Ranga Vemuri
2022 ch.
Behavioral Synthesis for Hardware Security
Richa Agrawal, Ranga Vemuri
2022 conf
MWSCAS
Christopher Chuvalas, Ranga Vemuri
2022 C conf
VLSI-SoC
Christopher Chuvalas, Ranga Vemuri
2022 conf
ISVLSI
Nikhil Saxena, Ranga Vemuri
2022 C conf
ICCD
Suriya Srinivasan, Ranga Vemuri
2022 ch.
Behavioral Synthesis for Hardware Security
Mike Borowczak, Ranga Vemuri
2021 conf
MWSCAS
Carla Purdy, John Marty Emmert, Rashmi Jha, Ranga Vemuri
2021 C conf
ICCD
Khitam M. Alatoun, Shanmukha Murali Achyutha, Ranga Vemuri
2021 J jnl
IEEE Access
David M. Luria, Ranga Vemuri
2021 conf
iSES
Nikhil Saxena, Ram Venkat Narayanan, Juneet Kumar Meka, Ranga Vemuri
2021 conf
MWSCAS
Padmaja Bhamidipati, Shanmukha Murali Achyutha, Ranga Vemuri
2021 conf
ISVLSI
Subashree Raja, Padmaja Bhamidipati, Xiaobang Liu, Ranga Vemuri
2021 conf
ISQED
Khitam Alatoun, Bharath Shankaranarayanan, Shanmukha Murali Achyutha, Ranga Vemuri
2020 conf
MWSCAS
Yasaswy Kasarabada, Vaishali Muralidharan, Ranga Vemuri
2020 conf
ISQED
Suprajaa Tummala, Xiaobang Liu, Ranga Vemuri
2020 Misc conf
VLSID
Yasaswy Kasarabada, Ranga Vemuri
2019 Misc conf
VLSID
Richa Agrawal, Mike Borowczak, Ranga Vemuri
2019 J jnl
J. Electron. Test.
Richa Agrawal, Ranga Vemuri, Mike Borowczak
2019 conf
ISQED
Xiaobang Liu, Ranga Vemuri
2019 conf
ISVLSI
Yasaswy Kasarabada, Sudheer Ram Thulasi Raman, Ranga Vemuri
2019 conf
HOST
Suyuan Chen, Ranga Vemuri
2019 J jnl
IET Comput. Digit. Tech.
Mike Borowczak, Ranga Vemuri
2019 conf
MWSCAS
Harsh Vamja, Richa Agrawal, Ranga Vemuri
2019 J jnl
CoRR
Harsh Vamja, Richa Agrawal, Ranga Vemuri
2019 conf
ISQED
Yasaswy Kasarabada, Suyuan Chen, Ranga Vemuri
2019 conf
IFIPIoT
Yasaswy Kasarabada, David M. Luria, Ranga Vemuri
2018 C conf
ICCE
Ankita Manjunath Nayak, Ranga Vemuri
2018 Misc conf
VLSID
Xiaobang Liu, Ranga Vemuri
2018 conf
ISVLSI
Pranav Dharmadhikari, Akhilesh Raju, Ranga Vemuri
2018 conf
ISVLSI
Xiaobang Liu, Ranga Vemuri
2018 conf
ACM Great Lakes Symposium on VLSI
Suyuan Chen, Ranga Vemuri
2018 conf
HOST
Richa Agrawal, Ranga Vemuri
2018 C conf
VLSI-SoC
Suyuan Chen, Ranga Vemuri
2018 C conf
ICCE
Renuka Lokare, Ranga Vemuri
2018 C conf
ICCD
Suyuan Chen, Ranga Vemuri
2017 C conf
ICCD
Xiaobang Liu, Ranga Vemuri
2016 C conf
ICCD
Prabanjan Komari, Ranga Vemuri
2016 J jnl
Comput. J.
Haibo Yi, Shaohua Tang, Ranga Vemuri
2014 conf
ISVLSI
Mike Borowczak, Ranga Vemuri
2014 conf
SoCC
Ramesh Nair, Ranga Vemuri
2013 conf
SoCC
Venkat Krishnan Balasubramanian, Hao Xu, Ranga Vemuri
2013 conf
MWSCAS
Mike Borowczak, Ranga Vemuri
2012 conf
IPDPS Workshops
Aishwariya Pattabiraman, Annie Avakian, Ranga Vemuri
2012 conf
ARC
Annie Avakian, Natwar Agrawal, Ranga Vemuri
2012 conf
HOST
Lakshmi Narasimhan Ramakrishnan, Manoj Chakkaravarthy, Antarpreet Singh Manchanda, Mike Borowczak, Ranga Vemuri
2011 J jnl
IEEE Trans. Very Large Scale Integr. Syst.
Hao Xu, Wen-Ben Jone, Ranga Vemuri
2011 conf
SoCC
Amayika Panda, Annie Avakian, Ranga Vemuri
2011 J jnl
IEEE Trans. Very Large Scale Integr. Syst.
Hao Xu, Ranga Vemuri, Wen-Ben Jone
2010 conf
SoCC
Jon Nafziger, Annie Avakian, Ranga Vemuri
2010 conf
IPDPS Workshops
Annie Avakian, Jon Nafziger, Amayika Panda, Ranga Vemuri
2010 A conf
ICCAD
Hao Xu, Ranga Vemuri, Wen-Ben Jone
2010 Misc conf
VLSI Design
Hao Xu, Wen-Ben Jone, Ranga Vemuri
2010 A conf
ICCAD
Hao Xu, Wen-Ben Jone, Ranga Vemuri
2010 J jnl
J. Low Power Electron.
Hao Xu, Wen-Ben Jone, Ranga Vemuri
2009 A conf
DATE
Angan Das, Ranga Vemuri
2009 conf
ACM Great Lakes Symposium on VLSI
Balasubramanian Sethuraman, Ranga Vemuri
2009 C conf
ICCD
Romana Fernandes, Ranga Vemuri
2009 Misc conf
VLSI Design
Almitra Pradhan, Ranga Vemuri
2009 Misc conf
VLSI Design
Angan Das, Ranga Vemuri
2009 A conf
DATE
Hao Xu, Ranga Vemuri, Wen-Ben Jone
2009 A conf
ICCAD
Hao Xu, Ranga Vemuri, Wen-Ben Jone
2009 Misc conf
VLSI Design
Shubhankar Basu, Balaji Kommineni, Ranga Vemuri
2008 conf
EvoWorkshops
Angan Das, Ranga Vemuri
2008 conf
ACM Great Lakes Symposium on VLSI
Almitra Pradhan, Ranga Vemuri
2008 C conf
ISCAS
Angan Das, Ranga Vemuri
2008 A conf
ICCAD
Hao Xu, Wen-Ben Jone, Ranga Vemuri
2008 A conf
ISLPED
Hao Xu, Ranga Vemuri, Wen-Ben Jone
2008 A conf
DATE
Almitra Pradhan, Ranga Vemuri
2008 Misc conf
VLSI Design
Shubhankar Basu, Balaji Kommineni, Ranga Vemuri
2008 Misc conf
VLSI Design
Almitra Pradhan, Ranga Vemuri
2008 Misc conf
VLSI Design
Srividhya Rammohan, Vijay Sundaresan, Ranga Vemuri
2008 C conf
ICCD
Hao Xu, Ranga Vemuri, Wen-Ben Jone
2008 A* conf
DAC
Angan Das, Ranga Vemuri
2008 conf
ISQED
Shubhankar Basu, Balaji Kommineni, Ranga Vemuri
2007 Misc conf
VLSI Design
Balasubramanian Sethuraman, Ranga Vemuri
2007 C conf
ICMLA
Balaji Kommineni, Shubhankar Basu, Ranga Vemuri
2007 conf
VLSI-SoC (Selected Papers)
Almitra Pradhan, Ranga Vemuri
2007 conf
ISVLSI
Angan Das, Ranga Vemuri
2007 J jnl
CoRR
Jawad Khan, Ranga Vemuri
2007 Misc conf
VLSI Design
Huiying Yang, Ranga Vemuri
2007 C conf
ISCAS
Angan Das, Ranga Vemuri
2007 J jnl
CoRR
Raoul F. Badaoui, Ranga Vemuri
2007 A conf
ISLPED
Balasubramanian Sethuraman, Ranga Vemuri
2007 C conf
VLSI-SoC
Vijay Sundaresan, Srividhya Rammohan, Ranga Vemuri
2007 C conf
ICCD
Balasubramanian Sethuraman, Ranga Vemuri
2007 conf
ISQED
Shubhankar Basu, Priyanka Thakore, Ranga Vemuri
2007 conf
ISVLSI
Shubhankar Basu, Ranga Vemuri
2007 C conf
VLSI-SoC
Almitra Pradhan, Ranga Vemuri
2006 conf
ISVLSI
Vijay Sundaresan, Ranga Vemuri
2006 Misc conf
VLSI Design
Xin Jia, Ranga Vemuri
2006 Misc conf
VLSI Design
Mengmeng Ding, Ranga Vemuri
2006 A conf
DATE
Huiying Yang, Ranga Vemuri
2006 J jnl
IEEE Trans. Very Large Scale Integr. Syst.
Jawad Khan, Ranga Vemuri
2006 C conf
ISCAS
Mukesh Ranjan, Ranga Vemuri
2006 J jnl
Integr.
Nagu R. Dhanwada, Alex Doboli, Adrián Núñez-Aldana, Ranga Vemuri
2006 B conf
FPL
Balasubramanian Sethuraman, Ranga Vemuri
2006 Misc conf
VLSI Design
Amitava Bhaduri, Ranga Vemuri
2006 A conf
ICCAD
Xin Jia, Ranga Vemuri
2006 Misc conf
VLSI Design
Ritochit Chakraborty, Mukesh Ranjan, Ranga Vemuri
2006 conf
ACM Great Lakes Symposium on VLSI
Renqiu Huang, Ranga Vemuri
2006 A conf
DATE
Balasubramanian Sethuraman, Ranga Vemuri
2005 B conf
FPL
Xin Jia, Ranga Vemuri
2005 A conf
DATE
Mengmeng Ding, Ranga Vemuri
2005 A* conf
DAC
Mengmeng Ding, Ranga Vemuri
2005 conf
ACM Great Lakes Symposium on VLSI
Anuradha Agarwal, Glenn Wolfe, Ranga Vemuri
2005 Misc conf
VLSI Design
Mengmeng Ding, Ranga Vemuri
2005 A conf
DATE
Jawad Khan, Ranga Vemuri
2005 conf
ASP-DAC
Mengmeng Ding, Glenn Wolfe, Ranga Vemuri
2005 conf
ISCAS (6)
Raoul F. Badaoui, Ranga Vemuri
2005 A conf
IPDPS
Jawad Khan, Ranga Vemuri
2005 conf
ASP-DAC
Huiying Yang, Mukesh Ranjan, Wim Verhaegen, Mengmeng Ding, Ranga Vemuri, Georges G. E. Gielen
2005 B conf
FPL
Jawad Khan, Ranga Vemuri
2005 conf
ISVLSI
Huiying Yang, Anuradha Agarwal, Ranga Vemuri
2005 J jnl
Int. J. Embed. Syst.
Manish Handa, Ranga Vemuri
2005 A conf
ICCAD
Anuradha Agarwal, Ranga Vemuri
2005 A conf
DATE
Amitava Bhaduri, Ranga Vemuri
2005 C conf
ICCD
Anuradha Agarwal, Ranga Vemuri
2005 conf
ACM Great Lakes Symposium on VLSI
Balasubramanian Sethuraman, Prasun Bhattacharya, Jawad Khan, Ranga Vemuri
2005 conf
ACM Great Lakes Symposium on VLSI
Amitava Bhaduri, Ranga Vemuri
2005 A conf
DATE
Raoul F. Badaoui, Ranga Vemuri
2005 Misc conf
VLSI Design
Madhubanti Mukherjee, Ranga Vemuri
2005 Misc conf
VLSI Design
Renqiu Huang, Ranga Vemuri
2005 B conf
FPL
Renqiu Huang, Ranga Vemuri
2005 conf
ISVLSI
Renqiu Huang, Ranga Vemuri
2005 Misc conf
FCCM
Xin Jia, Ranga Vemuri
2005 conf
ASP-DAC
Xin Jia, Ranga Vemuri
2004 conf
ESA/VLSI
Xin Jia, Ranga Vemuri
2004 B conf
FPL
Xin Jia, Jayanthi Rajagopalan, Ranga Vemuri
2004 A conf
DATE
Manish Handa, Ranga Vemuri
2004 conf
ERSA
Jawad Khan, Jayanthi Rajagopalan, Renqiu Huang, Ranga Vemuri
2004 conf
ERSA
Jawad Khan, Balasubramanian Sethuraman, Ranga Vemuri
2004 conf
ACM Great Lakes Symposium on VLSI
Raoul F. Badaoui, Hemanth Sampath, Anuradha Agarwal, Ranga Vemuri
2004 J jnl
ACM Trans. Design Autom. Electr. Syst.
Alex Doboli, Nagu R. Dhanwada, Adrián Núñez-Aldana, Ranga Vemuri
2004 A conf
DATE
Anuradha Agarwal, Hemanth Sampath, Veena Yelamanchili, Ranga Vemuri
2004 A conf
ICCAD
Ranga Vemuri, Glenn Wolfe
2004 B conf
FPL
Jawad Khan, Ranga Vemuri
2004 B conf
FPL
Manish Handa, Ranga Vemuri
2004 A* conf
DAC
Manish Handa, Ranga Vemuri
2004 A conf
ICCAD
Renqiu Huang, Ranga Vemuri
2004 B conf
FPL
Renqiu Huang, Manish Handa, Ranga Vemuri
2004 conf
ERSA
Manish Handa, Ranga Vemuri
2004 conf
SoCC
Balasubramanian Sethuraman, Jawad Khan, Ranga Vemuri
2004 A* conf
DAC
Anuradha Agarwal, Hemanth Sampath, Veena Yelamanchili, Ranga Vemuri
2004 A conf
DATE
Mukesh Ranjan, Wim Verhaegen, Anuradha Agarwal, Hemanth Sampath, Ranga Vemuri, Georges G. E. Gielen
2004 A conf
IPDPS
Renqiu Huang, Ranga Vemuri
2004 A conf
IPDPS
Manish Handa, Ranga Vemuri
2004 C conf
ICCD
Madhubanti Mukherjee, Ranga Vemuri
2003 Misc conf
VLSI Design
Manish Handa, Rajesh Radhakrishnan, Madhubanti Mukherjee, Ranga Vemuri
2003 C conf
ICCD
Madhubanti Mukherjee, Ranga Vemuri
2003 C conf
VLSI-SOC
Glenn Wolfe, Mengmeng Ding, Ranga Vemuri
2003 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Alex Doboli, Ranga Vemuri
2003 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Alex Doboli, Ranga Vemuri
2003 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Glenn Wolfe, Ranga Vemuri
2003 C conf
VLSI-SOC
Hemanth Sampath, Ranga Vemuri
2002 A conf
DATE
Alex Doboli, Ranga Vemuri
2002 J jnl
ACM Trans. Design Autom. Electr. Syst.
Ranga Vemuri, Srinivas Katkoori, Meenakshi Kaul, Jay Roy
2002 conf
ASP-DAC/VLSI Design
Srinivasan Dasasathyan, Rajesh Radhakrishnan, Ranga Vemuri
2002 J jnl
IEEE Trans. Very Large Scale Integr. Syst.
Karam S. Chatha, Ranga Vemuri
2002 B conf
FPL
Jawad Khan, Manish Handa, Ranga Vemuri
2001 A conf
DATE
Alex Doboli, Ranga Vemuri
2001 conf
ARVLSI
Sree Ganesan, Ranga Vemuri
2001 Misc conf
VLSI Design
Sujatha Sundararaman, Sriram Govindarajan, Ranga Vemuri
2001 A* conf
DAC
Sree Ganesan, Ranga Vemuri
2001 A conf
IPDPS
Yi Pan, Jie Li, Ranga Vemuri
2001 J jnl
IEEE Trans. Very Large Scale Integr. Syst.
V. Srinivasan, Sriram Govindarajan, Ranga Vemuri
2001 A conf
IPDPS
Iyad Ouaiss, Ranga Vemuri
2001 J jnl
IEEE Trans. Very Large Scale Integr. Syst.
Ranga Vemuri, Rajesh K. Gupta
2001 A conf
DATE
Iyad Ouaiss, Ranga Vemuri
2001 conf
ISCAS (5)
Alex Doboli, Ranga Vemuri
2001 A* conf
DAC
Alex Doboli, Ranga Vemuri
2001 Misc conf
VLSI Design
Sree Ganesan, Ranga Vemuri
2001 conf
CODES
Karam S. Chatha, Ranga Vemuri
2001 B conf
FPL
Amit Kasat, Iyad Ouaiss, Ranga Vemuri
2001 A conf
DATE
Elena Teica, Rajesh Radhakrishnan, Ranga Vemuri
2001 J jnl
Formal Methods Syst. Des.
Naren Narasimhan, Elena Teica, Rajesh Radhakrishnan, Sriram Govindarajan, Ranga Vemuri
2001 conf
CHARME
Rajesh Radhakrishnan, Elena Teica, Ranga Vemuri
2000 Misc conf
VLSI Design
Sriram Govindarajan, Vinoo Srinivasan, Preetham Lakshmikanthan, Ranga Vemuri
2000 C conf
ISCAS
Alex Doboli, Nagu R. Dhanwada, Ranga Vemuri
2000 A conf
DATE
Satish Ganesan, Ranga Vemuri
2000 J jnl
Des. Autom. Embed. Syst.
Karam S. Chatha, Ranga Vemuri
2000 conf
HLDVT
Rajesh Radhakrishnan, Elena Teica, Ranga Vemuri
2000 J jnl
Formal Methods Syst. Des.
Nazanin Mansouri, Ranga Vemuri
2000 conf
IPDPS Workshops
Preetham Lakshmikanthan, Sriram Govindarajan, Vinoo Srinivasan, Ranga Vemuri
2000 J jnl
Computer
Ranga Vemuri, Randolph E. Harr
2000 J jnl
J. VLSI Signal Process.
Meenakshi Kaul, Ranga Vemuri
2000 A conf
DATE
Iyad Ouaiss, Ranga Vemuri
2000 Misc conf
VLSI Design
Abhijit Ghosh, Ranga Vemuri
2000 A conf
DATE
Sriram Govindarajan, Ranga Vemuri
2000 C conf
ISCAS
Srinivas Katkoori, Ranga Vemuri
2000 A conf
DATE
Sree Ganesan, Ranga Vemuri
2000 B conf
FPL
Sriram Govindarajan, Ranga Vemuri
2000 conf
BMAS
Alex Doboli, Ranga Vemuri
1999 conf
VLSI
Alex Doboli, Ranga Vemuri
1999 conf
VLSI
Adrián Núñez-Aldana, Ranga Vemuri
1999 C conf
ICCD
Sree Ganesan, Ranga Vemuri
1999 A conf
DATE
Alex Doboli, Ranga Vemuri
1999 conf
ISCAS (6)
Nagu R. Dhanwada, Adrián Núñez-Aldana, Ranga Vemuri
1999 A conf
DATE
Nazanin Mansouri, Ranga Vemuri
1999 conf
Great Lakes Symposium on VLSI
Srinivas Katkoori, Ranga Vemuri
1999 A conf
DATE
Adrián Núñez-Aldana, Ranga Vemuri
1999 A* conf
DAC
Meenakshi Kaul, Ranga Vemuri, Sriram Govindarajan, Iyad Ouaiss
1999 C conf
IEEE International Workshop on Rapid System Prototyping
Karam S. Chatha, Ranga Vemuri
1999 conf
ASP-DAC
Nagu R. Dhanwada, Adrián Núñez-Aldana, Ranga Vemuri
1999 A* conf
DAC
Alex Doboli, Adrián Núñez-Aldana, Nagu R. Dhanwada, Sree Ganesan, Ranga Vemuri
1999 Misc conf
VLSI Design
Nagu R. Dhanwada, Adrián Núñez-Aldana, Ranga Vemuri
1999 Misc conf
VLSI Design
Sree Ganesan, Ranga Vemuri
1999 C conf
ICCD
Abhijit Ghosh, Ranga Vemuri
1999 B conf
FPL
Karam S. Chatha, Ranga Vemuri
1999 A conf
DATE
Nagu R. Dhanwada, Adrián Núñez-Aldana, Ranga Vemuri
1999 conf
Great Lakes Symposium on VLSI
Abhijit Ghosh, Sandeep K. Lodha, Ranga Vemuri
1999 conf
IPPS/SPDP Workshops
Meenakshi Kaul, Ranga Vemuri
1999 conf
IPPS/SPDP Workshops
Vinoo Srinivasan, Shankar Radhakrishnan, Ranga Vemuri, Jeffrey Walrath
1999 Misc conf
FCCM
Vinoo Srinivasan, Ranga Vemuri
1999 A conf
DATE
Meenakshi Kaul, Ranga Vemuri
1999 A conf
FPGA
Vinoo Srinivasan, Ranga Vemuri
1998 B conf
FMCAD
Nazanin Mansouri, Ranga Vemuri
1998 conf
IPPS/SPDP Workshops
Jeffrey Walrath, Ranga Vemuri
1998 Misc conf
VLSI Design
Vinoo Srinivasan, Ranga Vemuri
1998 conf
ISSS
Karam S. Chatha, Ranga Vemuri
1998 Misc conf
FCCM
Sriram Govindarajan, Iyad Ouaiss, Meenakshi Kaul, Vinoo Srinivasan, Ranga Vemuri
1998 conf
IPPS/SPDP Workshops
Iyad Ouaiss, Sriram Govindarajan, Vinoo Srinivasan, Meenakshi Kaul, Ranga Vemuri
1998 J jnl
VLSI Design
Srinivas Katkoori, Ranga Vemuri
1998 C conf
ICCD
Viresh Paruthi, Nazanin Mansouri, Ranga Vemuri
1998 Misc conf
VLSI Design
Nagu R. Dhanwada, Ranga Vemuri
1998 A conf
DATE
Vinoo Srinivasan, Shankar Radhakrishnan, Ranga Vemuri
1998 conf
TPHOLs
Naren Narasimhan, Ranga Vemuri
1998 A conf
DATE
Meenakshi Kaul, Ranga Vemuri
1998 C conf
International Workshop on Rapid System Prototyping
Karam S. Chatha, Ranga Vemuri
1998 conf
CODES
Karam S. Chatha, Ranga Vemuri
1998 C conf
ICCD
Naren Narasimhan, Elena Teica, Rajesh Radhakrishnan, Sriram Govindarajan, Ranga Vemuri
1997 conf
ASP-DAC
Natesan Venkateswaran, Anurag Gupta, Srinivas Katkoori, Dinesh Bhatia, Ranga Vemuri
1997 conf
ED&TC
Sriram Govindarajan, Ranga Vemuri
1997 C conf
ICCD
Sriram Govindarajan, Ranga Vemuri
1997 conf
ED&TC
Jeffrey Walrath, Ranga Vemuri, W. Bradley
1997 Misc conf
VLSI Design
Madhavi Vootukuru, Ranga Vemuri, Nand Kumar
1997 A* conf
DAC
Jeffrey Walrath, Ranga Vemuri
1996 Misc conf
VLSI Design
Srinivas Katkoori, Ranga Vemuri, Jay Roy
1996 conf
EURO-DAC
Vinoo Srinivasan, Nand Kumar, Ranga Vemuri
1996 J jnl
Computer
Ranga Vemuri, Ram Manday, Vijay Meduri
1996 conf
ASAP
Naren Narasimhan, Vinoo Srinivasan, Madhavi Vootukuru, Jeffrey Walrath, Sriram Govindarajan, Ranga Vemuri
1996 A conf
ISLPED
Srinivas Katkoori, Ranga Vemuri
1996 B conf
FMCAD
Naren Narasimhan, Ranga Vemuri
1996 Misc conf
VLSI Design
Naren Narasimhan, Ranga Vemuri, Jay Roy
1995 J jnl
IEEE Trans. Very Large Scale Integr. Syst.
Ranga Vemuri, R. Kalyanaraman
1995 C conf
ICCD
Srinivas Katkoori, Nand Kumar, Ranga Vemuri
1995 J jnl
IEEE Des. Test Comput.
Nand Kumar, Srinivas Katkoori, Leo Rader, Ranga Vemuri
1995 Misc conf
VLSI Design
William L. Bradley, Ranga Vemuri
1993 J jnl
Computer
Ranga Vemuri, Nand Kumar, Raghu Vutukuru, Prasad Subba Rao, Praveen Sinha, Ning Ren, Paddy Mamtora, Ram Mandayam, Ram Vemuri, Jayanta Roy
1993 A* conf
DAC
Ranga Vemuri, Paddy Mamtora, Praveen Sinha, Nand Kumar, Jayanta Roy, Raghu Vutukuru
1993 A* conf
DAC
Ram Mandayam, Ranga Vemuri
1993 conf
CHDL
Ram Mandayam, Ranga Vemuri
1992 J jnl
IEEE Des. Test Comput.
Jayanta Roy, Nand Kumar, Rajiv Dutta, Ranga Vemuri
1992 A* conf
DAC
Rajiv Dutta, Jayanta Roy, Ranga Vemuri
1992 conf
EURO-DAC
Nand Kumar, Ranga Vemuri
1991 conf
Great Lakes Symposium on VLSI
Ram Vemuri, Ranga Vemuri
1991 A* conf
CAV
Ranga Vemuri, Anuradha Sridhar
1990 conf
EURO-DAC
Ranga Vemuri
1986 A* conf
MICRO
Cris Koutsougeras, Christos A. Papachristou, Ranga Vemuri
1978 B conf
COMPSAC
Ranga Vemuri, J. V. Cornacchio
redb/extractors/decompiler/DecompileBinja.py
← Index redb/extractors/decompiler/DecompileBinja.py python
import hashlib
import inspect
import json
import logging
import os
import signal
import time
from datetime import datetime, timezone
from typing import Dict, Any, Optional
from pathlib import Path
import subprocess
import sys

from redb.extractors.enum import Tag
from redb.extractors.extractor import Extractor
import magic
import pefile
from elftools.elf.elffile import ELFFile

# Import our BinjaDecompiler (conditional)
from redb.extractors.decompiler.bninja.decompiler import BinaryNinjaDecompiler

class DecompileBinja(Extractor):
    def __init__(
        self,
        filepath,
        log,
        exporters=None,
        index_prefix=None,
        elastic_index=None,
        known_benign=False,
        known_malicious=False,
        filetype=None,
        decompile_modules=None,
    ):
        super().__init__(
            filepath,
            log,
            exporters,
            index_prefix,
            elastic_index,
            known_benign,
            known_malicious,
        )
        self.log.debug(inspect.currentframe().f_code.co_name)

        # Check if Binary Ninja is available
       # if not BINARYNINJA_AVAILABLE:
        #     self.log.error("Binary Ninja is not available in this container")
        #    raise ImportError(
        #        "Binary Ninja module not found - not available in feature extraction container"
        #    )
        self.analysis_results = None
        self.binja_decompiler = None
        self.filetype = filetype
        self.decompile_modules = decompile_modules or {"all"}
        self.goresym_data = None
        self.goresym_output_path = None

        # Convert TIMEOUT to integer with a default of 1200 seconds (20 minutes)
        try:
            self.BINJA_TIMEOUT = int(os.getenv("BINJA_TIMEOUT", "1200"))
        except ValueError:
            self.log.warning(
                "Invalid BINJA_TIMEOUT value, using default of 1200 seconds"
            )
            self.BINJA_TIMEOUT = 1200

        # Convert TIMEOUT to integer with a default of 1200 seconds (20 minutes)
        try:
            self.DECOMPILE_EXTRACTOR_TIMEOUT = int(
                os.getenv("DECOMPILE_EXTRACTOR_TIMEOUT", "2580")
            )
        except ValueError:
            self.log.warning(
                "Invalid DECOMPILE_EXTRACTOR_TIMEOUT value, using default of 2580 seconds"
            )
            self.DECOMPILE_EXTRACTOR_TIMEOUT = 2580

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.cleanup_run()

    def calculate_md5(self, input_str):
        """Calculate MD5 hash of a string."""
        return hashlib.md5(input_str.encode("utf-8")).hexdigest()

    def is_dotnet(self):
        """Check if the binary is a .NET assembly.

        Returns:
            bool: True if the file is a .NET assembly, False otherwise
        """
        try:
            if self.filetype == "pebin":
                file_type = magic.from_buffer(self.binary)
                if ".Net" in file_type:
                    return True
                pe = pefile.PE(self.filepath)
                for entry in pe.OPTIONAL_HEADER.DATA_DIRECTORY:
                    # IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR is typically 14
                    if (
                        entry.name == "IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR"
                        and entry.Size > 0
                    ):
                        return True
                return False
            return False
        except AttributeError as e:
            self.log.error(
                f"AttributeError error dotnet file {self.hash.sha256} Full error : {e}"
            )
            return False

    def is_golang(self):
        """Check if the binary is a Go-compiled binary (heuristic).

        Supports PE and ELF binaries.
        """
        try:
            if self.filetype == "pebin":
                pe = pefile.PE(self.filepath)
                signatures = [b"Go build ID:", b"runtime.main", b"main.main"]

                for section in pe.sections:
                    data = section.get_data()
                    if any(sig in data for sig in signatures):
                        return True

                return False

            elif self.filetype == "elf":
                with open(self.filepath, "rb") as f:
                    elf = ELFFile(f)

                    # 1. Section-based checks
                    section_names = [sec.name for sec in elf.iter_sections()]
                    if any(
                        s in section_names
                        for s in (".note.go.buildid", ".gopclntab")
                    ):
                        return True

                    # 2. String scan in loadable sections
                    signatures = [
                        b"Go build ID:",
                        b"runtime.main",
                        b"runtime.goexit",
                        b"runtime.morestack",
                        b"main.main",
                    ]

                    for sec in elf.iter_sections():
                        if sec["sh_flags"] & 0x2:  # SHF_ALLOC
                            data = sec.data()
                            if any(sig in data for sig in signatures):
                                return True

                return False

            return False

        except Exception as e:
            self.log.error(
                f"Golang detection error {self.hash.sha256}: {e}"
            )
            return False

    def cleanup_run(self):
        """Clean up after analysis."""
        try:
            # BinaryNinjaDecompiler uses context manager pattern (__enter__/__exit__)
            # Cleanup happens automatically when exiting the 'with' block
            self.binja_decompiler = None

            # Clean up goresym temp file if it exists (keep in debug mode)
            if self.goresym_output_path and os.path.exists(self.goresym_output_path):
                if self.log.isEnabledFor(logging.DEBUG):
                    self.log.debug(f"Debug mode: keeping goresym output at {self.goresym_output_path}")
                else:
                    os.remove(self.goresym_output_path)
                    self.goresym_output_path = None

            # Force garbage collection
            import gc

            gc.collect()

        except Exception as e:
            self.log.error(f"Error in cleanup: {e}")

    def run_goresym(self, binary_path, output_json_path):
        """
            Run goresym on a Go binary and export its JSON output to a file.
            binary_path: path to the Go binary to analyze
            output_json_path: path where the JSON output will be saved
            """
        binary_path = str(Path(binary_path).resolve())
        output_json_path = str(Path(output_json_path).resolve())
        goresym_path = os.getenv("GORESYM_PATH", "GoReSym")

        try:
            # Example: goresym -t json /path/to/binary
            self.log.info("DEBUG: starting GoReSym")
            result = subprocess.run(
                [goresym_path, binary_path],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True,
            )
        except FileNotFoundError:
            self.log.error("Error: 'goresym' not found in PATH. Make sure it is installed.")
            raise
        except subprocess.CalledProcessError as e:
            self.log.error("Error during goresym execution:")
            self.log.error(e.stderr)


        # Assuming goresym emits valid JSON to stdout.
        try:
            parsed = json.loads(result.stdout)
            # Store parsed JSON for later export to ClickHouse
            self.goresym_data = parsed
        except json.JSONDecodeError:
            # If it's not valid JSON, save the raw output instead.
            self.log.error("Warning: goresym output is not valid JSON; saving raw.")
            with open(output_json_path, "w", encoding="utf-8") as f:
                f.write(result.stdout)
            return

        # Save pretty-printed JSON for readability and debugging (used by BinaryNinja)
        with open(output_json_path, "w", encoding="utf-8") as f:
            json.dump(parsed, f, ensure_ascii=False, indent=2)
        self.goresym_output_path = output_json_path

        self.log.debug(f"goresym output saved to: {output_json_path}")

    def analyze_binary(self) -> Optional[Dict[str, Any]]:
        """Run Binary Ninja analysis and return results."""
        self.log.debug("Starting binary analysis")
        # if the binary is dotnet (only PE)
        if self.is_dotnet():
            self.log.debug("Skipping .NET binary - decompilation not supported")
            return None

        output_json_path = None
        ## if golang: run goresym
        try:
            if self.is_golang():
                output_json_path = "./goResym.json"
                self.run_goresym(self.filepath, output_json_path)
        except Exception as e:
            self.log.error(f"Error on GoReSym extraction: {e}")

        try:
            # Use BinaryNinjaDecompiler as a context manager to ensure proper setup/cleanup
            with BinaryNinjaDecompiler(
                filepath=self.filepath,
                timeout=self.BINJA_TIMEOUT,
                log=self.log,
                exporters=self.exporters,
                index_prefix=self.index_prefix,
                filetype=self.filetype,
                goresym=output_json_path,
                decompile_modules=self.decompile_modules,
            ) as decompiler:
                self.binja_decompiler = decompiler

                if decompiler.extract():
                    # Store results before context manager exits
                    results = decompiler.analysis_results
                    return results
                else:
                    self.log.error("BinaryNinjaDecompiler extraction failed")
                    return None

        except Exception as e:
            self.log.error(f"Error in Binary Ninja analysis: {e}")
            import traceback
            self.log.error(f"Traceback: {traceback.format_exc()}")
            return None

        finally:
            self.cleanup_run()

    def extract(self):
        """Extract and process all analysis results."""
        self.log.debug(inspect.currentframe().f_code.co_name)

        # Create a flag to track if extraction completed
        extraction_completed = False
        extraction_result = False
        extraction_error = None

        # Define the extraction process as a separate function
        def do_extraction():
            nonlocal extraction_completed, extraction_result, extraction_error
            try:
                results = self.analyze_binary()
                if not results:
                    extraction_result = False
                else:
                    self.analysis_results = results
                    # Add file hashes from parent Extractor class to analysis results
                    self.analysis_results["sha256"] = self.sha256
                    self.analysis_results["sha1"] = self.sha1
                    self.analysis_results["md5"] = self.md5
                    extraction_result = True
            except Exception as e:
                extraction_error = e
                extraction_result = False
            finally:
                extraction_completed = True

        # Run extraction directly with signal-based timeout (no thread overhead).
        # SIGALRM is delivered by the OS, so there's no GIL contention or polling.
        old_handler = signal.getsignal(signal.SIGALRM)
        def _timeout_handler(signum, frame):
            raise TimeoutError("Extraction timed out")

        signal.signal(signal.SIGALRM, _timeout_handler)
        signal.alarm(self.DECOMPILE_EXTRACTOR_TIMEOUT)
        try:
            do_extraction()
        except TimeoutError:
            self.log.error(
                f"Extraction timed out after {self.DECOMPILE_EXTRACTOR_TIMEOUT} seconds"
            )
            self.cleanup_run()
            return None
        finally:
            signal.alarm(0)
            signal.signal(signal.SIGALRM, old_handler)

        if extraction_error:
            self.log.error(f"Error in extraction: {extraction_error}")
            return None

        # Return the actual analysis results, not just a boolean
        return self.analysis_results if extraction_result else None

    def prepare_export_data(self, exporter_type: str) -> Any:
        """Prepare data for database export."""
        self.log.debug(inspect.currentframe().f_code.co_name)
        if not self.analysis_results:
            return None

        # # Delegate to the BinjaDecompiler for consistent export formatting
        # if self.binja_decompiler:
        #     return self.binja_decompiler.prepare_export_data(exporter_type)
        # else:
        #     self.log.error("BinjaDecompiler not available for export preparation")
        #     return None

        if exporter_type == "ClickHouseExporter":
            now = datetime.now(timezone.utc)

            def prepare_array_field(value, array_type):
                """Helper to prepare array fields with proper null handling"""
                if value is None:
                    return []
                return value

            # Add a helper function to handle empty strings
            def ensure_not_empty(value, default="UNKNOWN"):
                """Ensure a string value is not empty"""
                if value is None or value == "":
                    return default
                return value

            def prepare_register_usage_map(register_dict):
                """Convert register usage dict to Map format with tuples
                Input: {"rbx": {"reads": 3, "writes": 1}, ...}
                Output: {"rbx": (3, 1), ...}
                """
                if not register_dict:
                    return {}
                return {
                    reg: (info.get("reads", 0), info.get("writes", 0))
                    for reg, info in register_dict.items()
                }


            decompile_modules = getattr(self, "decompile_modules", {"all"})
            run_all = "all" in decompile_modules
            run_decompilation = run_all or "decompilation" in decompile_modules
            run_disassembly = run_all or "disassembly" in decompile_modules
            run_llil = run_all or "llil" in decompile_modules
            run_cfg = run_all or "cfg" in decompile_modules
            run_strings = run_all or "strings" in decompile_modules

            export = {"multi_table": True}

            # Decompilation tables
            if run_decompilation:
                export["decompiled_content"] = {
                    "table": "code_binja_decompiled_functions_content",
                    "data": [
                        [
                            f["decompiled_function_hash"],
                            f["decompiled_function"],
                            f["function_type"],
                            f.get("flattened_score"),
                            f.get("mba_score"),
                            now,
                        ]
                        for f in self.analysis_results["decompiled"]
                    ],
                    "column_names": [
                        "decompiled_function_hash",
                        "decompiled_function",
                        "function_type",
                        "flattened_score",
                        "mba_score",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "String",
                        "Enum8('USER'=1, 'LIBRARY'=2, 'THUNK'=3, 'EXTERNAL'=4, 'UNKNOWN'=5)",
                        "Nullable(Float64)",
                        "Nullable(Float64)",
                        "DateTime64(3, 'UTC')",
                    ],
                }
                export["decompiled_refs"] = {
                    "table": "code_binja_decompiled_functions_references",
                    "data": [
                        [
                            self.analysis_results["sha256"],
                            self.analysis_results["sha1"],
                            self.analysis_results["md5"],
                            f["decompiled_function_hash"],
                            f.get("disassembled_function_hash"),
                            f["decompiled_function_name"],
                            f["decompiled_function_prototype"],
                            f["decompiled_function_address"],
                            prepare_array_field(f.get("functions_caller"), "Array(String)"),
                            prepare_array_field(f.get("functions_call"), "Array(String)"),
                            now,
                        ]
                        for f in self.analysis_results["decompiled"]
                    ],
                    "column_names": [
                        "sha256",
                        "sha1",
                        "md5",
                        "decompiled_function_hash",
                        "disassembled_function_hash",
                        "decompiled_function_name",
                        "decompiled_function_prototype",
                        "decompiled_function_address",
                        "functions_caller",
                        "functions_call",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "FixedString(40)",
                        "FixedString(32)",
                        "FixedString(64)",
                        "Nullable(FixedString(64))",
                        "LowCardinality(String)",
                        "LowCardinality(String)",
                        "UInt64",
                        "Array(String)",
                        "Array(String)",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            # Disassembly tables
            if run_disassembly:
                export["disassembled_content"] = {
                    "table": "code_binja_disassembled_functions_content",
                    "data": [
                        [
                            f["disassembled_function_hash"],
                            f.get("disassembled_function", ""),
                            f.get("disassembled_function_no_addresses", ""),
                            f.get("function_type", "UNKNOWN"),
                            f.get("instructions_count", 0),
                            prepare_array_field(
                                f.get("instructions_types"), "LowCardinality(String)"
                            ),
                            f.get("control_flow_count", 0),
                            prepare_array_field(
                                f.get("memory_access_pattern"), "LowCardinality(String)"
                            ),
                            prepare_array_field(
                                f.get("register_usage"), "LowCardinality(String)"
                            ),
                            f.get("data_references_count", 0),
                            f.get("max_block_size"),
                            f.get("num_calls"),
                            f.get("stack_size"),
                            now,
                        ]
                        for f in self.analysis_results["disassembled"]
                    ],
                    "column_names": [
                        "disassembled_function_hash",
                        "disassembled_function",
                        "disassembled_function_no_addresses",
                        "function_type",
                        "instructions_count",
                        "instructions_types",
                        "control_flow_count",
                        "memory_access_pattern",
                        "register_usage",
                        "data_references_count",
                        "max_block_size",
                        "num_calls",
                        "stack_size",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "String",
                        "String",
                        "Enum8('USER'=1, 'LIBRARY'=2, 'THUNK'=3, 'EXTERNAL'=4, 'UNKNOWN'=5)",
                        "UInt32",
                        "Array(LowCardinality(String))",
                        "UInt32",
                        "Array(LowCardinality(String))",
                        "Array(LowCardinality(String))",
                        "UInt32",
                        "Nullable(UInt32)",
                        "Nullable(UInt32)",
                        "Nullable(Int32)",
                        "DateTime64(3, 'UTC')",
                    ],
                }
                export["disassembled_refs"] = {
                    "table": "code_binja_disassembled_functions_references",
                    "data": [
                        [
                            self.analysis_results["sha256"],
                            self.analysis_results["sha1"],
                            self.analysis_results["md5"],
                            f["disassembled_function_hash"],
                            f.get("decompiled_function_hash"),
                            f["disassembled_function_name"],
                            f["disassembled_function_address"],
                            f.get("tlsh_disassembly"),
                            f.get("tlsh_llil"),
                            now,
                        ]
                        for f in self.analysis_results["disassembled"]
                    ],
                    "column_names": [
                        "sha256",
                        "sha1",
                        "md5",
                        "disassembled_function_hash",
                        "decompiled_function_hash",
                        "disassembled_function_name",
                        "disassembled_function_address",
                        "tlsh_disassembly",
                        "tlsh_llil",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "FixedString(40)",
                        "FixedString(32)",
                        "FixedString(64)",
                        "Nullable(FixedString(64))",
                        "LowCardinality(String)",
                        "UInt64",
                        "Nullable(FixedString(72))",
                        "Nullable(FixedString(72))",
                        "DateTime64(3, 'UTC')",
                    ],
                }
                # Function similarity metrics table (derived from disassembly data)
                # Lookup maps to join LLIL/MLIL features by disassembled_function_hash
                llil_by_hash = {
                    l.get("disassembled_function_hash"): l
                    for l in self.analysis_results.get("llil", [])
                    if l and l.get("disassembled_function_hash")
                }
                mlil_by_hash = {
                    m.get("disassembled_function_hash"): m
                    for m in self.analysis_results.get("mlil", [])
                    if m and m.get("disassembled_function_hash")
                }

                export["function_similarity_metrics"] = {
                    "table": "code_binja_function_similarity_metrics",
                    "data": [
                        [
                            f["disassembled_function_hash"],
                            f.get("cyclomatic_complexity"),
                            f.get("tlsh_disassembly"),
                            f.get("tlsh_llil"),
                            prepare_array_field(f.get("minhash"), "Array(UInt8)"),
                            (llil_by_hash.get(f["disassembled_function_hash"]) or {}).get("tlsh_llil"),
                            (llil_by_hash.get(f["disassembled_function_hash"]) or {}).get(
                                "tlsh_instruction_typed_llil"),
                            prepare_array_field(
                                (llil_by_hash.get(f["disassembled_function_hash"]) or {}).get("minhash_llil_skeleton"),
                                "Array(UInt8)",
                            ),
                            prepare_array_field(
                                (llil_by_hash.get(f["disassembled_function_hash"]) or {}).get("minhash_llil_typed"),
                                "Array(UInt8)",
                            ),
                            (mlil_by_hash.get(f["disassembled_function_hash"]) or {}).get("tlsh_mlil_skeleton"),
                            (mlil_by_hash.get(f["disassembled_function_hash"]) or {}).get("tlsh_mlil_typed"),
                            prepare_array_field(
                                (mlil_by_hash.get(f["disassembled_function_hash"]) or {}).get("minhash_mlil_skeleton"),
                                "Array(UInt8)",
                            ),
                            prepare_array_field(
                                (mlil_by_hash.get(f["disassembled_function_hash"]) or {}).get("minhash_mlil_typed"),
                                "Array(UInt8)",
                            ),
                            now,
                        ]
                        for f in self.analysis_results.get("disassembled", [])
                    ],
                    "column_names": [
                        "disassembled_function_hash",
                        "cyclomatic_complexity",
                        "tlsh_disassembly",
                        "tlsh_llil",
                        "minhash",
                        "tlsh_llil_new",
                        "tlsh_instruction_typed_llil",
                        "minhash_llil_skeleton",
                        "minhash_llil_typed",
                        "tlsh_mlil_skeleton",
                        "tlsh_mlil_typed",
                        "minhash_mlil_skeleton",
                        "minhash_mlil_typed",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "Nullable(UInt16)",
                        "Nullable(FixedString(72))",
                        "Nullable(FixedString(72))",
                        "Array(UInt8)",
                        # new
                        "Nullable(FixedString(72))",
                        "Nullable(FixedString(72))",
                        "Array(UInt8)",
                        "Array(UInt8)",
                        "Nullable(FixedString(72))",
                        "Nullable(FixedString(72))",
                        "Array(UInt8)",
                        "Array(UInt8)",
                        "DateTime64(3, 'UTC')",
                    ],
                }


            # LLIL tables
            if run_llil:
                export["llil_content"] = {
                    "table": "code_binja_llil_functions_content",
                    "data": [
                        [
                            f["sha256_llil"],
                            f["function_type"],
                            prepare_array_field(
                                f.get("instructions_types_llil"), "LowCardinality(String)"
                            ),
                            f.get("control_flow_count_llil", 0),
                            prepare_array_field(
                                f.get("memory_access_pattern_llil"), "LowCardinality(String)"
                            ),
                            prepare_register_usage_map(f.get("register_usage", {})),
                            f.get("total_reg_reads", 0),
                            f.get("total_reg_written", 0),
                            f.get("data_references_count", 0),
                            f.get("max_block_size"),
                            f.get("num_calls"),
                            f.get("stack_size"),
                            prepare_array_field(f.get("body_llil_vector"), "Array(Tuple(UInt32, Array(UInt16)))"),
                            now,
                        ]
                        for f in self.analysis_results.get("llil", [])
                    ],
                    "column_names": [
                        "llil_function_hash",
                        "function_type",
                        "instructions_types_llil",
                        "control_flow_count_llil",
                        "memory_access_pattern_llil",
                        "register_usage_llil",
                        "total_reg_reads",
                        "total_reg_written",
                        "data_references_count",
                        "max_block_size",
                        "num_calls",
                        "stack_size",
                        "body_llil_vector",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "Enum8('USER'=1, 'LIBRARY'=2, 'THUNK'=3, 'EXTERNAL'=4, 'UNKNOWN'=5)",
                        "Array(LowCardinality(String))",
                        "UInt32",
                        "Array(LowCardinality(String))",
                        "Map(LowCardinality(String), Tuple(UInt32, UInt32))",
                        "UInt32",
                        "UInt32",
                        "UInt32",
                        "Nullable(UInt32)",
                        "Nullable(UInt32)",
                        "Nullable(Int32)",
                        "Array(Tuple(UInt32, Array(UInt16)))",
                        "DateTime64(3, 'UTC')",
                    ],
                }
                export["llil_refs"] = {
                    "table": "code_binja_llil_functions_references",
                    "data": [
                        [
                            self.analysis_results["sha256"],
                            self.analysis_results["sha1"],
                            self.analysis_results["md5"],
                            f.get("sha256_llil"),
                            f.get("disassembled_function_hash"),
                            f.get("function_address"),
                            f.get("tlsh_disassembly"),
                            f.get("tlsh_llil"),
                            now,
                        ]
                        for f in self.analysis_results.get("llil", [])
                    ],
                    "column_names": [
                        "sha256",
                        "sha1",
                        "md5",
                        "llil_function_hash",
                        "disassembled_function_hash",
                        "function_address",
                        "tlsh_disassembly",
                        "tlsh_llil",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "FixedString(40)",
                        "FixedString(32)",
                        "Nullable(FixedString(64))",
                        "FixedString(64)",
                        "UInt64",
                        "Nullable(FixedString(72))",
                        "Nullable(FixedString(72))",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            # Errors table (always include if per-function loop ran)
            if run_decompilation or run_disassembly or run_llil or run_cfg:
                export["function_analysis_errors"] = {
                    "table": "new_function_analysis_errors_binja",
                    "data": [
                        [
                            self.analysis_results["sha256"],
                            f["function_name"],
                            f["function_address"],
                            f.get("error_location", "unknown"),
                            f.get("error_message", ""),
                            f.get("error_details", ""),
                            f.get("error_type", "unknown"),
                            self.calculate_md5(
                                f"{f.get('error_message', '')}{f['function_name']}{f['function_address']}{f.get('error_location', 'unknown')}"
                            ),
                            "new",
                            now,
                        ]
                        for f in self.analysis_results.get("errors", [])
                    ],
                    "column_names": [
                        "sha256",
                        "function_name",
                        "function_address",
                        "error_location",
                        "error_message",
                        "error_details",
                        "error_type",
                        "error_hash",
                        "status",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "Nullable(String)",
                        "UInt64",
                        "LowCardinality(String)",
                        "Nullable(String)",
                        "Nullable(String)",
                        "Nullable(String)",
                        "FixedString(32)",
                        "Enum8('new'=1, 'investigating'=2, 'fixed'=3, 'wontfix'=4)",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            # Strings table
            if run_strings:
                export["strings_raw"] = {
                    "table": "code_binja_strings_raw",
                    "data": [
                        [
                            self.analysis_results["sha256"],
                            s["string"],
                            s["string_raw"],
                            s["string_encoding"],
                            s["string_offset"],
                            s["string_length"],
                            s["string_raw_length"],
                            s["string_entropy"],
                        ]
                        for s in self.analysis_results.get("strings", [])
                    ],
                    "column_names": [
                        "sha256",
                        "string",
                        "string_raw",
                        "string_encoding",
                        "string_offset",
                        "string_length",
                        "string_raw_length",
                        "string_entropy",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "String",
                        "String",
                        "LowCardinality(String)",
                        "UInt64",
                        "UInt32",
                        "UInt32",
                        "Float32",
                    ],
                }

            # CFG function-level features table
            if run_cfg:
                export["cfg_functions"] = {
                    "table": "code_binja_cfg_functions",
                    "data": [
                        [
                            cfg.get("disassembled_function_hash"),
                            cfg["cfg_topology_hash"],
                            cfg["block_count"],
                            cfg["edge_count"],
                            cfg.get("llil_total_operations", 0),
                            cfg.get("call_count", 0),
                            cfg["cyclomatic_complexity"],
                            cfg.get("loop_count", 0),
                            cfg.get("max_depth", 0),
                            cfg.get("max_fan_out", 0),
                            cfg.get("md_index_topdown", 0),
                            cfg.get("md_index_bottomup", 0),
                            cfg.get("prime_product_llil", 0),
                            cfg.get("cfg_feature_tlsh"),
                            cfg.get("wl_minhash", []),
                            cfg.get("bb_features", []),
                            cfg.get("cfg_adjacency", []),
                            now,
                        ]
                        for cfg in self.analysis_results.get("cfg", [])
                        if cfg is not None
                    ],
                    "column_names": [
                        "disassembled_function_hash",
                        "cfg_topology_hash",
                        "block_count",
                        "edge_count",
                        "llil_total_operations",
                        "call_count",
                        "cyclomatic_complexity",
                        "loop_count",
                        "max_depth",
                        "max_fan_out",
                        "md_index_topdown",
                        "md_index_bottomup",
                        "prime_product_llil",
                        "cfg_feature_tlsh",
                        "wl_minhash",
                        "bb_features",
                        "cfg_adjacency",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "FixedString(16)",
                        "UInt16",
                        "UInt16",
                        "UInt32",
                        "UInt16",
                        "UInt16",
                        "UInt8",
                        "UInt16",
                        "UInt8",
                        "UInt64",
                        "UInt64",
                        "UInt64",
                        "Nullable(FixedString(72))",
                        "Array(UInt8)",
                        "Array(Array(UInt16))",
                        "Array(UInt32)",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            # GoReSym metadata table (only if goresym data exists)
            if self.goresym_data:
                export["golang_metadata"] = {
                    "table": "redb_golang_metadata",
                    "data": [
                        [
                            self.analysis_results["sha256"],
                            json.dumps(self.goresym_data),
                            now,
                        ]
                    ],
                    "column_names": [
                        "sha256",
                        "goresym",
                        "analysis_date",
                    ],
                    "column_type_names": [
                        "FixedString(64)",
                        "JSON",
                        "DateTime64(3, 'UTC')",
                    ],
                }

            return export

    def tag(self) -> str:
        """Return the tag for this extractor."""
        return Tag.DECOMPILED.value

    def get_clickhouse_table(self) -> str:
        """Not used directly as we're handling multiple tables."""
        pass


if __name__ == "__main__":
    # Setup basic logging
    import logging
    import time

    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger("DecompileBinja")

    # Parse command line arguments
    import argparse

    parser = argparse.ArgumentParser(description="Binary Ninja Decompiler Wrapper")
    parser.add_argument("filepath", help="Path to the binary file to analyze")
    parser.add_argument(
        "--output", "-o", help="Output JSON file path (default: stdout)"
    )
    parser.add_argument(
        "--timeout",
        "-t",
        type=int,
        default=1200,
        help="Analysis timeout in seconds (default: 1200)",
    )
    args = parser.parse_args()
    start = time.perf_counter()
    # Create and run the extractor
    with DecompileBinja(args.filepath, logger) as extractor:
        success = extractor.extract()
        end = time.perf_counter()
        if not success:
            logger.error("Analysis failed")
            exit(1)

        # Output results
        if args.output:
            with open(args.output, "w") as f:
                json.dump(extractor.analysis_results, f)
            logger.info(f"Results written to {args.output}")
        else:
            print((extractor.analysis_results))
            with open("diff", "w") as f:
                f.write(str(f"{end - start:.3f} seconds"))