Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

speeding up svcscan --verbose mode #46

Closed
gleeda opened this issue Jul 10, 2014 · 2 comments
Closed

speeding up svcscan --verbose mode #46

gleeda opened this issue Jul 10, 2014 · 2 comments

Comments

@gleeda
Copy link
Member

gleeda commented Jul 10, 2014

currently the code is not very efficient when printing out service DLLs. This is because we are querying for running services and then querying for their appropriate registry key one at a time (currentcontrolset\services[SERVICE]\Parameters). This is fine if there are only a few services higher up in the alphabet, however since enumerating registry subkeys is an O(N) operation (for each key traversed) we get something like the following when choosing this method:

1 + 2 + 3 + 4 + ... + n

or n(n-1) / 2, which is pretty much n^2/2... (and in this case, because there are other paths that much be traversed, such as the paths to currentcontrolset and the path to services and also the path to parameters (each of which is roughly some m^2/2), so it's more than O(N^2) which is very slow...) You notice this especially when you get to services that start with letters towards the end of the alphabet. You can see this yourself when you run with --verbose that at first it will be very quick and then eventually it will slog down.

A better approach would be to get the service dlls ahead of time in a dictionary or something and then access them as needed.

For one sample you can see the speedup:

Before time (old method):

real 20m50.846s
user 16m38.999s
sys 3m41.336s

After fix:

real 1m28.326s
user 0m51.323s
sys 0m12.399s

I'll test it a bit more before committing

@gleeda
Copy link
Member Author

gleeda commented Jul 10, 2014

The patch is below and you can see that we are utilizing the given_root option so we can directly use the registry key objects instead of having to traverse for them again:

diff --git a/volatility/plugins/malware/svcscan.py b/volatility/plugins/malware/svcscan.py
index 1373758..2ec90ab 100644
--- a/volatility/plugins/malware/svcscan.py
+++ b/volatility/plugins/malware/svcscan.py
@@ -415,6 +415,15 @@ class SvcScan(common.AbstractWindowsCommand):
         if self._config.VERBOSE:
             regapi = registryapi.RegistryApi(self._config)
             ccs = regapi.reg_get_currentcontrolset()
+            key_name = "{0}\\services".format(ccs)
+            dlls = {}
+            for subkey in regapi.reg_get_all_subkeys(hive_name = "system", key = key_name):
+                for rootkey in regapi.reg_get_all_subkeys(hive_name = "system", key = "", given_root = subkey):
+                    if rootkey.Name == "Parameters":
+                        service_dll = regapi.reg_get_value(hive_name = "system", key = "", value = "ServiceDll", given_root = rootkey)
+                        if service_dll != None:
+                            dll = "{0}".format(service_dll)
+                            dlls[utils.remove_unprintable(str(subkey.Name))] = service_dll

         for rec in data:
             # This can't possibly look neat in a table with columns...
@@ -428,10 +437,7 @@ class SvcScan(common.AbstractWindowsCommand):
             outfd.write("Binary Path: {0}\n".format(rec.Binary))

             if self._config.VERBOSE:
-                val = regapi.reg_get_value(
-                                hive_name = "system", 
-                                key = "{0}\\services\\{1}\\Parameters".format(ccs, rec.ServiceName.dereference()), 
-                                value = "ServiceDll")
+                val = dlls.get("{0}".format(rec.ServiceName.dereference()), None)
                 if val is not None:
                     outfd.write("ServiceDll: {0}\n".format(val))

@iMHLv2
Copy link
Contributor

iMHLv2 commented Jul 11, 2014

sounds good to me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants