mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-24 21:21:56 +00:00
GP-4173 Complete transition to using --option params with bsim and bsim_ctl commands
This commit is contained in:
parent
0de3f53c11
commit
735cb1a5c3
@ -69,7 +69,7 @@ This is equivalent to:
|
||||
Use a command-line like this to generate and commit signatures from a Ghidra Server
|
||||
repository to the Elasticsearch database created above:
|
||||
|
||||
bsim generatesigs ghidra://1.2.3.4/repo bsim=elastic://1.2.3.4:9200/repo
|
||||
bsim generatesigs ghidra://1.2.3.4/repo --bsim elastic://1.2.3.4:9200/repo
|
||||
|
||||
Within Ghidra's BSim client, enter the same URL into the database connection
|
||||
panel in order to place queries to your Elasticsearch deployment. See the BSim
|
||||
|
@ -39,18 +39,18 @@
|
||||
<DIV class="informalexample">
|
||||
<PRE>
|
||||
<CODE class="computeroutput">
|
||||
bsim_ctl start </datadir-path [auth=pki|password|trust] [--noLocalAuth] [cafile=</cacert-path>] [dn=".."]
|
||||
bsim_ctl start </datadir-path> [--auth|-a pki|password|trust] [--noLocalAuth] [--cafile </cacert-path>] [--dn "<distinguished-name>"]
|
||||
bsim_ctl stop </datadir-path> [--force]
|
||||
bsim_ctl adduser </datadir-path> <username> [dn=".."]
|
||||
bsim_ctl adduser </datadir-path> <username> [--dn "<distinguished-name>"]
|
||||
bsim_ctl dropuser </datadir-path> <username>
|
||||
bsim_ctl resetpassword <username>
|
||||
bsim_ctl changeauth </datadir-path> [auth=pki|password|trust] [--noLocalAuth] [cafile=</cacert-path>] [dn=".."]
|
||||
bsim_ctl changeauth </datadir-path> [--auth|-a pki|password|trust] [--noLocalAuth] [--cafile </cacert-path>] [--dn "<distinguished-name>"]
|
||||
bsim_ctl changeprivilege <username> admin|user
|
||||
|
||||
Global Options:
|
||||
port=<portnum>
|
||||
user=<username>
|
||||
cert=</certfile-path>
|
||||
--port|-p <portnum>
|
||||
--user|-u <username>
|
||||
--cert </certfile-path>
|
||||
</CODE>
|
||||
</PRE>
|
||||
</DIV>
|
||||
@ -59,9 +59,11 @@
|
||||
starting and stopping a BSim server using the PostgreSQL back-end. The utility cannot be
|
||||
used with either an Elasticsearch server or a local H2 database.
|
||||
All commands must be run on the machine hosting the server.
|
||||
Optional parameters for a given command are indicated by square brackets '[' and ']'.
|
||||
Options with an '=' character require a user specified value. If the value string requires
|
||||
space characters, it should be enclosed in double quotes.</P>
|
||||
Optional parameters for a given command are indicated by square brackets '[' and ']'
|
||||
and always start with either '-' or '--' characters. If an associated value is required
|
||||
and contains space characters it should be enclosed in double quotes. Options which require
|
||||
a value may be separated by a space or a equal "=" character (e.g.,
|
||||
<SPAN class="command"><STRONG>--auth=password</STRONG></SPAN>).
|
||||
|
||||
<DIV class="informalexample">
|
||||
<DIV class="variablelist">
|
||||
@ -77,42 +79,42 @@
|
||||
database with <SPAN class="emphasis"><EM>admin</EM></SPAN> privileges.</P>
|
||||
|
||||
<P>During a restart, any authentication options (with the exception of the global
|
||||
<SPAN class="bold"><STRONG>cert=</STRONG></SPAN> option) are unnecessary and will
|
||||
<SPAN class="bold"><STRONG>--cert</STRONG></SPAN> option) are unnecessary and will
|
||||
be ignored. The PostgreSQL server will be restarted with the already established
|
||||
settings. To actually change the settings, use the <SPAN class=
|
||||
"bold"><STRONG>changeauth</STRONG></SPAN> command before restarting.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>auth=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>type</EM></SPAN> - specifies the authentication type (<B>pki |
|
||||
<P><SPAN class="command"><STRONG>--auth|-a </STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM><type></EM></SPAN> - specifies the authentication type (<B>pki |
|
||||
password | trust</B>) for a new database: <SPAN class=
|
||||
"emphasis"><EM>trust</EM></SPAN> for no authentication, <SPAN class=
|
||||
"emphasis"><EM>password</EM></SPAN> for password authentication, and <SPAN class=
|
||||
"emphasis"><EM>pki</EM></SPAN> for authentication using public key certificates.
|
||||
With the <SPAN class="emphasis"><EM>pki</EM></SPAN> setting, both the <SPAN class=
|
||||
"bold"><STRONG>cafile=</STRONG></SPAN> and the <SPAN class=
|
||||
"bold"><STRONG>dn=</STRONG></SPAN> options also need to be provided; additionally
|
||||
the <SPAN class="bold"><STRONG>cert=</STRONG></SPAN> option must be provided unless
|
||||
"bold"><STRONG>--cafile</STRONG></SPAN> and the <SPAN class=
|
||||
"bold"><STRONG>--dn</STRONG></SPAN> options also need to be provided; additionally
|
||||
the <SPAN class="bold"><STRONG>--cert</STRONG></SPAN> option must be provided unless
|
||||
the <SPAN class="bold"><STRONG>--noLocalAuth</STRONG></SPAN> option is also
|
||||
given.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>--noLocalAuth</STRONG></SPAN> - used together with
|
||||
the <SPAN class="command"><STRONG>auth=</STRONG></SPAN> option causes
|
||||
the <SPAN class="command"><STRONG>--auth</STRONG></SPAN> option causes
|
||||
authentication to not be required for local connections, i.e. localhost.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>cafile=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>/cafile-path</EM></SPAN> - specifies an absolute path to a
|
||||
<P><SPAN class="command"><STRONG>--cafile </STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM></cafile-path></EM></SPAN> - specifies an absolute path to a
|
||||
certificate authority file and is required for <SPAN class=
|
||||
"command"><STRONG>auth=pki</STRONG></SPAN>. This file should contain the
|
||||
"command"><STRONG>--auth pki</STRONG></SPAN>. This file should contain the
|
||||
certificates the PostgreSQL server will use to authenticate in PEM format
|
||||
concatenated together.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>dn=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>name</EM></SPAN> - specifies the Distinguished Name for the admin
|
||||
user and is required for <SPAN class=
|
||||
"command"><STRONG>auth=pki</STRONG></SPAN>.</P>
|
||||
<P><SPAN class="command"><STRONG>--dn </STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM><distinguished-name></EM></SPAN> - specifies the Distinguished
|
||||
Name for the admin user and is required for
|
||||
<SPAN class="command"><STRONG>--auth pki</STRONG></SPAN>.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>port=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>portnum</EM></SPAN> - specifies the port the PostgreSQL server will
|
||||
<P><SPAN class="command"><STRONG>--port|-p </STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM><portnum></EM></SPAN> - specifies the port the PostgreSQL server will
|
||||
listen on. For port numbers other than the default 5432, URLs and other
|
||||
command-lines must explicitly specify the port, when connecting to the server. This
|
||||
option only effects the initial start of a server. For subsequent (re)starts this
|
||||
@ -143,10 +145,10 @@
|
||||
(read-only) privileges, unless a subsequent <SPAN class=
|
||||
"command"><STRONG>changeprivilege</STRONG></SPAN> command is used.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>dn=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>name</EM></SPAN> - specifies the Distinguished Name of the new user,
|
||||
<P><SPAN class="command"><STRONG>--dn </STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM><distinguished-name></EM></SPAN> - specifies the Distinguished Name of the new user,
|
||||
which is required if the database enabled <SPAN class=
|
||||
"command"><STRONG>auth=pki</STRONG></SPAN>. This option can be used to provide a
|
||||
"command"><STRONG>--auth pki</STRONG></SPAN>. This option can be used to provide a
|
||||
Distinguished Name to a preexisting user, if the PostgreSQL server's authentication
|
||||
strategy is changed.</P>
|
||||
</DD>
|
||||
@ -170,23 +172,22 @@
|
||||
the same meaning as for the <SPAN class="command"><STRONG>start</STRONG></SPAN>
|
||||
command.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>port=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>portnum</EM></SPAN> - changes the port the PostgreSQL server will
|
||||
<P><SPAN class="command"><STRONG>--port|-p </STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM><portnum></EM></SPAN> - changes the port the PostgreSQL server will
|
||||
listen on. If this option is not present, the server will continue to listen on the
|
||||
same port.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>auth=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>type</EM></SPAN> - changes the authentication type (<B>pki |
|
||||
<P><SPAN class="command"><STRONG>--auth|-a </STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM><type></EM></SPAN> - changes the authentication type (<B>pki |
|
||||
password | trust</B>) used by the PostgreSQL server. No change is made if the
|
||||
option is not present. If the option is present, omitting the <SPAN class=
|
||||
"command"><STRONG>--noLocalAuth</STRONG></SPAN> causes local connections to require
|
||||
authentication. This command does not affect the presence or absence of passwords
|
||||
or Distinguished Names for existing users.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>dn=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>name</EM></SPAN> - specifies the Distinguished Name for the admin
|
||||
user and is required for <SPAN class=
|
||||
"command"><STRONG>auth=pki</STRONG></SPAN>.</P>
|
||||
<P><SPAN class="command"><STRONG>--dn </STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM><distinguished-name></EM></SPAN> - specifies the Distinguished Name for the admin
|
||||
user and is required for <SPAN class="command"><STRONG>--auth pki</STRONG></SPAN>.</P>
|
||||
</DD>
|
||||
|
||||
<DT><SPAN class="term"><SPAN class=
|
||||
@ -219,16 +220,16 @@
|
||||
"command"><STRONG>resetpassword</STRONG></SPAN>, and <SPAN class=
|
||||
"command"><STRONG>changeprivilege</STRONG></SPAN>.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>port=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>portnum</EM></SPAN> - specifies the port on which to connect with
|
||||
<P><SPAN class="command"><STRONG>--port|-p </STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM><portnum></EM></SPAN> - specifies the port on which to connect with
|
||||
the PostgreSQL server.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>user=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>username</EM></SPAN> - specifies a user name to use when connecting
|
||||
<P><SPAN class="command"><STRONG>--user|-u </STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM><username></EM></SPAN> - specifies a user name to use when connecting
|
||||
to the PostgreSQL server.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>cert=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>/certfile-path</EM></SPAN> - provides the absolute file path to the
|
||||
<P><SPAN class="command"><STRONG>--cert </STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM></certfile-path></EM></SPAN> - provides the absolute file path to the
|
||||
user's certificate when connecting to a PostgreSQL server that requires PKI
|
||||
authentication.</P>
|
||||
</DD>
|
||||
@ -249,31 +250,31 @@
|
||||
|
||||
<DIV class="informalexample">
|
||||
<PRE>
|
||||
<CODE class="computeroutput">
|
||||
bsim createdatabase <bsimURL> <config_template> [name="<name>"] [owner="<owner>"] [description="<text>"] [--nocallgraph]
|
||||
bsim setmetadata <bsimURL> [name="<name>"] [owner="<owner>"] [description="<text>"]\n" +
|
||||
<CODE class "computeroutput">
|
||||
bsim createdatabase <bsimURL> <config_template> [--name|-n "<name>"] [--owner|-o "<owner>"] [--description|-d "<text>"] [--nocallgraph]
|
||||
bsim setmetadata <bsimURL> [--name|-n "<name>"] [--owner|-o "<owner>"] [--description|-d "<text>"]\n" +
|
||||
bsim addexecategory <bsimURL> <category_name> [--date]
|
||||
bsim addfunctiontag <bsimURL> <tag_name>
|
||||
bsim dropindex <bsimURL>
|
||||
bsim rebuildindex <bsimURL>
|
||||
bsim prewarm <bsimURL>
|
||||
bsim generatesigs <ghidraURL> </xmldirectory> config=<config_template> [--overwrite]
|
||||
bsim generatesigs <ghidraURL> </xmldirectory> bsim=<bsimURL> [--commit] [--overwrite]
|
||||
bsim generatesigs <ghidraURL> bsim=<bsimURL>
|
||||
bsim commitsigs <bsimURL> </xmldirectory> [md5=<hash>] [override=<ghidraURL>]
|
||||
bsim generateupdates <ghidraURL> </xmldirectory> config=<config_template> [--overwrite]
|
||||
bsim generateupdates <ghidraURL> </xmldirectory> bsim=<bsimURL> [--commit] [--overwrite]
|
||||
bsim generateupdates <ghidraURL> bsim=<bsimURL>
|
||||
bsim generatesigs <ghidraURL> </xmldirectory> --config|-c <config_template> [--overwrite]
|
||||
bsim generatesigs <ghidraURL> </xmldirectory> --bsim|-b <bsimURL> [--commit] [--overwrite]
|
||||
bsim generatesigs <ghidraURL> --bsim|-b <bsimURL>
|
||||
bsim commitsigs <bsimURL> </xmldirectory> [--md5|-m <hash>] [--override <ghidraURL>]
|
||||
bsim generateupdates <ghidraURL> </xmldirectory> --config|-c <config_template> [--overwrite]
|
||||
bsim generateupdates <ghidraURL> </xmldirectory> --bsim|-b <bsimURL> [--commit] [--overwrite]
|
||||
bsim generateupdates <ghidraURL> --bsim|-b <bsimURL>
|
||||
bsim commitupdates <bsimURL> </xmldirectory>
|
||||
bsim listexes <bsimURL> [md5=<hash>] [name=<exe_name>] [arch=<languageID>] [compiler=<cspecID>] [sortcol=<column_name>] [limit=<exe_count>] [--includelibs]
|
||||
bsim getexecount <bsimURL> [md5=<hash>] [name=<exe_name>] [arch=<languageID>] [compiler=<cspecID>] [--includelibs]
|
||||
bsim delete <bsimURL> [md5=<hash>] [name=<exe_name> [arch=<languageID>] [compiler=<cspecID>]]
|
||||
bsim listfuncs <bsimURL> [md5=<hash>] [name=<exe_name> [arch=<languageID>] [compiler=<cspecID>]] [--printselfsig] [--callgraph] [--printjustexe] [maxfunc=<max_count>]
|
||||
bsim dumpsigs <bsimURL> </xmldirectory> [md5=<hash>] [name=<exe_name> [arch=<languageID>] [compiler=<cspecID>]]
|
||||
bsim listexes <bsimURL> [--md5|-m <hash>] [--name|-n <exe_name>] [--arch|-a <languageID>] [--compiler <cspecID>] [--sortcol|-s md5|name] [--limit|-l <exe_count>] [--includelibs]
|
||||
bsim getexecount <bsimURL> [--md5|-m <hash>] [--name|-n <exe_name>] [--arch|-a <languageID>] [--compiler <cspecID>] [--includelibs]
|
||||
bsim delete <bsimURL> [--md5|-m <hash>] [--name|-n <exe_name> [--arch|-a <languageID>] [--compiler <cspecID>]]
|
||||
bsim listfuncs <bsimURL> [--md5|-m <hash>] [--name|-n <exe_name> [--arch|-a <languageID>] [--compiler <cspecID>]] [--printselfsig] [--callgraph] [--printjustexe] [--maxfunc <max_count>]
|
||||
bsim dumpsigs <bsimURL> </xmldirectory> [--md5|-m <hash>] [--name|-n <exe_name> [--arch|-a <languageID>] [--compiler <cspecID>]]
|
||||
|
||||
Global options:
|
||||
user=<username>
|
||||
cert=<certfile-path>
|
||||
--user|-u <username>
|
||||
--cert <certfile-path>
|
||||
</CODE>
|
||||
</PRE>
|
||||
</DIV>
|
||||
@ -294,7 +295,12 @@
|
||||
"command"><STRONG>https:</STRONG></SPAN>, or <SPAN class=
|
||||
"command"><STRONG>file:</STRONG></SPAN> protocol specified. The <SPAN class=
|
||||
"command"><STRONG>elastic:</STRONG></SPAN> protocol is equivalent to and may be used in
|
||||
place of the <SPAN class="command"><STRONG>https:</STRONG></SPAN> protocol.</P>
|
||||
place of the <SPAN class="command"><STRONG>https:</STRONG></SPAN> protocol.
|
||||
Optional parameters for a given command are indicated by square brackets '[' and ']'
|
||||
and always start with either '-' or '--' characters. If an associated value is required
|
||||
and contains space characters it should be enclosed in double quotes. Options which require
|
||||
a value may be separated by a space or a equal "=" character (e.g.,
|
||||
<SPAN class="command"><STRONG>--name=myname</STRONG></SPAN>).</P>
|
||||
|
||||
<DIV class="informalexample">
|
||||
<DIV class="variablelist">
|
||||
@ -313,19 +319,18 @@
|
||||
(<SPAN class="bold"><STRONG>large_32, medium_32, medium_64, medium_cpool,
|
||||
medium_nosize</STRONG></SPAN>).</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>name=</STRONG></SPAN> - specifies a formal, more
|
||||
<P><SPAN class="command"><STRONG>--name|-n </STRONG></SPAN> - specifies a formal, more
|
||||
descriptive, name for the repository that can be used for the BSim client
|
||||
display.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>owner=</STRONG></SPAN> - gives a descriptive name
|
||||
<P><SPAN class="command"><STRONG>--owner|-o </STRONG></SPAN> - gives a descriptive name
|
||||
for the owner of the repository and/or the data it will contain.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>description=</STRONG></SPAN> - specifies a short
|
||||
<P><SPAN class="command"><STRONG>--description|-d </STRONG></SPAN> - specifies a short
|
||||
string describing the intended contents of the new repository.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>--nocallgraph=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>yes/no</EM></SPAN> - disables storing call relationships between
|
||||
ingested functions. Default is to store call relationships.</P>
|
||||
<P><SPAN class="command"><STRONG>--nocallgraph</STRONG></SPAN> - disables storing call
|
||||
relationships between ingested functions. Default is to store call relationships.</P>
|
||||
</DD>
|
||||
|
||||
<DT><SPAN class="term"><SPAN class=
|
||||
@ -337,14 +342,14 @@
|
||||
"emphasis"><EM>description</EM></SPAN> metadata associated with a BSim server. A
|
||||
BSim server URL is required.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>name=</STRONG></SPAN> - specifies a formal, more
|
||||
<P><SPAN class="command"><STRONG>--name|-n</STRONG></SPAN> - specifies a formal, more
|
||||
descriptive, name for the repository that can be used for the BSim client
|
||||
display.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>owner=</STRONG></SPAN> - gives a descriptive name
|
||||
<P><SPAN class="command"><STRONG>--owner|-o</STRONG></SPAN> - gives a descriptive name
|
||||
for the owner of the repository and/or the data it will contain.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>description=</STRONG></SPAN> - specifies a short
|
||||
<P><SPAN class="command"><STRONG>--description|-d</STRONG></SPAN> - specifies a short
|
||||
string describing the intended contents of the new repository.</P>
|
||||
</DD>
|
||||
|
||||
@ -413,17 +418,16 @@
|
||||
a Ghidra Server repository or project as specified by a Ghidra URL. The generated
|
||||
signatures may be retained as XML "sigs_" files within a specified XML storage
|
||||
directory and/or committed to a specified BSim database specified with the <SPAN
|
||||
class="command"><STRONG>bsim=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>bsimURL</EM></SPAN> option. If an XML storage directory is not
|
||||
class="command"><STRONG>--bsim</STRONG></SPAN> option. If an XML storage directory is not
|
||||
specified, a BSim URL must be specified to which the data will be committed.</P>
|
||||
|
||||
<P>The <SPAN class="command"><STRONG>config=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>config-template</EM></SPAN> option may be specified when generating
|
||||
<P>The <SPAN class="command"><STRONG>--config|-c </STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM><config-template></EM></SPAN> option may be specified when generating
|
||||
XML "sigs_" signature files in the absence of a BSim database (see
|
||||
<STRONG>createdatabase</STRONG> for supported configurations). The generated files
|
||||
will be written to the specified XML storage directory. Creation of the signature
|
||||
files can also be achieved by specifying the <STRONG>bsim=</STRONG><EM>bsimURL</EM>
|
||||
option instead of the <STRONG>config=</STRONG> option.</P>
|
||||
files can also be achieved by specifying the <STRONG>--bsim</STRONG>
|
||||
option instead of the <STRONG>--config</STRONG> option.</P>
|
||||
|
||||
<P>The <SPAN class="command"><STRONG>--overwrite</STRONG></SPAN> <SPAN class=
|
||||
"emphasis">option may be specified when an XML storage directory has also been
|
||||
@ -444,8 +448,8 @@
|
||||
repository and a path to a directory containing the "sigs_" XML files to commit are
|
||||
required.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>override=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>ghidraURL</EM></SPAN> - causes any Ghidra repository/project URL,
|
||||
<P><SPAN class="command"><STRONG>--override </STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM><ghidraURL></EM></SPAN> - causes any Ghidra repository/project URL,
|
||||
describing the storage repository and path of executables that was recorded in the
|
||||
"sigs_" XML files during signature generation, to be overridden during the commit
|
||||
operation with the specified Ghidra URL.</P>
|
||||
@ -461,17 +465,16 @@
|
||||
function tags, categories, etc. are changed. Signatures are not affected. The
|
||||
generated updates may be retained as XML "update_" files within a specified XML
|
||||
storage directory and/or committed to a specified BSim database specified with the
|
||||
<SPAN class="command"><STRONG>bsim=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>bsimURL</EM></SPAN> option. If an XML storage directory is not
|
||||
<SPAN class="command"><STRONG>--bsim</STRONG></SPAN> option. If an XML storage directory is not
|
||||
specified, a BSim URL must be specified to which the data will be committed.</P>
|
||||
|
||||
<P>The <SPAN class="command"><STRONG>config=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>config-template</EM></SPAN> option may be specified when generating
|
||||
<P>The <SPAN class="command"><STRONG>--config|-c </STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM><config-template></EM></SPAN> option may be specified when generating
|
||||
XML "update_" files in the absence of a BSim database (see
|
||||
<STRONG>createdatabase</STRONG> for supported configurations). The generated files
|
||||
will be written to the specified XML storage directory. Creation of the update
|
||||
files can also be achieved by specifying the <STRONG>bsim=</STRONG><EM>bsimURL</EM>
|
||||
option instead of the <STRONG>config=</STRONG> option.</P>
|
||||
files can also be achieved by specifying the <STRONG>--bsim</STRONG>
|
||||
option instead of the <STRONG>--config</STRONG> option.</P>
|
||||
|
||||
<P>The <SPAN class="command"><STRONG>--overwrite</STRONG></SPAN> <SPAN class=
|
||||
"emphasis">option may be specified when an XML storage directory has also been
|
||||
@ -499,30 +502,27 @@
|
||||
<P>List all executable program records within a specified BSim database repository
|
||||
which satisfy the specified criteria. A BSim URL specifying the repository must be
|
||||
provided, and one of two options, <SPAN class=
|
||||
"command"><STRONG>md5=</STRONG></SPAN> or <SPAN class=
|
||||
"command"><STRONG>name=</STRONG></SPAN>, that indicate the specific executable must
|
||||
"command"><STRONG>--md5</STRONG></SPAN> or <SPAN class=
|
||||
"command"><STRONG>--name </STRONG></SPAN>, that indicate the specific executable must
|
||||
also be given. All matching executable records will be listed.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>md5=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>32-hexdigits</EM></SPAN> - specifies an executable via its MD5
|
||||
checksum.</P>
|
||||
<P><SPAN class="command"><STRONG>--md5|-m</STRONG></SPAN> - specifies an executable via its MD5
|
||||
checksum as 32 hexidecimal digits.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>name=</STRONG></SPAN> - specifies an executable
|
||||
<P><SPAN class="command"><STRONG>--name|-n</STRONG></SPAN> - specifies an executable
|
||||
name which may match one or more executable records.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>arch=</STRONG></SPAN> - specifies an architecture
|
||||
<P><SPAN class="command"><STRONG>--arch|-a</STRONG></SPAN> - specifies an architecture
|
||||
as a Ghidra processor id which will be used to filter executables.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>compiler=</STRONG></SPAN> - specifies a compiler
|
||||
<P><SPAN class="command"><STRONG>--compiler</STRONG></SPAN> - specifies a compiler
|
||||
specification id which will be used to filter executables.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>sortcol=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>column</EM></SPAN> - Indicates which display column should be used
|
||||
to sort the results (<STRONG>MD5 | NAME</STRONG>; default:
|
||||
<STRONG>MD5</STRONG>).</P>
|
||||
<P><SPAN class="command"><STRONG>--sortcol|-s</STRONG></SPAN> - Specifies which display
|
||||
column should be used to sort the results (<STRONG>md5 | name</STRONG>; default:
|
||||
<STRONG>md5</STRONG>).</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>limit=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>max_count</EM></SPAN> - specifies the maximum number of executables
|
||||
<P><SPAN class="command"><STRONG>--limit|-l</STRONG></SPAN> - specifies the maximum number of executables
|
||||
to be listed which match the search criteria (default=20, a value of 0 indicates no
|
||||
limit).</P>
|
||||
|
||||
@ -538,21 +538,20 @@
|
||||
<P>Get the total number of executable program records within a specified BSim
|
||||
database repository which satisfy the specified criteria. A BSim URL specifying the
|
||||
repository must be provided, and one of two options, <SPAN class=
|
||||
"command"><STRONG>md5=</STRONG></SPAN> or <SPAN class=
|
||||
"command"><STRONG>name=</STRONG></SPAN>, that indicate the specific executable must
|
||||
"command"><STRONG>--md5</STRONG></SPAN> or <SPAN class=
|
||||
"command"><STRONG>--name</STRONG></SPAN>, that indicate the specific executable must
|
||||
also be given. All matching executable records will be listed.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>md5=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>32-hexdigits</EM></SPAN> - specifies an executable via its MD5
|
||||
checksum.</P>
|
||||
<P><SPAN class="command"><STRONG>--md5|-m</STRONG></SPAN> - specifies an executable via its MD5
|
||||
checksum as 32 hexidecimal digits.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>name=</STRONG></SPAN> - specifies an executable
|
||||
<P><SPAN class="command"><STRONG>--name|-n</STRONG></SPAN> - specifies an executable
|
||||
name which may match one or more executable records.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>arch=</STRONG></SPAN> - specifies an architecture
|
||||
<P><SPAN class="command"><STRONG>--arch|-a</STRONG></SPAN> - specifies an architecture
|
||||
as a Ghidra processor id which will be used to filter executables.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>compiler=</STRONG></SPAN> - specifies a compiler
|
||||
<P><SPAN class="command"><STRONG>--compiler</STRONG></SPAN> - specifies a compiler
|
||||
specification id which will be used to filter executables.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>--includelibs</STRONG> - If specified, executable
|
||||
@ -565,26 +564,25 @@
|
||||
<DD>
|
||||
<P>Remove all records associated with a specific executable from a BSim repository.
|
||||
A BSim URL specifying the repository must be provided, and one of two options,
|
||||
<SPAN class="command"><STRONG>md5=</STRONG></SPAN> or <SPAN class=
|
||||
"command"><STRONG>name=</STRONG></SPAN>, that indicate the specific executable must
|
||||
<SPAN class="command"><STRONG>--md5</STRONG></SPAN> or <SPAN class=
|
||||
"command"><STRONG>--name</STRONG></SPAN>, that indicate the specific executable must
|
||||
also be given. All associated executable and function records are removed.
|
||||
If an executable cannot be uniquely identified an error will result.
|
||||
</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>md5=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>32-hexdigits</EM></SPAN> - specifies the executable via its MD5
|
||||
checksum.</P>
|
||||
<P><SPAN class="command"><STRONG>--md5|-m</STRONG></SPAN> - specifies an executable via its MD5
|
||||
checksum as 32 hexidecimal digits.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>name=</STRONG></SPAN> - specifies an executable
|
||||
<P><SPAN class="command"><STRONG>--name|-n</STRONG></SPAN> - specifies an executable
|
||||
name which may match one or more executable records.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>arch=</STRONG></SPAN> - specifies an architecture
|
||||
<P><SPAN class="command"><STRONG>--arch|-a</STRONG></SPAN> - specifies an architecture
|
||||
as a Ghidra processor id, when the <SPAN class=
|
||||
"command"><STRONG>name</STRONG></SPAN> option is not enough to uniquely specify the
|
||||
"command"><STRONG>--name</STRONG></SPAN> option is not enough to uniquely specify the
|
||||
executable.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>compiler=</STRONG></SPAN> - specifies a compiler
|
||||
id string, when the <SPAN class="command"><STRONG>name</STRONG></SPAN> option is
|
||||
<P><SPAN class="command"><STRONG>--compiler</STRONG></SPAN> - specifies a compiler
|
||||
id string, when the <SPAN class="command"><STRONG>--name</STRONG></SPAN> option is
|
||||
not enough to uniquely specify the executable.</P>
|
||||
</DD>
|
||||
|
||||
@ -594,25 +592,24 @@
|
||||
<DD>
|
||||
<P>List all function records associated with a specific executable from a BSim
|
||||
repository. A BSim URL specifying the repository must be provided, and one of two
|
||||
options, <SPAN class="command"><STRONG>md5=</STRONG></SPAN> or <SPAN class=
|
||||
"command"><STRONG>name=</STRONG></SPAN>, that indicate the specific executable must
|
||||
options, <SPAN class="command"><STRONG>--md5</STRONG></SPAN> or <SPAN class=
|
||||
"command"><STRONG>--name</STRONG></SPAN>, that indicate the specific executable must
|
||||
also be given. All associated executable and function records are listed. If an
|
||||
executable cannot be uniquely identified an error will result.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>md5=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>32-hexdigits</EM></SPAN> - specifies the executable via its MD5
|
||||
checksum.</P>
|
||||
<P><SPAN class="command"><STRONG>--md5|-m</STRONG></SPAN> - specifies an executable via its MD5
|
||||
checksum as 32 hexidecimal digits.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>name=</STRONG></SPAN> - specifies an executable
|
||||
<P><SPAN class="command"><STRONG>--name|-n</STRONG></SPAN> - specifies an executable
|
||||
name which may match one or more executable records.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>arch=</STRONG></SPAN> - specifies an architecture
|
||||
<P><SPAN class="command"><STRONG>--arch|-a</STRONG></SPAN> - specifies an architecture
|
||||
as a Ghidra processor id, when the <SPAN class=
|
||||
"command"><STRONG>name</STRONG></SPAN> option is not enough to uniquely specify the
|
||||
"command"><STRONG>--name</STRONG></SPAN> option is not enough to uniquely specify the
|
||||
executable.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>compiler=</STRONG></SPAN> - specifies a compiler
|
||||
id string, when the <SPAN class="command"><STRONG>name</STRONG></SPAN> option is
|
||||
<P><SPAN class="command"><STRONG>--compiler</STRONG></SPAN> - specifies a compiler
|
||||
id string, when the <SPAN class="command"><STRONG>--name</STRONG></SPAN> option is
|
||||
not enough to uniquely specify the executable.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>--printselfsig</STRONG></SPAN> - If specified, each
|
||||
@ -628,8 +625,7 @@
|
||||
also specified only the called libraries will be listed and not the specified
|
||||
functions.</SPAN></P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>maxfunc=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>max_count</EM></SPAN> - specifies the maximum number of functions to
|
||||
<P><SPAN class="command"><STRONG>--maxfunc</STRONG></SPAN> - specifies the maximum number of functions to
|
||||
be listed which correspond to the identified executable (default=1000, a value of 0
|
||||
indicates no limit).</P>
|
||||
</DD>
|
||||
@ -641,25 +637,24 @@
|
||||
<P>Dump signature and metadata from a BSim repository for a specific executable to
|
||||
a "sigs_" XML file. A BSim server URL and a path to a directory where the new file
|
||||
will be stored must be given. One of two options, <SPAN class=
|
||||
"command"><STRONG>md5=</STRONG></SPAN> or <SPAN class=
|
||||
"command"><STRONG>name=</STRONG></SPAN>, that specify the particular executable
|
||||
"command"><STRONG>--md5</STRONG></SPAN> or <SPAN class=
|
||||
"command"><STRONG>--name</STRONG></SPAN>, that specify the particular executable
|
||||
must also be given. If an executable cannot be uniquely identified an error will result.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>md5=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>32-hexdigits</EM></SPAN> - specifies an executable via its MD5
|
||||
checksum.</P>
|
||||
<P><SPAN class="command"><STRONG>--md5|-m</STRONG></SPAN> - specifies an executable via its MD5
|
||||
checksum as 32 hexidecimal digits.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>name=</STRONG></SPAN> - specifies an executable
|
||||
<P><SPAN class="command"><STRONG>--name|-n</STRONG></SPAN> - specifies an executable
|
||||
name which may match one or more executable records.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>arch=</STRONG></SPAN> - specifies an architecture
|
||||
<P><SPAN class="command"><STRONG>--arch|-a</STRONG></SPAN> - specifies an architecture
|
||||
as a Ghidra processor id, when the <SPAN class=
|
||||
"command"><STRONG>name</STRONG></SPAN> option is not enough to uniquely specify the
|
||||
"command"><STRONG>--name</STRONG></SPAN> option is not enough to uniquely specify the
|
||||
executable.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>compiler=</STRONG></SPAN> - specifies a compiler
|
||||
<P><SPAN class="command"><STRONG>--compiler</STRONG></SPAN> - specifies a compiler
|
||||
specification id, when the <SPAN class=
|
||||
"command"><STRONG>name</STRONG></SPAN> option is not enough to uniquely specify the
|
||||
"command"><STRONG>--name</STRONG></SPAN> option is not enough to uniquely specify the
|
||||
executable.</P>
|
||||
|
||||
</DD>
|
||||
@ -671,12 +666,12 @@
|
||||
<P>These options apply to all <SPAN class="command"><STRONG>bsim</STRONG></SPAN>
|
||||
commands.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>user=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>name</EM></SPAN> - specifies a user to masquerade as when connecting
|
||||
<P><SPAN class="command"><STRONG>--user|-u </STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM><username></EM></SPAN> - specifies a user to masquerade as when connecting
|
||||
to the server.</P>
|
||||
|
||||
<P><SPAN class="command"><STRONG>cert=</STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM>path</EM></SPAN> - provides a path to the user's certificate when
|
||||
<P><SPAN class="command"><STRONG>--cert </STRONG></SPAN><SPAN class=
|
||||
"emphasis"><EM><certfile-path></EM></SPAN> - provides a path to the user's certificate when
|
||||
connecting to a server that requires PKI authentication.</P>
|
||||
</DD>
|
||||
</DL>
|
||||
|
@ -214,7 +214,7 @@
|
||||
|
||||
<TR>
|
||||
<TD><CODE class="computeroutput">$(ROOT)/support/bsim_ctl start /path/to/datadir
|
||||
port=8000</CODE></TD>
|
||||
--port 8000</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
@ -236,7 +236,7 @@
|
||||
be reused.</P>
|
||||
|
||||
<P>The <SPAN class="bold"><STRONG>start</STRONG></SPAN> command can take an optional
|
||||
<SPAN class="bold"><STRONG>port=</STRONG></SPAN> parameter. This can be used to specify
|
||||
<SPAN class="bold"><STRONG>--port</STRONG></SPAN> parameter. This can be used to specify
|
||||
a non-standard port for the PostgreSQL server to listen on. In this case, any
|
||||
subsequent reference to the BSim server, in the Ghidra client, or with the <SPAN class=
|
||||
"command"><STRONG>bsim</STRONG></SPAN> command described below, must specify the port.
|
||||
@ -293,7 +293,7 @@
|
||||
|
||||
<DD>
|
||||
<P><CODE class="computeroutput">bsim_ctl start /path/to/datadir
|
||||
auth=trust</CODE></P>
|
||||
--auth trust</CODE></P>
|
||||
|
||||
<P>This is currently the default. No authentication is performed and privilege
|
||||
is granted based on the user name presented. Masquerading is possible.</P>
|
||||
@ -304,7 +304,7 @@
|
||||
|
||||
<DD>
|
||||
<P><CODE class="computeroutput">bsim_ctl start /path/to/datadir
|
||||
auth=password</CODE></P>
|
||||
--auth password</CODE></P>
|
||||
|
||||
<P>Users are authenticated via password. A default password 'changeme' is
|
||||
established when the new user is created. Passwords can be changed by the user
|
||||
@ -315,12 +315,12 @@
|
||||
<DT><SPAN class="term"><SPAN class="bold"><STRONG>pki</STRONG></SPAN></SPAN></DT>
|
||||
|
||||
<DD>
|
||||
<P><CODE class="computeroutput">bsim_ctl start /path/to/datadir auth=pki
|
||||
ca=/path/to/rootcert</CODE></P>
|
||||
<P><CODE class="computeroutput">bsim_ctl start /path/to/datadir --auth pki
|
||||
--cafile "/path/to/rootcert"</CODE></P>
|
||||
|
||||
<P>Users are authenticated by PKI certificates. Upon initialization, the BSim
|
||||
server must be provided (via the <SPAN class=
|
||||
"command"><STRONG>ca=</STRONG></SPAN> option) a file containing the public keys
|
||||
"command"><STRONG>--cafile</STRONG></SPAN> option) a file containing the public keys
|
||||
for the certificate authorities used to issue user's certificates. The file
|
||||
consists of the authoritative certificates in PEM format concatenated
|
||||
together.</P>
|
||||
@ -338,7 +338,7 @@
|
||||
<P>With PKI authentication enabled, at the time a new user role is established
|
||||
with the server, the X.509 Distinguished Name, as bound to the user's
|
||||
certificate, must be associated with the user name via the <SPAN class=
|
||||
"command"><STRONG>dn=</STRONG></SPAN> option. See <A class="xref" href=
|
||||
"command"><STRONG>--dn</STRONG></SPAN> option. See <A class="xref" href=
|
||||
"#PostAddUser" title="Adding Users to the Database">“Adding Users to the
|
||||
Database”</A>.</P>
|
||||
</DD>
|
||||
@ -358,7 +358,7 @@
|
||||
<TABLE border="0" summary="Simple list" class="simplelist">
|
||||
<TR>
|
||||
<TD><CODE class="computeroutput">$(ROOT)/support/bsim_ctl changeauth
|
||||
/datadir/path auth=password</CODE></TD>
|
||||
/datadir/path --auth password</CODE></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DIV>
|
||||
@ -401,7 +401,7 @@
|
||||
|
||||
<TR>
|
||||
<TD><CODE class="computeroutput">$(ROOT)/support/bsim_ctl adduser <SPAN class=
|
||||
"emphasis"><EM>username</EM></SPAN> dn="C=US,ST=MD,CN=Firstname User"</CODE></TD>
|
||||
"emphasis"><EM>username</EM></SPAN> --dn "C=US,ST=MD,CN=Firstname User"</CODE></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DIV>
|
||||
@ -410,7 +410,7 @@
|
||||
initially be set to 'changeme'. If PKI authentication has been set for the server, The
|
||||
Distinguished Name, as bound to the new user's certificated must be provided when
|
||||
issuing the <SPAN class="command"><STRONG>adduser</STRONG></SPAN> command, via the
|
||||
<SPAN class="command"><STRONG>dn=</STRONG></SPAN> option. The Distinguished Name must
|
||||
<SPAN class="command"><STRONG>--dn</STRONG></SPAN> option. The Distinguished Name must
|
||||
be presented as a string containing a comma separated sequence of attribute/value pairs
|
||||
that uniquely identifies a certificate. Currently, the Common Name (CN=) is the only
|
||||
attribute inspected by the PostgreSQL server, so other attributes can be omitted.</P>
|
||||
@ -836,17 +836,17 @@ curl -k -u elastic:XXXXXX -X POST "https://localhost:9200/_security/user/ghidrau
|
||||
<TABLE border="0" summary="Simple list" class="simplelist">
|
||||
<TR>
|
||||
<TD><CODE class="computeroutput">$(ROOT)/support/bsim setmetadata <SPAN class=
|
||||
"emphasis"><EM>bsimURL</EM></SPAN> "name=BSim Database"</CODE></TD>
|
||||
"emphasis"><EM>bsimURL</EM></SPAN> --name "BSim Database"</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE class="computeroutput">$(ROOT)/support/bsim setmetadata <SPAN class=
|
||||
"emphasis"><EM>bsimURL</EM></SPAN> "owner=Administrators"</CODE></TD>
|
||||
"emphasis"><EM>bsimURL</EM></SPAN> --owner "Administrators"</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE class="computeroutput">$(ROOT)/support/bsim setmetadata <SPAN class=
|
||||
"emphasis"><EM>bsimURL</EM></SPAN> "description=Files of interest"</CODE></TD>
|
||||
"emphasis"><EM>bsimURL</EM></SPAN> --description "Files of interest"</CODE></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DIV>
|
||||
@ -855,8 +855,8 @@ curl -k -u elastic:XXXXXX -X POST "https://localhost:9200/_security/user/ghidrau
|
||||
changed at any time and do not otherwise affect the records contained in the database.
|
||||
Multiple command-line parameters can be fed to <SPAN class="command"><STRONG>bsim
|
||||
setmetadata</STRONG></SPAN> so long as each one starts with <SPAN class=
|
||||
"bold"><STRONG>name=</STRONG></SPAN>, <SPAN class="bold"><STRONG>owner=</STRONG></SPAN>, or
|
||||
<SPAN class="bold"><STRONG>description=</STRONG></SPAN> respectively. Quoting may be
|
||||
"bold"><STRONG>--name</STRONG></SPAN>, <SPAN class="bold"><STRONG>--owner</STRONG></SPAN>, or
|
||||
<SPAN class="bold"><STRONG>--description</STRONG></SPAN> respectively. Quoting of values may be
|
||||
necessary to get some strings to be interpreted as a single command-line parameter.</P>
|
||||
|
||||
<DIV class="sect2">
|
||||
|
@ -112,20 +112,20 @@
|
||||
"command"><STRONG>bsim generatesigs</STRONG></SPAN> command. Signatures may be written as
|
||||
XML files to a local directory and/or committed directly to a specified BSim database. If
|
||||
not immediately committing to a database and only storing the XML files an appropriate
|
||||
database <EM>config=</EM> may be specified in lieu of a BSim database URL
|
||||
(<EM>bsimURL</EM>) if database specific executable categories and function tags are not
|
||||
utilized. Use of the <EM>config=</EM> option does not require a running BSim server.</P>
|
||||
database configuration may be specified using the <EM>--config</EM> option in lieu of a BSim database URL
|
||||
(--bsim <EM><bsimURL></EM>) if database specific executable categories and function tags are not
|
||||
utilized. Use of the <EM>--config</EM> option does not require a running BSim server.</P>
|
||||
|
||||
<DIV class="informalexample">
|
||||
<TABLE border="0" summary="Simple list" class="simplelist">
|
||||
<TR>
|
||||
<TD><CODE class="computeroutput">$(ROOT)/support/bsim generatesigs
|
||||
<ghidraURL> </xmldirectory> config=<config_template>
|
||||
<ghidraURL> </xmldirectory> --config <config_template>
|
||||
[--overwrite]<BR>
|
||||
$(ROOT)/support/bsim generatesigs <ghidraURL> </xmldirectory>
|
||||
bsim=<bsimURL> [--commit] [--overwrite]<BR>
|
||||
--bsim <bsimURL> [--commit] [--overwrite]<BR>
|
||||
$(ROOT)/support/bsim generatesigs <ghidraURL>
|
||||
bsim=<bsimURL></CODE></TD>
|
||||
--bsim <bsimURL></CODE></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DIV>
|
||||
@ -137,7 +137,7 @@
|
||||
<TR>
|
||||
<TD><CODE class="computeroutput">$(ROOT)/support/bsim generatesigs
|
||||
ghidra://localhost/repo/folder /xmldirectory
|
||||
bsim=postgresql://localhost/repo</CODE></TD>
|
||||
--bsim postgresql://localhost/repo</CODE></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DIV>
|
||||
@ -148,7 +148,7 @@
|
||||
<TABLE border="0" summary="Simple list" class="simplelist">
|
||||
<TR>
|
||||
<TD><CODE class="computeroutput">$(ROOT)/support/bsim generatesigs
|
||||
ghidra://localhost/repo/folder /xmldirectory bsim=postgresql://localhost/repo
|
||||
ghidra://localhost/repo/folder /xmldirectory --bsim postgresql://localhost/repo
|
||||
--commit</CODE></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
@ -176,7 +176,7 @@
|
||||
the signature generation process, such as database specific executable categories or
|
||||
function tags. As in the example above, configuration information
|
||||
is pulled from the BSim server and signatures are generated from the Ghidra Server
|
||||
executables. If the <SPAN class="bold"><STRONG>config=</STRONG></SPAN>
|
||||
executables. If the <SPAN class="bold"><STRONG>--config</STRONG></SPAN>
|
||||
option is used, assuming the template it specifies is the same one used to create the
|
||||
database and there are no executable categories or function tags, the BSim server
|
||||
does not need to be running.</P>
|
||||
@ -199,7 +199,7 @@
|
||||
<TABLE border="0" summary="Simple list" class="simplelist">
|
||||
<TR>
|
||||
<TD><CODE class="computeroutput">$(ROOT)/support/bsim commitsigs
|
||||
postgresql://localhost/repo /xmldirectory [override=<EM>ghidraURL</EM>]</CODE></TD>
|
||||
postgresql://localhost/repo /xmldirectory [--override <EM><ghidraURL></EM>]</CODE></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DIV>
|
||||
@ -215,7 +215,7 @@
|
||||
"emphasis"><EM>repository</EM></SPAN> and <SPAN class="emphasis"><EM>path</EM></SPAN>
|
||||
associated with it in the form of a <SPAN class="emphasis"><EM>ghidra://</EM></SPAN> URL
|
||||
that was recorded when the XML files were generated. This path can be overridden with the
|
||||
optional <SPAN class="bold"><STRONG>override=</STRONG></SPAN> parameter where a revised
|
||||
optional <SPAN class="bold"><STRONG>--override</STRONG></SPAN> option where a revised
|
||||
Ghidra URL may be specified.</P>
|
||||
|
||||
<P>The <SPAN class="command"><STRONG>bsim commitsigs</STRONG></SPAN> command can be
|
||||
@ -526,21 +526,21 @@ public void adjustTags(Address myaddress) throws Exception {
|
||||
<TABLE border="0" summary="Simple list" class="simplelist">
|
||||
<TR>
|
||||
<TD><CODE class="computeroutput">$(ROOT)/support/bsim delete <SPAN class=
|
||||
"emphasis"><EM>bsimURL</EM></SPAN> md5=<SPAN class=
|
||||
"emphasis"><EM><bsimURL></EM></SPAN> --md5 <SPAN class=
|
||||
"emphasis"><EM>7abf...</EM></SPAN></CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE class="computeroutput">$(ROOT)/support/bsim delete <SPAN class=
|
||||
"emphasis"><EM>bsimURL</EM></SPAN> name=<SPAN class=
|
||||
"emphasis"><EM><bsimURL></EM></SPAN> --name <SPAN class=
|
||||
"emphasis"><EM>...</EM></SPAN></CODE></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DIV>
|
||||
|
||||
<P>In the <SPAN class="emphasis"><EM>md5</EM></SPAN> form, you specify the 32 character
|
||||
<P>In the <SPAN class="emphasis"><EM>--md5</EM></SPAN> form, you specify the 32 character
|
||||
hex representation of the md5 hash of the executable, which should identify it
|
||||
uniquely. Using the <SPAN class="emphasis"><EM>name</EM></SPAN> form, there is the
|
||||
uniquely. Using the <SPAN class="emphasis"><EM>--name</EM></SPAN> form, there is the
|
||||
possibility that the name is not unique, in which case the command will fail.</P>
|
||||
|
||||
<P>If a unique executable is identified, its metadata record will be removed, and the
|
||||
@ -580,11 +580,11 @@ public void adjustTags(Address myaddress) throws Exception {
|
||||
<TABLE border="0" summary="Simple list" class="simplelist">
|
||||
<TR>
|
||||
<TD><CODE class="computeroutput">$(ROOT)/support/bsim generateupdates
|
||||
<ghidraURL> </xmldirectory> config=<config_template>
|
||||
<ghidraURL> </xmldirectory> --config <config_template>
|
||||
[--overwrite]<BR>
|
||||
$(ROOT)/support/bsim generateupdates <ghidraURL> </xmldirectory>
|
||||
bsim=<bsimURL> [--commit] [--overwrite]<BR>
|
||||
$(ROOT)/support/bsim generateupdates <ghidraURL> bsim=<bsimURL><BR>
|
||||
--bsim <bsimURL> [--commit] [--overwrite]<BR>
|
||||
$(ROOT)/support/bsim generateupdates <ghidraURL> --bsim <bsimURL><BR>
|
||||
<BR>
|
||||
$(ROOT)/support/bsim commitupdates <bsimURL>
|
||||
</xmldirectory></CODE></TD>
|
||||
@ -596,11 +596,13 @@ public void adjustTags(Address myaddress) throws Exception {
|
||||
stripped down metadata XML files for every executable contained within the repository
|
||||
folder specified by the <EM>ghidraURL</EM>. Just like the <SPAN class=
|
||||
"bold"><STRONG>generatesigs</STRONG></SPAN> command, it can take an optional <SPAN
|
||||
class="bold"><STRONG>config=<EM>config_template</EM></STRONG></SPAN> parameter, which
|
||||
allows the command to execute without the BSim server running. It can also take an
|
||||
class="bold"><STRONG>--config <EM><config_template></EM></STRONG></SPAN> parameter, which
|
||||
allows the command to execute without the BSim server running, otherwise a <SPAN
|
||||
class="bold"><STRONG>--bsim <EM><bsimURL></EM></STRONG></SPAN>
|
||||
parameter is required. It can also take an
|
||||
optional <SPAN class="bold"><STRONG>--overwrite</STRONG></SPAN> parameter, causing it
|
||||
to overwrite any previously generated XML files. If a
|
||||
<STRONG>bsim=<EM>bsimURL</EM></STRONG> is specified with the <STRONG>--commit</STRONG>
|
||||
to overwrite any previously generated XML files. If the
|
||||
<STRONG>--bsim</STRONG> option is specified with the <STRONG>--commit</STRONG>
|
||||
option updates will be committed directly to the database. A BSim database commit is
|
||||
always performed using the specified <EM>bsimURL</EM> if an <EM>xmldirectory</EM> is
|
||||
not specified.</P>
|
||||
@ -635,7 +637,7 @@ public void adjustTags(Address myaddress) throws Exception {
|
||||
<TABLE border="0" summary="Simple list" class="simplelist">
|
||||
<TR>
|
||||
<TD><CODE class="computeroutput">$(ROOT)/support/bsim dropindex <SPAN class=
|
||||
"emphasis"><EM>bsimURL</EM></SPAN></CODE></TD>
|
||||
"emphasis"><EM><bsimURL></EM></SPAN></CODE></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DIV>
|
||||
@ -646,7 +648,7 @@ public void adjustTags(Address myaddress) throws Exception {
|
||||
<TABLE border="0" summary="Simple list" class="simplelist">
|
||||
<TR>
|
||||
<TD><CODE class="computeroutput">$(ROOT)/support/bsim rebuildindex <SPAN class=
|
||||
"emphasis"><EM>bsimURL</EM></SPAN></CODE></TD>
|
||||
"emphasis"><EM><bsimURL></EM></SPAN></CODE></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</DIV>
|
||||
|
793
Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimControlLaunchable.java
Executable file → Normal file
793
Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimControlLaunchable.java
Executable file → Normal file
@ -29,6 +29,7 @@ import javax.naming.ldap.LdapName;
|
||||
import javax.naming.ldap.Rdn;
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
@ -40,7 +41,7 @@ import ghidra.framework.client.ClientUtil;
|
||||
import ghidra.net.ApplicationKeyManagerUtils;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.xml.SpecXmlUtils;
|
||||
import ghidra.xml.NonThreadedXmlPullParserImpl;
|
||||
import ghidra.xml.XmlPullParser;
|
||||
@ -48,22 +49,68 @@ import utilities.util.FileUtilities;
|
||||
|
||||
public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
|
||||
public static final String PORT_OPTION = "port=";
|
||||
public static final String CAFILE_OPTION = "cafile=";
|
||||
public static final String AUTH_OPTION = "auth=";
|
||||
public static final String DN_OPTION = "dn=";
|
||||
public static final String CERT_OPTION = "cert=";
|
||||
// bsim_ctl commands
|
||||
public final static String COMMAND_START = "start";
|
||||
public final static String COMMAND_STOP = "stop";
|
||||
public final static String COMMAND_RESET_PASSWORD = "resetpassword";
|
||||
public final static String COMMAND_CHANGE_PRIVILEGE = "changeprivilege";
|
||||
public final static String COMMAND_ADDUSER = "adduser";
|
||||
public final static String COMMAND_DROPUSER = "dropuser";
|
||||
public final static String COMMAND_CHANGEAUTH = "changeauth";
|
||||
|
||||
// Options that require a value argument
|
||||
public static final String CAFILE_OPTION = "--cafile";
|
||||
public static final String AUTH_OPTION = "--auth";
|
||||
public static final String DN_OPTION = "--dn";
|
||||
|
||||
// Global options that require a value argument
|
||||
public static final String PORT_OPTION = "--port";
|
||||
public static final String USER_OPTION = "--user";
|
||||
public static final String CERT_OPTION = "--cert";
|
||||
|
||||
// Define set of options that require a second value argument
|
||||
private static final Set<String> VALUE_OPTIONS =
|
||||
Set.of(PORT_OPTION, USER_OPTION, CERT_OPTION, CAFILE_OPTION, AUTH_OPTION, DN_OPTION);
|
||||
|
||||
private static final Set<String> GLOBAL_OPTIONS = Set.of(PORT_OPTION, USER_OPTION, CERT_OPTION);
|
||||
|
||||
// Boolean options
|
||||
public static final String NO_LOCAL_AUTH_OPTION = "--noLocalAuth";
|
||||
public static final String USER_OPTION = "user=";
|
||||
public static final String FORCE_OPTION = "--force";
|
||||
|
||||
private final static String START_COMMAND = "start";
|
||||
private final static String STOP_COMMAND = "stop";
|
||||
private final static String PASSWORD_COMMAND = "resetpassword";
|
||||
private final static String PRIVILEGE_COMMAND = "changeprivilege";
|
||||
private final static String ADDUSER_COMMAND = "adduser";
|
||||
private final static String DROPUSER_COMMAND = "dropuser";
|
||||
private final static String RESET_COMMAND = "changeauth";
|
||||
private static final Map<String, String> SHORTCUT_OPTION_MAP = new HashMap<>();
|
||||
static {
|
||||
SHORTCUT_OPTION_MAP.put("-a", AUTH_OPTION);
|
||||
SHORTCUT_OPTION_MAP.put("-p", PORT_OPTION);
|
||||
SHORTCUT_OPTION_MAP.put("-u", USER_OPTION);
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
// Populate ALLOWED_OPTION_MAP for each command
|
||||
private static final Set<String> START_OPTIONS =
|
||||
Set.of(AUTH_OPTION, DN_OPTION, NO_LOCAL_AUTH_OPTION, CAFILE_OPTION);
|
||||
private static final Set<String> STOP_OPTIONS =
|
||||
Set.of(FORCE_OPTION);
|
||||
private static final Set<String> RESET_PASSWORD_OPTIONS = Set.of();
|
||||
private static final Set<String> CHANGE_PRIVILEGE_OPTIONS = Set.of();
|
||||
private static final Set<String> ADDUSER_OPTIONS =
|
||||
Set.of(DN_OPTION);
|
||||
private static final Set<String> DROPUSER_OPTIONS = Set.of();
|
||||
private static final Set<String> CHANGEAUTH_OPTIONS = Set.of(
|
||||
AUTH_OPTION, NO_LOCAL_AUTH_OPTION, CAFILE_OPTION);
|
||||
|
||||
//@formatter:on
|
||||
private static final Map<String, Set<String>> ALLOWED_OPTION_MAP = new HashMap<>();
|
||||
static {
|
||||
ALLOWED_OPTION_MAP.put(COMMAND_START, START_OPTIONS);
|
||||
ALLOWED_OPTION_MAP.put(COMMAND_STOP, STOP_OPTIONS);
|
||||
ALLOWED_OPTION_MAP.put(COMMAND_RESET_PASSWORD, RESET_PASSWORD_OPTIONS);
|
||||
ALLOWED_OPTION_MAP.put(COMMAND_CHANGE_PRIVILEGE, CHANGE_PRIVILEGE_OPTIONS);
|
||||
ALLOWED_OPTION_MAP.put(COMMAND_ADDUSER, ADDUSER_OPTIONS);
|
||||
ALLOWED_OPTION_MAP.put(COMMAND_DROPUSER, DROPUSER_OPTIONS);
|
||||
ALLOWED_OPTION_MAP.put(COMMAND_CHANGEAUTH, CHANGEAUTH_OPTIONS);
|
||||
}
|
||||
|
||||
private final static String POSTGRES = "postgresql";
|
||||
private final static String POSTGRES_BUILD_SCRIPT = "Ghidra/Features/BSim/make-postgres.sh";
|
||||
private final static String POSTGRES_CONFIGFILE = "postgresql.conf";
|
||||
@ -80,73 +127,245 @@ public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
private final static int AUTHENTICATION_NONE = 0;
|
||||
private final static int AUTHENTICATION_PASSWORD = 1;
|
||||
private final static int AUTHENTICATION_PKI = 2;
|
||||
private GhidraApplicationLayout layout = null; // For holding on to JDBC logger so we can filter messages
|
||||
private File dataDirectory; // Directory containing postgres datafiles
|
||||
private File postgresRoot; // Directory containing postgres software
|
||||
private File postgresControl; // "pg_ctl" utility within postgres software
|
||||
private File certAuthorityFile = null; // Certificate authority file provided by the user
|
||||
private String certParameter = null; // Path to certificate provided by user
|
||||
private String distinguishedName = null; // Certificate distinguished name provided by the user
|
||||
private String commonName = null; // Common name extracted from distinguishedName
|
||||
private String connectingUserName = null; // User-name used to establish connection
|
||||
private String specifiedUserName = null; // -username- (add/drop) operation is being performed on
|
||||
private boolean adminPrivilegeRequested = false; // true is attempting to give user admin privileges
|
||||
private boolean forceShutdown = false; // Whether or not to force a shutdown (--force)
|
||||
private String loadLibraryVar = null; // Environment variable pointing to postgres shared libraries
|
||||
private String loadLibraryValue = null; // Directory containing shared libraries within postgres software
|
||||
private int port = -1; // Port over which to connect to postgres server, (-1 indicates default port is used)
|
||||
private int localAuthentication = AUTHENTICATION_NONE; // Type of authentication required for local connections
|
||||
private int hostAuthentication = AUTHENTICATION_NONE; // Type of authentication for remote connections
|
||||
private boolean authConfigPresent = false; // True if the [auth=..] option or the [--noLocalAuth] is present
|
||||
private File passwordFile = null; // File containing newly established password
|
||||
private char[] adminPasswordData = null; // Password data being sent to postgres server for authentication
|
||||
|
||||
private GhidraApplicationLayout layout;
|
||||
|
||||
private File dataDirectory; // Directory containing postgres datafiles
|
||||
private File postgresRoot; // Directory containing postgres software
|
||||
private File postgresControl; // "pg_ctl" utility within postgres software
|
||||
private File certAuthorityFile; // Certificate authority file provided by the user
|
||||
private String certParameter; // Path to certificate provided by user
|
||||
private String distinguishedName; // Certificate distinguished name provided by the user
|
||||
private String commonName; // Common name extracted from distinguishedName
|
||||
private String connectingUserName; // User-name used to establish connection
|
||||
private String specifiedUserName; // -username- (add/drop) operation is being performed on
|
||||
private boolean adminPrivilegeRequested; // true is attempting to give user admin privileges
|
||||
private boolean forceShutdown; // Whether or not to force a shutdown (--force)
|
||||
private String loadLibraryVar; // Environment variable pointing to postgres shared libraries
|
||||
private String loadLibraryValue; // Directory containing shared libraries within postgres software
|
||||
private int port; // Port over which to connect to postgres server, (-1 indicates default port is used)
|
||||
private int localAuthentication; // Type of authentication required for local connections
|
||||
private int hostAuthentication; // Type of authentication for remote connections
|
||||
private boolean authConfigPresent; // True if the [auth=..] option or the [--noLocalAuth] is present
|
||||
private File passwordFile; // File containing newly established password
|
||||
private char[] adminPasswordData; // Password data being sent to postgres server for authentication
|
||||
|
||||
// Database connection that can be persisted so we don't need to recreate one
|
||||
// for every call.
|
||||
private Connection localConnection;
|
||||
|
||||
/**
|
||||
* Exception triggered by missing, unknown, or improperly formatted command-line arguments
|
||||
* Constructor for launching from the console
|
||||
*/
|
||||
public static class ArgumentException extends Exception {
|
||||
public ArgumentException(String message) {
|
||||
super(message);
|
||||
}
|
||||
public BSimControlLaunchable() {
|
||||
}
|
||||
|
||||
private void clearParams() {
|
||||
dataDirectory = null;
|
||||
postgresRoot = null;
|
||||
postgresControl = null;
|
||||
certAuthorityFile = null;
|
||||
certParameter = null;
|
||||
distinguishedName = null;
|
||||
commonName = null;
|
||||
connectingUserName = null;
|
||||
specifiedUserName = null;
|
||||
adminPrivilegeRequested = false;
|
||||
forceShutdown = false;
|
||||
loadLibraryVar = null;
|
||||
loadLibraryValue = null;
|
||||
port = -1;
|
||||
localAuthentication = AUTHENTICATION_NONE;
|
||||
hostAuthentication = AUTHENTICATION_NONE;
|
||||
authConfigPresent = false;
|
||||
passwordFile = null;
|
||||
adminPasswordData = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for processing standard output or standard error for processes invoked by BSimControl
|
||||
* The streams can be optionally suppressed or dumped to System.out
|
||||
* Read required parameters followed by optional parameters
|
||||
* @param params is the original array of command line parameters
|
||||
*/
|
||||
private class IOThread extends Thread {
|
||||
private BufferedReader shellOutput; // Reader for the particular output stream
|
||||
private boolean suppressOutput; // If false, shell output is printed on the console
|
||||
private String readCommandLine(String[] params) throws IllegalArgumentException, IOException {
|
||||
|
||||
public IOThread(InputStream input, boolean suppressOut) {
|
||||
shellOutput = new BufferedReader(new InputStreamReader(input));
|
||||
suppressOutput = suppressOut;
|
||||
int slot = 0;
|
||||
|
||||
checkRequiredParam(params, slot, "command");
|
||||
String command = params[slot++];
|
||||
|
||||
switch (command) {
|
||||
case COMMAND_START:
|
||||
scanDataDirectory(params, slot++);
|
||||
break;
|
||||
case COMMAND_STOP:
|
||||
scanDataDirectory(params, slot++);
|
||||
break;
|
||||
case COMMAND_ADDUSER:
|
||||
scanDataDirectory(params, slot++);
|
||||
scanUsername(params, slot++);
|
||||
break;
|
||||
case COMMAND_DROPUSER:
|
||||
scanDataDirectory(params, slot++);
|
||||
scanUsername(params, slot++);
|
||||
break;
|
||||
case COMMAND_RESET_PASSWORD:
|
||||
scanUsername(params, slot++);
|
||||
break;
|
||||
case COMMAND_CHANGEAUTH:
|
||||
scanDataDirectory(params, slot++);
|
||||
break;
|
||||
case COMMAND_CHANGE_PRIVILEGE:
|
||||
scanUsername(params, slot++);
|
||||
scanPrivilege(params, slot++);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown command: " + command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String line = null;
|
||||
try {
|
||||
while ((line = shellOutput.readLine()) != null) {
|
||||
if (!suppressOutput) {
|
||||
System.out.println(line);
|
||||
}
|
||||
readOptions(command, params, slot);
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read in any optional parameters, strip them from the parameter stream
|
||||
* @param command command name
|
||||
* @param params is the original array of command line parameters
|
||||
* @param discard number of params already consumed
|
||||
*/
|
||||
private void readOptions(String command, String[] params, int discard) {
|
||||
|
||||
boolean sawNoLocalAuth = false;
|
||||
|
||||
Set<String> allowedParams = ALLOWED_OPTION_MAP.get(command);
|
||||
if (allowedParams == null) {
|
||||
throw new IllegalArgumentException("Unsupported command: " + command);
|
||||
}
|
||||
|
||||
for (int i = discard; i < params.length; ++i) {
|
||||
String optionName = params[i];
|
||||
String value = null;
|
||||
|
||||
if (optionName.startsWith("-")) {
|
||||
// although not prefered, allow option value to be specified as --option=value
|
||||
int ix = optionName.indexOf("=");
|
||||
if (ix > 1) {
|
||||
value = optionName.substring(ix + 1);
|
||||
optionName = optionName.substring(0, ix);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
// DO NOT USE LOGGING HERE (class loader)
|
||||
System.err.println("Unexpected Exception: " + e.getMessage());
|
||||
e.printStackTrace(System.err);
|
||||
|
||||
String option = optionName;
|
||||
|
||||
if (optionName.startsWith("-") && !optionName.startsWith("--")) {
|
||||
option = SHORTCUT_OPTION_MAP.get(optionName); // map option to -- long form
|
||||
if (option == null) {
|
||||
throw new IllegalArgumentException("Unsupported option use: " + optionName);
|
||||
}
|
||||
}
|
||||
|
||||
if (!option.startsWith("--")) {
|
||||
throw new IllegalArgumentException("Unexpected argument: " + option);
|
||||
}
|
||||
|
||||
if (!GLOBAL_OPTIONS.contains(option) && !allowedParams.contains(option)) {
|
||||
throw new IllegalArgumentException("Unsupported option use: " + optionName);
|
||||
}
|
||||
|
||||
if (!VALUE_OPTIONS.contains(option)) {
|
||||
// option without value arg
|
||||
if (value != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported option specification: " + optionName + "=");
|
||||
}
|
||||
}
|
||||
else if (StringUtils.isBlank(value)) {
|
||||
// consume next param as option value
|
||||
if (++i == params.length) {
|
||||
throw new IllegalArgumentException("Missing option value: " + optionName);
|
||||
}
|
||||
value = params[i];
|
||||
}
|
||||
|
||||
switch (option) {
|
||||
case PORT_OPTION:
|
||||
port = parsePositiveIntegerOption(optionName, value);
|
||||
break;
|
||||
case USER_OPTION:
|
||||
connectingUserName = value;
|
||||
break;
|
||||
case CERT_OPTION:
|
||||
certParameter = value;
|
||||
break;
|
||||
case CAFILE_OPTION:
|
||||
certAuthorityFile = new File(value);
|
||||
break;
|
||||
case AUTH_OPTION:
|
||||
authConfigPresent = true;
|
||||
String type = value;
|
||||
if (type.equals("pki")) {
|
||||
hostAuthentication = AUTHENTICATION_PKI;
|
||||
localAuthentication = AUTHENTICATION_PKI;
|
||||
}
|
||||
else if (type.equals("password")) {
|
||||
hostAuthentication = AUTHENTICATION_PASSWORD;
|
||||
localAuthentication = AUTHENTICATION_PASSWORD;
|
||||
}
|
||||
else if (type.equals("trust") || type.equals("none")) {
|
||||
hostAuthentication = AUTHENTICATION_NONE;
|
||||
localAuthentication = AUTHENTICATION_NONE;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Unknown authentication method: " +
|
||||
type + " : options are trust, password or pki");
|
||||
}
|
||||
break;
|
||||
case DN_OPTION:
|
||||
distinguishedName = value;
|
||||
validateDistinguishedName();
|
||||
break;
|
||||
case NO_LOCAL_AUTH_OPTION:
|
||||
sawNoLocalAuth = true;
|
||||
break;
|
||||
case FORCE_OPTION:
|
||||
forceShutdown = true;
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError("Missing option handling: " + option);
|
||||
}
|
||||
}
|
||||
|
||||
if (sawNoLocalAuth) { // Turn off authentication for local connections
|
||||
authConfigPresent = true;
|
||||
localAuthentication = AUTHENTICATION_NONE;
|
||||
}
|
||||
if (connectingUserName == null) {
|
||||
connectingUserName = ClientUtil.getUserName();
|
||||
}
|
||||
}
|
||||
|
||||
public BSimControlLaunchable() {
|
||||
// Constructor for main launcher
|
||||
private void checkRequiredParam(String[] params, int index, String name) {
|
||||
if (params.length <= index) {
|
||||
throw new IllegalArgumentException("Missing required parameter: " + name);
|
||||
}
|
||||
String p = params[index];
|
||||
if (p.startsWith("--")) {
|
||||
throw new IllegalArgumentException(
|
||||
"Missing required parameter (" + name + ") before specified option: " + p);
|
||||
}
|
||||
}
|
||||
|
||||
private int parsePositiveIntegerOption(String option, String optionValue) {
|
||||
try {
|
||||
int value = Integer.valueOf(optionValue);
|
||||
if (value < 0) {
|
||||
throw new IllegalArgumentException("Negative value not permitted for " + option);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Invalid integer value specified for " + option);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -179,9 +398,12 @@ public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
* Parse the -distinguishedName- String, verifying it is has the correct format for a
|
||||
* X509 certificate distinguished name. Try to extract the common name portion of the
|
||||
* distinguished name and assign it to -commonName-
|
||||
* @throws ArgumentException if the distinguished name is improperly formatted or the common name is missing
|
||||
* @throws IllegalArgumentException if the distinguished name is improperly formatted or the common name is missing
|
||||
*/
|
||||
private void validateDistinguishedName() throws ArgumentException {
|
||||
private void validateDistinguishedName() throws IllegalArgumentException {
|
||||
if (distinguishedName == null) {
|
||||
return;
|
||||
}
|
||||
commonName = null;
|
||||
try {
|
||||
LdapName ldapName = new LdapName(distinguishedName);
|
||||
@ -192,11 +414,11 @@ public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
}
|
||||
}
|
||||
if (commonName == null) {
|
||||
throw new ArgumentException("Missing common name attribute");
|
||||
throw new IllegalArgumentException("Missing common name attribute");
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new ArgumentException("Improperly formatted distinguished name");
|
||||
throw new IllegalArgumentException("Improperly formatted distinguished name");
|
||||
}
|
||||
}
|
||||
|
||||
@ -297,6 +519,10 @@ public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
* @throws IOException if the password file cannot be deleted
|
||||
*/
|
||||
private void cleanupPasswordData() throws IOException {
|
||||
|
||||
clearPasswordData(adminPasswordData);
|
||||
adminPasswordData = null;
|
||||
|
||||
if (passwordFile != null) {
|
||||
if (!passwordFile.delete()) {
|
||||
throw new IOException(
|
||||
@ -304,8 +530,6 @@ public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
}
|
||||
passwordFile = null;
|
||||
}
|
||||
clearPasswordData(adminPasswordData);
|
||||
adminPasswordData = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -367,18 +591,6 @@ public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize enough of Ghidra to allow navigation of configuration files and to allow SSL connections
|
||||
* @throws IOException if the headless authenticator cannot be initialized
|
||||
* @throws ClassNotFoundException if the postgres driver class cannot be found
|
||||
*/
|
||||
private void initializeApplication() throws IOException, ClassNotFoundException {
|
||||
if (layout != null) {
|
||||
// Initialize application environment consistent with bsim command
|
||||
BSimLaunchable.initializeApplication(layout, 0, connectingUserName, certParameter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a local connection to a postgres server. A full SSL connection is created using
|
||||
* Ghidra's infrastructure. If the initial connection fails because password authentication
|
||||
@ -678,7 +890,7 @@ public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
else if (hostAuthentication == AUTHENTICATION_PKI) {
|
||||
if (commonName == null) {
|
||||
throw new GeneralSecurityException(
|
||||
"Distinguished name required for " + connectingUserName + " (dn=\"..\")");
|
||||
"Distinguished name option (--dn) required for " + connectingUserName);
|
||||
}
|
||||
checkCertAuthorityFile();
|
||||
}
|
||||
@ -717,19 +929,19 @@ public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
/**
|
||||
* Scan the PostgreSQL data directory from the command-line
|
||||
* Make sure the directory exists and establish the File object -dataDirectory-
|
||||
* @param params are the command-line options
|
||||
* @param slot is the position to retrieve the data directory
|
||||
* @throws ArgumentException if the data directory is invalid
|
||||
* @param params are the command-line arguments
|
||||
* @param slot is the position to retrieve the data directory argument
|
||||
* @throws IllegalArgumentException if the data directory is invalid
|
||||
* @throws IOException if the canonical file cannot be retrieved
|
||||
*/
|
||||
private void scanDataDirectory(String[] params, int slot)
|
||||
throws ArgumentException, IOException {
|
||||
throws IllegalArgumentException, IOException {
|
||||
if (params.length <= slot) {
|
||||
throw new ArgumentException("Missing data directory");
|
||||
throw new IllegalArgumentException("Missing data directory");
|
||||
}
|
||||
dataDirectory = new File(params[slot]);
|
||||
if (!dataDirectory.isDirectory()) {
|
||||
throw new ArgumentException(
|
||||
throw new IllegalArgumentException(
|
||||
"Data directory " + dataDirectory.getAbsolutePath() + " does not exist");
|
||||
}
|
||||
dataDirectory = dataDirectory.getCanonicalFile();
|
||||
@ -737,13 +949,13 @@ public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
|
||||
/**
|
||||
* Scan the username from the command-line
|
||||
* @param params are the command-line options
|
||||
* @param slot is the position to retrieve the username
|
||||
* @throws ArgumentException if the user name is not in the given params
|
||||
* @param params are the command-line arguments
|
||||
* @param slot is the position to retrieve the username argument
|
||||
* @throws IllegalArgumentException if the user name is not in the given params
|
||||
*/
|
||||
private void scanUsername(String[] params, int slot) throws ArgumentException {
|
||||
private void scanUsername(String[] params, int slot) throws IllegalArgumentException {
|
||||
if (params.length <= slot) {
|
||||
throw new ArgumentException("Missing username");
|
||||
throw new IllegalArgumentException("Missing username");
|
||||
}
|
||||
specifiedUserName = params[slot];
|
||||
}
|
||||
@ -751,13 +963,13 @@ public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
/**
|
||||
* Scan command-line for a particular privilege level. Administrator privileges are
|
||||
* requested with the exact String "admin", anything is a request for a read-only user
|
||||
* @param params are the command-line options
|
||||
* @param slot is the position to retrieve the user name
|
||||
* @throws ArgumentException the privilege parameter is missing
|
||||
* @param params are the command-line arguments
|
||||
* @param slot is the position to retrieve the user name argument
|
||||
* @throws IllegalArgumentException the privilege parameter is missing
|
||||
*/
|
||||
private void scanPrivilege(String[] params, int slot) throws ArgumentException {
|
||||
private void scanPrivilege(String[] params, int slot) throws IllegalArgumentException {
|
||||
if (params.length <= slot) {
|
||||
throw new ArgumentException("Missing desired privilege (admin or user)");
|
||||
throw new IllegalArgumentException("Missing desired privilege (admin or user)");
|
||||
}
|
||||
if (params[slot].equals("admin")) {
|
||||
adminPrivilegeRequested = true;
|
||||
@ -766,7 +978,7 @@ public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
adminPrivilegeRequested = false;
|
||||
}
|
||||
else {
|
||||
throw new ArgumentException("Expecting privilege option (admin or user)");
|
||||
throw new IllegalArgumentException("Expecting privilege option (admin or user)");
|
||||
}
|
||||
}
|
||||
|
||||
@ -789,7 +1001,7 @@ public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
|
||||
if (localAuthentication == AUTHENTICATION_PKI && certParameter == null) {
|
||||
throw new GeneralSecurityException(
|
||||
"Path to certificate necessary to start server (cert=/path/to/cert)");
|
||||
"Path to certificate necessary to start server (--cert /path/to/cert)");
|
||||
}
|
||||
File logFile = new File(dataDirectory, "logfile");
|
||||
List<String> command = new ArrayList<String>();
|
||||
@ -883,58 +1095,6 @@ public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
FileUtilities.copyFile(copyFile, identFile, false, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all users registered with the BSim server.
|
||||
*
|
||||
* Note: This will return all users minus those created by Postgres (those that
|
||||
* start with 'pg_'.
|
||||
*
|
||||
* @param dataDirectory the location of the Postgres database files
|
||||
* @return map of database users and their admin status
|
||||
* @throws Exception if there's a problem initializing the Application or searching for Postgres
|
||||
*/
|
||||
public Map<String, Boolean> getUserRolesCommand(String dataDirectory) throws Exception {
|
||||
|
||||
String[] params = { dataDirectory };
|
||||
scanDataDirectory(params, 0);
|
||||
initializeApplication();
|
||||
discoverPostgresInstall();
|
||||
|
||||
if (connectingUserName == null) {
|
||||
connectingUserName = ClientUtil.getUserName();
|
||||
}
|
||||
|
||||
adminPasswordData = null;
|
||||
|
||||
localConnection = getOrCreateLocalConnection();
|
||||
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("SELECT rolname, rolsuper from pg_roles");
|
||||
try (Statement st = localConnection.createStatement()) {
|
||||
Map<String, Boolean> userToAdminMap = new HashMap<>();
|
||||
try (ResultSet rs = st.executeQuery(buffer.toString())) {
|
||||
while (rs.next()) {
|
||||
String user = rs.getString(1);
|
||||
|
||||
if (user.startsWith("pg_")) { // default postgres role - ignore
|
||||
continue;
|
||||
}
|
||||
Boolean isAdmin = rs.getBoolean(2);
|
||||
userToAdminMap.put(user, isAdmin);
|
||||
}
|
||||
return userToAdminMap;
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
Msg.error(this, "Error retrieving user roles from the Postgres database", e);
|
||||
}
|
||||
finally {
|
||||
localConnection.close();
|
||||
}
|
||||
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new user to the currently running server on the local host.
|
||||
* A connection is established, using the local interface, and the "CREATE ROLE" command
|
||||
@ -1073,7 +1233,7 @@ public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
* @throws SAXException if the {@link #tuneConfig(File, File, File, File, File)} call fails
|
||||
* @throws GeneralSecurityException if there is no Distinguished Name supplied
|
||||
*/
|
||||
private void resetCommand()
|
||||
private void changeAuthCommand()
|
||||
throws IOException, InterruptedException, SAXException, GeneralSecurityException {
|
||||
discoverPostgresInstall();
|
||||
File configFile = new File(dataDirectory, POSTGRES_CONFIGFILE);
|
||||
@ -1195,7 +1355,7 @@ public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
}
|
||||
}
|
||||
|
||||
private void privilegeCommand() throws Exception {
|
||||
private void changePrivilegeCommand() throws Exception {
|
||||
localConnection = getOrCreateLocalConnection();
|
||||
try {
|
||||
if (adminPrivilegeRequested) {
|
||||
@ -1214,231 +1374,158 @@ public class BSimControlLaunchable implements GhidraLaunchable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the command-line. First argument is always a command, which may
|
||||
* require additional arguments. Additional optional arguments may follow
|
||||
* @param params is the array of command-line arguments
|
||||
* @throws ArgumentException if the data directory cannot be scanned or the authentication method is invalid
|
||||
* @throws IOException if the data directory cannot be scanned
|
||||
*/
|
||||
private void readCommandLine(String[] params) throws ArgumentException, IOException {
|
||||
String command = params[0];
|
||||
int slot = 1;
|
||||
if (command.equals(START_COMMAND)) {
|
||||
scanDataDirectory(params, slot);
|
||||
slot += 1;
|
||||
}
|
||||
else if (command.equals(STOP_COMMAND)) {
|
||||
scanDataDirectory(params, slot);
|
||||
slot += 1;
|
||||
}
|
||||
else if (command.equals(ADDUSER_COMMAND)) {
|
||||
scanDataDirectory(params, slot);
|
||||
slot += 1;
|
||||
scanUsername(params, slot);
|
||||
slot += 1;
|
||||
}
|
||||
else if (command.equals(DROPUSER_COMMAND)) {
|
||||
scanDataDirectory(params, slot);
|
||||
slot += 1;
|
||||
scanUsername(params, slot);
|
||||
slot += 1;
|
||||
}
|
||||
else if (command.equals(PASSWORD_COMMAND)) {
|
||||
scanUsername(params, slot);
|
||||
slot += 1;
|
||||
}
|
||||
else if (command.equals(RESET_COMMAND)) {
|
||||
scanDataDirectory(params, slot);
|
||||
slot += 1;
|
||||
}
|
||||
else if (command.equals(PRIVILEGE_COMMAND)) {
|
||||
scanUsername(params, slot);
|
||||
slot += 1;
|
||||
scanPrivilege(params, slot);
|
||||
slot += 1;
|
||||
}
|
||||
else {
|
||||
throw new ArgumentException("Unknown command: " + command);
|
||||
}
|
||||
|
||||
// Scan for optional arguments
|
||||
boolean sawNoLocalAuth = false;
|
||||
for (int i = slot; i < params.length; ++i) {
|
||||
String option = params[i];
|
||||
if (option.startsWith(PORT_OPTION)) {
|
||||
port = Integer.parseInt(option.substring(PORT_OPTION.length()));
|
||||
}
|
||||
else if (option.startsWith(CAFILE_OPTION)) {
|
||||
certAuthorityFile = new File(option.substring(CAFILE_OPTION.length()));
|
||||
}
|
||||
else if (option.startsWith(AUTH_OPTION)) {
|
||||
authConfigPresent = true;
|
||||
String type = option.substring(AUTH_OPTION.length());
|
||||
if (type.equals("pki")) {
|
||||
hostAuthentication = AUTHENTICATION_PKI;
|
||||
localAuthentication = AUTHENTICATION_PKI;
|
||||
}
|
||||
else if (type.equals("password")) {
|
||||
hostAuthentication = AUTHENTICATION_PASSWORD;
|
||||
localAuthentication = AUTHENTICATION_PASSWORD;
|
||||
}
|
||||
else if (type.equals("trust") || type.equals("none")) {
|
||||
hostAuthentication = AUTHENTICATION_NONE;
|
||||
localAuthentication = AUTHENTICATION_NONE;
|
||||
}
|
||||
else {
|
||||
throw new ArgumentException(
|
||||
"Unknown authentication method: " + type + " : options are trust, pki");
|
||||
}
|
||||
}
|
||||
else if (option.startsWith(DN_OPTION)) {
|
||||
distinguishedName = option.substring(DN_OPTION.length());
|
||||
validateDistinguishedName();
|
||||
}
|
||||
else if (option.startsWith(CERT_OPTION)) {
|
||||
certParameter = option.substring(CERT_OPTION.length());
|
||||
}
|
||||
else if (option.startsWith(NO_LOCAL_AUTH_OPTION)) {
|
||||
sawNoLocalAuth = true;
|
||||
}
|
||||
else if (option.equals(FORCE_OPTION)) {
|
||||
forceShutdown = true;
|
||||
}
|
||||
else if (option.startsWith(USER_OPTION)) {
|
||||
connectingUserName = option.substring(USER_OPTION.length());
|
||||
}
|
||||
else {
|
||||
throw new ArgumentException("Unknown option: " + option);
|
||||
}
|
||||
}
|
||||
if (sawNoLocalAuth) { // Turn off authentication for local connections
|
||||
authConfigPresent = true;
|
||||
localAuthentication = AUTHENTICATION_NONE;
|
||||
}
|
||||
if (connectingUserName == null) {
|
||||
connectingUserName = ClientUtil.getUserName();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the command specified by the given set of params.
|
||||
*
|
||||
* @param params the command parameters
|
||||
* @param monitor the task monitor
|
||||
* @throws Exception if there is a problem executing the command
|
||||
*/
|
||||
public void run(String[] params, TaskMonitor monitor) throws Exception {
|
||||
String command = params[0];
|
||||
try {
|
||||
readCommandLine(params);
|
||||
initializeApplication();
|
||||
if (command.equals(START_COMMAND)) {
|
||||
startCommand();
|
||||
}
|
||||
else if (command.equals(STOP_COMMAND)) {
|
||||
stopCommand();
|
||||
}
|
||||
else if (command.equals(ADDUSER_COMMAND)) {
|
||||
addUserCommand();
|
||||
}
|
||||
else if (command.equals(DROPUSER_COMMAND)) {
|
||||
dropUserCommand();
|
||||
}
|
||||
else if (command.equals(RESET_COMMAND)) {
|
||||
resetCommand();
|
||||
}
|
||||
else if (command.equals(PASSWORD_COMMAND)) {
|
||||
passwordCommand();
|
||||
}
|
||||
else if (command.equals(PRIVILEGE_COMMAND)) {
|
||||
privilegeCommand();
|
||||
}
|
||||
}
|
||||
catch (SAXException e1) {
|
||||
System.err.println("Error in server configuation data");
|
||||
System.err.println(e1.getMessage());
|
||||
throw e1;
|
||||
}
|
||||
catch (IOException e1) {
|
||||
System.err.println("Error configuring PostgreSQL for BSim");
|
||||
System.err.println(e1.getMessage());
|
||||
throw e1;
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
System.err.println("Command was interrupted");
|
||||
System.err.println(e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
catch (SQLException e) {
|
||||
System.err.println("Error connecting to the database");
|
||||
System.err.println(e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
catch (GeneralSecurityException e) {
|
||||
System.err.println("Error establishing server certificate");
|
||||
System.err.println(e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
catch (ArgumentException e) {
|
||||
System.err.println("Error in command line arguments");
|
||||
System.err.println(e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
System.err.println("Could not find PostgreSQL JDBC driver");
|
||||
System.err.println(e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
cleanupPasswordData();
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the command specified by the given set of params.
|
||||
*
|
||||
* @param params the command parameters
|
||||
* @throws Exception if there is a problem executing the command
|
||||
* @param params the parameters specifying the command
|
||||
* @throws IllegalArgumentException if invalid params have been specified
|
||||
* @throws Exception if there's an error during the operation
|
||||
* @throws CancelledException if processing is cancelled
|
||||
*/
|
||||
public void run(String[] params) throws Exception {
|
||||
run(params, TaskMonitor.DUMMY);
|
||||
try {
|
||||
clearParams();
|
||||
|
||||
String command = readCommandLine(params);
|
||||
|
||||
initializeApplication();
|
||||
|
||||
switch (command) {
|
||||
case COMMAND_START:
|
||||
startCommand();
|
||||
break;
|
||||
case COMMAND_STOP:
|
||||
stopCommand();
|
||||
break;
|
||||
case COMMAND_ADDUSER:
|
||||
addUserCommand();
|
||||
break;
|
||||
case COMMAND_DROPUSER:
|
||||
dropUserCommand();
|
||||
break;
|
||||
case COMMAND_CHANGEAUTH:
|
||||
changeAuthCommand();
|
||||
break;
|
||||
case COMMAND_RESET_PASSWORD:
|
||||
passwordCommand();
|
||||
break;
|
||||
case COMMAND_CHANGE_PRIVILEGE:
|
||||
changePrivilegeCommand();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown command: " + command);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
cleanupPasswordData();
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void launch(GhidraApplicationLayout ghidraLayout, String[] params) {
|
||||
if (params.length <= 1) {
|
||||
//@formatter:off
|
||||
System.err.println("USAGE:");
|
||||
System.err.println(" bsim_ctl start </datadir-path> [auth=pki|password|trust] [--noLocalAuth] [cafile=</cacert-path>] [dn=\"..\"]");
|
||||
System.err.println(" stop </datadir-path> [--force]");
|
||||
System.err.println(" adduser </datadir-path> <username> [dn=\"..\"]");
|
||||
System.err.println(" dropuser </datadir-path> <username>");
|
||||
System.err.println(" changeauth </datadir-path> [auth=pki|password|trust] [--noLocalAuth] [cafile=</cacert-path>]");
|
||||
System.err.println(" resetpassword <username>");
|
||||
System.err.println(" changeprivilege <username> admin|user");
|
||||
System.err.println("USAGE: bsim_ctl [command] required-args... [OPTIONS...}\n");
|
||||
System.err.println(" start </datadir-path> [--auth|-a pki|password|trust] [--noLocalAuth] [--cafile \"</cacert-path>\"] [--dn \"<distinguished-name>\"]");
|
||||
System.err.println(" stop </datadir-path> [--force]");
|
||||
System.err.println(" adduser </datadir-path> <username> [--dn \"<distinguished-name>\"]");
|
||||
System.err.println(" dropuser </datadir-path> <username>");
|
||||
System.err.println(" changeauth </datadir-path> [--auth|-a pki|password|trust] [--noLocalAuth] [--cafile \"</cacert-path>\"]");
|
||||
System.err.println(" resetpassword <username>");
|
||||
System.err.println(" changeprivilege <username> admin|user");
|
||||
System.err.println();
|
||||
System.err.println("Global options:");
|
||||
System.err.println(" port=<portnum>");
|
||||
System.err.println(" user=<username>");
|
||||
System.err.println(" cert=</certfile-path>");
|
||||
System.err.println(" --port|-p <portnum>");
|
||||
System.err.println(" --user|-u <username>");
|
||||
System.err.println(" --cert </certfile-path>");
|
||||
System.err.println();
|
||||
System.err.println("NOTE: Options with values may also be specified using the form: --option=value\n");
|
||||
System.err.println();
|
||||
//@formatter:on
|
||||
return;
|
||||
}
|
||||
layout = ghidraLayout; // Save layout for when we need to initialize application
|
||||
boolean success = false;
|
||||
try {
|
||||
run(params);
|
||||
success = true;
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
catch (SAXException e1) {
|
||||
System.err.println("Error in server configuation data");
|
||||
System.err.println(e1.getMessage());
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
System.err.println("Command was interrupted");
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
catch (SQLException e) {
|
||||
System.err.println("Error connecting to the database");
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
catch (GeneralSecurityException e) {
|
||||
System.err.println("Error establishing server certificate");
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
System.err.println("Error in command line arguments");
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.err.println("Unexpected error");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize enough of Ghidra to allow navigation of configuration files and to allow SSL connections
|
||||
* @throws IOException if the headless authenticator cannot be initialized
|
||||
* @throws ClassNotFoundException if the postgres driver class cannot be found
|
||||
*/
|
||||
private void initializeApplication() throws IOException, ClassNotFoundException {
|
||||
if (layout != null) {
|
||||
// Initialize application environment consistent with bsim command
|
||||
BSimLaunchable.initializeApplication(layout, 0, connectingUserName, certParameter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for processing standard output or standard error for processes invoked by BSimControl
|
||||
* The streams can be optionally suppressed or dumped to System.out
|
||||
*/
|
||||
private class IOThread extends Thread {
|
||||
private BufferedReader shellOutput; // Reader for the particular output stream
|
||||
private boolean suppressOutput; // If false, shell output is printed on the console
|
||||
|
||||
public IOThread(InputStream input, boolean suppressOut) {
|
||||
shellOutput = new BufferedReader(new InputStreamReader(input));
|
||||
suppressOutput = suppressOut;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String line = null;
|
||||
try {
|
||||
while ((line = shellOutput.readLine()) != null) {
|
||||
if (!suppressOutput) {
|
||||
System.out.println(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
// DO NOT USE LOGGING HERE (class loader)
|
||||
System.err.println("Unexpected Exception: " + e.getMessage());
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ public interface FunctionDatabase extends AutoCloseable {
|
||||
public static boolean checkSettingsForInsert(DescriptionManager manage,
|
||||
DatabaseInformation info) throws LSHException, DatabaseNonFatalException {
|
||||
if (manage.numFunctions() == 0) {
|
||||
throw new DatabaseNonFatalException("ls ~/junk" + "");
|
||||
throw new DatabaseNonFatalException("Empty signature file");
|
||||
}
|
||||
int res = info.checkSignatureSettings(manage.getMajorVersion(), manage.getMinorVersion(),
|
||||
manage.getSettings());
|
||||
|
@ -20,6 +20,7 @@ import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import ghidra.GhidraApplicationLayout;
|
||||
@ -77,27 +78,29 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
private static Set<String> COMMANDS_WITH_REPO_ACCESS =
|
||||
Set.of(COMMAND_GENERATE_SIGS, COMMAND_GENERATE_UPDATES);
|
||||
|
||||
/**
|
||||
* Constants for the option parameters that can be set in the various commands.
|
||||
*/
|
||||
private static final String BSIM_URL_OPTION = "bsim=";
|
||||
private static final String GHIDRA_URL_OPTION = "ghidra=";
|
||||
private static final String NAME_OPTION = "name=";
|
||||
private static final String OWNER_OPTION = "owner=";
|
||||
private static final String DESCRIPTION_OPTION = "description=";
|
||||
private static final String OVERRIDE_OPTION = "override=";
|
||||
private static final String CONFIG_OPTION = "config=";
|
||||
private static final String MD5_OPTION = "md5=";
|
||||
private static final String MAX_FUNC_OPTION = "maxfunc=";
|
||||
private static final String FILTER_OPTION = "filter=";
|
||||
private static final String ARCH_OPTION = "arch=";
|
||||
private static final String COMPILER_OPTION = "compiler=";
|
||||
private static final String LIMIT_OPTION = "limit=";
|
||||
private static final String SORT_COL_OPTION = "sortcol=";
|
||||
// Options that require a value argument
|
||||
private static final String BSIM_URL_OPTION = "--bsim";
|
||||
private static final String NAME_OPTION = "--name";
|
||||
private static final String OWNER_OPTION = "--owner";
|
||||
private static final String DESCRIPTION_OPTION = "--description";
|
||||
private static final String OVERRIDE_OPTION = "--override";
|
||||
private static final String CONFIG_OPTION = "--config";
|
||||
private static final String MD5_OPTION = "--md5";
|
||||
private static final String MAX_FUNC_OPTION = "--maxfunc";
|
||||
private static final String ARCH_OPTION = "--arch";
|
||||
private static final String COMPILER_OPTION = "--compiler";
|
||||
private static final String LIMIT_OPTION = "--limit";
|
||||
private static final String SORT_COL_OPTION = "--sortcol";
|
||||
|
||||
// Global options
|
||||
private static final String USER_OPTION = "user=";
|
||||
private static final String CERT_OPTION = "cert=";
|
||||
// Global options that require a value argument
|
||||
private static final String USER_OPTION = "--user";
|
||||
private static final String CERT_OPTION = "--cert";
|
||||
|
||||
// Define set of options that require a second value argument
|
||||
private static final Set<String> VALUE_OPTIONS =
|
||||
Set.of(USER_OPTION, CERT_OPTION, BSIM_URL_OPTION, NAME_OPTION, OWNER_OPTION,
|
||||
DESCRIPTION_OPTION, OVERRIDE_OPTION, CONFIG_OPTION, MD5_OPTION, MAX_FUNC_OPTION,
|
||||
ARCH_OPTION, COMPILER_OPTION, LIMIT_OPTION, SORT_COL_OPTION);
|
||||
|
||||
private static final Set<String> GLOBAL_OPTIONS = Set.of(CERT_OPTION, USER_OPTION);
|
||||
|
||||
@ -111,12 +114,30 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
private static final String CALL_GRAPH_OPTION = "--callgraph";
|
||||
private static final String PRINT_JUST_EXE_OPTION = "--printjustexe";
|
||||
|
||||
private static final Map<String, String> SHORTCUT_OPTION_MAP = new HashMap<>();
|
||||
static {
|
||||
SHORTCUT_OPTION_MAP.put("-a", ARCH_OPTION);
|
||||
SHORTCUT_OPTION_MAP.put("-b", BSIM_URL_OPTION);
|
||||
SHORTCUT_OPTION_MAP.put("-c", CONFIG_OPTION);
|
||||
SHORTCUT_OPTION_MAP.put("-d", DESCRIPTION_OPTION);
|
||||
SHORTCUT_OPTION_MAP.put("-l", LIMIT_OPTION);
|
||||
SHORTCUT_OPTION_MAP.put("-m", MD5_OPTION);
|
||||
SHORTCUT_OPTION_MAP.put("-n", NAME_OPTION);
|
||||
SHORTCUT_OPTION_MAP.put("-o", OWNER_OPTION);
|
||||
SHORTCUT_OPTION_MAP.put("-s", SORT_COL_OPTION);
|
||||
SHORTCUT_OPTION_MAP.put("-u", USER_OPTION);
|
||||
//SHORTCUT_OPTION_MAP.put("", OVERRIDE_OPTION);
|
||||
//SHORTCUT_OPTION_MAP.put("", MAX_FUNC_OPTION);
|
||||
//SHORTCUT_OPTION_MAP.put("", COMPILER_OPTION);
|
||||
//SHORTCUT_OPTION_MAP.put("", CERT_OPTION);
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
// Populate ALLOWED_OPTION_MAP for each command
|
||||
private static final Set<String> CREATE_DATABASE_OPTIONS =
|
||||
Set.of(NAME_OPTION, OWNER_OPTION, DESCRIPTION_OPTION, NO_CALLGRAPH_OPTION);
|
||||
private static final Set<String> COMMIT_SIGS_OPTIONS =
|
||||
Set.of(OVERRIDE_OPTION, GHIDRA_URL_OPTION); // url requires override param
|
||||
Set.of(OVERRIDE_OPTION, MD5_OPTION); // url requires override param
|
||||
private static final Set<String> COMMIT_UPDATES_OPTIONS = Set.of();
|
||||
private static final Set<String> DELETE_OPTIONS =
|
||||
Set.of(MD5_OPTION, NAME_OPTION, ARCH_OPTION, COMPILER_OPTION); // one or more params required
|
||||
@ -164,23 +185,7 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
private URL ghidraURL;
|
||||
private URL bsimURL;
|
||||
|
||||
private String bsimURLOption; // Command-line option: bsim=..
|
||||
private String ghidraURLOption; // Command-line option: ghidra=..
|
||||
private String nameOption; // Command-line option: name=..
|
||||
private String ownerOption; // Command-line option: owner=..
|
||||
private String archOption; // Command-line option: arch=..
|
||||
private String compOption; // Command-line option: compiler=..
|
||||
private String descOption; // Command-line option: description=
|
||||
private String filterOption; // Command-line option: filter=
|
||||
private String configOption; // Command-line option: config=..
|
||||
private String md5Option; // Command-line option: md5=..
|
||||
private Integer maxFunc; // Command-line option: maxfunc=..
|
||||
private String certOption; // Command-line option: cert=..
|
||||
private String connectingUserName; // Command-line option: user=..
|
||||
private Integer limitOption; // Command-line option: limit=..
|
||||
private String sortColumn; // Command-line option: sortcol=..
|
||||
private boolean overrideOption; // Command-line option: override=
|
||||
|
||||
private Map<String, String> optionValueMap = new HashMap<>();
|
||||
private Set<String> booleanOptions = new HashSet<>();
|
||||
|
||||
private GhidraApplicationLayout layout;
|
||||
@ -199,22 +204,8 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
private void clearParams() {
|
||||
ghidraURL = null;
|
||||
bsimURL = null;
|
||||
bsimURLOption = null;
|
||||
ghidraURLOption = null;
|
||||
connectingUserName = null;
|
||||
nameOption = null;
|
||||
ownerOption = null;
|
||||
archOption = null;
|
||||
compOption = null;
|
||||
descOption = null;
|
||||
filterOption = null;
|
||||
configOption = null;
|
||||
md5Option = null;
|
||||
certOption = null;
|
||||
limitOption = null;
|
||||
sortColumn = null;
|
||||
overrideOption = false;
|
||||
booleanOptions.clear();
|
||||
optionValueMap.clear();
|
||||
}
|
||||
|
||||
private BulkSignatures getBulkSignatures()
|
||||
@ -223,6 +214,7 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
if (bsimURL != null) {
|
||||
serverInfo = new BSimServerInfo(bsimURL);
|
||||
}
|
||||
String connectingUserName = optionValueMap.get(USER_OPTION);
|
||||
return new BulkSignatures(serverInfo, connectingUserName);
|
||||
}
|
||||
|
||||
@ -281,6 +273,8 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
*/
|
||||
private List<String> readOptions(String command, String[] params, int discard) {
|
||||
|
||||
boolean sawOptions = false;
|
||||
|
||||
Set<String> allowedParams = ALLOWED_OPTION_MAP.get(command);
|
||||
if (allowedParams == null) {
|
||||
throw new IllegalArgumentException("Unsupported command: " + command);
|
||||
@ -288,101 +282,61 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
|
||||
List<String> subParams = new ArrayList<String>();
|
||||
for (int i = discard; i < params.length; ++i) {
|
||||
String option = params[i];
|
||||
String optionName = params[i];
|
||||
String value = null;
|
||||
|
||||
int ix = option.indexOf('=');
|
||||
if (ix > 0) {
|
||||
String checkOption = option.substring(0, ix + 1); // include '=' in option name
|
||||
if (!GLOBAL_OPTIONS.contains(checkOption) && !allowedParams.contains(checkOption)) {
|
||||
throw new IllegalArgumentException("Unsupported option use: " + checkOption);
|
||||
if (optionName.startsWith("-")) {
|
||||
// although not prefered, allow option value to be specified as --option=value
|
||||
int ix = optionName.indexOf("=");
|
||||
if (ix > 1) {
|
||||
value = optionName.substring(ix + 1);
|
||||
optionName = optionName.substring(0, ix);
|
||||
}
|
||||
}
|
||||
else if (option.startsWith("--")) {
|
||||
if (!GLOBAL_OPTIONS.contains(option) && !allowedParams.contains(option)) {
|
||||
throw new IllegalArgumentException("Unsupported option use: " + option);
|
||||
|
||||
String option = optionName;
|
||||
|
||||
if (optionName.startsWith("-") && !optionName.startsWith("--")) {
|
||||
option = SHORTCUT_OPTION_MAP.get(optionName); // map option to -- long form
|
||||
if (option == null) {
|
||||
throw new IllegalArgumentException("Unsupported option use: " + optionName);
|
||||
}
|
||||
booleanOptions.add(option);
|
||||
}
|
||||
|
||||
if (!option.startsWith("--")) {
|
||||
if (sawOptions) {
|
||||
throw new IllegalArgumentException("Unexpected argument: " + option);
|
||||
}
|
||||
subParams.add(params[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (option.startsWith(BSIM_URL_OPTION)) {
|
||||
bsimURLOption = option.substring(BSIM_URL_OPTION.length());
|
||||
sawOptions = true;
|
||||
if (!GLOBAL_OPTIONS.contains(option) && !allowedParams.contains(option)) {
|
||||
throw new IllegalArgumentException("Unsupported option use: " + optionName);
|
||||
}
|
||||
else if (option.startsWith(GHIDRA_URL_OPTION)) {
|
||||
ghidraURLOption = option.substring(GHIDRA_URL_OPTION.length());
|
||||
}
|
||||
else if (option.startsWith(NAME_OPTION)) {
|
||||
nameOption = option.substring(NAME_OPTION.length());
|
||||
}
|
||||
else if (option.startsWith(OWNER_OPTION)) {
|
||||
ownerOption = option.substring(OWNER_OPTION.length());
|
||||
}
|
||||
else if (option.startsWith(DESCRIPTION_OPTION)) {
|
||||
descOption = option.substring(DESCRIPTION_OPTION.length());
|
||||
}
|
||||
else if (option.startsWith(OVERRIDE_OPTION)) {
|
||||
overrideOption = true;
|
||||
ghidraURLOption = option.substring(OVERRIDE_OPTION.length());
|
||||
}
|
||||
else if (option.startsWith(CONFIG_OPTION)) {
|
||||
configOption = option.substring(CONFIG_OPTION.length());
|
||||
}
|
||||
else if (option.startsWith(MD5_OPTION)) {
|
||||
md5Option = option.substring(MD5_OPTION.length());
|
||||
}
|
||||
else if (option.startsWith(MAX_FUNC_OPTION)) {
|
||||
String val = option.substring(MAX_FUNC_OPTION.length());
|
||||
try {
|
||||
maxFunc = Integer.valueOf(val);
|
||||
if (maxFunc < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Negative value not permitted for maxfunc");
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Invalid decimal value for maxfunc: " + val);
|
||||
if (!VALUE_OPTIONS.contains(option)) {
|
||||
// consume option without value arg as a boolean option
|
||||
if (value != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported option specification: " + optionName + "=");
|
||||
}
|
||||
booleanOptions.add(option);
|
||||
}
|
||||
else if (option.startsWith(FILTER_OPTION)) {
|
||||
filterOption = option.substring(FILTER_OPTION.length());
|
||||
}
|
||||
else if (option.startsWith(CERT_OPTION)) { // global option
|
||||
certOption = option.substring(CERT_OPTION.length());
|
||||
}
|
||||
else if (option.startsWith(USER_OPTION)) { // global option
|
||||
connectingUserName = option.substring(USER_OPTION.length());
|
||||
}
|
||||
else if (option.startsWith(ARCH_OPTION)) {
|
||||
archOption = option.substring(ARCH_OPTION.length());
|
||||
}
|
||||
else if (option.startsWith(COMPILER_OPTION)) {
|
||||
compOption = option.substring(COMPILER_OPTION.length());
|
||||
}
|
||||
else if (option.startsWith(LIMIT_OPTION)) {
|
||||
String val = option.substring(LIMIT_OPTION.length());
|
||||
try {
|
||||
limitOption = Integer.valueOf(val);
|
||||
if (limitOption < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Negative value not permitted for limit");
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Invalid decimal value for limit: " + val);
|
||||
}
|
||||
}
|
||||
else if (option.startsWith(SORT_COL_OPTION)) {
|
||||
sortColumn = option.substring(SORT_COL_OPTION.length());
|
||||
}
|
||||
else if (params[i].startsWith("--") || params[i].contains("=")) {
|
||||
throw new IllegalArgumentException("Unknown option: " + params[i]);
|
||||
else if (!StringUtils.isBlank(value)) {
|
||||
optionValueMap.put(option, value);
|
||||
}
|
||||
else {
|
||||
subParams.add(params[i]);
|
||||
// consume next param as option value
|
||||
if (++i == params.length) {
|
||||
throw new IllegalArgumentException("Missing option value: " + optionName);
|
||||
}
|
||||
optionValueMap.put(option, params[i]);
|
||||
}
|
||||
}
|
||||
String connectingUserName = optionValueMap.get(USER_OPTION);
|
||||
if (connectingUserName == null) {
|
||||
connectingUserName = ClientUtil.getUserName();
|
||||
connectingUserName = optionValueMap.put(USER_OPTION, ClientUtil.getUserName());
|
||||
}
|
||||
return subParams;
|
||||
}
|
||||
@ -398,6 +352,23 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
}
|
||||
}
|
||||
|
||||
private Integer parsePositiveIntegerOption(String option) {
|
||||
String optionValue = optionValueMap.get(option);
|
||||
if (optionValue == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
int value = Integer.valueOf(optionValue);
|
||||
if (value < 0) {
|
||||
throw new IllegalArgumentException("Negative value not permitted for " + option);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Invalid integer value specified for " + option);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the command specified by the given set of params.
|
||||
*
|
||||
@ -409,6 +380,8 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
*/
|
||||
public void run(String[] params, TaskMonitor monitor) throws Exception, CancelledException {
|
||||
|
||||
clearParams();
|
||||
|
||||
checkRequiredParam(params, 0, "command");
|
||||
String command = params[0];
|
||||
if (!COMMAND_SET.contains(command)) {
|
||||
@ -420,7 +393,6 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
|
||||
monitor.setCancelEnabled(true);
|
||||
|
||||
clearParams();
|
||||
List<String> subParams = readOptions(command, params, 2);
|
||||
|
||||
initializeApplication(command);
|
||||
@ -458,8 +430,10 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
doGenerateSigs(subParams, monitor);
|
||||
}
|
||||
else if (COMMAND_COMMIT_SIGS.equals(command)) {
|
||||
if (overrideOption) {
|
||||
setupURLs(ghidraURLOption, urlstring);
|
||||
// --override option specified ghidra URL
|
||||
String ghidraURLOverride = optionValueMap.get(OVERRIDE_OPTION);
|
||||
if (ghidraURLOverride != null) {
|
||||
setupURLs(ghidraURLOverride, urlstring);
|
||||
}
|
||||
else {
|
||||
bsimURL = BSimClientFactory.deriveBSimURL(urlstring);
|
||||
@ -500,10 +474,12 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
}
|
||||
|
||||
private void processSigAndUpdateOptions(String urlstring) throws MalformedURLException {
|
||||
String bsimURLOption = optionValueMap.get(BSIM_URL_OPTION);
|
||||
String configOption = optionValueMap.get(CONFIG_OPTION);
|
||||
if (configOption != null) {
|
||||
if (bsimURLOption != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"bsim= and config= parameters may not both be present");
|
||||
BSIM_URL_OPTION + " and " + CONFIG_OPTION + " options may not both be present");
|
||||
}
|
||||
setupGhidraURL(urlstring);
|
||||
}
|
||||
@ -512,7 +488,7 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(
|
||||
"Must specify either \"bsim=\" or \"config=\" option is required");
|
||||
"Must specify either " + BSIM_URL_OPTION + " or " + CONFIG_OPTION + " option");
|
||||
}
|
||||
}
|
||||
|
||||
@ -543,6 +519,10 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
String configTemplate = params.get(0);
|
||||
boolean noTrackCallGraph = booleanOptions.contains(NO_CALLGRAPH_OPTION);
|
||||
|
||||
String nameOption = optionValueMap.get(NAME_OPTION);
|
||||
String ownerOption = optionValueMap.get(OWNER_OPTION);
|
||||
String descOption = optionValueMap.get(DESCRIPTION_OPTION);
|
||||
|
||||
try (BulkSignatures bsim = getBulkSignatures()) {
|
||||
bsim.createDatabase(configTemplate, nameOption, ownerOption, descOption,
|
||||
!noTrackCallGraph);
|
||||
@ -551,19 +531,20 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
|
||||
private void doGenerateSigs(List<String> params, TaskMonitor monitor)
|
||||
throws Exception, CancelledException {
|
||||
// concurrent bsim= and config= option use already checked
|
||||
// concurrent --bsim and --config option use already checked
|
||||
if (params.size() > 1) {
|
||||
throw new IllegalArgumentException("Invalid generatesigs parameter use!");
|
||||
}
|
||||
boolean commitOption = booleanOptions.contains(COMMIT_OPTION);
|
||||
boolean overwriteOption = booleanOptions.contains(OVERWRITE_OPTION);
|
||||
String configOption = optionValueMap.get(CONFIG_OPTION);
|
||||
|
||||
String xmlDirectory = null;
|
||||
if (params.size() == 1) {
|
||||
xmlDirectory = params.get(0);
|
||||
if (configOption != null && commitOption) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid option use with config= option: " + COMMIT_OPTION);
|
||||
"Invalid option use with " + CONFIG_OPTION + " option: " + COMMIT_OPTION);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -588,19 +569,20 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
|
||||
private void doGenerateUpdates(List<String> params, TaskMonitor monitor)
|
||||
throws Exception, CancelledException {
|
||||
// concurrent bsim= and config= option use already checked
|
||||
// concurrent --bsim and --config option use already checked
|
||||
if (params.size() > 1) {
|
||||
throw new IllegalArgumentException("Invalid generateupdates parameter use!");
|
||||
}
|
||||
boolean commitOption = booleanOptions.contains(COMMIT_OPTION);
|
||||
boolean overwriteOption = booleanOptions.contains(OVERWRITE_OPTION);
|
||||
String configOption = optionValueMap.get(CONFIG_OPTION);
|
||||
|
||||
String xmlDirectory = null;
|
||||
if (params.size() == 1) {
|
||||
xmlDirectory = params.get(0);
|
||||
if (configOption != null && commitOption) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid option use with config= option: " + COMMIT_OPTION);
|
||||
"Invalid option use with " + CONFIG_OPTION + " option: " + COMMIT_OPTION);
|
||||
}
|
||||
|
||||
}
|
||||
@ -640,17 +622,16 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
if (params.size() < 1) {
|
||||
throw new IllegalArgumentException("Missing directory containing signature files");
|
||||
}
|
||||
if (!overrideOption && ghidraURLOption != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"The \"ghidra=\" option use requires \"override\" option");
|
||||
}
|
||||
|
||||
String xmlDirectory = params.get(0);
|
||||
|
||||
File dir = checkDirectory(xmlDirectory);
|
||||
|
||||
boolean hasOverride = optionValueMap.containsKey(OVERRIDE_OPTION);
|
||||
String md5Filter = optionValueMap.get(MD5_OPTION);
|
||||
|
||||
try (BulkSignatures bsim = getBulkSignatures()) {
|
||||
bsim.sendXmlToQueryServer(dir, overrideOption ? ghidraURL : null, filterOption,
|
||||
monitor);
|
||||
bsim.sendXmlToQueryServer(dir, hasOverride ? ghidraURL : null, md5Filter, monitor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -678,10 +659,17 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
}
|
||||
|
||||
private void fillinSingleExeSpecifier(ExeSpecifier spec) throws IllegalArgumentException {
|
||||
|
||||
String md5Option = optionValueMap.get(MD5_OPTION);
|
||||
String nameOption = optionValueMap.get(NAME_OPTION);
|
||||
String archOption = optionValueMap.get(ARCH_OPTION);
|
||||
String compOption = optionValueMap.get(COMPILER_OPTION);
|
||||
|
||||
if (md5Option != null) {
|
||||
if (!isAllNull(nameOption, archOption, compOption)) {
|
||||
throw new IllegalArgumentException(
|
||||
"The name=, arch= and compiler= options are not valid when md5= option is specified.");
|
||||
"The " + NAME_OPTION + ", " + ARCH_OPTION + ", " + COMPILER_OPTION +
|
||||
" options are not valid when " + MD5_OPTION + " option is specified.");
|
||||
}
|
||||
spec.exemd5 = md5Option;
|
||||
}
|
||||
@ -691,14 +679,18 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
spec.execompname = compOption;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Must specify either \"md5=\" or \"name=\" option");
|
||||
throw new IllegalArgumentException(
|
||||
"Must specify either " + MD5_OPTION + " or " + NAME_OPTION + " option");
|
||||
}
|
||||
}
|
||||
|
||||
private void doListFunctions(List<String> params) throws IOException, LSHException {
|
||||
|
||||
Integer maxFunc = parsePositiveIntegerOption(MAX_FUNC_OPTION);
|
||||
|
||||
QueryName query = new QueryName();
|
||||
fillinSingleExeSpecifier(query.spec);
|
||||
|
||||
if (maxFunc != null) {
|
||||
query.maxfunc = maxFunc;
|
||||
}
|
||||
@ -792,17 +784,28 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
private void doListExes(List<String> params) throws IOException, LSHException {
|
||||
|
||||
int limit = DEFAULT_LIST_EXE_LIMIT;
|
||||
Integer limitOption = parsePositiveIntegerOption(LIMIT_OPTION);
|
||||
if (limitOption != null) {
|
||||
limit = limitOption;
|
||||
}
|
||||
boolean includeLibs = booleanOptions.contains(INCLUDE_LIBS_OPTION);
|
||||
String md5Option = optionValueMap.get(MD5_OPTION);
|
||||
String nameOption = optionValueMap.get(NAME_OPTION);
|
||||
String archOption = optionValueMap.get(ARCH_OPTION);
|
||||
String compOption = optionValueMap.get(COMPILER_OPTION);
|
||||
String sortColumnOption = optionValueMap.get(SORT_COL_OPTION);
|
||||
|
||||
try (BulkSignatures bsim = getBulkSignatures()) {
|
||||
List<ExecutableRecord> exeList = bsim.getExes(limit, md5Option, nameOption, archOption,
|
||||
compOption, sortColumn, includeLibs);
|
||||
compOption, sortColumnOption, includeLibs);
|
||||
for (ExecutableRecord exeRec : exeList) {
|
||||
Msg.info(this, exeRec.printRaw());
|
||||
}
|
||||
String summary = exeList.size() + " executables found";
|
||||
if (limit > 0 && limit == exeList.size()) {
|
||||
summary += " (results limit reached)";
|
||||
}
|
||||
Msg.info(this, summary);
|
||||
}
|
||||
}
|
||||
|
||||
@ -814,7 +817,13 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
* @throws LSHException if there's an error issuing the query
|
||||
*/
|
||||
private void doGetCount(List<String> params) throws IOException, LSHException {
|
||||
|
||||
boolean includeFakes = booleanOptions.contains(INCLUDE_LIBS_OPTION);
|
||||
String md5Option = optionValueMap.get(MD5_OPTION);
|
||||
String nameOption = optionValueMap.get(NAME_OPTION);
|
||||
String archOption = optionValueMap.get(ARCH_OPTION);
|
||||
String compOption = optionValueMap.get(COMPILER_OPTION);
|
||||
|
||||
try (BulkSignatures bsim = getBulkSignatures()) {
|
||||
int count = bsim.getCount(md5Option, nameOption, archOption, compOption, includeFakes);
|
||||
System.out.println("Matching executable count: " + count);
|
||||
@ -832,9 +841,14 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
* @throws LSHException if there's an error issuing the query
|
||||
*/
|
||||
private void doInstallMetadata(List<String> params) throws IOException, LSHException {
|
||||
|
||||
String nameOption = optionValueMap.get(NAME_OPTION);
|
||||
String ownerOption = optionValueMap.get(OWNER_OPTION);
|
||||
String descOption = optionValueMap.get(DESCRIPTION_OPTION);
|
||||
|
||||
if (isAllNull(nameOption, ownerOption, descOption)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Missing one or more metadata options: [name=..] [owner=..] [description=..]");
|
||||
throw new IllegalArgumentException("Missing one or more metadata options: " +
|
||||
NAME_OPTION + ", " + OWNER_OPTION + ", " + DESCRIPTION_OPTION);
|
||||
}
|
||||
|
||||
try (BulkSignatures bsim = getBulkSignatures()) {
|
||||
@ -920,30 +934,30 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
//@formatter:off
|
||||
System.err.println(
|
||||
"USAGE: bsim [command] required-args... [OPTIONS...]\n" +
|
||||
" createdatabase <bsimURL> <config_template> [name=\"<name>\"] [owner=\"<owner>\"] [description=\"<text>\"] [--nocallgraph]\n" +
|
||||
" setmetadata <bsimURL> [name=\"<name>\"] [owner=\"<owner>\"] [description=\"<text>\"]\n" +
|
||||
" createdatabase <bsimURL> <config_template> [--name|-n \"<name>\"] [--owner|-o \"<owner>\"] [--description|-d \"<text>\"] [--nocallgraph]\n" +
|
||||
" setmetadata <bsimURL> [--name|-n \"<name>\"] [--owner|-o \"<owner>\"] [--description|-d \"<text>\"]\n" +
|
||||
" addexecategory <bsimURL> <category_name> [--date]\n" +
|
||||
" addfunctiontag <bsimURL> <tag_name>\n" +
|
||||
" dropindex <bsimURL>\n" +
|
||||
" rebuildindex <bsimURL>\n" +
|
||||
" prewarm <bsimURL>\n" +
|
||||
" generatesigs <ghidraURL> </xmldirectory> config=<config_template> [--overwrite]\n" +
|
||||
" generatesigs <ghidraURL> </xmldirectory> bsim=<bsimURL> [--commit] [--overwrite]\n" +
|
||||
" generatesigs <ghidraURL> bsim=<bsimURL>\n" +
|
||||
" commitsigs <bsimURL> </xmldirectory> [md5=<hash>] [override=<ghidraURL>]\n" +
|
||||
" generateupdates <ghidraURL> </xmldirectory> config=<config_template> [--overwrite]\n" +
|
||||
" generateupdates <ghidraURL> </xmldirectory> bsim=<bsimURL> [--commit] [--overwrite]\n" +
|
||||
" generateupdates <ghidraURL> bsim=<bsimURL>\n" +
|
||||
" generatesigs <ghidraURL> </xmldirectory> --config|-c <config_template> [--overwrite]\n" +
|
||||
" generatesigs <ghidraURL> </xmldirectory> --bsim|-b <bsimURL> [--commit] [--overwrite]\n" +
|
||||
" generatesigs <ghidraURL> --bsim|-b <bsimURL>\n" +
|
||||
" commitsigs <bsimURL> </xmldirectory> [--md5|-m <hash>] [--override <ghidraURL>]\n" +
|
||||
" generateupdates <ghidraURL> </xmldirectory> --config|-c <config_template> [--overwrite]\n" +
|
||||
" generateupdates <ghidraURL> </xmldirectory> --bsim|-b <bsimURL> [--commit] [--overwrite]\n" +
|
||||
" generateupdates <ghidraURL> --bsim|-b <bsimURL>\n" +
|
||||
" commitupdates <bsimURL> </xmldirectory>\n" +
|
||||
" listexes <bsimURL> [md5=<hash>] [name=<exe_name>] [arch=<languageID>] [compiler=<cspecID>] [sortcol=<column_name>] [limit=<exe_count>] [--includelibs]\n" +
|
||||
" getexecount <bsimURL> [md5=<hash>] [name=<exe_name>] [arch=<languageID>] [compiler=<cspecID>] [--includelibs]\n" +
|
||||
" delete <bsimURL> [md5=<hash>] [name=<exe_name> [arch=<languageID>] [compiler=<cspecID>]]\n" +
|
||||
" listfuncs <bsimURL> [md5=<hash>] [name=<exe_name> [arch=<languageID>] [compiler=<cspecID>]] [--printselfsig] [--callgraph] [--printjustexe] [maxfunc=<max_count>]\n" +
|
||||
" dumpsigs <bsimURL> </xmldirectory> [md5=<hash>] [name=<exe_name> [arch=<languageID>] [compiler=<cspecID>]]\n" +
|
||||
" listexes <bsimURL> [--md5|-m <hash>] [--name|-n <exe_name>] [--arch|-a <languageID>] [--compiler <cspecID>] [--sortcol|-s md5|name] [--limit|-l <exe_count>] [--includelibs]\n" +
|
||||
" getexecount <bsimURL> [--md5|-m <hash>] [--name|-n <exe_name>] [--arch|-a <languageID>] [--compiler <cspecID>] [--includelibs]\n" +
|
||||
" delete <bsimURL> [--md5|-m <hash>] [--name|-n <exe_name> [--arch|-a <languageID>] [--compiler <cspecID>]]\n" +
|
||||
" listfuncs <bsimURL> [--md5|-m <hash>] [--name|-n <exe_name> [--arch|-a <languageID>] [--compiler <cspecID>]] [--printselfsig] [--callgraph] [--printjustexe] [--maxfunc <max_count>]\n" +
|
||||
" dumpsigs <bsimURL> </xmldirectory> [--md5|-m <hash>] [--name|-n <exe_name> [--arch|-a <languageID>] [--compiler <cspecID>]]\n" +
|
||||
"\n" +
|
||||
"Global options:\n" +
|
||||
" user=<username>\n" +
|
||||
" cert=</certfile-path>\n" +
|
||||
" --user|-u <username>\n" +
|
||||
" --cert </certfile-path>\n" +
|
||||
"\n" +
|
||||
"Enumerated Options:\n" +
|
||||
" <config_template> - large_32 | medium_32 | medium_64 | medium_cpool | medium_nosize \n" +
|
||||
@ -957,7 +971,8 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
"Ghidra URL Forms (ghidraURL):\n" +
|
||||
" ghidra://<hostname>[:<port>]/<repo-name>[/<folder-path>]\n" +
|
||||
" ghidra:/[<local-dirpath>/]<project-name>[?/<folder-path>]\n" +
|
||||
"\n");
|
||||
"\n" +
|
||||
"NOTE: Options with values may also be specified using the form: --option=value\n");
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@ -991,6 +1006,10 @@ public class BSimLaunchable implements GhidraLaunchable {
|
||||
private void initializeApplication(String command) throws IOException {
|
||||
int initType = COMMANDS_WITH_REPO_ACCESS.contains(command) ? 2 : 1;
|
||||
if (layout != null) {
|
||||
|
||||
String connectingUserName = optionValueMap.get(USER_OPTION);
|
||||
String certOption = optionValueMap.get(CERT_OPTION);
|
||||
|
||||
initializeApplication(layout, initType, connectingUserName, certOption);
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ import ghidra.features.bsim.query.client.tables.ExeTable.ExeTableOrderColumn;
|
||||
import ghidra.features.bsim.query.description.*;
|
||||
import ghidra.features.bsim.query.protocol.*;
|
||||
import ghidra.features.bsim.query.protocol.ResponseDelete.DeleteResult;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.client.ClientUtil;
|
||||
import ghidra.framework.protocol.ghidra.GhidraURL;
|
||||
import ghidra.program.model.listing.*;
|
||||
@ -184,6 +185,10 @@ public class BulkSignatures implements AutoCloseable {
|
||||
insertreq.path_override = GhidraURL.getProjectPathname(ghidraOverrideURL);
|
||||
}
|
||||
loadSignatureXml(file, insertreq.manage);
|
||||
if (insertreq.manage.numFunctions() == 0) {
|
||||
Msg.warn(this, file.getName() + ": does not define any functions");
|
||||
continue;
|
||||
}
|
||||
if (insertreq.execute(querydb) == null) {
|
||||
Error lastError = querydb.getLastError();
|
||||
if ((lastError.category == ErrorCategory.Format) ||
|
||||
@ -646,7 +651,7 @@ public class BulkSignatures implements AutoCloseable {
|
||||
establishQueryServerConnection(false);
|
||||
ExeTableOrderColumn sortEnum;
|
||||
if (sortCol != null) {
|
||||
sortEnum = ExeTableOrderColumn.valueOf(sortCol);
|
||||
sortEnum = ExeTableOrderColumn.valueOf(sortCol.toUpperCase());
|
||||
}
|
||||
else {
|
||||
sortEnum = ExeTableOrderColumn.MD5;
|
||||
@ -961,11 +966,12 @@ public class BulkSignatures implements AutoCloseable {
|
||||
protected File establishTemporaryDirectory(String xmldir) throws IOException {
|
||||
File dir;
|
||||
if (xmldir == null) {
|
||||
String tempDirString = System.getProperty("java.io.tmpdir");
|
||||
if (tempDirString == null) {
|
||||
File tmpDir = Application.getUserTempDirectory();
|
||||
if (tmpDir == null) {
|
||||
throw new IOException("Could not find temporary directory");
|
||||
}
|
||||
dir = new File(tempDirString, "bulkinsert_xml");
|
||||
dir = new File(tmpDir, "bulkinsert_xml");
|
||||
deleteTemporaryDirectory(dir);
|
||||
}
|
||||
else {
|
||||
dir = new File(xmldir);
|
||||
@ -983,6 +989,9 @@ public class BulkSignatures implements AutoCloseable {
|
||||
}
|
||||
|
||||
private void deleteTemporaryDirectory(File tempDir) throws IOException {
|
||||
if (!tempDir.exists()) {
|
||||
return;
|
||||
}
|
||||
File[] listFiles = tempDir.listFiles();
|
||||
if (listFiles == null) {
|
||||
throw new IOException(
|
||||
@ -1106,6 +1115,7 @@ public class BulkSignatures implements AutoCloseable {
|
||||
if (manager.numFunctions() == 0) {
|
||||
Msg.warn(this, program.getDomainFile().getName() +
|
||||
" contains no functions with signatures");
|
||||
return;
|
||||
}
|
||||
FileWriter fwrite = new FileWriter(file);
|
||||
manager.saveXml(fwrite);
|
||||
|
@ -3,7 +3,7 @@
|
||||
# Command-line script for interacting with a BSim database
|
||||
|
||||
# maximum heap memory (may be increased)
|
||||
MAXMEM=1G
|
||||
MAXMEM=2G
|
||||
|
||||
# launch mode (fg, bg, debug, debug-suspend)
|
||||
LAUNCH_MODE=fg
|
||||
|
@ -3,9 +3,8 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
:: Maximum heap memory may be changed if default is inadequate. This will generally be up to 1/4 of
|
||||
:: the physical memory available to the OS. Uncomment MAXMEM setting if non-default value is needed.
|
||||
::set MAXMEM=2G
|
||||
:: maximum heap memory (may be increased)
|
||||
set MAXMEM=2G
|
||||
|
||||
:: launch mode (fg, bg, debug, debug-suspend)
|
||||
set LAUNCH_MODE=fg
|
||||
|
@ -23,13 +23,13 @@ Non-shared projects are locked when open, and the lock will prevent the signatur
|
||||
|
||||
<pre><code class="language-bash">cd <ghidra_install_dir>/support
|
||||
mkdir ~/bsim_sigs
|
||||
./bsim generatesigs ghidra:/<ghidra_project_dir>/postgres_object_files bsim=file:/<database_dir>/example ~/bsim_sigs
|
||||
./bsim generatesigs ghidra:/<ghidra_project_dir>/postgres_object_files --bsim file:/<database_dir>/example ~/bsim_sigs
|
||||
</code></pre>
|
||||
|
||||
<ul>
|
||||
<li>The <code>ghidra:/</code> argument is the local project which holds the analyzed binaries.
|
||||
Note that there is only one forward slash in the URL for a local project.</li>
|
||||
<li>The <code>bsim=</code> argument is the URL of the BSim database.
|
||||
<li>The <code>--bsim</code> argument is the URL of the BSim database.
|
||||
This command does not add any signatures to the database, but it does query the database for its settings.</li>
|
||||
</ul>
|
||||
|
||||
|
@ -22,12 +22,12 @@ To generate the signature files, execute the following commands in a shell (adju
|
||||
```bash
|
||||
cd <ghidra_install_dir>/support
|
||||
mkdir ~/bsim_sigs
|
||||
./bsim generatesigs ghidra:/<ghidra_project_dir>/postgres_object_files bsim=file:/<database_dir>/example ~/bsim_sigs
|
||||
./bsim generatesigs ghidra:/<ghidra_project_dir>/postgres_object_files --bsim file:/<database_dir>/example ~/bsim_sigs
|
||||
```
|
||||
|
||||
- The ``ghidra:/`` argument is the local project which holds the analyzed binaries.
|
||||
Note that there is only one forward slash in the URL for a local project.
|
||||
- The ``bsim=`` argument is the URL of the BSim database.
|
||||
- The ``--bsim`` argument is the URL of the BSim database.
|
||||
This command does not add any signatures to the database, but it does query the database for its settings.
|
||||
|
||||
## Committing Signature Files
|
||||
|
Loading…
Reference in New Issue
Block a user