NationalSecurityAgency / ghidra

Ghidra is a software reverse engineering (SRE) framework
https://www.nsa.gov/ghidra
Apache License 2.0
51.49k stars 5.86k forks source link

analyzeHeadless.bat puts all params in quote following the -import one, thus breaking the parsing of the rest of the command line #6146

Closed wisemanny closed 9 months ago

wisemanny commented 9 months ago

Describe the bug When I use analyzeHeadless.bat on Windows and use -import not as a last parameter, ghirda complains about not being able to get canonical name of the file. In reality, it changes all subsequent parameters by quoting them and as result the command becomes badly formatted.

To Reproduce Steps to reproduce the behavior:

  1. Try this command line:

    .\ghidra\11.0-20231222\support\analyzeHeadless.bat C:/projects/esp8266_fiddb.rep esp8266rtos -import "c:/temp/esp8/" -recursive -preScript FunctionIDHeadlessPrescript.java  -postScript FunctionIDHeadlessPostscript.java -processor "Xtensa:LE:32:default"
  2. It will complain with such exception:

    Exception in thread "main" ghidra.util.exception.InvalidInputException: Failed to get canonical form of: c:\temp\esp8" -log -recursive -preScript FunctionIDHeadlessPrescript.java -postScript FunctionIDHeadlessPostscript.java -processor Xtensa:LE:32:default
        at ghidra.app.util.headless.AnalyzeHeadless.parseOptions(AnalyzeHeadless.java:221)
        at ghidra.app.util.headless.AnalyzeHeadless.launch(AnalyzeHeadless.java:119)
        at ghidra.GhidraLauncher.launch(GhidraLauncher.java:78)
        at ghidra.Ghidra.main(Ghidra.java:54)
  3. This is the actual command it invokes:

    call "C:\Users\....\scoop\apps\ghidra\11.0-20231222\support\launch.bat" fg jdk Ghidra-Headless "2G" "-XX:ParallelGCThreads=2 -XX:CICompilerCount=2" ghidra.app.util.headless.AnalyzeHeadless  "C:/projects/esp8266_fiddb.rep" "esp8266rtos" -import "c:\temp\esp8\" "-recursive" "-preScript" "FunctionIDHeadlessPrescript.java" "-postScript" "FunctionIDHeadlessPostscript.java" "-processor" "Xtensa:LE:32:default"
  4. As you see, after -import, all param names and values are quoted: "-recursive" "-preScript" "FunctionIDHeadlessPrescript.java" "-postScript" "FunctionIDHeadlessPostscript.java" "-processor" "Xtensa:LE:32:default"

  5. It works only if -import is the last parameter in the command line. This is the workaround.

Expected behavior It runs ghidra and it processes the analysis.

Environment (please complete the following information):

Additional context There is a part of the bat files that handles the -import argument, I think it is the culprit. I wish I knew bat files processing to submit a PR...

ryanmkurtz commented 9 months ago

I am not reproducing this. Are you running the command from a standard Windows Command Prompt?

ryanmkurtz commented 9 months ago

Nevermind, i am reproducing it now.

ryanmkurtz commented 9 months ago

I think in your -import "c:/temp/esp8/" piece, the /'s are getting converted to \, and the resulting trailing \ is escaping the " that follows. Can you try removing the trailing \?

wisemanny commented 9 months ago

Sure, so I tried this:

❯ ~\scoop\apps\ghidra\11.0-20231222\support\analyzeHeadless.bat C:\projects\esp8266_fiddb.rep esp8266rtos -import "c:\temp\esp8\" -recursive -preScript FunctionIDHeadlessPrescript.java -postScript FunctionIDHeadlessPostscript.java -processor "Xtensa:LE:32:default"

It did call it without quotes:

C:\projects\esp8266_fiddb.rep>call "C:\Users\.....\scoop\apps\ghidra\11.0-20231222\support\launch.bat" fg jdk Ghidra-Headless "2G" "-XX:ParallelGCThreads=2 -XX:CICompilerCount=2" ghidra.app.util.headless.AnalyzeHeadless C:\projects\esp8266_fiddb.rep esp8266rtos -import "c:\temp\esp8\" -recursive -preScript FunctionIDHeadlessPrescript.java -postScript FunctionIDHeadlessPostscript.java -processor Xtensa:LE:32:default

