From 03002c76152d18a60db9d06cdcd4ec3c3ed32736 Mon Sep 17 00:00:00 2001 From: Joachim Metz Date: Wed, 13 Mar 2024 20:45:30 +0100 Subject: [PATCH] Worked on WPS name resolution tool --- .gitignore | 1 + msvscpp/Makefile.am | 1 + msvscpp/assorted.sln | 14 ++ msvscpp/wpsname/wpsname.vcproj | 234 +++++++++++++++++++++++++ src/Makefile.am | 19 +++ src/assorted_libfguid.h | 49 ++++++ src/winshellfolder.c | 2 +- src/winshelllink.c | 2 +- src/wpsname.c | 302 +++++++++++++++++++++++++++++++++ 9 files changed, 622 insertions(+), 2 deletions(-) create mode 100644 msvscpp/wpsname/wpsname.vcproj create mode 100644 src/assorted_libfguid.h create mode 100644 src/wpsname.c diff --git a/.gitignore b/.gitignore index c67db7b..63a76db 100644 --- a/.gitignore +++ b/.gitignore @@ -140,6 +140,7 @@ stamp-h[1-9] /src/serpentcrypt /src/unicodetouch /src/wevtinfo +/src/wpsname /src/winregsave /src/winshellfolder /src/winshelllink diff --git a/msvscpp/Makefile.am b/msvscpp/Makefile.am index 968f2f4..e7f1cc0 100644 --- a/msvscpp/Makefile.am +++ b/msvscpp/Makefile.am @@ -55,6 +55,7 @@ MSVSCPP_FILES = \ winregsave/winregsave.vcproj \ winshellfolder/winshellfolder.vcproj \ winshelllink/winshelllink.vcproj \ + wpsname/wpsname.vcproj \ xor32sum/xor32sum.vcproj \ xor64sum/xor64sum.vcproj \ zcompress/zcompress.vcproj \ diff --git a/msvscpp/assorted.sln b/msvscpp/assorted.sln index b2bb7c7..d667b38 100644 --- a/msvscpp/assorted.sln +++ b/msvscpp/assorted.sln @@ -221,6 +221,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wevtinfo", "wevtinfo\wevtin {DD4C0210-D36E-4E74-AA91-B39E54E81E22} = {DD4C0210-D36E-4E74-AA91-B39E54E81E22} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wpsname", "wpsname\wpsname.vcproj", "{703A8EDC-5601-4662-A226-1C4FFBFEB6C3}" + ProjectSection(ProjectDependencies) = postProject + {16510E82-C099-4A58-8ABE-E62D36E945E8} = {16510E82-C099-4A58-8ABE-E62D36E945E8} + {7CCEB0A1-5BFC-4006-A364-EDAFC545EBF3} = {7CCEB0A1-5BFC-4006-A364-EDAFC545EBF3} + {2B851ED2-22C8-4BB6-AE22-E49A75536FF5} = {2B851ED2-22C8-4BB6-AE22-E49A75536FF5} + {12DF7DB4-FC19-44F7-89B6-B7221EA77BE6} = {12DF7DB4-FC19-44F7-89B6-B7221EA77BE6} + {952218B5-15F2-4EEC-B67D-164407BAE738} = {952218B5-15F2-4EEC-B67D-164407BAE738} + {DD4C0210-D36E-4E74-AA91-B39E54E81E22} = {DD4C0210-D36E-4E74-AA91-B39E54E81E22} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winregsave", "winregsave\winregsave.vcproj", "{9A2ECE73-F064-437E-A379-D4DE6A040116}" ProjectSection(ProjectDependencies) = postProject {7CCEB0A1-5BFC-4006-A364-EDAFC545EBF3} = {7CCEB0A1-5BFC-4006-A364-EDAFC545EBF3} @@ -574,6 +584,10 @@ Global {4600994E-D3A1-43F0-BCEE-A4AA7C7781C8}.Release|Win32.Build.0 = Release|Win32 {4600994E-D3A1-43F0-BCEE-A4AA7C7781C8}.VSDebug|Win32.ActiveCfg = VSDebug|Win32 {4600994E-D3A1-43F0-BCEE-A4AA7C7781C8}.VSDebug|Win32.Build.0 = VSDebug|Win32 + {703A8EDC-5601-4662-A226-1C4FFBFEB6C3}.Release|Win32.ActiveCfg = Release|Win32 + {703A8EDC-5601-4662-A226-1C4FFBFEB6C3}.Release|Win32.Build.0 = Release|Win32 + {703A8EDC-5601-4662-A226-1C4FFBFEB6C3}.VSDebug|Win32.ActiveCfg = VSDebug|Win32 + {703A8EDC-5601-4662-A226-1C4FFBFEB6C3}.VSDebug|Win32.Build.0 = VSDebug|Win32 {9A2ECE73-F064-437E-A379-D4DE6A040116}.Release|Win32.ActiveCfg = Release|Win32 {9A2ECE73-F064-437E-A379-D4DE6A040116}.Release|Win32.Build.0 = Release|Win32 {9A2ECE73-F064-437E-A379-D4DE6A040116}.VSDebug|Win32.ActiveCfg = VSDebug|Win32 diff --git a/msvscpp/wpsname/wpsname.vcproj b/msvscpp/wpsname/wpsname.vcproj new file mode 100644 index 0000000..321084b --- /dev/null +++ b/msvscpp/wpsname/wpsname.vcproj @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Makefile.am b/src/Makefile.am index 83a8915..ab0ef13 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -48,6 +48,7 @@ bin_PROGRAMS = \ serpentcrypt \ unicodetouch \ wevtinfo \ + wpsname \ winregsave \ winshellfolder \ winshelllink \ @@ -478,6 +479,24 @@ wevtinfo_LDADD = \ @LIBCDATA_LIBADD@ \ @LIBCERROR_LIBADD@ +wpsname_SOURCES = \ + assorted_getopt.c assorted_getopt.h \ + assorted_i18n.h \ + assorted_libcerror.h \ + assorted_libcfile.h \ + assorted_libcnotify.h \ + assorted_libfguid.h \ + assorted_output.c assorted_output.h \ + wpsname.c + +wpsname_LDADD = \ + @LIBFGUID_LIBADD@ \ + @LIBCFILE_LIBADD@ \ + @LIBUNA_LIBADD@ \ + @LIBCNOTIFY_LIBADD@ \ + @LIBCLOCALE_LIBADD@ \ + @LIBCERROR_LIBADD@ + winregsave_SOURCES = \ assorted_getopt.c assorted_getopt.h \ assorted_i18n.h \ diff --git a/src/assorted_libfguid.h b/src/assorted_libfguid.h new file mode 100644 index 0000000..6723cea --- /dev/null +++ b/src/assorted_libfguid.h @@ -0,0 +1,49 @@ +/* + * The libfguid header wrapper + * + * Copyright (C) 2008-2024, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#if !defined( _ASSORTED_LIBFGUID_H ) +#define _ASSORTED_LIBFGUID_H + +#include + +/* Define HAVE_LOCAL_LIBFGUID for local use of libfguid + */ +#if defined( HAVE_LOCAL_LIBFGUID ) + +#include +#include +#include + +#else + +/* If libtool DLL support is enabled set LIBFGUID_DLL_IMPORT + * before including libfguid.h + */ +#if defined( _WIN32 ) && defined( DLL_IMPORT ) && !defined( HAVE_STATIC_EXECUTABLES ) +#define LIBFGUID_DLL_IMPORT +#endif + +#include + +#endif /* defined( HAVE_LOCAL_LIBFGUID ) */ + +#endif /* !defined( _ASSORTED_LIBFGUID_H ) */ + diff --git a/src/winshellfolder.c b/src/winshellfolder.c index e0d107e..4260a5a 100644 --- a/src/winshellfolder.c +++ b/src/winshellfolder.c @@ -54,7 +54,7 @@ void usage_fprint( } fprintf( stream, "Use winshellfolder to determine a Shell Folder from a path.\n\n" ); - fprintf( stream, "Usage: winshellfolder [ -12hvV ] path\n\n" ); + fprintf( stream, "Usage: winshellfolder [ -hvV ] path\n\n" ); fprintf( stream, "\tpath: the path to determine the shell folder of.\n" ); diff --git a/src/winshelllink.c b/src/winshelllink.c index 3e999e4..f71790f 100644 --- a/src/winshelllink.c +++ b/src/winshelllink.c @@ -55,7 +55,7 @@ void usage_fprint( } fprintf( stream, "Use winshelllink to determine a Shell Link from a path.\n\n" ); - fprintf( stream, "Usage: winshelllink [ -12hvV ] path\n\n" ); + fprintf( stream, "Usage: winshelllink [ -hvV ] path\n\n" ); fprintf( stream, "\tpath: the path to determine the shell link of.\n" ); diff --git a/src/wpsname.c b/src/wpsname.c new file mode 100644 index 0000000..2b23b18 --- /dev/null +++ b/src/wpsname.c @@ -0,0 +1,302 @@ +/* + * Determines the name of a Windows Property Store (WPS) property key + * + * Copyright (C) 2008-2024, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +#if defined( HAVE_STDLIB_H ) +#include +#endif + +#if defined( WINAPI ) +#include +#include +#endif + +#include "assorted_getopt.h" +#include "assorted_libcerror.h" +#include "assorted_libcfile.h" +#include "assorted_libcnotify.h" +#include "assorted_libfguid.h" +#include "assorted_output.h" + +/* Prints the executable usage information + */ +void usage_fprint( + FILE *stream ) +{ + if( stream == NULL ) + { + return; + } + fprintf( stream, "Use wpsname to determine the name of a Windows Property Store\n" + " (WPS) property key.\n\n" ); + + fprintf( stream, "Usage: wpsname [ -hvV ] guid pid\n\n" ); + + fprintf( stream, "\tguid: format identifier.\n" ); + fprintf( stream, "\tpid: property identifier.\n" ); + + fprintf( stream, "\t-h: shows this help\n" ); + fprintf( stream, "\t-v: verbose output to stderr\n" ); + fprintf( stream, "\t-V: print version\n" ); + fprintf( stream, "\n" ); +} + +/* The main program + */ +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) +int wmain( int argc, wchar_t * const argv[] ) +#else +int main( int argc, char * const argv[] ) +#endif +{ + libcerror_error_t *error = NULL; + system_character_t *options_string = NULL; + system_character_t *format_identifier = NULL; + system_character_t *property_identifier = NULL; + char *program = "wpsname"; + system_integer_t option = 0; + size_t string_length = 0; + int verbose = 0; + +#if defined( WINAPI ) + PROPERTYKEY property_key; + + wchar_t *name = NULL; + HRESULT result = 0; +#endif + + assorted_output_version_fprint( + stdout, + program ); + + options_string = _SYSTEM_STRING( "hvV" ); + + while( ( option = assorted_getopt( + argc, + argv, + options_string ) ) != (system_integer_t) -1 ) + { + switch( option ) + { + case (system_integer_t) '?': + default: + fprintf( + stderr, + "Invalid argument: %" PRIs_SYSTEM "\n", + argv[ optind ] ); + + usage_fprint( + stdout ); + + return( EXIT_FAILURE ); + + case (system_integer_t) 'h': + usage_fprint( + stdout ); + + return( EXIT_SUCCESS ); + + case (system_integer_t) 'v': + verbose = 1; + + break; + + case (system_integer_t) 'V': + assorted_output_copyright_fprint( + stdout ); + + return( EXIT_SUCCESS ); + } + } + if( optind == argc ) + { + fprintf( + stderr, + "Missing format identifier (GUID).\n" ); + + usage_fprint( + stdout ); + + return( EXIT_FAILURE ); + } + format_identifier = argv[ optind++ ]; + + if( optind == argc ) + { + fprintf( + stderr, + "Missing property identifier (PID).\n" ); + + usage_fprint( + stdout ); + + return( EXIT_FAILURE ); + } + property_identifier = argv[ optind++ ]; + + libcnotify_stream_set( + stderr, + NULL ); + libcnotify_verbose_set( + verbose ); + +#if defined( WINAPI ) + string_length = system_string_length( + format_identifier ); + + if( libfguid_identifier_initialize( + &guid, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create GUID.", + function ); + + goto on_error; + } + if( libfguid_identifier_copy_from_utf8_string( + guid, + format_identifier, + string_length, + LIBFGUID_STRING_FORMAT_FLAG_USE_MIXED_CASE, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to copy GUID from string.", + function ); + + goto on_error; + } + if( libfguid_identifier_copy_to_byte_stream( + guid, + property_key.fmtid, + 16, + LIBFGUID_ENDIAN_LITTLE, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to copy GUID to byte stream.", + function ); + + goto on_error; + } + if( libfguid_identifier_free( + &guid, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free GUID.", + function ); + + goto on_error; + } + + result = CoInitialize( + NULL ); + + if( FAILED( result ) ) + { + result = GetLastError(); + + libcerror_system_set_error( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GENERIC, + (uint32_t) result, + "unable to initialize COM." ); + + goto on_error; + } + property_key.pid = atol( property_identifier ); + + result = PSGetNameFromPropertyKey( + &property_key, &name ); + + if( SUCCEEDED( result ) ) + { + fprintf( + stdout, + "%ls\n", + name ); + + CoTaskMemFree( + name ); + + name = NULL; + } + CoUninitialize(); + + return( EXIT_SUCCESS ); +#else + fprintf( + stderr, + "This program requires WINAPI.\n" ); + + return( EXIT_FAILURE ); + +#endif /* defined( WINAPI ) */ + +on_error: + if( error != NULL ) + { + libcnotify_print_error_backtrace( + error ); + libcerror_error_free( + &error ); + } +#if defined( WINAPI ) + if( name != NULL ) + { + CoTaskMemFree( + name ); + + name = NULL; + } + if( guid != NULL ) + { + libfguid_identifier_free( + &guid, + NULL ); + } + CoUninitialize(); + +#endif /* defined( WINAPI ) */ + + return( EXIT_FAILURE ); +} +