But it still fails to properly parse the command line. This was original issue that I started to tackle:

Exception in thread "main" ghidra.util.exception.InvalidInputException: Failed to get canonical form of: c:\temp\esp8" -recursive -preScript FunctionIDHeadlessPrescript.java -postScript FunctionIDHeadlessPostscript.java -processor Xtensa:LE:32:default
        at ghidra.app.util.headless.AnalyzeHeadless.parseOptions(AnalyzeHeadless.java:221)
        at ghidra.app.util.headless.AnalyzeHeadless.launch(AnalyzeHeadless.java:119)
        at ghidra.GhidraLauncher.launch(GhidraLauncher.java:78)
        at ghidra.Ghidra.main(Ghidra.java:54)

It considers the full line after the import part as a name of the file. I did echo on in the launch.bat and it seems like something is happening there, that is what it generates at the end:

"C:\Users\....\scoop\apps\temurin17-jdk\current\bin\java" -XX:ParallelGCThreads=2 -XX:CICompilerCount=2 -Duser.home="C:\Users\......" -Djava.system.class.loader=ghidra.GhidraClassLoader -Dfile.encoding=UTF8 -Duser.country=US -Duser.language=en -Duser.variant= -Dsun.java2d.opengl=false -Djdk.tls.client.protocols=TLSv1.2,TLSv1.3 -Dcpu.core.limit= -Dcpu.core.override= -Dfont.size.override= -Dpython.console.encoding=UTF-8 -Xshare:off -Dsun.java2d.d3d=false -Dlog4j.skipJansi=true -Xmx2G -cp "C:\Users\.....\scoop\apps\ghidra\11.0-20231222\support\..\Ghidra\Framework\Utility\lib\Utility.jar" ghidra.Ghidra ghidra.app.util.headless.AnalyzeHeadless "C:\projects\esp8266_fiddb.rep" "esp8266rtos" "-import" "c:\temp\esp8\" "-recursive" "-preScript" "FunctionIDHeadlessPrescript.java" "-postScript" "FunctionIDHeadlessPostscript.java" "-processor" "Xtensa:LE:32:default"

ryanmkurtz commented 9 months ago

I was hoping you would try removing the slash at the end of c:\temp\esp8\. So just c:\temp\esp8.

wisemanny commented 9 months ago

It works but still puts double quotes around the rest of the params, so I guess my \ was an escape char before:

Here is the cmd:

~\scoop\apps\ghidra\11.0-20231222\support\analyzeHeadless.bat C:\projects\esp8266_fiddb.rep esp8266rtos -import "c:\temp\esp8" -recursive -preScript FunctionIDHeadlessPrescript.java -postScript FunctionIDHeadlessPostscript.java -processor "Xtensa:LE:32:default"

Here is the calling line:

"C:\Users\mmmmm\scoop\apps\temurin17-jdk\current\bin\java" -XX:ParallelGCThreads=2 -XX:CICompilerCount=2 -Duser.home="C:\Users\mmmmm" -Djava.system.class.loader=ghidra.GhidraClassLoader -Dfile.encoding=UTF8 -Duser.country=US -Duser.language=en -Duser.variant= -Dsun.java2d.opengl=false -Djdk.tls.client.protocols=TLSv1.2,TLSv1.3 -Dcpu.core.limit= -Dcpu.core.override= -Dfont.size.override= -Dpython.console.encoding=UTF-8 -Xshare:off -Dsun.java2d.d3d=false -Dlog4j.skipJansi=true -Xmx2G -cp "C:\Users\mmmm\scoop\apps\ghidra\11.0-20231222\support\..\Ghidra\Framework\Utility\lib\Utility.jar" ghidra.Ghidra ghidra.app.util.headless.AnalyzeHeadless "C:\projects\esp8266_fiddb.rep" "esp8266rtos" "-import" "c:\temp\esp8" "-recursive" "-preScript" "FunctionIDHeadlessPrescript.java" "-postScript" "FunctionIDHeadlessPostscript.java" "-processor" "Xtensa:LE:32:default" It does import files. So maybe not super intuitive, but does the job done. I think we can close it.