From 14aa63bbc255def73994b67d946a671c42d748f7 Mon Sep 17 00:00:00 2001 From: kwakmu18 Date: Sun, 15 Dec 2024 17:58:21 +0900 Subject: [PATCH 1/5] Add New Features Add New Features --- FindInterface/FindInterface.cpp | 101 + FindInterface/FindInterface.vcxproj | 143 + FindInterface/FindInterface.vcxproj.filters | 22 + FindInterfaceInproc/FindInterfaceInproc.cpp | 94 + .../FindInterfaceInproc.vcxproj | 141 + .../FindInterfaceInproc.vcxproj.filters | 22 + OleViewDotNet.sln | 72 + OleViewDotNet/Forms/COMRegistryViewer.cs | 4499 +++++++++-------- .../Forms/CallSequenceForm.Designer.cs | 138 + OleViewDotNet/Forms/CallSequenceForm.cs | 202 + OleViewDotNet/Forms/DllFixForm.Designer.cs | 103 + OleViewDotNet/Forms/DllFixForm.cs | 73 + .../Forms/FindInterfaceForm.Designer.cs | 123 + OleViewDotNet/Forms/FindInterfaceForm.cs | 61 + OleViewDotNet/Forms/FindInterfaceForm.resx | 120 + OleViewDotNet/Forms/IDAPathForm.Designer.cs | 108 + OleViewDotNet/Forms/IDAPathForm.cs | 23 + OleViewDotNet/Forms/IDAPathForm.resx | 120 + OleViewDotNet/Forms/MainForm.Designer.cs | 290 +- OleViewDotNet/Forms/MainForm.cs | 1759 +++---- OleViewDotNet/Forms/ResolveMethod.cs | 589 +++ OleViewDotNet/Forms/ResolvingForm.Designer.cs | 103 + OleViewDotNet/Forms/ResolvingForm.cs | 57 + OleViewDotNet/Forms/ResolvingForm.resx | 120 + .../Forms/SourceCodeViewerControl.Designer.cs | 9 + .../Forms/SourceCodeViewerControl.cs | 343 +- OleViewDotNet/ProgramSettings.cs | 118 +- 27 files changed, 6414 insertions(+), 3139 deletions(-) create mode 100644 FindInterface/FindInterface.cpp create mode 100644 FindInterface/FindInterface.vcxproj create mode 100644 FindInterface/FindInterface.vcxproj.filters create mode 100644 FindInterfaceInproc/FindInterfaceInproc.cpp create mode 100644 FindInterfaceInproc/FindInterfaceInproc.vcxproj create mode 100644 FindInterfaceInproc/FindInterfaceInproc.vcxproj.filters create mode 100644 OleViewDotNet/Forms/CallSequenceForm.Designer.cs create mode 100644 OleViewDotNet/Forms/CallSequenceForm.cs create mode 100644 OleViewDotNet/Forms/DllFixForm.Designer.cs create mode 100644 OleViewDotNet/Forms/DllFixForm.cs create mode 100644 OleViewDotNet/Forms/FindInterfaceForm.Designer.cs create mode 100644 OleViewDotNet/Forms/FindInterfaceForm.cs create mode 100644 OleViewDotNet/Forms/FindInterfaceForm.resx create mode 100644 OleViewDotNet/Forms/IDAPathForm.Designer.cs create mode 100644 OleViewDotNet/Forms/IDAPathForm.cs create mode 100644 OleViewDotNet/Forms/IDAPathForm.resx create mode 100644 OleViewDotNet/Forms/ResolveMethod.cs create mode 100644 OleViewDotNet/Forms/ResolvingForm.Designer.cs create mode 100644 OleViewDotNet/Forms/ResolvingForm.cs create mode 100644 OleViewDotNet/Forms/ResolvingForm.resx diff --git a/FindInterface/FindInterface.cpp b/FindInterface/FindInterface.cpp new file mode 100644 index 00000000..28d61073 --- /dev/null +++ b/FindInterface/FindInterface.cpp @@ -0,0 +1,101 @@ +#define _CRT_SECURE_NO_WARNINGS +#include +#include + +#pragma comment(lib, "Ole32.lib") + +MULTI_QI mq[50000]; +WCHAR keys[50000][256]; +CLSID clsid; +DWORD index; + +DWORD WINAPI FindInterface(LPVOID args) { + DWORD retval; + __try { + HANDLE hFile = CreateFile(L"now.local", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == NULL) return GetLastError(); + char line[256]; + + SIZE_T convertedSize; + INT cnt = 0; + DWORD nBytes; + + HRESULT hr = CoCreateInstanceEx(clsid, NULL, CLSCTX_LOCAL_SERVER, NULL, index, mq); + if (hr < 0) { + printf("CoCreateInstanceEx(LOCAL) Failed. hr: 0x%X\n", hr); + retval = hr; + } + else { + for (INT i = 0; i < index; i++) { + + if (mq[i].hr == S_OK) { + memset(line, 0, 256); + wcstombs_s(&convertedSize, line, keys[i], 256); + strcat(line, "\n"); + if (!WriteFile(hFile, line, strlen(line), &nBytes, NULL)) return GetLastError(); + cnt++; + mq[i].pItf->Release(); + } + } + } + if (cnt != 0) return 0; + else return 0x80004002; + } + __except (EXCEPTION_EXECUTE_HANDLER) { + printf("Exception!"); + return GetExceptionCode(); + } + return retval; +} + +INT wmain(INT argc, WCHAR **argv) { + CoInitializeEx(NULL, COINIT_MULTITHREADED); + + HRESULT hr; + + hr = CLSIDFromString(argv[1], &clsid); + if (hr < 0) { + printf("CLSIDFromString() Failed. hr: 0x%X\n", hr); + return hr; + } + + HKEY hKey; + LSTATUS status; + status = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Interface", 0, KEY_READ, &hKey); + if (status != ERROR_SUCCESS) { + printf("RegOpenKeyExW() Failed. LastError: %lu\n", GetLastError()); + } + FILETIME lastWriteTime; + WCHAR keyName[256]; + DWORD keyNameSize; + while (true) { + keyNameSize = sizeof(keyName) / sizeof(keyName[0]); + status = RegEnumKeyExW(hKey, index, keyName, &keyNameSize, NULL, NULL, NULL, &lastWriteTime); + lstrcpy(keys[index], keyName); + if (status == ERROR_NO_MORE_ITEMS) break; + + IID* iid = (IID*)malloc(sizeof(IID)); + IIDFromString(keyName, iid); + + mq[index].pIID = iid; + index++; + } + + DWORD tid; + HANDLE hThread = CreateThread(NULL, 0, FindInterface, NULL, 0, &tid); + + DWORD waitResult = WaitForSingleObject(hThread, 10000); + + + DWORD retval; + if (waitResult == WAIT_OBJECT_0) { + GetExitCodeThread(hThread, &retval); + } + else if (waitResult == WAIT_TIMEOUT) { + retval = 0xFFFFFFFF; + } + else retval = 0xEEEEEEEE; + + CoUninitialize(); + return retval; +} \ No newline at end of file diff --git a/FindInterface/FindInterface.vcxproj b/FindInterface/FindInterface.vcxproj new file mode 100644 index 00000000..8645ec6b --- /dev/null +++ b/FindInterface/FindInterface.vcxproj @@ -0,0 +1,143 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {5d31fa24-fe76-4f13-9cc8-41ff178beecb} + FindInterface + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)bin\$(Configuration)\ + + + $(SolutionDir)bin\$(Configuration)\ + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/FindInterface/FindInterface.vcxproj.filters b/FindInterface/FindInterface.vcxproj.filters new file mode 100644 index 00000000..430de387 --- /dev/null +++ b/FindInterface/FindInterface.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 소스 파일 + + + \ No newline at end of file diff --git a/FindInterfaceInproc/FindInterfaceInproc.cpp b/FindInterfaceInproc/FindInterfaceInproc.cpp new file mode 100644 index 00000000..dc61dd5e --- /dev/null +++ b/FindInterfaceInproc/FindInterfaceInproc.cpp @@ -0,0 +1,94 @@ +#define _CRT_SECURE_NO_WARNINGS +#include +#include + +#pragma comment(lib, "Ole32.lib") + +MULTI_QI mq[50000]; +WCHAR keys[50000][256]; +CLSID clsid; +DWORD index; + +DWORD WINAPI FindInterface(LPVOID args) { + DWORD retval; + __try { + HANDLE hFile = CreateFile(L"now.inproc", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == NULL) return GetLastError(); + char line[256]; + + SIZE_T convertedSize; + INT cnt = 0; + DWORD nBytes; + + HRESULT hr; + IID iid; + LPVOID ppv; + for (INT i = 0; i < index; i++) { + IIDFromString(keys[i], &iid); + hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, &ppv); + if (hr < 0) continue; + memset(line, 0, 256); + wcstombs_s(&convertedSize, line, keys[i], 256); + if (!WriteFile(hFile, line, strlen(line), &nBytes, NULL)) return GetLastError(); + } + if (cnt != 0) return 0; + else return 0x80004002; + } + __except (EXCEPTION_EXECUTE_HANDLER) { + printf("Exception!"); + return GetExceptionCode(); + } + return retval; +} + +INT wmain(INT argc, WCHAR** argv) { + CoInitializeEx(NULL, COINIT_MULTITHREADED); + + HRESULT hr; + + hr = CLSIDFromString(argv[1], &clsid); + if (hr < 0) { + printf("CLSIDFromString() Failed. hr: 0x%X\n", hr); + return hr; + } + + HKEY hKey; + LSTATUS status; + status = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Interface", 0, KEY_READ, &hKey); + if (status != ERROR_SUCCESS) { + printf("RegOpenKeyExW() Failed. LastError: %lu\n", GetLastError()); + } + FILETIME lastWriteTime; + WCHAR keyName[256]; + DWORD keyNameSize; + while (true) { + keyNameSize = sizeof(keyName) / sizeof(keyName[0]); + status = RegEnumKeyExW(hKey, index, keyName, &keyNameSize, NULL, NULL, NULL, &lastWriteTime); + lstrcpy(keys[index], keyName); + if (status == ERROR_NO_MORE_ITEMS) break; + + IID* iid = (IID*)malloc(sizeof(IID)); + IIDFromString(keyName, iid); + + mq[index].pIID = iid; + index++; + } + + DWORD tid; + HANDLE hThread = CreateThread(NULL, 0, FindInterface, NULL, 0, &tid); + + DWORD waitResult = WaitForSingleObject(hThread, 20000); + + + DWORD retval; + if (waitResult == WAIT_OBJECT_0) { + GetExitCodeThread(hThread, &retval); + } + else if (waitResult == WAIT_TIMEOUT) { + retval = 0xFFFFFFFF; + } + else retval = 0xEEEEEEEE; + + CoUninitialize(); + return retval; +} \ No newline at end of file diff --git a/FindInterfaceInproc/FindInterfaceInproc.vcxproj b/FindInterfaceInproc/FindInterfaceInproc.vcxproj new file mode 100644 index 00000000..603833ee --- /dev/null +++ b/FindInterfaceInproc/FindInterfaceInproc.vcxproj @@ -0,0 +1,141 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {4091323f-6487-4800-a38e-09b61dcb977e} + FindInterfaceInproc + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)bin\$(Configuration)\ + + + $(SolutionDir)bin\$(Configuration)\ + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/FindInterfaceInproc/FindInterfaceInproc.vcxproj.filters b/FindInterfaceInproc/FindInterfaceInproc.vcxproj.filters new file mode 100644 index 00000000..43bdbee0 --- /dev/null +++ b/FindInterfaceInproc/FindInterfaceInproc.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 소스 파일 + + + \ No newline at end of file diff --git a/OleViewDotNet.sln b/OleViewDotNet.sln index 74e72c68..71d879de 100644 --- a/OleViewDotNet.sln +++ b/OleViewDotNet.sln @@ -13,32 +13,104 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OleViewDotNetPS", "OleViewD EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OleViewDotNet32", "OleViewDotNet32\OleViewDotNet32.csproj", "{1B4FF6CE-EBEB-43DE-BC06-5AD348F5CEAC}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FindInterface", "FindInterface\FindInterface.vcxproj", "{5D31FA24-FE76-4F13-9CC8-41FF178BEECB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FindInterfaceInproc", "FindInterfaceInproc\FindInterfaceInproc.vcxproj", "{4091323F-6487-4800-A38E-09B61DCB977E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {81F5C6AA-AC60-4F6E-9467-426997BB9D80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {81F5C6AA-AC60-4F6E-9467-426997BB9D80}.Debug|Any CPU.Build.0 = Debug|Any CPU + {81F5C6AA-AC60-4F6E-9467-426997BB9D80}.Debug|x64.ActiveCfg = Debug|Any CPU + {81F5C6AA-AC60-4F6E-9467-426997BB9D80}.Debug|x64.Build.0 = Debug|Any CPU + {81F5C6AA-AC60-4F6E-9467-426997BB9D80}.Debug|x86.ActiveCfg = Debug|Any CPU + {81F5C6AA-AC60-4F6E-9467-426997BB9D80}.Debug|x86.Build.0 = Debug|Any CPU {81F5C6AA-AC60-4F6E-9467-426997BB9D80}.Release|Any CPU.ActiveCfg = Release|Any CPU {81F5C6AA-AC60-4F6E-9467-426997BB9D80}.Release|Any CPU.Build.0 = Release|Any CPU + {81F5C6AA-AC60-4F6E-9467-426997BB9D80}.Release|x64.ActiveCfg = Release|Any CPU + {81F5C6AA-AC60-4F6E-9467-426997BB9D80}.Release|x64.Build.0 = Release|Any CPU + {81F5C6AA-AC60-4F6E-9467-426997BB9D80}.Release|x86.ActiveCfg = Release|Any CPU + {81F5C6AA-AC60-4F6E-9467-426997BB9D80}.Release|x86.Build.0 = Release|Any CPU {44641991-3F1B-46CB-A1B2-0690E6B5181E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {44641991-3F1B-46CB-A1B2-0690E6B5181E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {44641991-3F1B-46CB-A1B2-0690E6B5181E}.Debug|x64.ActiveCfg = Debug|Any CPU + {44641991-3F1B-46CB-A1B2-0690E6B5181E}.Debug|x64.Build.0 = Debug|Any CPU + {44641991-3F1B-46CB-A1B2-0690E6B5181E}.Debug|x86.ActiveCfg = Debug|Any CPU + {44641991-3F1B-46CB-A1B2-0690E6B5181E}.Debug|x86.Build.0 = Debug|Any CPU {44641991-3F1B-46CB-A1B2-0690E6B5181E}.Release|Any CPU.ActiveCfg = Release|Any CPU {44641991-3F1B-46CB-A1B2-0690E6B5181E}.Release|Any CPU.Build.0 = Release|Any CPU + {44641991-3F1B-46CB-A1B2-0690E6B5181E}.Release|x64.ActiveCfg = Release|Any CPU + {44641991-3F1B-46CB-A1B2-0690E6B5181E}.Release|x64.Build.0 = Release|Any CPU + {44641991-3F1B-46CB-A1B2-0690E6B5181E}.Release|x86.ActiveCfg = Release|Any CPU + {44641991-3F1B-46CB-A1B2-0690E6B5181E}.Release|x86.Build.0 = Release|Any CPU {96B8EEAD-60FC-4B74-A3AC-9380D315C1FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {96B8EEAD-60FC-4B74-A3AC-9380D315C1FB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96B8EEAD-60FC-4B74-A3AC-9380D315C1FB}.Debug|x64.ActiveCfg = Debug|Any CPU + {96B8EEAD-60FC-4B74-A3AC-9380D315C1FB}.Debug|x64.Build.0 = Debug|Any CPU + {96B8EEAD-60FC-4B74-A3AC-9380D315C1FB}.Debug|x86.ActiveCfg = Debug|Any CPU + {96B8EEAD-60FC-4B74-A3AC-9380D315C1FB}.Debug|x86.Build.0 = Debug|Any CPU {96B8EEAD-60FC-4B74-A3AC-9380D315C1FB}.Release|Any CPU.ActiveCfg = Release|Any CPU {96B8EEAD-60FC-4B74-A3AC-9380D315C1FB}.Release|Any CPU.Build.0 = Release|Any CPU + {96B8EEAD-60FC-4B74-A3AC-9380D315C1FB}.Release|x64.ActiveCfg = Release|Any CPU + {96B8EEAD-60FC-4B74-A3AC-9380D315C1FB}.Release|x64.Build.0 = Release|Any CPU + {96B8EEAD-60FC-4B74-A3AC-9380D315C1FB}.Release|x86.ActiveCfg = Release|Any CPU + {96B8EEAD-60FC-4B74-A3AC-9380D315C1FB}.Release|x86.Build.0 = Release|Any CPU {9743D720-4663-4F21-A685-E4CF3E0CFA87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9743D720-4663-4F21-A685-E4CF3E0CFA87}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9743D720-4663-4F21-A685-E4CF3E0CFA87}.Debug|x64.ActiveCfg = Debug|Any CPU + {9743D720-4663-4F21-A685-E4CF3E0CFA87}.Debug|x64.Build.0 = Debug|Any CPU + {9743D720-4663-4F21-A685-E4CF3E0CFA87}.Debug|x86.ActiveCfg = Debug|Any CPU + {9743D720-4663-4F21-A685-E4CF3E0CFA87}.Debug|x86.Build.0 = Debug|Any CPU {9743D720-4663-4F21-A685-E4CF3E0CFA87}.Release|Any CPU.ActiveCfg = Release|Any CPU {9743D720-4663-4F21-A685-E4CF3E0CFA87}.Release|Any CPU.Build.0 = Release|Any CPU + {9743D720-4663-4F21-A685-E4CF3E0CFA87}.Release|x64.ActiveCfg = Release|Any CPU + {9743D720-4663-4F21-A685-E4CF3E0CFA87}.Release|x64.Build.0 = Release|Any CPU + {9743D720-4663-4F21-A685-E4CF3E0CFA87}.Release|x86.ActiveCfg = Release|Any CPU + {9743D720-4663-4F21-A685-E4CF3E0CFA87}.Release|x86.Build.0 = Release|Any CPU {1B4FF6CE-EBEB-43DE-BC06-5AD348F5CEAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1B4FF6CE-EBEB-43DE-BC06-5AD348F5CEAC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1B4FF6CE-EBEB-43DE-BC06-5AD348F5CEAC}.Debug|x64.ActiveCfg = Debug|Any CPU + {1B4FF6CE-EBEB-43DE-BC06-5AD348F5CEAC}.Debug|x64.Build.0 = Debug|Any CPU + {1B4FF6CE-EBEB-43DE-BC06-5AD348F5CEAC}.Debug|x86.ActiveCfg = Debug|Any CPU + {1B4FF6CE-EBEB-43DE-BC06-5AD348F5CEAC}.Debug|x86.Build.0 = Debug|Any CPU {1B4FF6CE-EBEB-43DE-BC06-5AD348F5CEAC}.Release|Any CPU.ActiveCfg = Release|Any CPU {1B4FF6CE-EBEB-43DE-BC06-5AD348F5CEAC}.Release|Any CPU.Build.0 = Release|Any CPU + {1B4FF6CE-EBEB-43DE-BC06-5AD348F5CEAC}.Release|x64.ActiveCfg = Release|Any CPU + {1B4FF6CE-EBEB-43DE-BC06-5AD348F5CEAC}.Release|x64.Build.0 = Release|Any CPU + {1B4FF6CE-EBEB-43DE-BC06-5AD348F5CEAC}.Release|x86.ActiveCfg = Release|Any CPU + {1B4FF6CE-EBEB-43DE-BC06-5AD348F5CEAC}.Release|x86.Build.0 = Release|Any CPU + {5D31FA24-FE76-4F13-9CC8-41FF178BEECB}.Debug|Any CPU.ActiveCfg = Debug|x64 + {5D31FA24-FE76-4F13-9CC8-41FF178BEECB}.Debug|Any CPU.Build.0 = Debug|x64 + {5D31FA24-FE76-4F13-9CC8-41FF178BEECB}.Debug|x64.ActiveCfg = Debug|x64 + {5D31FA24-FE76-4F13-9CC8-41FF178BEECB}.Debug|x64.Build.0 = Debug|x64 + {5D31FA24-FE76-4F13-9CC8-41FF178BEECB}.Debug|x86.ActiveCfg = Debug|Win32 + {5D31FA24-FE76-4F13-9CC8-41FF178BEECB}.Debug|x86.Build.0 = Debug|Win32 + {5D31FA24-FE76-4F13-9CC8-41FF178BEECB}.Release|Any CPU.ActiveCfg = Release|x64 + {5D31FA24-FE76-4F13-9CC8-41FF178BEECB}.Release|Any CPU.Build.0 = Release|x64 + {5D31FA24-FE76-4F13-9CC8-41FF178BEECB}.Release|x64.ActiveCfg = Release|x64 + {5D31FA24-FE76-4F13-9CC8-41FF178BEECB}.Release|x64.Build.0 = Release|x64 + {5D31FA24-FE76-4F13-9CC8-41FF178BEECB}.Release|x86.ActiveCfg = Release|Win32 + {5D31FA24-FE76-4F13-9CC8-41FF178BEECB}.Release|x86.Build.0 = Release|Win32 + {4091323F-6487-4800-A38E-09B61DCB977E}.Debug|Any CPU.ActiveCfg = Debug|x64 + {4091323F-6487-4800-A38E-09B61DCB977E}.Debug|Any CPU.Build.0 = Debug|x64 + {4091323F-6487-4800-A38E-09B61DCB977E}.Debug|x64.ActiveCfg = Debug|x64 + {4091323F-6487-4800-A38E-09B61DCB977E}.Debug|x64.Build.0 = Debug|x64 + {4091323F-6487-4800-A38E-09B61DCB977E}.Debug|x86.ActiveCfg = Debug|Win32 + {4091323F-6487-4800-A38E-09B61DCB977E}.Debug|x86.Build.0 = Debug|Win32 + {4091323F-6487-4800-A38E-09B61DCB977E}.Release|Any CPU.ActiveCfg = Release|x64 + {4091323F-6487-4800-A38E-09B61DCB977E}.Release|Any CPU.Build.0 = Release|x64 + {4091323F-6487-4800-A38E-09B61DCB977E}.Release|x64.ActiveCfg = Release|x64 + {4091323F-6487-4800-A38E-09B61DCB977E}.Release|x64.Build.0 = Release|x64 + {4091323F-6487-4800-A38E-09B61DCB977E}.Release|x86.ActiveCfg = Release|Win32 + {4091323F-6487-4800-A38E-09B61DCB977E}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/OleViewDotNet/Forms/COMRegistryViewer.cs b/OleViewDotNet/Forms/COMRegistryViewer.cs index 2226a030..d730d921 100644 --- a/OleViewDotNet/Forms/COMRegistryViewer.cs +++ b/OleViewDotNet/Forms/COMRegistryViewer.cs @@ -1,60 +1,69 @@ -// This file is part of OleViewDotNet. -// Copyright (C) James Forshaw 2014 -// -// OleViewDotNet is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// OleViewDotNet 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 General Public License -// along with OleViewDotNet. If not, see . - -using NtApiDotNet; -using OleViewDotNet.Database; -using OleViewDotNet.Interop; -using OleViewDotNet.Processes; -using OleViewDotNet.Proxy; -using OleViewDotNet.Security; -using OleViewDotNet.TypeLib; -using OleViewDotNet.Utilities; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using System.Windows.Forms; - +// This file is part of OleViewDotNet. +// Copyright (C) James Forshaw 2014 +// +// OleViewDotNet is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// OleViewDotNet 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 General Public License +// along with OleViewDotNet. If not, see . + +using NtApiDotNet; +using OleViewDotNet.Database; +using OleViewDotNet.Interop; +using OleViewDotNet.Processes; +using OleViewDotNet.Proxy; +using OleViewDotNet.Security; +using OleViewDotNet.TypeLib; +using OleViewDotNet.Utilities; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Windows.Forms; + +/* ADDED */ +using Microsoft.Win32; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; +using System.Threading; +using System.Security.Claims; +/* ADDED */ + namespace OleViewDotNet.Forms; - -/// -/// Form to view the COM registration information -/// -internal partial class COMRegistryViewer : UserControl + +/// +/// Form to view the COM registration information +/// +internal partial class COMRegistryViewer : UserControl { - #region Private Members - private readonly COMRegistry m_registry; - private readonly HashSet m_filter_types; - private readonly COMRegistryDisplayMode m_mode; - private readonly IEnumerable m_processes; + #region Private Members + private readonly COMRegistry m_registry; + private readonly HashSet m_filter_types; + private readonly COMRegistryDisplayMode m_mode; + private readonly IEnumerable m_processes; private readonly TreeNode m_visible_node; - private RegistryViewerFilter m_filter; + private RegistryViewerFilter m_filter; private TreeNode[] m_original_nodes; - private const string FolderKey = "folder.ico"; - private const string InterfaceKey = "interface.ico"; - private const string ClassKey = "class.ico"; - private const string FolderOpenKey = "folderopen.ico"; - private const string ProcessKey = "process.ico"; + private const string FolderKey = "folder.ico"; + private const string InterfaceKey = "interface.ico"; + private const string ClassKey = "class.ico"; + private const string FolderOpenKey = "folderopen.ico"; + private const string ProcessKey = "process.ico"; private const string ApplicationKey = "application.ico"; private sealed class DynamicPlaceholderTreeNode : TreeNode @@ -88,8 +97,8 @@ private static bool IsLeafNode(TreeNode node) return node.Tag is ICOMClassEntry; } - private static string GetDisplayName(COMRegistryDisplayMode mode) - { + private static string GetDisplayName(COMRegistryDisplayMode mode) + { return mode switch { COMRegistryDisplayMode.CLSIDsByName => "CLSIDs by Name", @@ -116,1539 +125,1720 @@ private static string GetDisplayName(COMRegistryDisplayMode mode) COMRegistryDisplayMode.RuntimeInterfaces or COMRegistryDisplayMode.RuntimeInterfacesTree => "Runtime Interfaces", _ => throw new ArgumentException("Invalid mode value"), }; - } - - private static IEnumerable GetFilterTypes(COMRegistryDisplayMode mode) - { - HashSet filter_types = new(); - switch (mode) - { - case COMRegistryDisplayMode.CLSIDsByName: - case COMRegistryDisplayMode.CLSIDs: - filter_types.Add(FilterType.CLSID); - filter_types.Add(FilterType.Interface); - break; - case COMRegistryDisplayMode.ProgIDs: - filter_types.Add(FilterType.ProgID); - filter_types.Add(FilterType.Interface); - break; - case COMRegistryDisplayMode.CLSIDsByServer: - case COMRegistryDisplayMode.CLSIDsByLocalServer: - case COMRegistryDisplayMode.CLSIDsWithSurrogate: - case COMRegistryDisplayMode.ProxyCLSIDs: - filter_types.Add(FilterType.CLSID); - filter_types.Add(FilterType.Server); - filter_types.Add(FilterType.Interface); - break; - case COMRegistryDisplayMode.Interfaces: + } + + private static IEnumerable GetFilterTypes(COMRegistryDisplayMode mode) + { + HashSet filter_types = new(); + switch (mode) + { + case COMRegistryDisplayMode.CLSIDsByName: + case COMRegistryDisplayMode.CLSIDs: + filter_types.Add(FilterType.CLSID); + filter_types.Add(FilterType.Interface); + break; + case COMRegistryDisplayMode.ProgIDs: + filter_types.Add(FilterType.ProgID); + filter_types.Add(FilterType.Interface); + break; + case COMRegistryDisplayMode.CLSIDsByServer: + case COMRegistryDisplayMode.CLSIDsByLocalServer: + case COMRegistryDisplayMode.CLSIDsWithSurrogate: + case COMRegistryDisplayMode.ProxyCLSIDs: + filter_types.Add(FilterType.CLSID); + filter_types.Add(FilterType.Server); + filter_types.Add(FilterType.Interface); + break; + case COMRegistryDisplayMode.Interfaces: case COMRegistryDisplayMode.InterfacesByName: case COMRegistryDisplayMode.RuntimeInterfaces: - case COMRegistryDisplayMode.RuntimeInterfacesTree: - filter_types.Add(FilterType.Interface); - break; - case COMRegistryDisplayMode.ImplementedCategories: - filter_types.Add(FilterType.Category); - filter_types.Add(FilterType.CLSID); - filter_types.Add(FilterType.Interface); - break; - case COMRegistryDisplayMode.PreApproved: - filter_types.Add(FilterType.CLSID); - filter_types.Add(FilterType.Interface); - break; - case COMRegistryDisplayMode.IELowRights: - filter_types.Add(FilterType.LowRights); - filter_types.Add(FilterType.CLSID); - filter_types.Add(FilterType.Interface); - break; - case COMRegistryDisplayMode.AppIDs: - case COMRegistryDisplayMode.AppIDsWithIL: - case COMRegistryDisplayMode.AppIDsWithAC: - case COMRegistryDisplayMode.LocalServices: - filter_types.Add(FilterType.AppID); - filter_types.Add(FilterType.CLSID); - filter_types.Add(FilterType.Interface); - break; - case COMRegistryDisplayMode.Typelibs: - filter_types.Add(FilterType.TypeLib); - break; - case COMRegistryDisplayMode.MimeTypes: - filter_types.Add(FilterType.MimeType); - filter_types.Add(FilterType.CLSID); - filter_types.Add(FilterType.Interface); - break; - case COMRegistryDisplayMode.Processes: - filter_types.Add(FilterType.Process); - filter_types.Add(FilterType.Ipid); - filter_types.Add(FilterType.AppID); - break; - case COMRegistryDisplayMode.RuntimeClasses: - filter_types.Add(FilterType.RuntimeClass); - filter_types.Add(FilterType.Interface); - break; - case COMRegistryDisplayMode.RuntimeServers: - filter_types.Add(FilterType.RuntimeServer); - filter_types.Add(FilterType.RuntimeClass); - filter_types.Add(FilterType.Interface); - break; - default: - throw new ArgumentException("Invalid mode value"); - } - return filter_types; - } - - private void UpdateStatusLabel() - { - toolStripStatusLabelCount.Text = $"Showing {treeComRegistry.Nodes.Count} of {m_original_nodes.Length} entries"; - } - - private static TreeNode CreateNode(string text, string image_key, object tag, string tooltip = null) - { - bool dynamic = false; + case COMRegistryDisplayMode.RuntimeInterfacesTree: + filter_types.Add(FilterType.Interface); + break; + case COMRegistryDisplayMode.ImplementedCategories: + filter_types.Add(FilterType.Category); + filter_types.Add(FilterType.CLSID); + filter_types.Add(FilterType.Interface); + break; + case COMRegistryDisplayMode.PreApproved: + filter_types.Add(FilterType.CLSID); + filter_types.Add(FilterType.Interface); + break; + case COMRegistryDisplayMode.IELowRights: + filter_types.Add(FilterType.LowRights); + filter_types.Add(FilterType.CLSID); + filter_types.Add(FilterType.Interface); + break; + case COMRegistryDisplayMode.AppIDs: + case COMRegistryDisplayMode.AppIDsWithIL: + case COMRegistryDisplayMode.AppIDsWithAC: + case COMRegistryDisplayMode.LocalServices: + filter_types.Add(FilterType.AppID); + filter_types.Add(FilterType.CLSID); + filter_types.Add(FilterType.Interface); + break; + case COMRegistryDisplayMode.Typelibs: + filter_types.Add(FilterType.TypeLib); + break; + case COMRegistryDisplayMode.MimeTypes: + filter_types.Add(FilterType.MimeType); + filter_types.Add(FilterType.CLSID); + filter_types.Add(FilterType.Interface); + break; + case COMRegistryDisplayMode.Processes: + filter_types.Add(FilterType.Process); + filter_types.Add(FilterType.Ipid); + filter_types.Add(FilterType.AppID); + break; + case COMRegistryDisplayMode.RuntimeClasses: + filter_types.Add(FilterType.RuntimeClass); + filter_types.Add(FilterType.Interface); + break; + case COMRegistryDisplayMode.RuntimeServers: + filter_types.Add(FilterType.RuntimeServer); + filter_types.Add(FilterType.RuntimeClass); + filter_types.Add(FilterType.Interface); + break; + default: + throw new ArgumentException("Invalid mode value"); + } + return filter_types; + } + + private void UpdateStatusLabel() + { + toolStripStatusLabelCount.Text = $"Showing {treeComRegistry.Nodes.Count} of {m_original_nodes.Length} entries"; + } + + private static TreeNode CreateNode(string text, string image_key, object tag, string tooltip = null) + { + bool dynamic = false; if (tag is ICOMClassEntry || tag is COMTypeLibVersionEntry || tag is COMTypeLibCoClass || tag is COMProxyFormatter) { dynamic = true; - } - + } + TreeNode node = new(text) { ImageKey = image_key, SelectedImageKey = image_key, Tag = tag ?? new object() - }; + }; if (tooltip is not null) - { + { node.ToolTipText = tooltip; - } + } if (dynamic) { node.Nodes.Add(new DynamicPlaceholderTreeNode()); - } - return node; - } - - private static IEnumerable SetupTree(COMRegistry registry, COMRegistryDisplayMode mode, IEnumerable processes) - { - try - { - switch (mode) - { - case COMRegistryDisplayMode.CLSIDsByName: - return LoadCLSIDsByNames(registry); - case COMRegistryDisplayMode.CLSIDs: - return LoadCLSIDs(registry); - case COMRegistryDisplayMode.ProgIDs: - return LoadProgIDs(registry); - case COMRegistryDisplayMode.CLSIDsByServer: - return LoadCLSIDByServer(registry, ServerType.None); - case COMRegistryDisplayMode.CLSIDsByLocalServer: - return LoadCLSIDByServer(registry, ServerType.Local); - case COMRegistryDisplayMode.CLSIDsWithSurrogate: - return LoadCLSIDByServer(registry, ServerType.Surrogate); - case COMRegistryDisplayMode.Interfaces: - return LoadInterfaces(registry, false, false); - case COMRegistryDisplayMode.InterfacesByName: + } + return node; + } + + private static IEnumerable SetupTree(COMRegistry registry, COMRegistryDisplayMode mode, IEnumerable processes) + { + try + { + switch (mode) + { + case COMRegistryDisplayMode.CLSIDsByName: + return LoadCLSIDsByNames(registry); + case COMRegistryDisplayMode.CLSIDs: + return LoadCLSIDs(registry); + case COMRegistryDisplayMode.ProgIDs: + return LoadProgIDs(registry); + case COMRegistryDisplayMode.CLSIDsByServer: + return LoadCLSIDByServer(registry, ServerType.None); + case COMRegistryDisplayMode.CLSIDsByLocalServer: + return LoadCLSIDByServer(registry, ServerType.Local); + case COMRegistryDisplayMode.CLSIDsWithSurrogate: + return LoadCLSIDByServer(registry, ServerType.Surrogate); + case COMRegistryDisplayMode.Interfaces: + return LoadInterfaces(registry, false, false); + case COMRegistryDisplayMode.InterfacesByName: return LoadInterfaces(registry, true, false); - case COMRegistryDisplayMode.RuntimeInterfaces: + case COMRegistryDisplayMode.RuntimeInterfaces: return LoadInterfaces(registry, true, true); - case COMRegistryDisplayMode.RuntimeInterfacesTree: - return LoadRuntimeInterfacesTree(registry); - case COMRegistryDisplayMode.ImplementedCategories: - return LoadImplementedCategories(registry); - case COMRegistryDisplayMode.PreApproved: - return LoadPreApproved(registry); - case COMRegistryDisplayMode.IELowRights: - return LoadIELowRights(registry); - case COMRegistryDisplayMode.LocalServices: - return LoadLocalServices(registry); - case COMRegistryDisplayMode.AppIDs: - return LoadAppIDs(registry, false, false); - case COMRegistryDisplayMode.AppIDsWithIL: - return LoadAppIDs(registry, true, false); - case COMRegistryDisplayMode.AppIDsWithAC: - return LoadAppIDs(registry, false, true); - case COMRegistryDisplayMode.Typelibs: - return LoadTypeLibs(registry); - case COMRegistryDisplayMode.MimeTypes: - return LoadMimeTypes(registry); - case COMRegistryDisplayMode.ProxyCLSIDs: - return LoadCLSIDByServer(registry, ServerType.Proxies); - case COMRegistryDisplayMode.Processes: - return LoadProcesses(registry, processes); - case COMRegistryDisplayMode.RuntimeClasses: - return LoadRuntimeClasses(registry); - case COMRegistryDisplayMode.RuntimeServers: - return LoadRuntimeServers(registry); - default: - break; - } - } - catch (Exception ex) - { - EntryPoint.ShowError(null, ex); - } - - return new TreeNode[0]; - } - - private static string BuildCLSIDToolTip(COMRegistry registry, COMCLSIDEntry ent) - { - StringBuilder strRet = new(); - - strRet.AppendLine($"CLSID: {ent.Clsid.FormatGuid()}"); - strRet.AppendLine($"Name: {ent.Name}"); - strRet.AppendLine($"{ent.DefaultServerType}: {ent.DefaultServer}"); - IEnumerable progids = registry.GetProgIdsForClsid(ent.Clsid).Select(p => p.ProgID); - if (progids.Any()) - { - strRet.AppendLine("ProgIDs:"); - foreach (string progid in progids) - { - strRet.AppendLine($"{progid}"); - } - } - if (ent.AppID != Guid.Empty) - { - strRet.AppendLine($"AppID: {ent.AppID.FormatGuid()}"); - } - if (ent.TypeLib != Guid.Empty) - { - strRet.AppendLine($"TypeLib: {ent.TypeLib.FormatGuid()}"); - } - - COMInterfaceEntry[] proxies = registry.GetProxiesForClsid(ent); - if (proxies.Length > 0) - { - strRet.AppendLine($"Interface Proxies: {proxies.Length}"); - } - - if (ent.InterfacesLoaded) - { - strRet.AppendLine($"Instance Interfaces: {ent.Interfaces.Count()}"); - strRet.AppendLine($"Factory Interfaces: {ent.FactoryInterfaces.Count()}"); - } - if (ent.DefaultServerType == COMServerType.InProcServer32) - { - COMCLSIDServerEntry server = ent.Servers[COMServerType.InProcServer32]; - if (server.HasDotNet) - { - strRet.AppendLine($"Assembly: {server.DotNet.AssemblyName}"); - strRet.AppendLine($"Class: {server.DotNet.ClassName}"); - if (!string.IsNullOrWhiteSpace(server.DotNet.CodeBase)) - { - strRet.AppendLine($"Codebase: {server.DotNet.CodeBase}"); - } - if (!string.IsNullOrWhiteSpace(server.DotNet.RuntimeVersion)) - { - strRet.AppendLine($"Runtime Version: {server.DotNet.RuntimeVersion}"); - } - } - } - - return strRet.ToString(); - } - - /// - /// Build a ProgID entry tooltip - /// - /// The ProgID entry - /// The ProgID tooltip - private static string BuildProgIDToolTip(COMRegistry registry, COMProgIDEntry ent) - { - string strRet; - COMCLSIDEntry entry = registry.MapClsidToEntry(ent.Clsid); - if (entry is not null) - { - strRet = BuildCLSIDToolTip(registry, entry); - } - else - { - strRet = $"CLSID: {ent.Clsid.FormatGuid()}\n"; - } - - return strRet; - } - - private static string BuildInterfaceToolTip(COMInterfaceEntry ent, COMInterfaceInstance instance) - { - StringBuilder builder = new(); - - builder.AppendLine($"Name: {ent.Name}"); - builder.AppendLine($"IID: {ent.Iid.FormatGuid()}"); - if (ent.ProxyClsid != Guid.Empty) - { - builder.AppendLine($"ProxyCLSID: {ent.ProxyClsid.FormatGuid()}"); - } - if (instance is not null && instance.Module is not null) - { - builder.AppendLine($"VTable Address: {instance.Module}+0x{instance.VTableOffset:X}"); - } - if (ent.HasTypeLib) - { - builder.AppendLine($"TypeLib: {ent.TypeLib.FormatGuid()}"); - } - - return builder.ToString(); - } - - private static TreeNode CreateCLSIDNode(COMRegistry registry, COMCLSIDEntry ent) - { - return CreateNode($"{ent.Clsid.FormatGuid()} - {ent.Name}", ClassKey, ent, BuildCLSIDToolTip(registry, ent)); - } - - private static TreeNode CreateInterfaceNode(COMRegistry registry, COMInterfaceEntry ent) - { - return CreateNode($"{ent.Iid.FormatGuid()} - {ent.Name}", - InterfaceKey, ent, BuildInterfaceToolTip(ent, null)); - } - - private static TreeNode CreateInterfaceNameNode(COMRegistry registry, COMInterfaceEntry ent, COMInterfaceInstance instance) - { - return CreateNode(ent.Name, InterfaceKey, ent, BuildInterfaceToolTip(ent, instance)); - } - - private static IEnumerable LoadCLSIDs(COMRegistry registry) - { - return registry.Clsids.Values.Select(ent => CreateCLSIDNode(registry, ent)); - } - - private static TreeNode CreateRuntimeClassNode(COMRuntimeClassEntry ent) - { - return CreateNode(ent.Name, ClassKey, ent); - } - - private static IEnumerable LoadRuntimeClasses(COMRegistry registry) - { - return registry.RuntimeClasses.Select(p => CreateRuntimeClassNode(p.Value)); - } - - private static IEnumerable LoadRuntimeServers(COMRegistry registry) - { - List serverNodes = new(registry.Clsids.Count); - foreach (var group in registry.RuntimeClasses.Values.GroupBy(p => p.Server.ToLower())) - { - COMRuntimeServerEntry server = registry.MapServerNameToEntry(group.Key); - if (server is null) - { - continue; - } - TreeNode node = CreateNode(server.Name, FolderKey, server); - node.Nodes.AddRange(group.Select(p => CreateRuntimeClassNode(p)).ToArray()); - serverNodes.Add(node); - } - return serverNodes.OrderBy(n => n.Text); - } - - private static IEnumerable LoadProgIDs(COMRegistry registry) - { - return registry.Progids.Values.Select(p => - CreateNode(p.ProgID, ClassKey, p, BuildProgIDToolTip(registry, p))); - } - - private static IEnumerable LoadCLSIDsByNames(COMRegistry registry) - { - return registry.Clsids.Values.Select(ent - => CreateNode(ent.Name, ClassKey, - ent, BuildCLSIDToolTip(registry, ent))).OrderBy(n => n.Text); - } - - private static string BuildCOMProcessTooltip(COMProcessEntry proc) - { - StringBuilder builder = new(); - builder.AppendLine($"Path: {proc.ExecutablePath}"); - builder.AppendLine($"User: {proc.User}"); - if (proc.AppId != Guid.Empty) - { - builder.AppendLine($"AppID: {proc.AppId}"); - } - builder.AppendLine($"Access Permissions: {proc.AccessPermissions}"); - builder.AppendLine($"LRPC Permissions: {proc.LRpcPermissions}"); - if (!string.IsNullOrEmpty(proc.RpcEndpoint)) - { - builder.AppendLine($"LRPC Endpoint: {proc.RpcEndpoint}"); - } - builder.AppendLine($"Capabilities: {proc.Capabilities}"); - builder.AppendLine($"Authn Level: {proc.AuthnLevel}"); - builder.AppendLine($"Imp Level: {proc.ImpLevel}"); - if (proc.AccessControl != IntPtr.Zero) - { - builder.AppendLine($"Access Control: 0x{proc.AccessControl.ToInt64():X}"); - } - builder.AppendLine(AppUtilities.FormatBitness(proc.Is64Bit)); - return builder.ToString(); - } - - private static string BuildCOMIpidTooltip(COMIPIDEntry ipid) - { - StringBuilder builder = new(); - builder.AppendLine($"Interface: 0x{ipid.Interface.ToInt64():X}"); - if (!string.IsNullOrWhiteSpace(ipid.InterfaceVTable)) - { - builder.AppendLine($"Interface VTable: {ipid.InterfaceVTable}"); - } - builder.AppendLine($"Stub: 0x{ipid.Stub.ToInt64():X}"); - if (!string.IsNullOrWhiteSpace(ipid.StubVTable)) - { - builder.AppendLine($"Stub VTable: {ipid.StubVTable}"); - } - builder.AppendLine($"Flags: {ipid.Flags}"); - builder.AppendLine($"Strong Refs: {ipid.StrongRefs}"); - builder.AppendLine($"Weak Refs: {ipid.WeakRefs}"); - builder.AppendLine($"Private Refs: {ipid.PrivateRefs}"); + case COMRegistryDisplayMode.RuntimeInterfacesTree: + return LoadRuntimeInterfacesTree(registry); + case COMRegistryDisplayMode.ImplementedCategories: + return LoadImplementedCategories(registry); + case COMRegistryDisplayMode.PreApproved: + return LoadPreApproved(registry); + case COMRegistryDisplayMode.IELowRights: + return LoadIELowRights(registry); + case COMRegistryDisplayMode.LocalServices: + return LoadLocalServices(registry); + case COMRegistryDisplayMode.AppIDs: + return LoadAppIDs(registry, false, false); + case COMRegistryDisplayMode.AppIDsWithIL: + return LoadAppIDs(registry, true, false); + case COMRegistryDisplayMode.AppIDsWithAC: + return LoadAppIDs(registry, false, true); + case COMRegistryDisplayMode.Typelibs: + return LoadTypeLibs(registry); + case COMRegistryDisplayMode.MimeTypes: + return LoadMimeTypes(registry); + case COMRegistryDisplayMode.ProxyCLSIDs: + return LoadCLSIDByServer(registry, ServerType.Proxies); + case COMRegistryDisplayMode.Processes: + return LoadProcesses(registry, processes); + case COMRegistryDisplayMode.RuntimeClasses: + return LoadRuntimeClasses(registry); + case COMRegistryDisplayMode.RuntimeServers: + return LoadRuntimeServers(registry); + default: + break; + } + } + catch (Exception ex) + { + EntryPoint.ShowError(null, ex); + } - return builder.ToString(); - } - - private static string BuildCOMProcessName(COMProcessEntry proc) - { - return $"{proc.ProcessId,-8} - {proc.Name} - {proc.User}"; - } - - private static void PopulatorIpids(COMRegistry registry, TreeNode node, COMProcessEntry proc) - { - foreach (COMIPIDEntry ipid in proc.Ipids.Where(i => i.IsRunning)) - { - COMInterfaceEntry intf = registry.MapIidToInterface(ipid.Iid); - TreeNode ipid_node = CreateNode($"IPID: {ipid.Ipid.FormatGuid()} - IID: {intf.Name}", InterfaceKey, ipid); - ipid_node.ToolTipText = BuildCOMIpidTooltip(ipid); - node.Nodes.Add(ipid_node); - } - } - - private static TreeNode CreateCOMProcessNode(COMRegistry registry, COMProcessEntry proc, - IDictionary> appIdsByPid, IDictionary> clsidsByAppId) - { - TreeNode node = CreateNode(BuildCOMProcessName(proc), ApplicationKey, proc); - node.ToolTipText = BuildCOMProcessTooltip(proc); - - if (appIdsByPid.ContainsKey(proc.ProcessId) && appIdsByPid[proc.ProcessId].Count() > 0) - { - TreeNode services_node = CreateNode("Services", FolderKey, null); - foreach (COMAppIDEntry appid in appIdsByPid[proc.ProcessId]) - { - if (clsidsByAppId.ContainsKey(appid.AppId)) - { - services_node.Nodes.Add(CreateLocalServiceNode(registry, appid, clsidsByAppId[appid.AppId])); - } - } - node.Nodes.Add(services_node); - } - - var server_classes = proc.Classes.Where(c => (c.Context & CLSCTX.LOCAL_SERVER) != 0); - - if (server_classes.Any()) - { - TreeNode classes_node = CreateNode("Classes", FolderKey, null); - foreach (var c in server_classes) - { - classes_node.Nodes.Add(CreateCLSIDNode(registry, registry.MapClsidToEntry(c.Clsid))); - } - - node.Nodes.Add(classes_node); - } - - PopulatorIpids(registry, node, proc); - return node; - } - - private static IEnumerable LoadProcesses(COMRegistry registry, IEnumerable processes) - { - var servicesById = COMUtilities.GetServicePids(); - var appidsByService = registry.AppIDs.Values.Where(a => a.IsService). - GroupBy(a => a.LocalService.Name, StringComparer.OrdinalIgnoreCase).ToDictionary(g => g.Key, g => g, StringComparer.OrdinalIgnoreCase); - var clsidsByAppId = registry.ClsidsByAppId; - var appsByPid = servicesById.ToDictionary(p => p.Key, p => p.Value.Where(v => appidsByService.ContainsKey(v)).SelectMany(v => appidsByService[v])); - - return processes.Where(p => p.Ipids.Any()).Select(p => CreateCOMProcessNode(registry, p, appsByPid, clsidsByAppId)); - } - - private enum ServerType - { - None, - Local, - Surrogate, - Proxies, - } - - private static bool IsProxyClsid(COMRegistry registry, COMCLSIDEntry ent) - { - return ent.DefaultServerType == COMServerType.InProcServer32 && registry.GetProxiesForClsid(ent).Length > 0; - } - - private static bool HasSurrogate(COMRegistry registry, COMCLSIDEntry ent) - { - return registry.AppIDs.ContainsKey(ent.AppID) && !string.IsNullOrWhiteSpace(registry.AppIDs[ent.AppID].DllSurrogate); - } - - private class COMCLSIDServerEqualityComparer : IEqualityComparer - { - public bool Equals(COMCLSIDServerEntry x, COMCLSIDServerEntry y) - { - return x.Server.Equals(y.Server, StringComparison.OrdinalIgnoreCase); - } - - public int GetHashCode(COMCLSIDServerEntry obj) - { - return obj.Server.ToLower().GetHashCode(); - } - } - - private static IEnumerable LoadCLSIDByServer(COMRegistry registry, ServerType serverType) - { - IEnumerable>> servers = null; - - if (serverType == ServerType.Surrogate) - { - servers = registry.Clsids.Values.Where(c => HasSurrogate(registry, c)) - .GroupBy(c => registry.AppIDs[c.AppID].DllSurrogate, StringComparer.OrdinalIgnoreCase) - .ToDictionary(g => new COMCLSIDServerEntry(COMServerType.LocalServer32, g.Key), g => g.AsEnumerable().ToList()); - } - else - { - Dictionary> dict = - new(new COMCLSIDServerEqualityComparer()); - IEnumerable clsids = registry.Clsids.Values.Where(e => e.Servers.Count > 0); - if (serverType == ServerType.Proxies) - { - clsids = clsids.Where(c => IsProxyClsid(registry, c)); - } - - foreach (COMCLSIDEntry entry in clsids) - { - foreach (COMCLSIDServerEntry server in entry.Servers.Values) - { - var curr_server = server; - if (curr_server.AppIdHosted) - { - var local_service = entry.AppIDEntry?.LocalService; - if (local_service is null) - continue; - if (!string.IsNullOrEmpty(local_service.ServiceDll)) - { - curr_server = new COMCLSIDServerEntry(COMServerType.LocalServer32, local_service.ServiceDll); - } - else - { - curr_server = new COMCLSIDServerEntry(COMServerType.LocalServer32, local_service.ImagePath); - } - } - - if (!dict.ContainsKey(curr_server)) - { - dict[curr_server] = new List(); - } - dict[curr_server].Add(entry); - } - } - - servers = dict; - - if (serverType == ServerType.Local) - { - servers = servers.Where(p => p.Key.ServerType == COMServerType.LocalServer32); - } - else if (serverType == ServerType.Proxies) - { - servers = servers.Where(p => p.Key.ServerType == COMServerType.InProcServer32); - } - } - - List serverNodes = new(registry.Clsids.Count); - foreach (var pair in servers) - { - TreeNode node = CreateNode(pair.Key.Server, FolderKey, pair.Key); - node.ToolTipText = pair.Key.Server; - node.Nodes.AddRange(pair.Value.OrderBy(c => c.Name).Select(c => CreateClsidNode(registry, c)).ToArray()); - serverNodes.Add(node); - } - - return serverNodes.OrderBy(n => n.Text); - } - - private static IEnumerable LoadInterfaces(COMRegistry registry, bool by_name, bool runtime_interfaces) - { - var total_intfs = registry.Interfaces.Values.AsEnumerable(); - if (runtime_interfaces) - total_intfs = total_intfs.Where(i => i.IsWinRTType); - - if (by_name) - { - return total_intfs.OrderBy(i => i.Name).Select(i => CreateInterfaceNameNode(registry, i, null)); - } - - return total_intfs.Select(i => CreateInterfaceNode(registry, i)); - } - - private static TreeNode CreateClsidNode(COMRegistry registry, COMCLSIDEntry ent) - { - TreeNode currNode = CreateNode(ent.Name, ClassKey, ent); - currNode.ToolTipText = BuildCLSIDToolTip(registry, ent); - return currNode; - } - - private static TreeNode CreateLocalServiceNode(COMRegistry registry, COMAppIDEntry appidEnt, IEnumerable clsids) - { - string name = appidEnt.LocalService.DisplayName; - if (string.IsNullOrWhiteSpace(name)) - { - name = appidEnt.LocalService.Name; - } - - TreeNode node = CreateNode(name, FolderKey, appidEnt); - node.ToolTipText = BuildAppIdTooltip(appidEnt); - node.Nodes.AddRange(clsids.OrderBy(c => c.Name).Select(c => CreateClsidNode(registry, c)).ToArray()); - return node; - } - - private static IEnumerable LoadLocalServices(COMRegistry registry) - { - var clsidsByAppId = registry.ClsidsByAppId; - var appids = registry.AppIDs; - - List serverNodes = new(); - foreach (var pair in clsidsByAppId) - { - if (appids.ContainsKey(pair.Key) && appids[pair.Key].IsService) - { - serverNodes.Add(CreateLocalServiceNode(registry, appids[pair.Key], pair.Value)); - } - } - - return serverNodes.OrderBy(n => n.Text); - } - - private static string LimitString(string s, int max) - { - if (s is null) - return string.Empty; - if (s.Length > max) - { - return s.Substring(0, max) + "..."; - } - return s; - } - - private static string BuildAppIdTooltip(COMAppIDEntry appidEnt) - { - StringBuilder builder = new(); - - builder.AppendLine($"AppID: {appidEnt.AppId}"); - if (!string.IsNullOrWhiteSpace(appidEnt.RunAs)) - { - builder.AppendLine($"RunAs: {appidEnt.RunAs}"); - } - - if (appidEnt.IsService) - { - COMAppIDServiceEntry service = appidEnt.LocalService; - builder.AppendLine($"Service Name: {service.Name}"); - if (!string.IsNullOrWhiteSpace(service.DisplayName)) - { - builder.AppendLine($"Display Name: {service.DisplayName}"); - } - if (!string.IsNullOrWhiteSpace(service.UserName)) - { - builder.AppendLine($"Service User: {service.UserName}"); - } - builder.AppendLine($"Image Path: {service.ImagePath}"); - if (!string.IsNullOrWhiteSpace(service.ServiceDll)) - { - builder.AppendLine($"Service DLL: {service.ServiceDll}"); - } - } - - if (appidEnt.HasLaunchPermission) - { - builder.AppendLine($"Launch: {LimitString(appidEnt.LaunchPermission?.ToSddl(), 64)}"); - } - - if (appidEnt.HasAccessPermission) - { - builder.AppendLine($"Access: {LimitString(appidEnt.AccessPermission?.ToSddl(), 64)}"); - } - - if (appidEnt.RotFlags != COMAppIDRotFlags.None) - { - builder.AppendLine($"RotFlags: {appidEnt.RotFlags}"); - } - - if (!string.IsNullOrWhiteSpace(appidEnt.DllSurrogate)) - { - builder.AppendLine($"DLL Surrogate: {appidEnt.DllSurrogate}"); - } - - if (appidEnt.Flags != COMAppIDFlags.None) - { - builder.AppendLine($"Flags: {appidEnt.Flags}"); - } - - return builder.ToString(); - } - - private static IEnumerable LoadAppIDs(COMRegistry registry, bool filterIL, bool filterAC) - { - var clsidsByAppId = registry.ClsidsByAppId; - var appids = registry.AppIDs; - - List serverNodes = new(); - foreach (var pair in appids) - { - COMAppIDEntry appidEnt = appids[pair.Key]; + return new TreeNode[0]; + } - if (filterIL && COMSecurity.GetILForSD(appidEnt.AccessPermission) == TokenIntegrityLevel.Medium && - COMSecurity.GetILForSD(appidEnt.LaunchPermission) == TokenIntegrityLevel.Medium) - { - continue; - } - - if (filterAC && !appidEnt.HasACAccess && !appidEnt.HasACLaunch) - { - continue; - } - - TreeNode node = CreateNode(appidEnt.Name, FolderKey, appidEnt); - node.ToolTipText = BuildAppIdTooltip(appidEnt); - - if (clsidsByAppId.ContainsKey(pair.Key)) - { - node.Nodes.AddRange(clsidsByAppId[pair.Key].OrderBy(c => c.Name).Select(c => CreateClsidNode(registry, c)).ToArray()); - } - - serverNodes.Add(node); - } - - - return serverNodes.OrderBy(n => n.Text); - } - - private static IEnumerable LoadImplementedCategories(COMRegistry registry) - { - SortedDictionary sortedNodes = new(); - - foreach (var cat in registry.ImplementedCategories.Values) - { - TreeNode currNode = CreateNode(cat.Name, FolderKey, cat); - currNode.ToolTipText = $"CATID: {cat.CategoryID.FormatGuid()}"; - sortedNodes.Add(currNode.Text, currNode); - - IEnumerable clsids = cat.ClassEntries.OrderBy(c => c.Name); - IEnumerable clsidNodes = clsids.Select(n => CreateClsidNode(registry, n)); - currNode.Nodes.AddRange(clsidNodes.ToArray()); - } - - return sortedNodes.Values; - } - - private static IEnumerable LoadPreApproved(COMRegistry registry) - { - List nodes = new(); - foreach (COMCLSIDEntry ent in registry.PreApproved) - { - nodes.Add(CreateCLSIDNode(registry, ent)); - } - - return nodes; - } - - private static IEnumerable LoadIELowRights(COMRegistry registry) - { - List clsidNodes = new(); - foreach (COMIELowRightsElevationPolicy ent in registry.LowRights) - { - StringBuilder tooltip = new(); - List clsids = new(); - COMCLSIDEntry entry = ent.ClassEntry; - if (entry is not null) - { - clsids.Add(entry); - } - - if (!string.IsNullOrWhiteSpace(ent.AppPath) && registry.ClsidsByServer.ContainsKey(ent.AppPath)) - { - clsids.AddRange(registry.ClsidsByServer[ent.AppPath]); - tooltip.AppendLine($"{ent.AppPath}"); - } - - if (clsids.Count == 0) - { - continue; - } - - TreeNode currNode = CreateNode(ent.Name, FolderKey, ent); - clsidNodes.Add(currNode); - - foreach (COMCLSIDEntry cls in clsids) - { - currNode.Nodes.Add(CreateCLSIDNode(registry, cls)); - } - - tooltip.AppendLine($"Policy: {ent.Policy}"); - currNode.ToolTipText = tooltip.ToString(); - } - - return clsidNodes; - } - - private static IEnumerable LoadMimeTypes(COMRegistry registry) - { - List nodes = new(registry.MimeTypes.Count()); - foreach (COMMimeType ent in registry.MimeTypes) - { - TreeNode node = CreateNode(ent.MimeType, FolderKey, ent); - if (registry.Clsids.ContainsKey(ent.Clsid)) - { - node.Nodes.Add(CreateCLSIDNode(registry, registry.Clsids[ent.Clsid])); - } - - if (!string.IsNullOrWhiteSpace(ent.Extension)) - { - node.ToolTipText = $"Extension {ent.Extension}"; - } - nodes.Add(node); - } - - return nodes; - } - - private static TreeNode CreateTypelibVersionNode(COMTypeLibVersionEntry entry) - { - TreeNode node = CreateNode($"{entry.Name} : Version {entry.Version}", - ClassKey, entry); - List entries = new(); - if (!string.IsNullOrWhiteSpace(entry.Win32Path)) - { - entries.Add($"Win32: {entry.Win32Path}"); - } - if (!string.IsNullOrWhiteSpace(entry.Win64Path)) - { - entries.Add($"Win64: {entry.Win64Path}"); - } - node.ToolTipText = string.Join("\r\n", entries); - - return node; - } - - private static IEnumerable LoadTypeLibs(COMRegistry registry) - { - List typeLibNodes = new(); - foreach (COMTypeLibEntry ent in registry.Typelibs.Values) - { - var root = CreateNode(ent.Name, FolderKey, ent); - root.Nodes.AddRange(ent.Versions.Select(v => CreateTypelibVersionNode(v)).ToArray()); - typeLibNodes.Add(root); - } - return typeLibNodes.OrderBy(n => n.Text); - } - - private static TreeNode CreateNodes(List base_nodes, Dictionary tree, string name) + private static string BuildCLSIDToolTip(COMRegistry registry, COMCLSIDEntry ent) { - string base_name = string.Empty; - string node_name = name; - int index = name.LastIndexOf('.'); + StringBuilder strRet = new(); - if (index >= 0) + strRet.AppendLine($"CLSID: {ent.Clsid.FormatGuid()}"); + strRet.AppendLine($"Name: {ent.Name}"); + strRet.AppendLine($"{ent.DefaultServerType}: {ent.DefaultServer}"); + IEnumerable progids = registry.GetProgIdsForClsid(ent.Clsid).Select(p => p.ProgID); + if (progids.Any()) { - base_name = name.Substring(0, index); - node_name = name.Substring(index + 1); + strRet.AppendLine("ProgIDs:"); + foreach (string progid in progids) + { + strRet.AppendLine($"{progid}"); + } + } + if (ent.AppID != Guid.Empty) + { + strRet.AppendLine($"AppID: {ent.AppID.FormatGuid()}"); + } + if (ent.TypeLib != Guid.Empty) + { + strRet.AppendLine($"TypeLib: {ent.TypeLib.FormatGuid()}"); } - TreeNode node = new(node_name); - node.ImageKey = FolderKey; - node.SelectedImageKey = FolderOpenKey; + COMInterfaceEntry[] proxies = registry.GetProxiesForClsid(ent); + if (proxies.Length > 0) + { + strRet.AppendLine($"Interface Proxies: {proxies.Length}"); + } - if (base_name == string.Empty) + if (ent.InterfacesLoaded) { - if (!tree.ContainsKey(node_name)) - { - tree[node_name] = node; - base_nodes.Add(node); - } + strRet.AppendLine($"Instance Interfaces: {ent.Interfaces.Count()}"); + strRet.AppendLine($"Factory Interfaces: {ent.FactoryInterfaces.Count()}"); } - else + if (ent.DefaultServerType == COMServerType.InProcServer32) { - if (!tree.TryGetValue(base_name, out TreeNode root_node)) + COMCLSIDServerEntry server = ent.Servers[COMServerType.InProcServer32]; + if (server.HasDotNet) { - root_node = CreateNodes(base_nodes, tree, base_name); - tree[base_name] = root_node; + strRet.AppendLine($"Assembly: {server.DotNet.AssemblyName}"); + strRet.AppendLine($"Class: {server.DotNet.ClassName}"); + if (!string.IsNullOrWhiteSpace(server.DotNet.CodeBase)) + { + strRet.AppendLine($"Codebase: {server.DotNet.CodeBase}"); + } + if (!string.IsNullOrWhiteSpace(server.DotNet.RuntimeVersion)) + { + strRet.AppendLine($"Runtime Version: {server.DotNet.RuntimeVersion}"); + } } - root_node.Nodes.Add(node); } - return node; - } - - private static IEnumerable LoadRuntimeInterfacesTree(COMRegistry registry) + return strRet.ToString(); + } + + /// + /// Build a ProgID entry tooltip + /// + /// The ProgID entry + /// The ProgID tooltip + private static string BuildProgIDToolTip(COMRegistry registry, COMProgIDEntry ent) { - Dictionary tree = new(); - List base_nodes = new(); - foreach (var intf in registry.Interfaces.Values.Where(i => i.HasRuntimeType).OrderBy(i => i.Name)) + string strRet; + COMCLSIDEntry entry = registry.MapClsidToEntry(ent.Clsid); + if (entry is not null) { - var node = CreateNodes(base_nodes, tree, intf.Name); - node.ImageKey = InterfaceKey; - node.SelectedImageKey = InterfaceKey; - node.Tag = intf; + strRet = BuildCLSIDToolTip(registry, entry); + } + else + { + strRet = $"CLSID: {ent.Clsid.FormatGuid()}\n"; } - return base_nodes; - } - - private void AddInterfaceNodes(TreeNode node, IEnumerable intfs) - { - node.Nodes.AddRange(intfs.Select(i => CreateInterfaceNameNode(m_registry, m_registry.MapIidToInterface(i.Iid), i)).OrderBy(n => n.Text).ToArray()); - } - - private async Task SetupCLSIDNodeTree(ICOMClassEntry clsid, TreeNode node, bool bRefresh) - { - node.Nodes.Clear(); - TreeNode wait_node = CreateNode("Please Wait, Populating Interfaces", InterfaceKey, null); - node.Nodes.Add(wait_node); - try - { - await clsid.LoadSupportedInterfacesAsync(bRefresh, null); - int interface_count = clsid.Interfaces.Count(); - int factory_count = clsid.FactoryInterfaces.Count(); - if (interface_count == 0 && factory_count == 0) - { - wait_node.Text = "Error querying COM interfaces - Timeout"; - } - else - { - treeComRegistry.SuspendLayout(); - if (interface_count > 0) - { - node.Nodes.Remove(wait_node); - AddInterfaceNodes(node, clsid.Interfaces); - } - else - { - wait_node.Text = "Error querying COM interfaces - No Instance Interfaces"; - } - - if (factory_count > 0) - { - TreeNode factory = CreateNode("Factory Interfaces", FolderKey, null); - AddInterfaceNodes(factory, clsid.FactoryInterfaces); - node.Nodes.Add(factory); - - if (clsid is COMCLSIDEntry clsid_entry && - (clsid.FactoryInterfaces.Any(i => i.Iid == COMKnownGuids.IID_IPSFactoryBuffer) - || m_registry.ProxiesByClsid.ContainsKey(clsid_entry.Clsid))) - { - TreeNode proxy = CreateNode("Proxy", ProcessKey, new COMProxyFormatter(clsid_entry)); - node.Nodes.Add(proxy); - } - } - - var typelib = m_registry.MapClsidToEntry(clsid.Clsid)?.TypeLibEntry; - if (typelib is not null) - { - TreeNode typelib_node = CreateNode("Typelib", ProcessKey, typelib); - typelib_node.Nodes.AddRange(typelib.Versions.Select(v => CreateTypelibVersionNode(v)).ToArray()); - node.Nodes.Add(typelib_node); - } - - treeComRegistry.ResumeLayout(); - } - } - catch (Win32Exception ex) - { - wait_node.Text = $"Error querying COM interfaces - {ex.Message}"; - } - } - - private static void AddTypeLibNodes(TreeNode node, IEnumerable types, string category, string image_key) + return strRet; + } + + private static string BuildInterfaceToolTip(COMInterfaceEntry ent, COMInterfaceInstance instance) { - if (types.Any()) + StringBuilder builder = new(); + + builder.AppendLine($"Name: {ent.Name}"); + builder.AppendLine($"IID: {ent.Iid.FormatGuid()}"); + if (ent.ProxyClsid != Guid.Empty) { - var sub_node = CreateNode(category, FolderKey, types); - node.Nodes.Add(sub_node); - sub_node.Nodes.AddRange(types.Select(type => CreateNode(type.Name, image_key, type)).ToArray()); + builder.AppendLine($"ProxyCLSID: {ent.ProxyClsid.FormatGuid()}"); } - } - - private static void SetupTypeLibNodeTree(COMTypeLib typelib, TreeNode node) + if (instance is not null && instance.Module is not null) + { + builder.AppendLine($"VTable Address: {instance.Module}+0x{instance.VTableOffset:X}"); + } + if (ent.HasTypeLib) + { + builder.AppendLine($"TypeLib: {ent.TypeLib.FormatGuid()}"); + } + + return builder.ToString(); + } + + private static TreeNode CreateCLSIDNode(COMRegistry registry, COMCLSIDEntry ent) { - AddTypeLibNodes(node, typelib.Interfaces, "Interfaces", InterfaceKey); - AddTypeLibNodes(node, typelib.Dispatch, "Dispatch Interfaces", InterfaceKey); - AddTypeLibNodes(node, typelib.Classes, "Classes", ClassKey); - AddTypeLibNodes(node, typelib.Records, "Records", ClassKey); - AddTypeLibNodes(node, typelib.Unions, "Unions", ClassKey); - AddTypeLibNodes(node, typelib.Enums, "Enums", ClassKey); - AddTypeLibNodes(node, typelib.Modules, "Modules", ProcessKey); - AddTypeLibNodes(node, typelib.Aliases, "Aliases", ClassKey); - } - - private async Task SetupTypeLibNodeTree(COMTypeLibVersionEntry typelib, TreeNode node) - { - treeComRegistry.SuspendLayout(); - node.Nodes.Clear(); - TreeNode wait_node = CreateNode("Please Wait, Parsing type library", FolderKey, null); - node.Nodes.Add(wait_node); - treeComRegistry.ResumeLayout(); - try - { - var parsed_typelib = await Task.Run(() => typelib.Parse()); - treeComRegistry.SuspendLayout(); - node.Nodes.Remove(wait_node); - SetupTypeLibNodeTree(parsed_typelib, node); - treeComRegistry.ResumeLayout(); - sourceCodeViewerControl.SelectedObject = typelib; - } - catch (Exception ex) - { - wait_node.Text = $"Error parsing type library - {ex.Message}"; - } + return CreateNode($"{ent.Clsid.FormatGuid()} - {ent.Name}", ClassKey, ent, BuildCLSIDToolTip(registry, ent)); } - private static void AddProxyNodes(TreeNode node, IEnumerable types, string category, string image_key) + private static TreeNode CreateInterfaceNode(COMRegistry registry, COMInterfaceEntry ent) { - if (types.Any()) + return CreateNode($"{ent.Iid.FormatGuid()} - {ent.Name}", + InterfaceKey, ent, BuildInterfaceToolTip(ent, null)); + } + + private static TreeNode CreateInterfaceNameNode(COMRegistry registry, COMInterfaceEntry ent, COMInterfaceInstance instance) + { + return CreateNode(ent.Name, InterfaceKey, ent, BuildInterfaceToolTip(ent, instance)); + } + + /* ADDED */ + private TreeNode CreateInterfaceNameNode(COMRegistry registry, COMInterfaceEntry ent, COMInterfaceInstance instance, String clsid) + { + if (!Directory.Exists("interfaces\\iids")) Directory.CreateDirectory("interfaces\\iids"); + String path = "interfaces\\iids\\" + ent.Iid.ToString() + ".txt"; + TreeNode treeNode = CreateNode(ent.Name, InterfaceKey, ent, BuildInterfaceToolTip(ent, instance)); + sourceCodeViewerControl.AutoParse = true; + using (StreamWriter writer = new StreamWriter(path)) { - var sub_node = CreateNode(category, FolderKey, types); - node.Nodes.Add(sub_node); - sub_node.Nodes.AddRange(types.Select(type => CreateNode(type.Name, image_key, type)).ToArray()); + writer.Write(clsid); } - } - - private static void SetupProxyNodeTree(COMProxyFile proxy_file, TreeNode node) + return treeNode; + } + /* ADDED */ + + private static IEnumerable LoadCLSIDs(COMRegistry registry) { - AddProxyNodes(node, proxy_file.Entries, "Interfaces", InterfaceKey); - AddProxyNodes(node, proxy_file.ComplexTypes.Where(t => !t.IsUnion), "Structs", ClassKey); - AddProxyNodes(node, proxy_file.ComplexTypes.Where(t => t.IsUnion), "Unions", ClassKey); - } - - private async Task SetupCOMProxyNodeTree(COMProxyFormatter proxy, TreeNode node) - { - treeComRegistry.SuspendLayout(); - node.Nodes.Clear(); - TreeNode wait_node = CreateNode("Please Wait, Parsing proxy file.", FolderKey, null); - node.Nodes.Add(wait_node); - treeComRegistry.ResumeLayout(); - try - { - await Task.Run(() => proxy.ParseSourceCode()); - treeComRegistry.SuspendLayout(); - node.Nodes.Remove(wait_node); - SetupProxyNodeTree(proxy.ProxyFile, node); - treeComRegistry.ResumeLayout(); - sourceCodeViewerControl.SelectedObject = proxy; - } - catch (Exception ex) - { - wait_node.Text = $"Error parsing proxy file - {ex.Message}"; - } + return registry.Clsids.Values.Select(ent => CreateCLSIDNode(registry, ent)); } - private static TreeNode CreateProxyNodes(COMProxyFile proxy) + private static TreeNode CreateRuntimeClassNode(COMRuntimeClassEntry ent) { - TreeNode root_node = CreateNode(proxy.Path, ClassKey, proxy); - SetupProxyNodeTree(proxy, root_node); - return root_node; - } - - private async void treeComRegistry_BeforeExpand(object sender, TreeViewCancelEventArgs e) - { - Cursor currCursor = Cursor.Current; - Cursor.Current = Cursors.WaitCursor; - - if (IsDynamicNode(e.Node)) + return CreateNode(ent.Name, ClassKey, ent); + } + + private static IEnumerable LoadRuntimeClasses(COMRegistry registry) + { + return registry.RuntimeClasses.Select(p => CreateRuntimeClassNode(p.Value)); + } + + private static IEnumerable LoadRuntimeServers(COMRegistry registry) + { + List serverNodes = new(registry.Clsids.Count); + foreach (var group in registry.RuntimeClasses.Values.GroupBy(p => p.Server.ToLower())) { - if (e.Node.Tag is ICOMClassEntry class_entry) - { - await SetupCLSIDNodeTree(class_entry, e.Node, false); - } - else if (e.Node.Tag is COMTypeLibVersionEntry typelib_entry) - { - await SetupTypeLibNodeTree(typelib_entry, e.Node); - } - else if (e.Node.Tag is COMTypeLibCoClass typelib_class) + COMRuntimeServerEntry server = registry.MapServerNameToEntry(group.Key); + if (server is null) { - await SetupCLSIDNodeTree(m_registry.MapClsidToEntry(typelib_class.Uuid), e.Node, false); + continue; } - else if (e.Node.Tag is COMProxyFormatter proxy) + TreeNode node = CreateNode(server.Name, FolderKey, server); + node.Nodes.AddRange(group.Select(p => CreateRuntimeClassNode(p)).ToArray()); + serverNodes.Add(node); + } + return serverNodes.OrderBy(n => n.Text); + } + + private static IEnumerable LoadProgIDs(COMRegistry registry) + { + return registry.Progids.Values.Select(p => + CreateNode(p.ProgID, ClassKey, p, BuildProgIDToolTip(registry, p))); + } + + private static IEnumerable LoadCLSIDsByNames(COMRegistry registry) + { + return registry.Clsids.Values.Select(ent + => CreateNode(ent.Name, ClassKey, + ent, BuildCLSIDToolTip(registry, ent))).OrderBy(n => n.Text); + } + + private static string BuildCOMProcessTooltip(COMProcessEntry proc) + { + StringBuilder builder = new(); + builder.AppendLine($"Path: {proc.ExecutablePath}"); + builder.AppendLine($"User: {proc.User}"); + if (proc.AppId != Guid.Empty) + { + builder.AppendLine($"AppID: {proc.AppId}"); + } + builder.AppendLine($"Access Permissions: {proc.AccessPermissions}"); + builder.AppendLine($"LRPC Permissions: {proc.LRpcPermissions}"); + if (!string.IsNullOrEmpty(proc.RpcEndpoint)) + { + builder.AppendLine($"LRPC Endpoint: {proc.RpcEndpoint}"); + } + builder.AppendLine($"Capabilities: {proc.Capabilities}"); + builder.AppendLine($"Authn Level: {proc.AuthnLevel}"); + builder.AppendLine($"Imp Level: {proc.ImpLevel}"); + if (proc.AccessControl != IntPtr.Zero) + { + builder.AppendLine($"Access Control: 0x{proc.AccessControl.ToInt64():X}"); + } + builder.AppendLine(AppUtilities.FormatBitness(proc.Is64Bit)); + return builder.ToString(); + } + + private static string BuildCOMIpidTooltip(COMIPIDEntry ipid) + { + StringBuilder builder = new(); + builder.AppendLine($"Interface: 0x{ipid.Interface.ToInt64():X}"); + if (!string.IsNullOrWhiteSpace(ipid.InterfaceVTable)) + { + builder.AppendLine($"Interface VTable: {ipid.InterfaceVTable}"); + } + builder.AppendLine($"Stub: 0x{ipid.Stub.ToInt64():X}"); + if (!string.IsNullOrWhiteSpace(ipid.StubVTable)) + { + builder.AppendLine($"Stub VTable: {ipid.StubVTable}"); + } + builder.AppendLine($"Flags: {ipid.Flags}"); + builder.AppendLine($"Strong Refs: {ipid.StrongRefs}"); + builder.AppendLine($"Weak Refs: {ipid.WeakRefs}"); + builder.AppendLine($"Private Refs: {ipid.PrivateRefs}"); + + return builder.ToString(); + } + + private static string BuildCOMProcessName(COMProcessEntry proc) + { + return $"{proc.ProcessId,-8} - {proc.Name} - {proc.User}"; + } + + private static void PopulatorIpids(COMRegistry registry, TreeNode node, COMProcessEntry proc) + { + foreach (COMIPIDEntry ipid in proc.Ipids.Where(i => i.IsRunning)) + { + COMInterfaceEntry intf = registry.MapIidToInterface(ipid.Iid); + TreeNode ipid_node = CreateNode($"IPID: {ipid.Ipid.FormatGuid()} - IID: {intf.Name}", InterfaceKey, ipid); + ipid_node.ToolTipText = BuildCOMIpidTooltip(ipid); + node.Nodes.Add(ipid_node); + } + } + + private static TreeNode CreateCOMProcessNode(COMRegistry registry, COMProcessEntry proc, + IDictionary> appIdsByPid, IDictionary> clsidsByAppId) + { + TreeNode node = CreateNode(BuildCOMProcessName(proc), ApplicationKey, proc); + node.ToolTipText = BuildCOMProcessTooltip(proc); + + if (appIdsByPid.ContainsKey(proc.ProcessId) && appIdsByPid[proc.ProcessId].Count() > 0) + { + TreeNode services_node = CreateNode("Services", FolderKey, null); + foreach (COMAppIDEntry appid in appIdsByPid[proc.ProcessId]) { - await SetupCOMProxyNodeTree(proxy, e.Node); + if (clsidsByAppId.ContainsKey(appid.AppId)) + { + services_node.Nodes.Add(CreateLocalServiceNode(registry, appid, clsidsByAppId[appid.AppId])); + } } - else + node.Nodes.Add(services_node); + } + + var server_classes = proc.Classes.Where(c => (c.Context & CLSCTX.LOCAL_SERVER) != 0); + + if (server_classes.Any()) + { + TreeNode classes_node = CreateNode("Classes", FolderKey, null); + foreach (var c in server_classes) { - e.Node.Nodes.Clear(); + classes_node.Nodes.Add(CreateCLSIDNode(registry, registry.MapClsidToEntry(c.Clsid))); } - } - - Cursor.Current = currCursor; - } - - private static bool CanGetGuid(TreeNode node) - { - object tag = node?.Tag; - return tag is ICOMGuid || tag is Guid; - } - - private static Guid GetGuidFromType(TreeNode node) - { - object tag = node?.Tag; - if (tag is ICOMGuid com_guid) - { - return com_guid.ComGuid; - } - - if (tag is Guid guid) - { - return guid; - } - - return Guid.Empty; - } - - private void copyGUIDToolStripMenuItem_Click(object sender, EventArgs e) - { - Guid guid = GetGuidFromType(treeComRegistry.SelectedNode); - if (guid != Guid.Empty) - { - MiscUtilities.CopyGuidToClipboard(guid, GuidFormat.String); - } - } - - private void copyGUIDCStructureToolStripMenuItem_Click(object sender, EventArgs e) - { - Guid guid = GetGuidFromType(treeComRegistry.SelectedNode); - - if (guid != Guid.Empty) - { - MiscUtilities.CopyGuidToClipboard(guid, GuidFormat.Structure); - } - } - - private void copyGUIDHexStringToolStripMenuItem_Click(object sender, EventArgs e) - { - Guid guid = GetGuidFromType(treeComRegistry.SelectedNode); - - if (guid != Guid.Empty) - { - MiscUtilities.CopyGuidToClipboard(guid, GuidFormat.HexString); - } - } - - private void copyObjectTagToolStripMenuItem_Click(object sender, EventArgs e) - { - TreeNode node = treeComRegistry.SelectedNode; - Guid guid = Guid.Empty; - - if (node?.Tag is COMCLSIDEntry clsid) - { - guid = clsid.Clsid; - } - else if (node?.Tag is COMProgIDEntry prog_id) - { - guid = prog_id.Clsid; - } - - if (guid != Guid.Empty) - { - MiscUtilities.CopyGuidToClipboard(guid, GuidFormat.Object); - } - } - - private async Task SetupObjectView(ICOMClassEntry ent, object obj, bool factory) - { - await EntryPoint.GetMainForm(m_registry).HostObject(ent, obj, factory); - } - - private ICOMClassEntry GetSelectedClassEntry() - { - TreeNode node = treeComRegistry.SelectedNode; - if (node?.Tag is ICOMClassEntry clsid) - { - return clsid; - } - else if (node?.Tag is COMProgIDEntry prog_id) - { - return m_registry.MapClsidToEntry(prog_id.Clsid); - } - else if (node?.Tag is COMTypeLibCoClass typelib_class) - { - return m_registry.MapClsidToEntry(typelib_class.Uuid); - } - return null; - } - - private async Task CreateInstance(CLSCTX clsctx, string server) - { - ICOMClassEntry ent = GetSelectedClassEntry(); - if (ent is null) - return; - try - { - object comObj = ent.CreateInstanceAsObject(clsctx, server); - if (comObj is not null) - { - await SetupObjectView(ent, comObj, false); - } - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - private async Task CreateClassFactory(string server) - { - ICOMClassEntry ent = GetSelectedClassEntry(); - if (ent is null) - return; - try - { - object comObj = ent.CreateClassFactory(CLSCTX.ALL, server); - if (comObj is not null) - { - await SetupObjectView(ent, comObj, true); - } - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - private async void createInstanceToolStripMenuItem_Click(object sender, EventArgs e) - { - await CreateInstance(CLSCTX.ALL, null); - } - - private void EnableViewPermissions(COMAppIDEntry appid) - { - if (appid.HasAccessPermission) - { - contextMenuStrip.Items.Add(viewAccessPermissionsToolStripMenuItem); - } - if (appid.HasLaunchPermission) - { - contextMenuStrip.Items.Add(viewLaunchPermissionsToolStripMenuItem); - } - } - - private void SetupCreateSpecialSessions() - { - createInSessionToolStripMenuItem.DropDownItems.Clear(); - createInSessionToolStripMenuItem.DropDownItems.Add(consoleToolStripMenuItem); - foreach (int session_id in COMSecurity.GetSessionIds()) - { - ToolStripMenuItem item = new(session_id.ToString()); - item.Tag = session_id.ToString(); - item.Click += consoleToolStripMenuItem_Click; - createInSessionToolStripMenuItem.DropDownItems.Add(item); - } - createSpecialToolStripMenuItem.DropDownItems.Add(createInSessionToolStripMenuItem); - } - - private static bool HasServerType(COMCLSIDEntry clsid, COMServerType type) - { - if (clsid is null) - { - return false; - } - - if (clsid.DefaultServerType == COMServerType.UnknownServer) - { - // If we have no servers we assume anything is possible. - return true; - } - - return clsid.Servers.ContainsKey(type); - } - - private void contextMenuStrip_Opening(object sender, CancelEventArgs e) - { - TreeNode node = treeComRegistry.SelectedNode; - - if ((node is not null) && (node.Tag is not null)) - { - contextMenuStrip.Items.Clear(); - contextMenuStrip.Items.Add(copyToolStripMenuItem); - if (CanGetGuid(node)) - { - contextMenuStrip.Items.Add(copyGUIDToolStripMenuItem); - contextMenuStrip.Items.Add(copyGUIDHexStringToolStripMenuItem); - contextMenuStrip.Items.Add(copyGUIDCStructureToolStripMenuItem); - } - - if ((node.Tag is ICOMClassEntry) || (node.Tag is COMProgIDEntry) || (node.Tag is COMTypeLibCoClass)) - { - contextMenuStrip.Items.Add(copyObjectTagToolStripMenuItem); - contextMenuStrip.Items.Add(createInstanceToolStripMenuItem); - - COMCLSIDEntry clsid = node.Tag as COMCLSIDEntry; - COMRuntimeClassEntry runtime_class = node.Tag as COMRuntimeClassEntry; - ICOMClassEntry entry = node.Tag as ICOMClassEntry; - if (node.Tag is COMProgIDEntry progid) - { - clsid = m_registry.MapClsidToEntry(progid.Clsid); - entry = clsid; - } - else if (node.Tag is COMTypeLibCoClass typelib_class) - { - clsid = m_registry.MapClsidToEntry(typelib_class.Uuid); - entry = clsid; - } - - createSpecialToolStripMenuItem.DropDownItems.Clear(); - - if (HasServerType(clsid, COMServerType.InProcServer32)) - { - createSpecialToolStripMenuItem.DropDownItems.Add(createInProcServerToolStripMenuItem); - } - - if (HasServerType(clsid, COMServerType.InProcHandler32)) - { - createSpecialToolStripMenuItem.DropDownItems.Add(createInProcHandlerToolStripMenuItem); - } - - if (HasServerType(clsid, COMServerType.LocalServer32)) - { - createSpecialToolStripMenuItem.DropDownItems.Add(createLocalServerToolStripMenuItem); - SetupCreateSpecialSessions(); - if (clsid.CanElevate) - { - createSpecialToolStripMenuItem.DropDownItems.Add(createElevatedToolStripMenuItem); - } - createSpecialToolStripMenuItem.DropDownItems.Add(createRemoteToolStripMenuItem); - } - - createSpecialToolStripMenuItem.DropDownItems.Add(createClassFactoryToolStripMenuItem); - if (entry is not null && entry.SupportsRemoteActivation) - { - createSpecialToolStripMenuItem.DropDownItems.Add(createClassFactoryRemoteToolStripMenuItem); - } - - if (runtime_class is not null && runtime_class.TrustLevel == TrustLevel.PartialTrust) - { - createSpecialToolStripMenuItem.DropDownItems.Add(createInRuntimeBrokerToolStripMenuItem); - createSpecialToolStripMenuItem.DropDownItems.Add(createInPerUserRuntimeBrokerToolStripMenuItem); - createSpecialToolStripMenuItem.DropDownItems.Add(createFactoryInRuntimeBrokerToolStripMenuItem); - createSpecialToolStripMenuItem.DropDownItems.Add(createFactoryInPerUserRuntimeBrokerToolStripMenuItem); - } + + node.Nodes.Add(classes_node); + } + + PopulatorIpids(registry, node, proc); + return node; + } + + private static IEnumerable LoadProcesses(COMRegistry registry, IEnumerable processes) + { + var servicesById = COMUtilities.GetServicePids(); + var appidsByService = registry.AppIDs.Values.Where(a => a.IsService). + GroupBy(a => a.LocalService.Name, StringComparer.OrdinalIgnoreCase).ToDictionary(g => g.Key, g => g, StringComparer.OrdinalIgnoreCase); + var clsidsByAppId = registry.ClsidsByAppId; + var appsByPid = servicesById.ToDictionary(p => p.Key, p => p.Value.Where(v => appidsByService.ContainsKey(v)).SelectMany(v => appidsByService[v])); + + return processes.Where(p => p.Ipids.Any()).Select(p => CreateCOMProcessNode(registry, p, appsByPid, clsidsByAppId)); + } + + private enum ServerType + { + None, + Local, + Surrogate, + Proxies, + } + + private static bool IsProxyClsid(COMRegistry registry, COMCLSIDEntry ent) + { + return ent.DefaultServerType == COMServerType.InProcServer32 && registry.GetProxiesForClsid(ent).Length > 0; + } + + private static bool HasSurrogate(COMRegistry registry, COMCLSIDEntry ent) + { + return registry.AppIDs.ContainsKey(ent.AppID) && !string.IsNullOrWhiteSpace(registry.AppIDs[ent.AppID].DllSurrogate); + } + + private class COMCLSIDServerEqualityComparer : IEqualityComparer + { + public bool Equals(COMCLSIDServerEntry x, COMCLSIDServerEntry y) + { + return x.Server.Equals(y.Server, StringComparison.OrdinalIgnoreCase); + } + + public int GetHashCode(COMCLSIDServerEntry obj) + { + return obj.Server.ToLower().GetHashCode(); + } + } + + private static IEnumerable LoadCLSIDByServer(COMRegistry registry, ServerType serverType) + { + IEnumerable>> servers = null; + + if (serverType == ServerType.Surrogate) + { + servers = registry.Clsids.Values.Where(c => HasSurrogate(registry, c)) + .GroupBy(c => registry.AppIDs[c.AppID].DllSurrogate, StringComparer.OrdinalIgnoreCase) + .ToDictionary(g => new COMCLSIDServerEntry(COMServerType.LocalServer32, g.Key), g => g.AsEnumerable().ToList()); + } + else + { + Dictionary> dict = + new(new COMCLSIDServerEqualityComparer()); + IEnumerable clsids = registry.Clsids.Values.Where(e => e.Servers.Count > 0); + if (serverType == ServerType.Proxies) + { + clsids = clsids.Where(c => IsProxyClsid(registry, c)); + } + + foreach (COMCLSIDEntry entry in clsids) + { + foreach (COMCLSIDServerEntry server in entry.Servers.Values) + { + var curr_server = server; + if (curr_server.AppIdHosted) + { + var local_service = entry.AppIDEntry?.LocalService; + if (local_service is null) + continue; + if (!string.IsNullOrEmpty(local_service.ServiceDll)) + { + curr_server = new COMCLSIDServerEntry(COMServerType.LocalServer32, local_service.ServiceDll); + } + else + { + curr_server = new COMCLSIDServerEntry(COMServerType.LocalServer32, local_service.ImagePath); + } + } + + if (!dict.ContainsKey(curr_server)) + { + dict[curr_server] = new List(); + } + dict[curr_server].Add(entry); + } + } + + servers = dict; + + if (serverType == ServerType.Local) + { + servers = servers.Where(p => p.Key.ServerType == COMServerType.LocalServer32); + } + else if (serverType == ServerType.Proxies) + { + servers = servers.Where(p => p.Key.ServerType == COMServerType.InProcServer32); + } + } + + List serverNodes = new(registry.Clsids.Count); + foreach (var pair in servers) + { + TreeNode node = CreateNode(pair.Key.Server, FolderKey, pair.Key); + node.ToolTipText = pair.Key.Server; + node.Nodes.AddRange(pair.Value.OrderBy(c => c.Name).Select(c => CreateClsidNode(registry, c)).ToArray()); + serverNodes.Add(node); + } + + return serverNodes.OrderBy(n => n.Text); + } + + private static IEnumerable LoadInterfaces(COMRegistry registry, bool by_name, bool runtime_interfaces) + { + var total_intfs = registry.Interfaces.Values.AsEnumerable(); + if (runtime_interfaces) + total_intfs = total_intfs.Where(i => i.IsWinRTType); + + if (by_name) + { + return total_intfs.OrderBy(i => i.Name).Select(i => CreateInterfaceNameNode(registry, i, null)); + } + + return total_intfs.Select(i => CreateInterfaceNode(registry, i)); + } + + private static TreeNode CreateClsidNode(COMRegistry registry, COMCLSIDEntry ent) + { + TreeNode currNode = CreateNode(ent.Name, ClassKey, ent); + currNode.ToolTipText = BuildCLSIDToolTip(registry, ent); + return currNode; + } + + private static TreeNode CreateLocalServiceNode(COMRegistry registry, COMAppIDEntry appidEnt, IEnumerable clsids) + { + string name = appidEnt.LocalService.DisplayName; + if (string.IsNullOrWhiteSpace(name)) + { + name = appidEnt.LocalService.Name; + } + + TreeNode node = CreateNode(name, FolderKey, appidEnt); + node.ToolTipText = BuildAppIdTooltip(appidEnt); + node.Nodes.AddRange(clsids.OrderBy(c => c.Name).Select(c => CreateClsidNode(registry, c)).ToArray()); + return node; + } + + private static IEnumerable LoadLocalServices(COMRegistry registry) + { + var clsidsByAppId = registry.ClsidsByAppId; + var appids = registry.AppIDs; + + List serverNodes = new(); + foreach (var pair in clsidsByAppId) + { + if (appids.ContainsKey(pair.Key) && appids[pair.Key].IsService) + { + serverNodes.Add(CreateLocalServiceNode(registry, appids[pair.Key], pair.Value)); + } + } + + return serverNodes.OrderBy(n => n.Text); + } + + private static string LimitString(string s, int max) + { + if (s is null) + return string.Empty; + if (s.Length > max) + { + return s.Substring(0, max) + "..."; + } + return s; + } + + private static string BuildAppIdTooltip(COMAppIDEntry appidEnt) + { + StringBuilder builder = new(); + + builder.AppendLine($"AppID: {appidEnt.AppId}"); + if (!string.IsNullOrWhiteSpace(appidEnt.RunAs)) + { + builder.AppendLine($"RunAs: {appidEnt.RunAs}"); + } + + if (appidEnt.IsService) + { + COMAppIDServiceEntry service = appidEnt.LocalService; + builder.AppendLine($"Service Name: {service.Name}"); + if (!string.IsNullOrWhiteSpace(service.DisplayName)) + { + builder.AppendLine($"Display Name: {service.DisplayName}"); + } + if (!string.IsNullOrWhiteSpace(service.UserName)) + { + builder.AppendLine($"Service User: {service.UserName}"); + } + builder.AppendLine($"Image Path: {service.ImagePath}"); + if (!string.IsNullOrWhiteSpace(service.ServiceDll)) + { + builder.AppendLine($"Service DLL: {service.ServiceDll}"); + } + } + + if (appidEnt.HasLaunchPermission) + { + builder.AppendLine($"Launch: {LimitString(appidEnt.LaunchPermission?.ToSddl(), 64)}"); + } + + if (appidEnt.HasAccessPermission) + { + builder.AppendLine($"Access: {LimitString(appidEnt.AccessPermission?.ToSddl(), 64)}"); + } + + if (appidEnt.RotFlags != COMAppIDRotFlags.None) + { + builder.AppendLine($"RotFlags: {appidEnt.RotFlags}"); + } + + if (!string.IsNullOrWhiteSpace(appidEnt.DllSurrogate)) + { + builder.AppendLine($"DLL Surrogate: {appidEnt.DllSurrogate}"); + } + + if (appidEnt.Flags != COMAppIDFlags.None) + { + builder.AppendLine($"Flags: {appidEnt.Flags}"); + } + + return builder.ToString(); + } + + private static IEnumerable LoadAppIDs(COMRegistry registry, bool filterIL, bool filterAC) + { + var clsidsByAppId = registry.ClsidsByAppId; + var appids = registry.AppIDs; + + List serverNodes = new(); + foreach (var pair in appids) + { + COMAppIDEntry appidEnt = appids[pair.Key]; + + if (filterIL && COMSecurity.GetILForSD(appidEnt.AccessPermission) == TokenIntegrityLevel.Medium && + COMSecurity.GetILForSD(appidEnt.LaunchPermission) == TokenIntegrityLevel.Medium) + { + continue; + } + + if (filterAC && !appidEnt.HasACAccess && !appidEnt.HasACLaunch) + { + continue; + } + + TreeNode node = CreateNode(appidEnt.Name, FolderKey, appidEnt); + node.ToolTipText = BuildAppIdTooltip(appidEnt); + + if (clsidsByAppId.ContainsKey(pair.Key)) + { + node.Nodes.AddRange(clsidsByAppId[pair.Key].OrderBy(c => c.Name).Select(c => CreateClsidNode(registry, c)).ToArray()); + } + + serverNodes.Add(node); + } + + + return serverNodes.OrderBy(n => n.Text); + } + + private static IEnumerable LoadImplementedCategories(COMRegistry registry) + { + SortedDictionary sortedNodes = new(); + + foreach (var cat in registry.ImplementedCategories.Values) + { + TreeNode currNode = CreateNode(cat.Name, FolderKey, cat); + currNode.ToolTipText = $"CATID: {cat.CategoryID.FormatGuid()}"; + sortedNodes.Add(currNode.Text, currNode); + + IEnumerable clsids = cat.ClassEntries.OrderBy(c => c.Name); + IEnumerable clsidNodes = clsids.Select(n => CreateClsidNode(registry, n)); + currNode.Nodes.AddRange(clsidNodes.ToArray()); + } + + return sortedNodes.Values; + } + + private static IEnumerable LoadPreApproved(COMRegistry registry) + { + List nodes = new(); + foreach (COMCLSIDEntry ent in registry.PreApproved) + { + nodes.Add(CreateCLSIDNode(registry, ent)); + } + + return nodes; + } + + private static IEnumerable LoadIELowRights(COMRegistry registry) + { + List clsidNodes = new(); + foreach (COMIELowRightsElevationPolicy ent in registry.LowRights) + { + StringBuilder tooltip = new(); + List clsids = new(); + COMCLSIDEntry entry = ent.ClassEntry; + if (entry is not null) + { + clsids.Add(entry); + } + + if (!string.IsNullOrWhiteSpace(ent.AppPath) && registry.ClsidsByServer.ContainsKey(ent.AppPath)) + { + clsids.AddRange(registry.ClsidsByServer[ent.AppPath]); + tooltip.AppendLine($"{ent.AppPath}"); + } + + if (clsids.Count == 0) + { + continue; + } + + TreeNode currNode = CreateNode(ent.Name, FolderKey, ent); + clsidNodes.Add(currNode); + + foreach (COMCLSIDEntry cls in clsids) + { + currNode.Nodes.Add(CreateCLSIDNode(registry, cls)); + } + + tooltip.AppendLine($"Policy: {ent.Policy}"); + currNode.ToolTipText = tooltip.ToString(); + } + + return clsidNodes; + } + + private static IEnumerable LoadMimeTypes(COMRegistry registry) + { + List nodes = new(registry.MimeTypes.Count()); + foreach (COMMimeType ent in registry.MimeTypes) + { + TreeNode node = CreateNode(ent.MimeType, FolderKey, ent); + if (registry.Clsids.ContainsKey(ent.Clsid)) + { + node.Nodes.Add(CreateCLSIDNode(registry, registry.Clsids[ent.Clsid])); + } + + if (!string.IsNullOrWhiteSpace(ent.Extension)) + { + node.ToolTipText = $"Extension {ent.Extension}"; + } + nodes.Add(node); + } + + return nodes; + } + + private static TreeNode CreateTypelibVersionNode(COMTypeLibVersionEntry entry) + { + TreeNode node = CreateNode($"{entry.Name} : Version {entry.Version}", + ClassKey, entry); + List entries = new(); + if (!string.IsNullOrWhiteSpace(entry.Win32Path)) + { + entries.Add($"Win32: {entry.Win32Path}"); + } + if (!string.IsNullOrWhiteSpace(entry.Win64Path)) + { + entries.Add($"Win64: {entry.Win64Path}"); + } + node.ToolTipText = string.Join("\r\n", entries); + + return node; + } + + private static IEnumerable LoadTypeLibs(COMRegistry registry) + { + List typeLibNodes = new(); + foreach (COMTypeLibEntry ent in registry.Typelibs.Values) + { + var root = CreateNode(ent.Name, FolderKey, ent); + root.Nodes.AddRange(ent.Versions.Select(v => CreateTypelibVersionNode(v)).ToArray()); + typeLibNodes.Add(root); + } + return typeLibNodes.OrderBy(n => n.Text); + } + + private static TreeNode CreateNodes(List base_nodes, Dictionary tree, string name) + { + string base_name = string.Empty; + string node_name = name; + int index = name.LastIndexOf('.'); + + if (index >= 0) + { + base_name = name.Substring(0, index); + node_name = name.Substring(index + 1); + } + + TreeNode node = new(node_name); + node.ImageKey = FolderKey; + node.SelectedImageKey = FolderOpenKey; + + if (base_name == string.Empty) + { + if (!tree.ContainsKey(node_name)) + { + tree[node_name] = node; + base_nodes.Add(node); + } + } + else + { + if (!tree.TryGetValue(base_name, out TreeNode root_node)) + { + root_node = CreateNodes(base_nodes, tree, base_name); + tree[base_name] = root_node; + } + root_node.Nodes.Add(node); + } + + return node; + } + + private static IEnumerable LoadRuntimeInterfacesTree(COMRegistry registry) + { + Dictionary tree = new(); + List base_nodes = new(); + foreach (var intf in registry.Interfaces.Values.Where(i => i.HasRuntimeType).OrderBy(i => i.Name)) + { + var node = CreateNodes(base_nodes, tree, intf.Name); + node.ImageKey = InterfaceKey; + node.SelectedImageKey = InterfaceKey; + node.Tag = intf; + } + + return base_nodes; + } + + private void AddInterfaceNodes(TreeNode node, IEnumerable intfs) + { + node.Nodes.AddRange(intfs.Select(i => CreateInterfaceNameNode(m_registry, m_registry.MapIidToInterface(i.Iid), i)).OrderBy(n => n.Text).ToArray()); + } + + /* Added */ + private void AddInterfaceNodes(TreeNode node, IEnumerable intfs, String clsid) + { + node.Nodes.AddRange(intfs.Select(i => CreateInterfaceNameNode(m_registry, m_registry.MapIidToInterface(i.Iid), i, clsid)).OrderBy(n => n.Text).ToArray()); + } + /* Added */ + + private async Task SetupCLSIDNodeTree(ICOMClassEntry clsid, TreeNode node, bool bRefresh) + { + /* Added */ + bool success = true; + /* Added */ + node.Nodes.Clear(); + TreeNode wait_node = CreateNode("Please Wait, Populating Interfaces", InterfaceKey, null); + node.Nodes.Add(wait_node); + try + { + await clsid.LoadSupportedInterfacesAsync(bRefresh, null); + int interface_count = clsid.Interfaces.Count(); + int factory_count = clsid.FactoryInterfaces.Count(); + if (interface_count == 0 && factory_count == 0) + { + wait_node.Text = "Error querying COM interfaces - Timeout"; + success = false; + } + else + { + treeComRegistry.SuspendLayout(); + if (interface_count > 0) + { + AddInterfaceNodes(node, clsid.Interfaces, clsid.Clsid.ToString()); + } + else + { + wait_node.Text = "Error querying COM interfaces - No Instance Interfaces"; + success = false; + } + + if (factory_count > 0) + { + TreeNode factory = CreateNode("Factory Interfaces", FolderKey, null); + AddInterfaceNodes(factory, clsid.FactoryInterfaces); + node.Nodes.Add(factory); + + if (clsid is COMCLSIDEntry clsid_entry && + (clsid.FactoryInterfaces.Any(i => i.Iid == COMKnownGuids.IID_IPSFactoryBuffer) + || m_registry.ProxiesByClsid.ContainsKey(clsid_entry.Clsid))) + { + TreeNode proxy = CreateNode("Proxy", ProcessKey, new COMProxyFormatter(clsid_entry)); + node.Nodes.Add(proxy); + } + } + + var typelib = m_registry.MapClsidToEntry(clsid.Clsid)?.TypeLibEntry; + if (typelib is not null) + { + TreeNode typelib_node = CreateNode("Typelib", ProcessKey, typelib); + typelib_node.Nodes.AddRange(typelib.Versions.Select(v => CreateTypelibVersionNode(v)).ToArray()); + node.Nodes.Add(typelib_node); + } + + treeComRegistry.ResumeLayout(); + } + } + catch (Win32Exception ex) + { + wait_node.Text = $"Error querying COM interfaces - {ex.Message}"; + success = false; + } + + /* Added */ + // If oleviewdotnet failed to extract interfaces from class, + // will create FindInterfaceForm and runs FindInterface.exe, FindInterfaceInproc.exe to find interface. + // FindInterface.exe will call CoCreateInstance(CLSCTX_LOCAL_SERVER) with iids registered in HKEY_CLASSES_ROOT\Interface. + // FindInterfaceInproc.exe will call CoCreateInstance(CLSCTX_INPROC_SERVER) with iids registered in HKEY_CLASSES_ROOT\Interface. + + if (success == false || clsid.Interfaces.Count() < 2) + { + this.findInterfaceForm = new FindInterfaceForm(); + Thread uiThread = new Thread(StartFindInterfaceForm); + uiThread.Start(); + + findInterfaceForm.UpdateLabel1($"Finding Interface for CLSID {clsid.Clsid.ToString()}"); + findInterfaceForm.UpdateLabel5("Waiting"); + findInterfaceForm.UpdateLabel6("Waiting"); + Application.DoEvents(); + + Thread inProcThread = new Thread(RunFindInterface); + Thread localThread = new Thread(RunFindInterface); + + inProcThread.Start((true, clsid)); + localThread.Start((false, clsid)); + + inProcThread.Join(); + localThread.Join(); + + if (findInterfaceForm.inProcRetval != 0 && findInterfaceForm.localRetval != 0) + { + wait_node.Text = $"Failed to find interfaces."; + if (File.Exists("now.local")) File.Delete("now.local"); + if (File.Exists("now.inproc")) File.Delete("now.inproc"); + Thread.Sleep(1000); + findInterfaceForm.Close(); + return; + } + node.Nodes.Clear(); + if (findInterfaceForm.inProcRetval == 0) + { + using (StreamReader reader = new StreamReader("now.inproc")) + { + string line; + while ((line = reader.ReadLine()) != null) + { + if (string.IsNullOrWhiteSpace(line)) break; + Guid guid = new Guid(line); + COMInterfaceInstance comInterfaceInstance = new COMInterfaceInstance(guid, m_registry); + node.Nodes.Add(CreateInterfaceNameNode(m_registry, m_registry.MapIidToInterface(comInterfaceInstance.Iid), comInterfaceInstance)); + using (StreamWriter writer = new StreamWriter($"interfaces\\iids\\{comInterfaceInstance.Iid}.txt")) + { + writer.Write(clsid.Clsid.ToString()); + } + } + } + } + else if (findInterfaceForm.localRetval == 0) + { + using (StreamReader reader = new StreamReader("now.local")) + { + string line; + while ((line = reader.ReadLine()) != null) + { + if (string.IsNullOrWhiteSpace(line)) break; + Guid guid = new Guid(line); + COMInterfaceInstance comInterfaceInstance = new COMInterfaceInstance(guid, m_registry); + node.Nodes.Add(CreateInterfaceNameNode(m_registry, m_registry.MapIidToInterface(comInterfaceInstance.Iid), comInterfaceInstance)); + using (StreamWriter writer = new StreamWriter($"interfaces\\iids\\{comInterfaceInstance.Iid}.txt")) + { + writer.Write(clsid.Clsid.ToString()); + } + } + } + } + if (File.Exists("now.local")) File.Delete("now.local"); + if (File.Exists("now.inproc")) File.Delete("now.inproc"); + Thread.Sleep(1000); + findInterfaceForm.Close(); + } + else node.Nodes.Remove(wait_node); + /* Added */ + } + + /* Add */ + // UI Thread for FindInterface Form. + public void RunFindInterface(object obj) + { + var data = ((bool isInproc, ICOMClassEntry clsid))obj; + bool isInproc = data.isInproc; + ICOMClassEntry clsid = data.clsid; + + Thread repeatThread = new Thread(findInterfaceForm.RepeatUpdateLabel); + repeatThread.Start(isInproc); + Process process = new Process(); + if (isInproc) process.StartInfo.FileName = "FindInterfaceInproc.exe"; + else process.StartInfo.FileName = "FindInterface.exe"; + process.StartInfo.Arguments = $"{{{clsid.Clsid.ToString()}}}"; + process.StartInfo.CreateNoWindow = true; + process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + + try + { + process.Start(); + process.WaitForExit(); + } + catch + { + } + int exitCode = process.ExitCode; + process.Close(); + process.Dispose(); + + Thread.Sleep(100); + repeatThread.Abort(); + + if (exitCode == 0) + { + if (isInproc) findInterfaceForm.UpdateLabel6("Success"); + else findInterfaceForm.UpdateLabel5("Success"); + } + else if (exitCode == -1) + { + if (isInproc) findInterfaceForm.UpdateLabel6("Error: TIMEOUT"); + else findInterfaceForm.UpdateLabel5("Error: TIMEOUT"); + } + else if (exitCode == -286331154) + { + if (isInproc) findInterfaceForm.UpdateLabel6("Error: UNKNOWN"); + else findInterfaceForm.UpdateLabel5("Error: UNKNOWN"); + } + else if (exitCode == -2147467262) + { + if (isInproc) findInterfaceForm.UpdateLabel6("Error: No matching interface."); + else findInterfaceForm.UpdateLabel5("Error: No matching interface."); + } + else if (exitCode > 0) + { + if (isInproc) findInterfaceForm.UpdateLabel6($"Error: LastErrorValue {exitCode}"); + findInterfaceForm.UpdateLabel5($"Error: LastErrorValue {exitCode}"); + } + Application.DoEvents(); + if (isInproc) findInterfaceForm.inProcRetval = exitCode; + else findInterfaceForm.localRetval = exitCode; + } + + public FindInterfaceForm findInterfaceForm; + + void StartFindInterfaceForm() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + + Application.Run(findInterfaceForm); + } + + /* Add */ + + private static void AddTypeLibNodes(TreeNode node, IEnumerable types, string category, string image_key) + { + if (types.Any()) + { + var sub_node = CreateNode(category, FolderKey, types); + node.Nodes.Add(sub_node); + sub_node.Nodes.AddRange(types.Select(type => CreateNode(type.Name, image_key, type)).ToArray()); + } + } + + private static void SetupTypeLibNodeTree(COMTypeLib typelib, TreeNode node) + { + AddTypeLibNodes(node, typelib.Interfaces, "Interfaces", InterfaceKey); + AddTypeLibNodes(node, typelib.Dispatch, "Dispatch Interfaces", InterfaceKey); + AddTypeLibNodes(node, typelib.Classes, "Classes", ClassKey); + AddTypeLibNodes(node, typelib.Records, "Records", ClassKey); + AddTypeLibNodes(node, typelib.Unions, "Unions", ClassKey); + AddTypeLibNodes(node, typelib.Enums, "Enums", ClassKey); + AddTypeLibNodes(node, typelib.Modules, "Modules", ProcessKey); + AddTypeLibNodes(node, typelib.Aliases, "Aliases", ClassKey); + } + + private async Task SetupTypeLibNodeTree(COMTypeLibVersionEntry typelib, TreeNode node) + { + treeComRegistry.SuspendLayout(); + node.Nodes.Clear(); + TreeNode wait_node = CreateNode("Please Wait, Parsing type library", FolderKey, null); + node.Nodes.Add(wait_node); + treeComRegistry.ResumeLayout(); + try + { + var parsed_typelib = await Task.Run(() => typelib.Parse()); + treeComRegistry.SuspendLayout(); + node.Nodes.Remove(wait_node); + SetupTypeLibNodeTree(parsed_typelib, node); + treeComRegistry.ResumeLayout(); + sourceCodeViewerControl.SelectedObject = typelib; + } + catch (Exception ex) + { + wait_node.Text = $"Error parsing type library - {ex.Message}"; + } + } + + private static void AddProxyNodes(TreeNode node, IEnumerable types, string category, string image_key) + { + if (types.Any()) + { + var sub_node = CreateNode(category, FolderKey, types); + node.Nodes.Add(sub_node); + sub_node.Nodes.AddRange(types.Select(type => CreateNode(type.Name, image_key, type)).ToArray()); + } + } + + private static void SetupProxyNodeTree(COMProxyFile proxy_file, TreeNode node) + { + AddProxyNodes(node, proxy_file.Entries, "Interfaces", InterfaceKey); + AddProxyNodes(node, proxy_file.ComplexTypes.Where(t => !t.IsUnion), "Structs", ClassKey); + AddProxyNodes(node, proxy_file.ComplexTypes.Where(t => t.IsUnion), "Unions", ClassKey); + } + + private async Task SetupCOMProxyNodeTree(COMProxyFormatter proxy, TreeNode node) + { + treeComRegistry.SuspendLayout(); + node.Nodes.Clear(); + TreeNode wait_node = CreateNode("Please Wait, Parsing proxy file.", FolderKey, null); + node.Nodes.Add(wait_node); + treeComRegistry.ResumeLayout(); + try + { + await Task.Run(() => proxy.ParseSourceCode()); + treeComRegistry.SuspendLayout(); + node.Nodes.Remove(wait_node); + SetupProxyNodeTree(proxy.ProxyFile, node); + treeComRegistry.ResumeLayout(); + sourceCodeViewerControl.SelectedObject = proxy; + } + catch (Exception ex) + { + wait_node.Text = $"Error parsing proxy file - {ex.Message}"; + } + } + + private static TreeNode CreateProxyNodes(COMProxyFile proxy) + { + TreeNode root_node = CreateNode(proxy.Path, ClassKey, proxy); + SetupProxyNodeTree(proxy, root_node); + return root_node; + } + + private async void treeComRegistry_BeforeExpand(object sender, TreeViewCancelEventArgs e) + { + Cursor currCursor = Cursor.Current; + Cursor.Current = Cursors.WaitCursor; + + if (IsDynamicNode(e.Node)) + { + if (e.Node.Tag is ICOMClassEntry class_entry) + { + await SetupCLSIDNodeTree(class_entry, e.Node, false); + } + else if (e.Node.Tag is COMTypeLibVersionEntry typelib_entry) + { + await SetupTypeLibNodeTree(typelib_entry, e.Node); + } + else if (e.Node.Tag is COMTypeLibCoClass typelib_class) + { + await SetupCLSIDNodeTree(m_registry.MapClsidToEntry(typelib_class.Uuid), e.Node, false); + } + else if (e.Node.Tag is COMProxyFormatter proxy) + { + await SetupCOMProxyNodeTree(proxy, e.Node); + } + else + { + e.Node.Nodes.Clear(); + } + } + + Cursor.Current = currCursor; + } + + private static bool CanGetGuid(TreeNode node) + { + object tag = node?.Tag; + return tag is ICOMGuid || tag is Guid; + } + + private static Guid GetGuidFromType(TreeNode node) + { + object tag = node?.Tag; + if (tag is ICOMGuid com_guid) + { + return com_guid.ComGuid; + } + + if (tag is Guid guid) + { + return guid; + } + + return Guid.Empty; + } + + private void copyGUIDToolStripMenuItem_Click(object sender, EventArgs e) + { + Guid guid = GetGuidFromType(treeComRegistry.SelectedNode); + if (guid != Guid.Empty) + { + MiscUtilities.CopyGuidToClipboard(guid, GuidFormat.String); + } + } + + private void copyGUIDCStructureToolStripMenuItem_Click(object sender, EventArgs e) + { + Guid guid = GetGuidFromType(treeComRegistry.SelectedNode); + + if (guid != Guid.Empty) + { + MiscUtilities.CopyGuidToClipboard(guid, GuidFormat.Structure); + } + } + + private void copyGUIDHexStringToolStripMenuItem_Click(object sender, EventArgs e) + { + Guid guid = GetGuidFromType(treeComRegistry.SelectedNode); + + if (guid != Guid.Empty) + { + MiscUtilities.CopyGuidToClipboard(guid, GuidFormat.HexString); + } + } + + private void copyObjectTagToolStripMenuItem_Click(object sender, EventArgs e) + { + TreeNode node = treeComRegistry.SelectedNode; + Guid guid = Guid.Empty; + + if (node?.Tag is COMCLSIDEntry clsid) + { + guid = clsid.Clsid; + } + else if (node?.Tag is COMProgIDEntry prog_id) + { + guid = prog_id.Clsid; + } + + if (guid != Guid.Empty) + { + MiscUtilities.CopyGuidToClipboard(guid, GuidFormat.Object); + } + } + + private async Task SetupObjectView(ICOMClassEntry ent, object obj, bool factory) + { + await EntryPoint.GetMainForm(m_registry).HostObject(ent, obj, factory); + } + + private ICOMClassEntry GetSelectedClassEntry() + { + TreeNode node = treeComRegistry.SelectedNode; + if (node?.Tag is ICOMClassEntry clsid) + { + return clsid; + } + else if (node?.Tag is COMProgIDEntry prog_id) + { + return m_registry.MapClsidToEntry(prog_id.Clsid); + } + else if (node?.Tag is COMTypeLibCoClass typelib_class) + { + return m_registry.MapClsidToEntry(typelib_class.Uuid); + } + return null; + } + + private async Task CreateInstance(CLSCTX clsctx, string server) + { + ICOMClassEntry ent = GetSelectedClassEntry(); + if (ent is null) + return; + try + { + object comObj = ent.CreateInstanceAsObject(clsctx, server); + if (comObj is not null) + { + await SetupObjectView(ent, comObj, false); + } + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + private async Task CreateClassFactory(string server) + { + ICOMClassEntry ent = GetSelectedClassEntry(); + if (ent is null) + return; + try + { + object comObj = ent.CreateClassFactory(CLSCTX.ALL, server); + if (comObj is not null) + { + await SetupObjectView(ent, comObj, true); + } + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + private async void createInstanceToolStripMenuItem_Click(object sender, EventArgs e) + { + await CreateInstance(CLSCTX.ALL, null); + } + + private void EnableViewPermissions(COMAppIDEntry appid) + { + if (appid.HasAccessPermission) + { + contextMenuStrip.Items.Add(viewAccessPermissionsToolStripMenuItem); + } + if (appid.HasLaunchPermission) + { + contextMenuStrip.Items.Add(viewLaunchPermissionsToolStripMenuItem); + } + } + + private void SetupCreateSpecialSessions() + { + createInSessionToolStripMenuItem.DropDownItems.Clear(); + createInSessionToolStripMenuItem.DropDownItems.Add(consoleToolStripMenuItem); + foreach (int session_id in COMSecurity.GetSessionIds()) + { + ToolStripMenuItem item = new(session_id.ToString()); + item.Tag = session_id.ToString(); + item.Click += consoleToolStripMenuItem_Click; + createInSessionToolStripMenuItem.DropDownItems.Add(item); + } + createSpecialToolStripMenuItem.DropDownItems.Add(createInSessionToolStripMenuItem); + } + + private static bool HasServerType(COMCLSIDEntry clsid, COMServerType type) + { + if (clsid is null) + { + return false; + } + + if (clsid.DefaultServerType == COMServerType.UnknownServer) + { + // If we have no servers we assume anything is possible. + return true; + } + + return clsid.Servers.ContainsKey(type); + } + + private void contextMenuStrip_Opening(object sender, CancelEventArgs e) + { + TreeNode node = treeComRegistry.SelectedNode; + + if ((node is not null) && (node.Tag is not null)) + { + contextMenuStrip.Items.Clear(); + contextMenuStrip.Items.Add(copyToolStripMenuItem); + if (CanGetGuid(node)) + { + contextMenuStrip.Items.Add(copyGUIDToolStripMenuItem); + contextMenuStrip.Items.Add(copyGUIDHexStringToolStripMenuItem); + contextMenuStrip.Items.Add(copyGUIDCStructureToolStripMenuItem); + } + + if ((node.Tag is ICOMClassEntry) || (node.Tag is COMProgIDEntry) || (node.Tag is COMTypeLibCoClass)) + { + contextMenuStrip.Items.Add(copyObjectTagToolStripMenuItem); + contextMenuStrip.Items.Add(createInstanceToolStripMenuItem); + + COMCLSIDEntry clsid = node.Tag as COMCLSIDEntry; + COMRuntimeClassEntry runtime_class = node.Tag as COMRuntimeClassEntry; + ICOMClassEntry entry = node.Tag as ICOMClassEntry; + if (node.Tag is COMProgIDEntry progid) + { + clsid = m_registry.MapClsidToEntry(progid.Clsid); + entry = clsid; + } + else if (node.Tag is COMTypeLibCoClass typelib_class) + { + clsid = m_registry.MapClsidToEntry(typelib_class.Uuid); + entry = clsid; + } + + createSpecialToolStripMenuItem.DropDownItems.Clear(); + + if (HasServerType(clsid, COMServerType.InProcServer32)) + { + createSpecialToolStripMenuItem.DropDownItems.Add(createInProcServerToolStripMenuItem); + } + + if (HasServerType(clsid, COMServerType.InProcHandler32)) + { + createSpecialToolStripMenuItem.DropDownItems.Add(createInProcHandlerToolStripMenuItem); + } + + if (HasServerType(clsid, COMServerType.LocalServer32)) + { + createSpecialToolStripMenuItem.DropDownItems.Add(createLocalServerToolStripMenuItem); + SetupCreateSpecialSessions(); + if (clsid.CanElevate) + { + createSpecialToolStripMenuItem.DropDownItems.Add(createElevatedToolStripMenuItem); + } + createSpecialToolStripMenuItem.DropDownItems.Add(createRemoteToolStripMenuItem); + } + + createSpecialToolStripMenuItem.DropDownItems.Add(createClassFactoryToolStripMenuItem); + if (entry is not null && entry.SupportsRemoteActivation) + { + createSpecialToolStripMenuItem.DropDownItems.Add(createClassFactoryRemoteToolStripMenuItem); + } + + if (runtime_class is not null && runtime_class.TrustLevel == TrustLevel.PartialTrust) + { + createSpecialToolStripMenuItem.DropDownItems.Add(createInRuntimeBrokerToolStripMenuItem); + createSpecialToolStripMenuItem.DropDownItems.Add(createInPerUserRuntimeBrokerToolStripMenuItem); + createSpecialToolStripMenuItem.DropDownItems.Add(createFactoryInRuntimeBrokerToolStripMenuItem); + createSpecialToolStripMenuItem.DropDownItems.Add(createFactoryInPerUserRuntimeBrokerToolStripMenuItem); + } if (runtime_class is not null && runtime_class.HasRuntimeType) { - createSpecialToolStripMenuItem.DropDownItems.Add(createRuntimeClassToolStripMenuItem); - } - - contextMenuStrip.Items.Add(createSpecialToolStripMenuItem); - contextMenuStrip.Items.Add(refreshInterfacesToolStripMenuItem); - - if (clsid is not null) - { - if (m_registry.Typelibs.ContainsKey(clsid.TypeLib)) - { - contextMenuStrip.Items.Add(viewTypeLibraryToolStripMenuItem); - } - - if (!clsid.IsAutomationProxy && m_registry.GetProxiesForClsid(clsid).Length > 0) - { - contextMenuStrip.Items.Add(viewProxyLibraryToolStripMenuItem); - } - - if (m_registry.AppIDs.ContainsKey(clsid.AppID)) - { - EnableViewPermissions(m_registry.AppIDs[clsid.AppID]); - } - } - - if (runtime_class is not null) - { - COMRuntimeServerEntry server = - runtime_class.HasServer - ? m_registry.MapServerNameToEntry(runtime_class.Server) : null; - if (runtime_class.HasPermission || (server is not null && server.HasPermission)) - { - contextMenuStrip.Items.Add(viewAccessPermissionsToolStripMenuItem); - } - } - } - else if (node.Tag is COMAppIDEntry appid_entry) - { - EnableViewPermissions(appid_entry); - } - else if (node.Tag is COMInterfaceEntry intf) - { - if (intf.HasTypeLib) - { - contextMenuStrip.Items.Add(viewTypeLibraryToolStripMenuItem); - } - - if (intf.HasProxy && intf.ProxyClassEntry?.IsAutomationProxy == false) - { - contextMenuStrip.Items.Add(viewProxyLibraryToolStripMenuItem); - } - - if (intf.TryGetRuntimeType(out _)) - { - contextMenuStrip.Items.Add(viewRuntimeInterfaceToolStripMenuItem); - } - } - else if (node.Tag is COMProcessEntry) - { - contextMenuStrip.Items.Add(refreshProcessToolStripMenuItem); - contextMenuStrip.Items.Add(viewAccessPermissionsToolStripMenuItem); - } + createSpecialToolStripMenuItem.DropDownItems.Add(createRuntimeClassToolStripMenuItem); + } + + contextMenuStrip.Items.Add(createSpecialToolStripMenuItem); + contextMenuStrip.Items.Add(refreshInterfacesToolStripMenuItem); + + if (clsid is not null) + { + if (m_registry.Typelibs.ContainsKey(clsid.TypeLib)) + { + contextMenuStrip.Items.Add(viewTypeLibraryToolStripMenuItem); + } + + if (!clsid.IsAutomationProxy && m_registry.GetProxiesForClsid(clsid).Length > 0) + { + contextMenuStrip.Items.Add(viewProxyLibraryToolStripMenuItem); + } + + if (m_registry.AppIDs.ContainsKey(clsid.AppID)) + { + EnableViewPermissions(m_registry.AppIDs[clsid.AppID]); + } + } + + if (runtime_class is not null) + { + COMRuntimeServerEntry server = + runtime_class.HasServer + ? m_registry.MapServerNameToEntry(runtime_class.Server) : null; + if (runtime_class.HasPermission || (server is not null && server.HasPermission)) + { + contextMenuStrip.Items.Add(viewAccessPermissionsToolStripMenuItem); + } + } + } + else if (node.Tag is COMAppIDEntry appid_entry) + { + EnableViewPermissions(appid_entry); + } + else if (node.Tag is COMInterfaceEntry intf) + { + if (intf.HasTypeLib) + { + contextMenuStrip.Items.Add(viewTypeLibraryToolStripMenuItem); + } + + if (intf.HasProxy && intf.ProxyClassEntry?.IsAutomationProxy == false) + { + contextMenuStrip.Items.Add(viewProxyLibraryToolStripMenuItem); + } + + if (intf.TryGetRuntimeType(out _)) + { + contextMenuStrip.Items.Add(viewRuntimeInterfaceToolStripMenuItem); + } + } + else if (node.Tag is COMProcessEntry) + { + contextMenuStrip.Items.Add(refreshProcessToolStripMenuItem); + contextMenuStrip.Items.Add(viewAccessPermissionsToolStripMenuItem); + } else if (node.Tag is COMIPIDEntry ipid) - { - intf = m_registry.MapIidToInterface(ipid.Iid); - - if (intf.HasTypeLib) - { - contextMenuStrip.Items.Add(viewTypeLibraryToolStripMenuItem); - } - - if (intf.HasProxy && m_registry.Clsids.ContainsKey(intf.ProxyClsid)) - { - contextMenuStrip.Items.Add(viewProxyLibraryToolStripMenuItem); - } - - contextMenuStrip.Items.Add(unmarshalToolStripMenuItem); - } + { + intf = m_registry.MapIidToInterface(ipid.Iid); + + if (intf.HasTypeLib) + { + contextMenuStrip.Items.Add(viewTypeLibraryToolStripMenuItem); + } + + if (intf.HasProxy && m_registry.Clsids.ContainsKey(intf.ProxyClsid)) + { + contextMenuStrip.Items.Add(viewProxyLibraryToolStripMenuItem); + } + + contextMenuStrip.Items.Add(unmarshalToolStripMenuItem); + } else if (node.Tag is COMRuntimeClassEntry runtime_class) - { - if (runtime_class.HasPermission) - { - contextMenuStrip.Items.Add(viewAccessPermissionsToolStripMenuItem); - } - } + { + if (runtime_class.HasPermission) + { + contextMenuStrip.Items.Add(viewAccessPermissionsToolStripMenuItem); + } + } else if (node.Tag is COMRuntimeServerEntry runtime_server) - { - if (runtime_server.HasPermission) - { - contextMenuStrip.Items.Add(viewAccessPermissionsToolStripMenuItem); - } - } - + { + if (runtime_server.HasPermission) + { + contextMenuStrip.Items.Add(viewAccessPermissionsToolStripMenuItem); + } + } + if (m_filter_types.Contains(FilterType.CLSID) || m_filter_types.Contains(FilterType.RuntimeClass) || - m_filter_types.Contains(FilterType.ProgID)) - { - contextMenuStrip.Items.Add(queryAllInterfacesToolStripMenuItem); - } - - if (treeComRegistry.Nodes.Count > 0) - { - contextMenuStrip.Items.Add(cloneTreeToolStripMenuItem); - selectedToolStripMenuItem.Enabled = treeComRegistry.SelectedNode is not null; - } - - if (PropertiesControl.SupportsProperties(node.Tag)) - { - contextMenuStrip.Items.Add(propertiesToolStripMenuItem); - } - - contextMenuStrip.Items.Add(showSourceCodeToolStripMenuItem); - } - else - { - e.Cancel = true; - } - } - - private async void refreshInterfacesToolStripMenuItem_Click(object sender, EventArgs e) - { - TreeNode node = treeComRegistry.SelectedNode; + m_filter_types.Contains(FilterType.ProgID)) + { + contextMenuStrip.Items.Add(queryAllInterfacesToolStripMenuItem); + } + + if (treeComRegistry.Nodes.Count > 0) + { + contextMenuStrip.Items.Add(cloneTreeToolStripMenuItem); + selectedToolStripMenuItem.Enabled = treeComRegistry.SelectedNode is not null; + } + + if (PropertiesControl.SupportsProperties(node.Tag)) + { + contextMenuStrip.Items.Add(propertiesToolStripMenuItem); + } + + contextMenuStrip.Items.Add(showSourceCodeToolStripMenuItem); + } + else + { + e.Cancel = true; + } + } + + private async void refreshInterfacesToolStripMenuItem_Click(object sender, EventArgs e) + { + TreeNode node = treeComRegistry.SelectedNode; if (node is not null) - { - ICOMClassEntry class_entry = node.Tag as ICOMClassEntry; - + { + ICOMClassEntry class_entry = node.Tag as ICOMClassEntry; + if (node.Tag is COMTypeLibCoClass typelib_class) { class_entry = m_registry.MapClsidToEntry(typelib_class.Uuid); - } - + } + if (class_entry is not null) - { - await SetupCLSIDNodeTree(class_entry, node, true); - } - } - } - - /// - /// Convert a basic Glob to a regular expression - /// - /// The glob string - /// Indicates that match should ignore case - /// The regular expression - private static Regex GlobToRegex(string glob, bool ignoreCase) - { - StringBuilder builder = new(); - - builder.Append("^"); - - foreach (char ch in glob) - { - if (ch == '*') - { - builder.Append(".*"); - } - else if (ch == '?') - { - builder.Append("."); - } - else - { - builder.Append(Regex.Escape(new string(ch, 1))); - } - } - - builder.Append("$"); - - return new Regex(builder.ToString(), ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None); - } - - private enum FilterMode - { - Contains, - BeginsWith, - EndsWith, - Equals, - Glob, - Regex, - Accessible, - NotAccessible, - Complex, - } - - private static Func CreateFilter(string filter, FilterMode mode, bool caseSensitive) - { - filter = filter.Trim(); - if (string.IsNullOrEmpty(filter)) - { - return null; - } - - StringComparison comp = caseSensitive ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase; - - switch (mode) - { - case FilterMode.Contains: - return caseSensitive ? (n => n.Contains(filter)) : (n => n.ToLower().Contains(filter.ToLower())); - case FilterMode.BeginsWith: - return n => n.StartsWith(filter, comp); - case FilterMode.EndsWith: - return n => n.EndsWith(filter, comp); - case FilterMode.Equals: - return n => n.Equals(filter, comp); - case FilterMode.Glob: - { - Regex r = GlobToRegex(filter, caseSensitive); - - return n => r.IsMatch(n); - } - case FilterMode.Regex: - { - Regex r = new(filter, caseSensitive ? RegexOptions.None : RegexOptions.IgnoreCase); - - return n => r.IsMatch(n); - } - default: - throw new ArgumentException("Invalid mode value"); - } - } - + { + await SetupCLSIDNodeTree(class_entry, node, true); + } + } + } + + /// + /// Convert a basic Glob to a regular expression + /// + /// The glob string + /// Indicates that match should ignore case + /// The regular expression + private static Regex GlobToRegex(string glob, bool ignoreCase) + { + StringBuilder builder = new(); + + builder.Append("^"); + + foreach (char ch in glob) + { + if (ch == '*') + { + builder.Append(".*"); + } + else if (ch == '?') + { + builder.Append("."); + } + else + { + builder.Append(Regex.Escape(new string(ch, 1))); + } + } + + builder.Append("$"); + + return new Regex(builder.ToString(), ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None); + } + + private enum FilterMode + { + Contains, + BeginsWith, + EndsWith, + Equals, + Glob, + Regex, + Accessible, + NotAccessible, + Complex, + } + + private static Func CreateFilter(string filter, FilterMode mode, bool caseSensitive) + { + filter = filter.Trim(); + if (string.IsNullOrEmpty(filter)) + { + return null; + } + + StringComparison comp = caseSensitive ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase; + + switch (mode) + { + case FilterMode.Contains: + return caseSensitive ? (n => n.Contains(filter)) : (n => n.ToLower().Contains(filter.ToLower())); + case FilterMode.BeginsWith: + return n => n.StartsWith(filter, comp); + case FilterMode.EndsWith: + return n => n.EndsWith(filter, comp); + case FilterMode.Equals: + return n => n.Equals(filter, comp); + case FilterMode.Glob: + { + Regex r = GlobToRegex(filter, caseSensitive); + + return n => r.IsMatch(n); + } + case FilterMode.Regex: + { + Regex r = new(filter, caseSensitive ? RegexOptions.None : RegexOptions.IgnoreCase); + + return n => r.IsMatch(n); + } + default: + throw new ArgumentException("Invalid mode value"); + } + } + private FilterResult FilterLeafNode(TreeNode n, IRegistryViewerFilter filter) { FilterResult result = FilterResult.None; @@ -1669,54 +1859,54 @@ private FilterResult FilterLeafNode(TreeNode n, IRegistryViewerFilter filter) } } return result; - } - - // Check if top node or one of its subnodes matches the filter - private FilterResult FilterNode(TreeNode n, IRegistryViewerFilter filter) - { - FilterResult result = filter.Filter(n.Text, n.Tag); - - if (result == FilterResult.None) - { + } + + // Check if top node or one of its subnodes matches the filter + private FilterResult FilterNode(TreeNode n, IRegistryViewerFilter filter) + { + FilterResult result = filter.Filter(n.Text, n.Tag); + + if (result == FilterResult.None) + { if (IsLeafNode(n)) { result = FilterLeafNode(n, filter); - } + } else if (!IsDynamicNode(n) && n.Nodes.Count > 0) { - var nodes = n.Nodes.OfType().ToArray(); - n.Nodes.Clear(); - bool has_children = false; - foreach (TreeNode node in nodes) - { - result = FilterNode(node, filter); - if (result == FilterResult.Include) - { - n.Nodes.Add(node); - has_children = true; - } - } + var nodes = n.Nodes.OfType().ToArray(); + n.Nodes.Clear(); + bool has_children = false; + foreach (TreeNode node in nodes) + { + result = FilterNode(node, filter); + if (result == FilterResult.Include) + { + n.Nodes.Add(node); + has_children = true; + } + } if (has_children) { result = FilterResult.Include; } } - } - - return result; - } - - private async void btnApply_Click(object sender, EventArgs e) - { - NtToken token = null; - try - { - TreeNode[] nodes = null; - IRegistryViewerFilter filter = null; - FilterMode mode = (FilterMode)comboBoxMode.SelectedItem; - - if (mode == FilterMode.Complex) - { + } + + return result; + } + + private async void btnApply_Click(object sender, EventArgs e) + { + NtToken token = null; + try + { + TreeNode[] nodes = null; + IRegistryViewerFilter filter = null; + FilterMode mode = (FilterMode)comboBoxMode.SelectedItem; + + if (mode == FilterMode.Complex) + { using ViewFilterForm form = new(m_filter, m_filter_types); if (form.ShowDialog(this) == DialogResult.OK) { @@ -1729,10 +1919,10 @@ private async void btnApply_Click(object sender, EventArgs e) else { return; - } - } - else if (mode == FilterMode.Accessible || mode == FilterMode.NotAccessible) - { + } + } + else if (mode == FilterMode.Accessible || mode == FilterMode.NotAccessible) + { using SelectSecurityCheckForm form = new(m_mode == COMRegistryDisplayMode.Processes); if (form.ShowDialog(this) == DialogResult.OK) { @@ -1742,269 +1932,269 @@ private async void btnApply_Click(object sender, EventArgs e) else { return; - } - } - else - { - Func filterFunc = CreateFilter(textBoxFilter.Text, mode, false); - if (filterFunc is not null) - { - filter = new RegistryViewerDisplayFilter(filterFunc); - } - } - - if (filter is not null) - { + } + } + else + { + Func filterFunc = CreateFilter(textBoxFilter.Text, mode, false); + if (filterFunc is not null) + { + filter = new RegistryViewerDisplayFilter(filterFunc); + } + } + + if (filter is not null) + { using (filter) - { + { nodes = await Task.Run(() => m_original_nodes.Select(n => (TreeNode)n.Clone()). Where(n => FilterNode(n, filter) == FilterResult.Include).ToArray()); - } - } - else - { - nodes = m_original_nodes; - } - - treeComRegistry.SuspendLayout(); - bool node_expanded = treeComRegistry.SelectedNode?.IsExpanded ?? false; - TreeNode visible_node = FindVisibleNode(nodes, treeComRegistry.SelectedNode?.Tag); - treeComRegistry.Nodes.Clear(); - treeComRegistry.Nodes.AddRange(nodes); + } + } + else + { + nodes = m_original_nodes; + } + + treeComRegistry.SuspendLayout(); + bool node_expanded = treeComRegistry.SelectedNode?.IsExpanded ?? false; + TreeNode visible_node = FindVisibleNode(nodes, treeComRegistry.SelectedNode?.Tag); + treeComRegistry.Nodes.Clear(); + treeComRegistry.Nodes.AddRange(nodes); visible_node?.EnsureVisible(); if (node_expanded) { visible_node?.Expand(); - } - treeComRegistry.SelectedNode = visible_node; - treeComRegistry.ResumeLayout(); - UpdateStatusLabel(); - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - finally - { - token?.Close(); - } - } - - private void textBoxFilter_KeyDown(object sender, KeyEventArgs e) - { - if ((e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return)) - { - btnApply.PerformClick(); - } - } - - private void treeComRegistry_MouseDown(object sender, MouseEventArgs e) - { - if (e.Button == MouseButtons.Right) - { - TreeNode node = treeComRegistry.GetNodeAt(e.X, e.Y); - - if (node is not null) - { - treeComRegistry.SelectedNode = node; - } - } + } + treeComRegistry.SelectedNode = visible_node; + treeComRegistry.ResumeLayout(); + UpdateStatusLabel(); + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + finally + { + token?.Close(); + } + } + + private void textBoxFilter_KeyDown(object sender, KeyEventArgs e) + { + if ((e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return)) + { + btnApply.PerformClick(); + } + } + + private void treeComRegistry_MouseDown(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + TreeNode node = treeComRegistry.GetNodeAt(e.X, e.Y); + + if (node is not null) + { + treeComRegistry.SelectedNode = node; + } + } + } + + private static TreeNode CreateTypeLibNodes(COMTypeLib typelib) + { + TreeNode root_node = CreateNode($"{typelib.Name} : Version {typelib.Version}", + ClassKey, typelib); + SetupTypeLibNodeTree(typelib, root_node); + return root_node; + } + + private async void viewTypeLibraryToolStripMenuItem_Click(object sender, EventArgs e) + { + TreeNode node = treeComRegistry.SelectedNode; + if (node?.Tag is null) + return; + + try + { + COMTypeLibVersionEntry typelib = null; + ICOMClassEntry class_entry = node.Tag as ICOMClassEntry; + COMInterfaceEntry intf_entry = node.Tag as COMInterfaceEntry; + + if (class_entry is not null) + { + typelib = m_registry.MapClsidToEntry(class_entry.Clsid)?.TypeLibEntry?. + Versions.First() ?? throw new ArgumentException("No type library registered for class."); + } + else if (intf_entry is not null) + { + typelib = intf_entry.TypeLibVersionEntry ?? throw new ArgumentException("No type library registered for interface."); + } + else + { + throw new ArgumentException("No type library registered."); + } + + var parsed_typelib = await Task.Run(() => typelib.Parse()); + COMTypeLibTypeInfo visible_type = null; + if (class_entry is not null) + { + visible_type = parsed_typelib.Classes.FirstOrDefault(c => c.Uuid == class_entry.Clsid); + } + else + { + visible_type = parsed_typelib.Interfaces.FirstOrDefault(i => i.Uuid == intf_entry.Iid); + if (visible_type is null) + { + visible_type = parsed_typelib.Dispatch.FirstOrDefault(i => i.Uuid == intf_entry.Iid); + } + } + + COMRegistryViewer viewer = new(m_registry, parsed_typelib, visible_type); + EntryPoint.GetMainForm(m_registry).HostControl(viewer); + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + private void propertiesToolStripMenuItem_Click(object sender, EventArgs e) + { + TreeNode node = treeComRegistry.SelectedNode; + if (node is not null) + { + EntryPoint.GetMainForm(m_registry).HostControl(new PropertiesControl(m_registry, node.Text, node.Tag)); + } + } + + private void ViewPermissions(bool access) + { + TreeNode node = treeComRegistry.SelectedNode; + if (node is not null) + { + if (node.Tag is COMProcessEntry proc) + { + COMSecurity.ViewSecurity(m_registry, $"{proc.Name} Access", proc.AccessPermissions, true); + } + else if (node.Tag is COMRuntimeClassEntry || node.Tag is COMRuntimeServerEntry) + { + COMRuntimeServerEntry runtime_server = node.Tag as COMRuntimeServerEntry; + COMRuntimeClassEntry runtime_class = node.Tag as COMRuntimeClassEntry; + string name = runtime_class is not null ? runtime_class.Name : runtime_server.Name; + if (runtime_class is not null && runtime_class.HasServer) + { + runtime_server = m_registry.MapServerNameToEntry(runtime_class.Server); + } + + COMSecurityDescriptor perms = runtime_server?.Permissions ?? runtime_class.Permissions; + + COMSecurity.ViewSecurity(m_registry, $"{name} Access", perms, false); + } + else + { + COMAppIDEntry appid = node.Tag as COMAppIDEntry; + if (appid is null) + { + COMCLSIDEntry clsid = node.Tag as COMCLSIDEntry; + if (clsid is null && node.Tag is COMProgIDEntry prog_id) + { + clsid = m_registry.MapClsidToEntry(prog_id.Clsid); + } + + if (clsid is not null && m_registry.AppIDs.ContainsKey(clsid.AppID)) + { + appid = m_registry.AppIDs[clsid.AppID]; + } + } + + if (appid is not null) + { + COMSecurity.ViewSecurity(m_registry, appid, access); + } + } + } + } + + private void viewLaunchPermissionsToolStripMenuItem_Click(object sender, EventArgs e) + { + ViewPermissions(false); + } + + private void viewAccessPermissionsToolStripMenuItem_Click(object sender, EventArgs e) + { + ViewPermissions(true); + } + + private async void createLocalServerToolStripMenuItem_Click(object sender, EventArgs e) + { + await CreateInstance(CLSCTX.LOCAL_SERVER, null); + } + + private async void createInProcServerToolStripMenuItem_Click(object sender, EventArgs e) + { + await CreateInstance(CLSCTX.INPROC_SERVER, null); + } + + private async Task CreateFromMoniker(COMCLSIDEntry ent, string moniker) + { + try + { + object obj = COMUtilities.CreateFromMoniker(moniker, CLSCTX.LOCAL_SERVER); + await SetupObjectView(ent, obj, obj is IClassFactory); + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + private async Task CreateInSession(COMCLSIDEntry ent, string session_id) + { + await CreateFromMoniker(ent, $"session:{session_id}!new:{ent.Clsid}"); + } + + private async Task CreateElevated(COMCLSIDEntry ent, bool factory) + { + await CreateFromMoniker(ent, $"Elevation:Administrator!{(factory ? "clsid" : "new")}:{ent.Clsid}"); } - private static TreeNode CreateTypeLibNodes(COMTypeLib typelib) + private async void consoleToolStripMenuItem_Click(object sender, EventArgs e) { - TreeNode root_node = CreateNode($"{typelib.Name} : Version {typelib.Version}", - ClassKey, typelib); - SetupTypeLibNodeTree(typelib, root_node); - return root_node; - } - - private async void viewTypeLibraryToolStripMenuItem_Click(object sender, EventArgs e) - { - TreeNode node = treeComRegistry.SelectedNode; - if (node?.Tag is null) - return; + if (GetSelectedClassEntry() is COMCLSIDEntry ent && sender is ToolStripMenuItem item && item.Tag is string) + { + await CreateInSession(ent, (string)item.Tag); + } + } - try + private void copyToolStripMenuItem_Click(object sender, EventArgs e) + { + TreeNode node = treeComRegistry.SelectedNode; + if (node is not null) { - COMTypeLibVersionEntry typelib = null; - ICOMClassEntry class_entry = node.Tag as ICOMClassEntry; - COMInterfaceEntry intf_entry = node.Tag as COMInterfaceEntry; - - if (class_entry is not null) - { - typelib = m_registry.MapClsidToEntry(class_entry.Clsid)?.TypeLibEntry?. - Versions.First() ?? throw new ArgumentException("No type library registered for class."); - } - else if (intf_entry is not null) - { - typelib = intf_entry.TypeLibVersionEntry ?? throw new ArgumentException("No type library registered for interface."); - } - else - { - throw new ArgumentException("No type library registered."); - } + MiscUtilities.CopyTextToClipboard(node.Text); + } + } - var parsed_typelib = await Task.Run(() => typelib.Parse()); - COMTypeLibTypeInfo visible_type = null; - if (class_entry is not null) - { - visible_type = parsed_typelib.Classes.FirstOrDefault(c => c.Uuid == class_entry.Clsid); - } - else + private void viewProxyLibraryToolStripMenuItem_Click(object sender, EventArgs e) + { + TreeNode node = treeComRegistry.SelectedNode; + if (node is not null) + { + COMCLSIDEntry clsid = node.Tag as COMCLSIDEntry; + Guid selected_iid = Guid.Empty; + if (clsid is null && (node.Tag is COMInterfaceEntry || node.Tag is COMIPIDEntry)) { - visible_type = parsed_typelib.Interfaces.FirstOrDefault(i => i.Uuid == intf_entry.Iid); - if (visible_type is null) - { - visible_type = parsed_typelib.Dispatch.FirstOrDefault(i => i.Uuid == intf_entry.Iid); - } - } + COMInterfaceEntry intf = node.Tag as COMInterfaceEntry; + intf ??= m_registry.MapIidToInterface(((COMIPIDEntry)node.Tag).Iid); - COMRegistryViewer viewer = new(m_registry, parsed_typelib, visible_type); - EntryPoint.GetMainForm(m_registry).HostControl(viewer); - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - private void propertiesToolStripMenuItem_Click(object sender, EventArgs e) - { - TreeNode node = treeComRegistry.SelectedNode; - if (node is not null) - { - EntryPoint.GetMainForm(m_registry).HostControl(new PropertiesControl(m_registry, node.Text, node.Tag)); - } - } - - private void ViewPermissions(bool access) - { - TreeNode node = treeComRegistry.SelectedNode; - if (node is not null) - { - if (node.Tag is COMProcessEntry proc) - { - COMSecurity.ViewSecurity(m_registry, $"{proc.Name} Access", proc.AccessPermissions, true); - } - else if (node.Tag is COMRuntimeClassEntry || node.Tag is COMRuntimeServerEntry) - { - COMRuntimeServerEntry runtime_server = node.Tag as COMRuntimeServerEntry; - COMRuntimeClassEntry runtime_class = node.Tag as COMRuntimeClassEntry; - string name = runtime_class is not null ? runtime_class.Name : runtime_server.Name; - if (runtime_class is not null && runtime_class.HasServer) - { - runtime_server = m_registry.MapServerNameToEntry(runtime_class.Server); - } + selected_iid = intf.Iid; + clsid = m_registry.Clsids[intf.ProxyClsid]; + } - COMSecurityDescriptor perms = runtime_server?.Permissions ?? runtime_class.Permissions; - - COMSecurity.ViewSecurity(m_registry, $"{name} Access", perms, false); - } - else - { - COMAppIDEntry appid = node.Tag as COMAppIDEntry; - if (appid is null) - { - COMCLSIDEntry clsid = node.Tag as COMCLSIDEntry; - if (clsid is null && node.Tag is COMProgIDEntry prog_id) - { - clsid = m_registry.MapClsidToEntry(prog_id.Clsid); - } - - if (clsid is not null && m_registry.AppIDs.ContainsKey(clsid.AppID)) - { - appid = m_registry.AppIDs[clsid.AppID]; - } - } - - if (appid is not null) - { - COMSecurity.ViewSecurity(m_registry, appid, access); - } - } - } - } - - private void viewLaunchPermissionsToolStripMenuItem_Click(object sender, EventArgs e) - { - ViewPermissions(false); - } - - private void viewAccessPermissionsToolStripMenuItem_Click(object sender, EventArgs e) - { - ViewPermissions(true); - } - - private async void createLocalServerToolStripMenuItem_Click(object sender, EventArgs e) - { - await CreateInstance(CLSCTX.LOCAL_SERVER, null); - } - - private async void createInProcServerToolStripMenuItem_Click(object sender, EventArgs e) - { - await CreateInstance(CLSCTX.INPROC_SERVER, null); - } - - private async Task CreateFromMoniker(COMCLSIDEntry ent, string moniker) - { - try - { - object obj = COMUtilities.CreateFromMoniker(moniker, CLSCTX.LOCAL_SERVER); - await SetupObjectView(ent, obj, obj is IClassFactory); - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - private async Task CreateInSession(COMCLSIDEntry ent, string session_id) - { - await CreateFromMoniker(ent, $"session:{session_id}!new:{ent.Clsid}"); - } - - private async Task CreateElevated(COMCLSIDEntry ent, bool factory) - { - await CreateFromMoniker(ent, $"Elevation:Administrator!{(factory ? "clsid" : "new")}:{ent.Clsid}"); - } - - private async void consoleToolStripMenuItem_Click(object sender, EventArgs e) - { - if (GetSelectedClassEntry() is COMCLSIDEntry ent && sender is ToolStripMenuItem item && item.Tag is string) - { - await CreateInSession(ent, (string)item.Tag); - } - } - - private void copyToolStripMenuItem_Click(object sender, EventArgs e) - { - TreeNode node = treeComRegistry.SelectedNode; - if (node is not null) - { - MiscUtilities.CopyTextToClipboard(node.Text); - } - } - - private void viewProxyLibraryToolStripMenuItem_Click(object sender, EventArgs e) - { - TreeNode node = treeComRegistry.SelectedNode; - if (node is not null) - { - COMCLSIDEntry clsid = node.Tag as COMCLSIDEntry; - Guid selected_iid = Guid.Empty; - if (clsid is null && (node.Tag is COMInterfaceEntry || node.Tag is COMIPIDEntry)) - { - COMInterfaceEntry intf = node.Tag as COMInterfaceEntry; - intf ??= m_registry.MapIidToInterface(((COMIPIDEntry)node.Tag).Iid); - - selected_iid = intf.Iid; - clsid = m_registry.Clsids[intf.ProxyClsid]; - } - - if (clsid is not null) - { - try + if (clsid is not null) + { + try { COMProxyFile proxy_file = COMProxyFile.GetFromCLSID(clsid); COMProxyTypeInfo visible_interface = proxy_file.Entries.Where(e => e.Iid == selected_iid).FirstOrDefault(); @@ -2015,39 +2205,39 @@ private void viewProxyLibraryToolStripMenuItem_Click(object sender, EventArgs e) proxy_file, visible_interface ) - ); - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - } - } - - private async void createClassFactoryToolStripMenuItem_Click(object sender, EventArgs e) - { - await CreateClassFactory(null); - } - - private void GetClsidsFromNodes(List clsids, TreeNodeCollection nodes) - { - foreach (TreeNode node in nodes) - { - if (node.Tag is ICOMClassEntry clsid) - { - clsids.Add(clsid); - } - - if (node.Nodes.Count > 0) - { - GetClsidsFromNodes(clsids, node.Nodes); - } - } - } - - private void queryAllInterfacesToolStripMenuItem_Click(object sender, EventArgs e) - { + ); + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + } + } + + private async void createClassFactoryToolStripMenuItem_Click(object sender, EventArgs e) + { + await CreateClassFactory(null); + } + + private void GetClsidsFromNodes(List clsids, TreeNodeCollection nodes) + { + foreach (TreeNode node in nodes) + { + if (node.Tag is ICOMClassEntry clsid) + { + clsids.Add(clsid); + } + + if (node.Nodes.Count > 0) + { + GetClsidsFromNodes(clsids, node.Nodes); + } + } + } + + private void queryAllInterfacesToolStripMenuItem_Click(object sender, EventArgs e) + { using QueryInterfacesOptionsForm options = new(); if (options.ShowDialog(this) == DialogResult.OK) { @@ -2059,125 +2249,125 @@ private void queryAllInterfacesToolStripMenuItem_Click(object sender, EventArgs options.ServerTypes, options.ConcurrentQueries, options.RefreshInterfaces); } - } - } - - private async void createInProcHandlerToolStripMenuItem_Click(object sender, EventArgs e) - { - await CreateInstance(CLSCTX.INPROC_HANDLER, null); - } - - private async void instanceToolStripMenuItem_Click(object sender, EventArgs e) - { - if (GetSelectedClassEntry() is COMCLSIDEntry clsid) - { - await CreateElevated(clsid, false); - } - } - - private async void classFactoryToolStripMenuItem_Click(object sender, EventArgs e) - { - if (GetSelectedClassEntry() is COMCLSIDEntry clsid) - { - await CreateElevated(clsid, true); - } - } - - private void comboBoxMode_SelectedIndexChanged(object sender, EventArgs e) - { - if (comboBoxMode.SelectedItem is not null) - { - FilterMode mode = (FilterMode)comboBoxMode.SelectedItem; - textBoxFilter.Enabled = mode != FilterMode.Complex && mode != FilterMode.Accessible && mode != FilterMode.NotAccessible; - } - } - - private async void createRemoteToolStripMenuItem_Click(object sender, EventArgs e) - { + } + } + + private async void createInProcHandlerToolStripMenuItem_Click(object sender, EventArgs e) + { + await CreateInstance(CLSCTX.INPROC_HANDLER, null); + } + + private async void instanceToolStripMenuItem_Click(object sender, EventArgs e) + { + if (GetSelectedClassEntry() is COMCLSIDEntry clsid) + { + await CreateElevated(clsid, false); + } + } + + private async void classFactoryToolStripMenuItem_Click(object sender, EventArgs e) + { + if (GetSelectedClassEntry() is COMCLSIDEntry clsid) + { + await CreateElevated(clsid, true); + } + } + + private void comboBoxMode_SelectedIndexChanged(object sender, EventArgs e) + { + if (comboBoxMode.SelectedItem is not null) + { + FilterMode mode = (FilterMode)comboBoxMode.SelectedItem; + textBoxFilter.Enabled = mode != FilterMode.Complex && mode != FilterMode.Accessible && mode != FilterMode.NotAccessible; + } + } + + private async void createRemoteToolStripMenuItem_Click(object sender, EventArgs e) + { using GetTextForm frm = new("localhost"); frm.Text = "Enter Remote Host"; if (frm.ShowDialog(this) == DialogResult.OK) { await CreateInstance(CLSCTX.REMOTE_SERVER, frm.Data); - } - } - - private async void createClassFactoryRemoteToolStripMenuItem_Click(object sender, EventArgs e) - { + } + } + + private async void createClassFactoryRemoteToolStripMenuItem_Click(object sender, EventArgs e) + { using GetTextForm frm = new("localhost"); frm.Text = "Enter Remote Host"; if (frm.ShowDialog(this) == DialogResult.OK) { await CreateClassFactory(frm.Data); - } - } - - private void treeComRegistry_AfterExpand(object sender, TreeViewEventArgs e) - { - TreeNode node = e.Node; - if (node.ImageKey == FolderKey) - { - node.ImageKey = FolderOpenKey; - node.SelectedImageKey = FolderOpenKey; - } - } - - private void treeComRegistry_AfterCollapse(object sender, TreeViewEventArgs e) - { - TreeNode node = e.Node; - if (node.ImageKey == FolderOpenKey) - { - node.ImageKey = FolderKey; - node.SelectedImageKey = FolderKey; - } - } - - private void refreshProcessToolStripMenuItem_Click(object sender, EventArgs e) - { - TreeNode node = treeComRegistry.SelectedNode; - if (node is not null && node.Tag is COMProcessEntry) - { - COMProcessEntry process = (COMProcessEntry)node.Tag; - process = COMProcessParser.ParseProcess(process.ProcessId, COMProcessParserConfig.Default, m_registry); - if (process is null) - { - treeComRegistry.Nodes.Remove(treeComRegistry.SelectedNode); - m_original_nodes = m_original_nodes.Where(n => n != node).ToArray(); - } - else - { - node.Tag = process; - node.Nodes.Clear(); - PopulatorIpids(m_registry, node, process); - } - } - } - - private COMIPIDEntry GetSelectedIpid() - { - if (treeComRegistry.SelectedNode is not null) - { - return treeComRegistry.SelectedNode.Tag as COMIPIDEntry; - } - return null; - } - - private void toHexEditorToolStripMenuItem_Click(object sender, EventArgs e) - { - COMIPIDEntry ipid = GetSelectedIpid(); - if (ipid is not null) - { + } + } + + private void treeComRegistry_AfterExpand(object sender, TreeViewEventArgs e) + { + TreeNode node = e.Node; + if (node.ImageKey == FolderKey) + { + node.ImageKey = FolderOpenKey; + node.SelectedImageKey = FolderOpenKey; + } + } + + private void treeComRegistry_AfterCollapse(object sender, TreeViewEventArgs e) + { + TreeNode node = e.Node; + if (node.ImageKey == FolderOpenKey) + { + node.ImageKey = FolderKey; + node.SelectedImageKey = FolderKey; + } + } + + private void refreshProcessToolStripMenuItem_Click(object sender, EventArgs e) + { + TreeNode node = treeComRegistry.SelectedNode; + if (node is not null && node.Tag is COMProcessEntry) + { + COMProcessEntry process = (COMProcessEntry)node.Tag; + process = COMProcessParser.ParseProcess(process.ProcessId, COMProcessParserConfig.Default, m_registry); + if (process is null) + { + treeComRegistry.Nodes.Remove(treeComRegistry.SelectedNode); + m_original_nodes = m_original_nodes.Where(n => n != node).ToArray(); + } + else + { + node.Tag = process; + node.Nodes.Clear(); + PopulatorIpids(m_registry, node, process); + } + } + } + + private COMIPIDEntry GetSelectedIpid() + { + if (treeComRegistry.SelectedNode is not null) + { + return treeComRegistry.SelectedNode.Tag as COMIPIDEntry; + } + return null; + } + + private void toHexEditorToolStripMenuItem_Click(object sender, EventArgs e) + { + COMIPIDEntry ipid = GetSelectedIpid(); + if (ipid is not null) + { EntryPoint.GetMainForm(m_registry).HostControl(new ObjectHexEditor(m_registry, - ipid.Ipid.ToString(), - ipid.ToObjref())); - } - } - - private void toFileToolStripMenuItem_Click(object sender, EventArgs e) - { - COMIPIDEntry ipid = GetSelectedIpid(); - if (ipid is not null) - { + ipid.Ipid.ToString(), + ipid.ToObjref())); + } + } + + private void toFileToolStripMenuItem_Click(object sender, EventArgs e) + { + COMIPIDEntry ipid = GetSelectedIpid(); + if (ipid is not null) + { using SaveFileDialog dlg = new(); dlg.Filter = "All Files (*.*)|*.*"; if (dlg.ShowDialog(this) == DialogResult.OK) @@ -2190,59 +2380,59 @@ private void toFileToolStripMenuItem_Click(object sender, EventArgs e) { EntryPoint.ShowError(this, ex); } - } - } - } - - private async void toObjectToolStripMenuItem_Click(object sender, EventArgs e) - { - COMIPIDEntry ipid = GetSelectedIpid(); - if (ipid is not null) - { - try - { - await EntryPoint.GetMainForm(m_registry).OpenObjectInformation( - COMUtilities.UnmarshalObject(ipid.ToObjref()), - $"IPID {ipid.Ipid}"); - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - } - - private void CreateClonedTree(IEnumerable nodes, bool cloned = false) - { - string text = Text; - if (!text.StartsWith("Clone of ")) - { - text = "Clone of " + text; - } + } + } + } + + private async void toObjectToolStripMenuItem_Click(object sender, EventArgs e) + { + COMIPIDEntry ipid = GetSelectedIpid(); + if (ipid is not null) + { + try + { + await EntryPoint.GetMainForm(m_registry).OpenObjectInformation( + COMUtilities.UnmarshalObject(ipid.ToObjref()), + $"IPID {ipid.Ipid}"); + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + } + + private void CreateClonedTree(IEnumerable nodes, bool cloned = false) + { + string text = Text; + if (!text.StartsWith("Clone of ")) + { + text = "Clone of " + text; + } if (!cloned) { nodes = nodes.Select(n => (TreeNode)n.Clone()); - } - COMRegistryViewer viewer = new(m_registry, m_mode, m_processes, nodes, m_filter_types, text); - EntryPoint.GetMainForm(m_registry).HostControl(viewer); - } - - private void allVisibleToolStripMenuItem_Click(object sender, EventArgs e) - { - CreateClonedTree(treeComRegistry.Nodes.OfType()); - } - - private void selectedToolStripMenuItem_Click(object sender, EventArgs e) - { - TreeNode selected = treeComRegistry.SelectedNode; - if (selected is not null) - { - CreateClonedTree(new TreeNode[] { selected }); - } - } - - private async void filteredToolStripMenuItem_Click(object sender, EventArgs e) - { + } + COMRegistryViewer viewer = new(m_registry, m_mode, m_processes, nodes, m_filter_types, text); + EntryPoint.GetMainForm(m_registry).HostControl(viewer); + } + + private void allVisibleToolStripMenuItem_Click(object sender, EventArgs e) + { + CreateClonedTree(treeComRegistry.Nodes.OfType()); + } + + private void selectedToolStripMenuItem_Click(object sender, EventArgs e) + { + TreeNode selected = treeComRegistry.SelectedNode; + if (selected is not null) + { + CreateClonedTree(new TreeNode[] { selected }); + } + } + + private async void filteredToolStripMenuItem_Click(object sender, EventArgs e) + { using ViewFilterForm form = new(new RegistryViewerFilter(), m_filter_types); if (form.ShowDialog(this) == DialogResult.OK && form.Filter.Filters.Count > 0) { @@ -2250,91 +2440,91 @@ private async void filteredToolStripMenuItem_Click(object sender, EventArgs e) await Task.Run(() => m_original_nodes.Select(n => (TreeNode)n.Clone()).Where(n => FilterNode(n, form.Filter) == FilterResult.Include).ToArray()); CreateClonedTree(nodes, true); - } - } - - private void treeComRegistry_AfterSelect(object sender, TreeViewEventArgs e) - { - var main_form = EntryPoint.GetMainForm(m_registry); - object obj = treeComRegistry.SelectedNode?.Tag; - main_form.UpdatePropertyGrid(obj); - sourceCodeViewerControl.SelectedObject = obj; - } - - private void allChildrenToolStripMenuItem_Click(object sender, EventArgs e) - { - TreeNode selected = treeComRegistry.SelectedNode; - if (selected is not null && selected.Nodes.Count > 0) - { - CreateClonedTree(selected.Nodes.OfType()); - } - } - - private void viewRuntimeInterfaceToolStripMenuItem_Click(object sender, EventArgs e) - { - TreeNode node = treeComRegistry.SelectedNode; - if (node is not null) - { - if (node.Tag is COMInterfaceEntry ent) - { + } + } + + private void treeComRegistry_AfterSelect(object sender, TreeViewEventArgs e) + { + var main_form = EntryPoint.GetMainForm(m_registry); + object obj = treeComRegistry.SelectedNode?.Tag; + main_form.UpdatePropertyGrid(obj); + sourceCodeViewerControl.SelectedObject = obj; + } + + private void allChildrenToolStripMenuItem_Click(object sender, EventArgs e) + { + TreeNode selected = treeComRegistry.SelectedNode; + if (selected is not null && selected.Nodes.Count > 0) + { + CreateClonedTree(selected.Nodes.OfType()); + } + } + + private void viewRuntimeInterfaceToolStripMenuItem_Click(object sender, EventArgs e) + { + TreeNode node = treeComRegistry.SelectedNode; + if (node is not null) + { + if (node.Tag is COMInterfaceEntry ent) + { try - { - Assembly asm = ent.GetRuntimeType().Assembly; + { + Assembly asm = ent.GetRuntimeType().Assembly; EntryPoint.GetMainForm(m_registry).HostControl(new TypeLibControl(asm.GetName().Name, asm, ent.Iid, false)); - } - catch (Exception ex) + } + catch (Exception ex) { EntryPoint.ShowError(this, ex); - } - } - } - } - - private async void CreateInRuntimeBroker(bool per_user, bool factory) - { - try - { - if (GetSelectedClassEntry() is COMRuntimeClassEntry runtime_class) - { - IRuntimeBroker broker = COMUtilities.CreateBroker(per_user); - object comObj; - if (factory) - { - comObj = broker.GetActivationFactory(runtime_class.Name, COMKnownGuids.IID_IUnknown); - } - else - { - comObj = broker.ActivateInstance(runtime_class.Name); - } - - await SetupObjectView(runtime_class, comObj, factory); - } - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - private void createInRuntimeBrokerToolStripMenuItem_Click(object sender, EventArgs e) - { - CreateInRuntimeBroker(false, false); - } - - private void createInPerUserRuntimeBrokerToolStripMenuItem_Click(object sender, EventArgs e) - { - CreateInRuntimeBroker(true, false); - } - - private void createFactoryInRuntimeBrokerToolStripMenuItem_Click(object sender, EventArgs e) - { - CreateInRuntimeBroker(false, true); - } - - private void createFactoryInPerUserRuntimeBrokerToolStripMenuItem_Click(object sender, EventArgs e) - { - CreateInRuntimeBroker(false, true); + } + } + } + } + + private async void CreateInRuntimeBroker(bool per_user, bool factory) + { + try + { + if (GetSelectedClassEntry() is COMRuntimeClassEntry runtime_class) + { + IRuntimeBroker broker = COMUtilities.CreateBroker(per_user); + object comObj; + if (factory) + { + comObj = broker.GetActivationFactory(runtime_class.Name, COMKnownGuids.IID_IUnknown); + } + else + { + comObj = broker.ActivateInstance(runtime_class.Name); + } + + await SetupObjectView(runtime_class, comObj, factory); + } + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + private void createInRuntimeBrokerToolStripMenuItem_Click(object sender, EventArgs e) + { + CreateInRuntimeBroker(false, false); + } + + private void createInPerUserRuntimeBrokerToolStripMenuItem_Click(object sender, EventArgs e) + { + CreateInRuntimeBroker(true, false); + } + + private void createFactoryInRuntimeBrokerToolStripMenuItem_Click(object sender, EventArgs e) + { + CreateInRuntimeBroker(false, true); + } + + private void createFactoryInPerUserRuntimeBrokerToolStripMenuItem_Click(object sender, EventArgs e) + { + CreateInRuntimeBroker(false, true); } private void showSourceCodeToolStripMenuItem_Click(object sender, EventArgs e) @@ -2345,8 +2535,8 @@ private void showSourceCodeToolStripMenuItem_Click(object sender, EventArgs e) private void COMRegistryViewer_Load(object sender, EventArgs e) { - treeComRegistry.SuspendLayout(); - treeComRegistry.Nodes.AddRange(m_original_nodes); + treeComRegistry.SuspendLayout(); + treeComRegistry.Nodes.AddRange(m_original_nodes); treeComRegistry.ResumeLayout(); UpdateStatusLabel(); m_visible_node?.EnsureVisible(); @@ -2376,23 +2566,23 @@ private static TreeNode FindVisibleNode(IEnumerable nodes, object tag) private void createRuntimeClassToolStripMenuItem_Click(object sender, EventArgs e) { - try - { - if (GetSelectedClassEntry() is COMRuntimeClassEntry runtime_class) - { - Type runtime_type = runtime_class.GetRuntimeType(); + try + { + if (GetSelectedClassEntry() is COMRuntimeClassEntry runtime_class) + { + Type runtime_type = runtime_class.GetRuntimeType(); if (runtime_type is null) { return; } - TypedObjectViewer viewer = new(m_registry, runtime_class.Name, runtime_type); - EntryPoint.GetMainForm(m_registry).HostControl(viewer, runtime_class.Name); - } - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); + TypedObjectViewer viewer = new(m_registry, runtime_class.Name, runtime_type); + EntryPoint.GetMainForm(m_registry).HostControl(viewer, runtime_class.Name); + } + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); } } @@ -2405,45 +2595,45 @@ private COMRegistryViewer(COMRegistry reg, COMRegistryDisplayMode mode, splitContainer.Panel2Collapsed = false; showSourceCodeToolStripMenuItem.Visible = false; root_node.Expand(); - } - + } + private COMRegistryViewer(COMRegistry reg, COMRegistryDisplayMode mode, IEnumerable processes, IEnumerable nodes, - IEnumerable filter_types, string text) - { - InitializeComponent(); - m_registry = reg; - m_filter_types = new HashSet(filter_types); - m_filter = new RegistryViewerFilter(); - m_mode = mode; - m_processes = processes; - treeImageList.Images.Add(ApplicationKey, SystemIcons.Application); - sourceCodeViewerControl.SetRegistry(reg); - - foreach (FilterMode filter in Enum.GetValues(typeof(FilterMode))) - { - comboBoxMode.Items.Add(filter); - } - comboBoxMode.SelectedIndex = 0; - + IEnumerable filter_types, string text) + { + InitializeComponent(); + m_registry = reg; + m_filter_types = new HashSet(filter_types); + m_filter = new RegistryViewerFilter(); + m_mode = mode; + m_processes = processes; + treeImageList.Images.Add(ApplicationKey, SystemIcons.Application); + sourceCodeViewerControl.SetRegistry(reg); + + foreach (FilterMode filter in Enum.GetValues(typeof(FilterMode))) + { + comboBoxMode.Items.Add(filter); + } + comboBoxMode.SelectedIndex = 0; + Text = text; splitContainer.Panel2Collapsed = !ProgramSettings.AlwaysShowSourceCode; showSourceCodeToolStripMenuItem.Checked = ProgramSettings.AlwaysShowSourceCode; - sourceCodeViewerControl.AutoParse = ProgramSettings.EnableAutoParsing; - m_original_nodes = nodes.ToArray(); - } - #endregion + sourceCodeViewerControl.AutoParse = ProgramSettings.EnableAutoParsing; + m_original_nodes = nodes.ToArray(); + } + #endregion - #region Constructors + #region Constructors public COMRegistryViewer(COMRegistry reg, COMRegistryDisplayMode mode, IEnumerable processes) - : this(reg, mode, processes, SetupTree(reg, mode, processes), GetFilterTypes(mode), GetDisplayName(mode)) + : this(reg, mode, processes, SetupTree(reg, mode, processes), GetFilterTypes(mode), GetDisplayName(mode)) { if (m_mode == COMRegistryDisplayMode.RuntimeInterfacesTree) { treeComRegistry.TreeViewNodeSorter = new RuntimeNodeComparer(); - } - } - + } + } + public COMRegistryViewer(COMRegistry reg, COMTypeLib typelib, COMTypeLibTypeInfo visible_type) : this(reg, COMRegistryDisplayMode.Typelibs, CreateTypeLibNodes(typelib), new[] { FilterType.TypeLibTypeInfo }, typelib.ToString(), visible_type) @@ -2454,6 +2644,71 @@ public COMRegistryViewer(COMRegistry reg, COMProxyFile proxy, COMProxyTypeInfo v : this(reg, COMRegistryDisplayMode.ProxyCLSIDs, CreateProxyNodes(proxy), new[] { FilterType.TypeLibTypeInfo }, proxy.Path, visible_type) { - } + /* Added */ + // When we open class folder in Local Service tab or something, + // this will create .txt and write clsid in "iids\" directory to use ResolveMethod. + // And also, when we use "View Proxy Library", this will create .txt and write idl in "sequence\now" directory to use CallSequence. + + String fileName = Path.GetFileName(proxy.Path); + String path = $"interfaces\\{fileName}.txt"; + if (File.Exists(path)) File.Delete(path); + sourceCodeViewerControl.ChangeToCpp(); + var tempNode = CreateNode("temp", ClassKey, proxy.ComplexTypes.Where(t => !t.IsUnion)); + tempNode = CreateNode("temp", FolderKey, proxy.Entries); + tempNode.Nodes.AddRange(proxy.Entries.Select(type=>CreateNode(type.Name, "temp", type)).ToArray()); + if (!Directory.Exists("interfaces\\sequence")) Directory.CreateDirectory("interfaces\\sequence"); + using (StreamWriter writer = new StreamWriter(path, append: true)) + { + writer.WriteLine(proxy.Path); + String clsid = null; + sourceCodeViewerControl.m_isReally = false; + foreach (TreeNode nowNode in tempNode.Nodes) + { + sourceCodeViewerControl.SelectedObject = nowNode?.Tag; + + if (File.Exists($"interfaces\\iids\\{sourceCodeViewerControl.GetIid()}.txt")) + { + using (StreamReader reader = new StreamReader($"interfaces\\iids\\{sourceCodeViewerControl.GetIid()}.txt")) + { + clsid = reader.ReadToEnd(); + break; + } + } + } + String[] fileNames = Directory.GetFiles("interfaces\\sequence"); + + foreach (String file in fileNames) + { + File.Delete(file); + } + using (StreamWriter tempwriter = new StreamWriter($"interfaces\\sequence\\now")) + { + tempwriter.Write(proxy.Path); + } + foreach (TreeNode nowNode in tempNode.Nodes) + { + sourceCodeViewerControl.SelectedObject = nowNode?.Tag; + using (StreamWriter tempwriter = new StreamWriter($"interfaces\\sequence\\{sourceCodeViewerControl.GetIid()}.txt")) + { + tempwriter.Write(sourceCodeViewerControl.Format()); + } + } + if (clsid != null) + { + foreach (TreeNode nowNode in tempNode.Nodes) + { + sourceCodeViewerControl.SelectedObject = nowNode?.Tag; + if (File.Exists($"interfaces\\iids\\{sourceCodeViewerControl.GetIid()}.txt")) File.Delete($"interfaces\\iids\\{sourceCodeViewerControl.GetIid()}.txt"); + using (StreamWriter tempwriter = new StreamWriter($"interfaces\\iids\\{sourceCodeViewerControl.GetIid()}.txt")) + { + tempwriter.Write(clsid); + } + } + } + sourceCodeViewerControl.m_isReally = true; + } + + /* Added */ + } #endregion -} +} diff --git a/OleViewDotNet/Forms/CallSequenceForm.Designer.cs b/OleViewDotNet/Forms/CallSequenceForm.Designer.cs new file mode 100644 index 00000000..e0e565e5 --- /dev/null +++ b/OleViewDotNet/Forms/CallSequenceForm.Designer.cs @@ -0,0 +1,138 @@ +namespace OleViewDotNet.Forms +{ + partial class CallSequenceForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.textBox2 = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.comboBox1 = new System.Windows.Forms.ComboBox(); + this.label3 = new System.Windows.Forms.Label(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 40); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(91, 12); + this.label1.TabIndex = 1; + this.label1.Text = "Interface Name"; + // + // textBox2 + // + this.textBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textBox2.Location = new System.Drawing.Point(12, 80); + this.textBox2.Multiline = true; + this.textBox2.Name = "textBox2"; + this.textBox2.ReadOnly = true; + this.textBox2.Size = new System.Drawing.Size(776, 419); + this.textBox2.TabIndex = 3; + System.Drawing.Font font = new System.Drawing.Font("Consolas", 14); + this.textBox2.Font = font; + // + // label2 + // + this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(12, 65); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(40, 12); + this.label2.TabIndex = 4; + this.label2.Text = "Result"; + // + // comboBox1 + // + this.comboBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.comboBox1.FormattingEnabled = true; + this.comboBox1.Location = new System.Drawing.Point(125, 36); + this.comboBox1.Name = "comboBox1"; + this.comboBox1.Size = new System.Drawing.Size(663, 20); + this.comboBox1.TabIndex = 5; + this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); + // + // label3 + // + this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(12, 13); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(109, 12); + this.label3.TabIndex = 6; + this.label3.Text = "Current Proxy DLL"; + // + // textBox1 + // + this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textBox1.Location = new System.Drawing.Point(125, 7); + this.textBox1.Name = "textBox1"; + this.textBox1.ReadOnly = true; + this.textBox1.Size = new System.Drawing.Size(663, 21); + this.textBox1.TabIndex = 7; + // + // CallSequenceForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 511); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.label3); + this.Controls.Add(this.comboBox1); + this.Controls.Add(this.label2); + this.Controls.Add(this.textBox2); + this.Controls.Add(this.label1); + this.Name = "CallSequenceForm"; + this.Text = "CallSequenceForm"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox2; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.ComboBox comboBox1; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox textBox1; + } +} \ No newline at end of file diff --git a/OleViewDotNet/Forms/CallSequenceForm.cs b/OleViewDotNet/Forms/CallSequenceForm.cs new file mode 100644 index 00000000..a388b5f3 --- /dev/null +++ b/OleViewDotNet/Forms/CallSequenceForm.cs @@ -0,0 +1,202 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Windows.Forms; +using static System.Windows.Forms.VisualStyles.VisualStyleElement; + +// When we wants to get WalletService's IWalletCustomProperty interface, +// we must get it by IWallet → IWalletTransactionManager → IWalletItem → IWalletCustomProperty. (not a unique path) +// This form will analyze call sequence like above and show it. + +namespace OleViewDotNet.Forms +{ + public partial class CallSequenceForm : Form + { + Dictionary> interfaces = null; + List> sequence; + + public CallSequenceForm() + { + String[] fileNames = Directory.GetFiles("interfaces\\sequence"); + + if (fileNames.Length == 0) + { + MessageBox.Show("View Proxy Library First."); + return; + } + InitializeComponent(); + if (interfaces == null) + { + interfaces = new Dictionary>(); + var stringList = new List(); + foreach (String file in fileNames) + { + String idl = null; + using (StreamReader sr = new StreamReader(file)) + { + idl = sr.ReadToEnd(); + } + if (Path.GetFileName(file) == "now") + { + textBox1.Text = idl; + continue; + } + String[] lines = idl.Split('\n'); + String interfaceName = null; + + for (int i = 0; i < lines.Length; i++) + { + String line = lines[i].Trim(); + if (line.StartsWith("interface")) + { + interfaceName = line.Split(' ')[1]; + break; + } + } + stringList.Add(interfaceName); + interfaces[interfaceName] = new List(); + for (int i = 0; i < lines.Length; i++) + { + String line = lines[i].Trim(); + if (line.StartsWith("HRESULT")) + { + List parameters = GetParameters(line); + for (int j = 1; j < parameters.Count; j++) + { + String[] param = parameters[j].Trim().Split(' '); + if (param[0].Contains("out") && !param[param.Length - 2].StartsWith("int") && + !param[param.Length - 2].StartsWith("HSTRING") && !param[param.Length - 2].StartsWith("wchar") && + !param[param.Length - 2].StartsWith("GUID") && !param[param.Length - 2].StartsWith("byte") && + !param[param.Length - 2].StartsWith("__int") && !param[param.Length - 2].StartsWith("uint") && + !param[param.Length - 2].StartsWith("Struct") && !param[param.Length - 2].ToLower().StartsWith("handle") && + !param[param.Length - 2].StartsWith("float") && !param[param.Length - 2].StartsWith("double") && + !param[param.Length - 2].StartsWith("char") && !param[param.Length - 2].StartsWith("HWND") && + !param[param.Length - 2].StartsWith("handle") && !param[param.Length - 2].StartsWith("BSTR") && + !param[param.Length - 2].StartsWith("short") && !param[param.Length - 2].StartsWith("VARIANT")) + { + param[param.Length - 2] = param[param.Length - 2].Replace("*", ""); + if (!interfaces.Keys.Contains(param[param.Length - 2])) + { + interfaces[param[param.Length - 2]] = new List(); + } + interfaces[interfaceName].Add(param[param.Length - 2]); + } + } + } + } + } + stringList.Sort(); + comboBox1.DataSource = stringList; + } + + } + + // Get parameters from idl methods. + public List GetParameters(string functionDeclaration) + { + if (functionDeclaration.Trim().EndsWith("(void)")) + return new List(); + string functionDefinition = Regex.Replace(functionDeclaration, @"<.*?>", ""); + Match match = Regex.Match(functionDefinition, @"([\w:~]+|`.*?')\s*\((.*?)\)\s*(?:const)?(?:override)?;?$"); + if (!match.Success) + return new List(); + + string functionName = match.Groups[1].Value; + string parameters = match.Groups[2].Value; + + if (string.IsNullOrWhiteSpace(parameters)) + return new List(); + parameters = Regex.Replace(parameters, @"\[([^\]]*)\]", m => m.Groups[0].Value.Replace(",", "")); + + parameters = Regex.Replace(parameters, @"<([^>]*)>", m => m.Groups[0].Value.Replace(",", "")); + + var paramList = parameters.Split(',').Select(p => p.Replace("", ",")).ToList(); + paramList.Insert(0, functionName); + return paramList; + } + + // Find sequence by Search method and store with Dictionary structure. + public void GetSequence(String baseInterface) + { + if (!interfaces.Keys.Contains(baseInterface)) + { + textBox2.Text = $"No Interface \"{baseInterface}\" in Proxy."; + return; + } + sequence = new List>(); + for (int i = 0; i < interfaces[baseInterface].Count; i++) + { + List nowSequence = new List(); + nowSequence.Add(baseInterface); + Search(nowSequence, interfaces[baseInterface][i]); + } + if (sequence.Count == 0) + { + textBox2.Text = "No Results."; + return; + } + textBox2.Text = ""; + foreach (List now in sequence) + { + textBox2.Text += String.Join(" → ", now) + "\r\n"; + } + } + + // Parse interface's each method and find interface parameters recursively. + public void Search(List nowSequence, String next) + { + + if (interfaces[next].Count == 0) + { + nowSequence.Add(next); + bool flag = true; + foreach (List now in sequence) + { + if (now.SequenceEqual(nowSequence)) + { + flag = false; + break; + } + } + if (flag) sequence.Add(nowSequence); + return; + } + + if (nowSequence.Contains(next)) + { + bool flag = true; + foreach (List now in sequence) + { + if (now.SequenceEqual(nowSequence)) + { + flag = false; + break; + } + } + if (flag) sequence.Add(nowSequence); + return; + } + nowSequence.Add(next); + foreach (String now in interfaces[next]) + { + List newSequence = nowSequence.ToList(); + Search(newSequence, now); + } + return; + } + + private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) + { + String interfaceName = this.comboBox1.Text; + GetSequence(interfaceName); + } + } +} diff --git a/OleViewDotNet/Forms/DllFixForm.Designer.cs b/OleViewDotNet/Forms/DllFixForm.Designer.cs new file mode 100644 index 00000000..0d928291 --- /dev/null +++ b/OleViewDotNet/Forms/DllFixForm.Designer.cs @@ -0,0 +1,103 @@ +namespace OleViewDotNet.Forms +{ + partial class DllFixForm + { + /// + /// + /// + private System.ComponentModel.IContainer components = null; + + /// + /// + /// + /// + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + /// + /// + /// + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.comboBox1 = new System.Windows.Forms.ComboBox(); + this.label2 = new System.Windows.Forms.Label(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.button1 = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(305, 34); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(135, 12); + this.label1.TabIndex = 0; + this.label1.Text = "Select DLL/EXE to Fix."; + // + // comboBox1 + // + this.comboBox1.FormattingEnabled = true; + this.comboBox1.Location = new System.Drawing.Point(42, 62); + this.comboBox1.Name = "comboBox1"; + this.comboBox1.Size = new System.Drawing.Size(688, 20); + this.comboBox1.TabIndex = 1; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(256, 131); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(228, 12); + this.label2.TabIndex = 2; + this.label2.Text = "Or directly input binary\'s absolute path."; + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point(42, 160); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(688, 21); + this.textBox1.TabIndex = 3; + // + // button1 + // + this.button1.Location = new System.Drawing.Point(339, 309); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 23); + this.button1.TabIndex = 4; + this.button1.Text = "OK"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // DllFixForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(771, 344); + this.Controls.Add(this.button1); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.label2); + this.Controls.Add(this.comboBox1); + this.Controls.Add(this.label1); + this.Name = "DllFixForm"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.ComboBox comboBox1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.Button button1; + } +} diff --git a/OleViewDotNet/Forms/DllFixForm.cs b/OleViewDotNet/Forms/DllFixForm.cs new file mode 100644 index 00000000..2e919a67 --- /dev/null +++ b/OleViewDotNet/Forms/DllFixForm.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using static System.Windows.Forms.VisualStyles.VisualStyleElement; + +namespace OleViewDotNet.Forms +{ + + // This form will get DLL/EXE filename and fix DLL/EXE used by ResolveMethod. + + public partial class DllFixForm : Form + { + public DllFixForm() + { + InitializeComponent(); + if (!Directory.Exists("DLLs")) Directory.CreateDirectory("DLLs"); + String[] fileNames = Directory.GetFiles("DLLs"); + List fileList = new List(); + foreach (String fileName in fileNames) + { + if (fileName.EndsWith(".dll") || fileName.EndsWith(".exe")) + { + fileList.Add(fileName); + } + } + fileList.Sort(); + this.comboBox1.DataSource = fileList; + } + + private void button1_Click(object sender, EventArgs e) + { + if (comboBox1.Text != "" && textBox1.Text != "") + { + MessageBox.Show("Please Select Only One."); + } + else if (comboBox1.Text != "") + { + if (!File.Exists(comboBox1.Text)) + { + MessageBox.Show("File Doesn't Exist!"); + } + else + { + ProgramSettings.FixedDll = comboBox1.Text; + this.Close(); + } + } + else if (textBox1.Text != "") + { + if (!File.Exists(textBox1.Text)) + { + MessageBox.Show("File Doesn't Exist!"); + } + else + { + ProgramSettings.FixedDll = textBox1.Text; + this.Close(); + } + } + else + { + MessageBox.Show("Please Input DLL/EXE Path."); + } + } + } +} diff --git a/OleViewDotNet/Forms/FindInterfaceForm.Designer.cs b/OleViewDotNet/Forms/FindInterfaceForm.Designer.cs new file mode 100644 index 00000000..7b0ee24a --- /dev/null +++ b/OleViewDotNet/Forms/FindInterfaceForm.Designer.cs @@ -0,0 +1,123 @@ +namespace OleViewDotNet.Forms +{ + partial class FindInterfaceForm + { + public System.Windows.Forms.Label label1; + public System.Windows.Forms.Label label2; + public System.Windows.Forms.Label label3; + public System.Windows.Forms.Label label4; + public System.Windows.Forms.Label label5; + public System.Windows.Forms.Label label6; + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.label4 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.label6 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // label1 + // + this.label1.Font = new System.Drawing.Font("굴림", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129))); + this.label1.Location = new System.Drawing.Point(12, 9); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(539, 23); + this.label1.TabIndex = 0; + this.label1.Text = "Finding Interface for CLSID "; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label2 + // + this.label2.Location = new System.Drawing.Point(12, 32); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(539, 23); + this.label2.TabIndex = 1; + this.label2.Text = "It may take several minutes..."; + this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label3 + // + this.label3.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.label3.Location = new System.Drawing.Point(133, 63); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(164, 23); + this.label3.TabIndex = 2; + this.label3.Text = "CLSCTX_LOCAL_SERVER"; + this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // label4 + // + this.label4.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.label4.Location = new System.Drawing.Point(133, 86); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(166, 29); + this.label4.TabIndex = 3; + this.label4.Text = "CLSCTX_INPROC_SERVER"; + this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // label5 + // + this.label5.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.label5.Location = new System.Drawing.Point(346, 68); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(205, 23); + this.label5.TabIndex = 4; + this.label5.Text = "STATE"; + // + // label6 + // + this.label6.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.label6.Location = new System.Drawing.Point(346, 94); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(205, 23); + this.label6.TabIndex = 5; + this.label6.Text = "STATE"; + // + // FindInterfaceForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(563, 124); + this.Controls.Add(this.label6); + this.Controls.Add(this.label5); + this.Controls.Add(this.label4); + this.Controls.Add(this.label3); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FindInterfaceForm"; + this.Text = "FindInterfaceForm"; + this.ResumeLayout(false); + + } + + #endregion + } +} \ No newline at end of file diff --git a/OleViewDotNet/Forms/FindInterfaceForm.cs b/OleViewDotNet/Forms/FindInterfaceForm.cs new file mode 100644 index 00000000..2edee01a --- /dev/null +++ b/OleViewDotNet/Forms/FindInterfaceForm.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Reflection.Emit; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Threading; + +namespace OleViewDotNet.Forms +{ + + // This form is used by FindInterface. + public partial class FindInterfaceForm : Form + { + public int inProcRetval = -1; + public int localRetval = -1; + public FindInterfaceForm() + { + InitializeComponent(); + } + + public void UpdateLabel1(String data) + { + if (this.label1.InvokeRequired) this.label1.BeginInvoke(new Action(() => this.label1.Text = data)); + else this.label1.Text = data; + } + public void UpdateLabel5(String data) + { + if (this.label5.InvokeRequired) this.label5.BeginInvoke(new Action(() => this.label5.Text = data)); + else this.label5.Text = data; + } + public void UpdateLabel6(String data) + { + if (this.label6.InvokeRequired) this.label6.BeginInvoke(new Action(() => this.label6.Text = data)); + else this.label6.Text = data; + } + + public void RepeatUpdateLabel(object arg) + { + bool isInproc = (bool)arg; + int i = 1; + while (true) + { + Thread.Sleep(300); + String label = "Running"; + for (int j = 1; j <= i; j++) label += "."; + if (isInproc) UpdateLabel6(label); + else UpdateLabel5(label); + Application.DoEvents(); + i = i % 4 + 1; + } + } + + } + + +} diff --git a/OleViewDotNet/Forms/FindInterfaceForm.resx b/OleViewDotNet/Forms/FindInterfaceForm.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/OleViewDotNet/Forms/FindInterfaceForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/OleViewDotNet/Forms/IDAPathForm.Designer.cs b/OleViewDotNet/Forms/IDAPathForm.Designer.cs new file mode 100644 index 00000000..11fbe292 --- /dev/null +++ b/OleViewDotNet/Forms/IDAPathForm.Designer.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.IO; + +namespace OleViewDotNet.Forms +{ + partial class IDAPathForm: Form + { + + private System.Windows.Forms.Button button1; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.Label label1; + + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.button1 = new System.Windows.Forms.Button(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // button1 + // + this.button1.Location = new System.Drawing.Point(196, 103); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 23); + this.button1.TabIndex = 5; + this.button1.Text = "OK"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point(33, 60); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size(404, 21); + this.textBox1.TabIndex = 4; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(31, 31); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(406, 12); + this.label1.TabIndex = 3; + this.label1.Text = "Failed to find idat64.exe. Please input idat64.exe absolute path directly."; + // + // IDAPathForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(468, 157); + this.Controls.Add(this.button1); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.label1); + this.Name = "IDAPathForm"; + this.Text = "IDAPathForm"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private void button1_Click(object sender, EventArgs e) + { + String path = textBox1.Text; + if (path.EndsWith("idat64.exe") && File.Exists(path)) + { + ResolveMethod.IDAPath = path; + this.Close(); + } + else + { + MessageBox.Show("Invalid idat64.exe path. Please re-input."); + } + } + } +} \ No newline at end of file diff --git a/OleViewDotNet/Forms/IDAPathForm.cs b/OleViewDotNet/Forms/IDAPathForm.cs new file mode 100644 index 00000000..bbbdc216 --- /dev/null +++ b/OleViewDotNet/Forms/IDAPathForm.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace OleViewDotNet.Forms +{ + + // When oleviewdotnet failed to find IDA path from Registry, you can input IDA path manually by this form. + + public partial class IDAPathForm : Form + { + public IDAPathForm() + { + InitializeComponent(); + } + } +} diff --git a/OleViewDotNet/Forms/IDAPathForm.resx b/OleViewDotNet/Forms/IDAPathForm.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/OleViewDotNet/Forms/IDAPathForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/OleViewDotNet/Forms/MainForm.Designer.cs b/OleViewDotNet/Forms/MainForm.Designer.cs index 44eda934..45e9b42d 100644 --- a/OleViewDotNet/Forms/MainForm.Designer.cs +++ b/OleViewDotNet/Forms/MainForm.Designer.cs @@ -1,33 +1,33 @@ -namespace OleViewDotNet.Forms; - -partial class MainForm -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components is not null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { +namespace OleViewDotNet.Forms; + +partial class MainForm +{ + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components is not null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); this.mainMenu = new System.Windows.Forms.MainMenu(this.components); @@ -118,7 +118,15 @@ private void InitializeComponent() this.menuProcessesOptionsParseStubs = new System.Windows.Forms.MenuItem(); this.menuProcessesOptionsParseRegisteredClasses = new System.Windows.Forms.MenuItem(); this.menuProcessesOptionsParseActCtx = new System.Windows.Forms.MenuItem(); - this.menuItemStorage = new System.Windows.Forms.MenuItem(); + + /* Added */ + this.menuResolveMethodDllFix = new System.Windows.Forms.MenuItem(); + this.menuResolveMethodNamesFromIDAHard = new System.Windows.Forms.MenuItem(); + this.menuResolveMethodNamesFromIDA = new System.Windows.Forms.MenuItem(); + this.menuGetSequence = new System.Windows.Forms.MenuItem(); + /* Added */ + + this.menuItemStorage = new System.Windows.Forms.MenuItem(); this.menuStorageNewStorage = new System.Windows.Forms.MenuItem(); this.menuStorageOpenStorage = new System.Windows.Forms.MenuItem(); this.menuItemView = new System.Windows.Forms.MenuItem(); @@ -662,8 +670,19 @@ private void InitializeComponent() this.menuProcessesSelectProcess, this.menuItemProcessesAllProcesses, this.menuItem16, - this.menuProcessesOptions}); + this.menuProcessesOptions + /* Added */, + this.menuResolveMethodNamesFromIDA, + this.menuResolveMethodNamesFromIDAHard, + this.menuResolveMethodDllFix, + this.menuGetSequence + /* Added */}); this.menuProcesses.Text = "&Processes"; + + /* Added */ + this.menuProcesses.Popup += new System.EventHandler(this.menuProcesses_Popup); + /* Added */ + // // menuProcessesSelectProcess // @@ -737,10 +756,31 @@ private void InitializeComponent() this.menuProcessesOptionsParseActCtx.Index = 3; this.menuProcessesOptionsParseActCtx.Text = "Parse &Activation Context"; this.menuProcessesOptionsParseActCtx.Click += new System.EventHandler(this.menuProcessesOptionsParseActCtx_Click); - // - // menuItemStorage - // - this.menuItemStorage.Index = 5; + + /* Added */ + + this.menuResolveMethodNamesFromIDA.Index = 4; + this.menuResolveMethodNamesFromIDA.Text = "Resolve Method Name by IDA"; + this.menuResolveMethodNamesFromIDA.Click += new System.EventHandler(this.menuResolveMethodNamesFromIDA_Click); + + this.menuResolveMethodNamesFromIDAHard.Index = 5; + this.menuResolveMethodNamesFromIDAHard.Text = "Resolve Method Name by IDA (HARD)"; + this.menuResolveMethodNamesFromIDAHard.Click += new System.EventHandler(this.menuResolveMethodNamesFromIDAHard_Click); + + this.menuResolveMethodDllFix.Index = 6; + this.menuResolveMethodDllFix.Text = "Resolve Method Name by IDA (Fix Mode)"; + this.menuResolveMethodDllFix.Click += new System.EventHandler(this.menuResolveMethodDllFix_Click); + + this.menuGetSequence.Index = 7; + this.menuGetSequence.Text = "Get Call Sequence"; + this.menuGetSequence.Click += new System.EventHandler(this.menuGetSequence_Click); + + /* Added */ + + // + // menuItemStorage + // + this.menuItemStorage.Index = 5; this.menuItemStorage.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.menuStorageNewStorage, this.menuStorageOpenStorage}); @@ -832,89 +872,89 @@ private void InitializeComponent() this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyUp); this.ResumeLayout(false); - } - - #endregion - - private System.Windows.Forms.MainMenu mainMenu; - private System.Windows.Forms.MenuItem menuFile; - private System.Windows.Forms.MenuItem menuFileExit; - private System.Windows.Forms.MenuItem menuRegistry; - private System.Windows.Forms.MenuItem menuViewCLSIDs; - private System.Windows.Forms.MenuItem menuViewCLSIDsByName; - private System.Windows.Forms.MenuItem menuViewProgIDs; - private System.Windows.Forms.MenuItem menuViewCLSIDsByServer; - private System.Windows.Forms.MenuItem menuViewInterfaces; - private System.Windows.Forms.MenuItem menuViewInterfacesByName; - private System.Windows.Forms.MenuItem menuObjectROT; - private System.Windows.Forms.MenuItem menuViewImplementedCategories; - private System.Windows.Forms.MenuItem menuViewPreApproved; - private System.Windows.Forms.MenuItem menuItem1; - private System.Windows.Forms.MenuItem menuObjectCreateInstanceFromCLSID; - private System.Windows.Forms.MenuItem menuObject; - private System.Windows.Forms.MenuItem menuViewCLSIDsByLocalServer; - private System.Windows.Forms.MenuItem menuViewIELowRights; - private System.Windows.Forms.MenuItem menuViewLocalServices; - private System.Windows.Forms.MenuItem menuViewAppIDs; - private System.Windows.Forms.MenuItem menuObjectFromMarshalledStream; - private System.Windows.Forms.MenuItem menuObjectFromSerializedStream; - private System.Windows.Forms.MenuItem menuHelp; - private System.Windows.Forms.MenuItem menuHelpAbout; - private System.Windows.Forms.MenuItem menuRegistryTypeLibraries; - private System.Windows.Forms.MenuItem menuRegistryAppIDsIL; - private System.Windows.Forms.MenuItem menuViewCLSIDsWithSurrogate; - private System.Windows.Forms.MenuItem menuFileOpen32BitViewer; - private System.Windows.Forms.MenuItem menuObjectBindMoniker; - private System.Windows.Forms.MenuItem menuFileOpenDatabase; - private System.Windows.Forms.MenuItem menuFileSaveDatabase; - private System.Windows.Forms.MenuItem menuRegistryMimeTypes; - private System.Windows.Forms.MenuItem menuRegistryAppIDsWithAC; - private System.Windows.Forms.MenuItem menuSecurity; - private System.Windows.Forms.MenuItem menuSecurityDefaultAccess; - private System.Windows.Forms.MenuItem menuSecurityDefaultAccessRestriction; - private System.Windows.Forms.MenuItem menuSecurityDefaultLaunch; - private System.Windows.Forms.MenuItem menuSecurityDefaultLaunchRestriction; - private System.Windows.Forms.MenuItem menuItem4; - private System.Windows.Forms.MenuItem menuItem5; - private System.Windows.Forms.MenuItem menuItem6; - private System.Windows.Forms.MenuItem menuRegistryProperties; - private System.Windows.Forms.MenuItem menuFileOpenMachineOnly; - private System.Windows.Forms.MenuItem menuFileOpenUserOnly; - private System.Windows.Forms.MenuItem menuFileDiff; - private System.Windows.Forms.MenuItem menuObjectFromFile; - private System.Windows.Forms.MenuItem menuObjectParseMoniker; - private System.Windows.Forms.MenuItem menuHexEditor; - private System.Windows.Forms.MenuItem menuHexEditorFromFile; - private System.Windows.Forms.MenuItem menuHexEditorEmpty; - private System.Windows.Forms.MenuItem menuItem7; - private System.Windows.Forms.MenuItem menuItem8; - private System.Windows.Forms.MenuItem menuFileOpenTypeLib; - private System.Windows.Forms.MenuItem menuItem3; - private System.Windows.Forms.MenuItem menuItem9; - private System.Windows.Forms.MenuItem menuRegistryInterfaceProxies; - private System.Windows.Forms.MenuItem menuFileOpenProxyDll; - private System.Windows.Forms.MenuItem menuFileQueryAllInterfaces; - private System.Windows.Forms.MenuItem menuItem10; - private System.Windows.Forms.MenuItem menuFileSaveAsDatabase; - private System.Windows.Forms.MenuItem menuFileSettings; - private System.Windows.Forms.MenuItem menuItem12; - private System.Windows.Forms.MenuItem menuProcesses; - private System.Windows.Forms.MenuItem menuItem13; - private System.Windows.Forms.MenuItem menuProcessesAllProcessesByPid; - private System.Windows.Forms.MenuItem menuProcessesAllProcessesByName; - private System.Windows.Forms.MenuItem menuProcessesAllProcessesByUser; - private System.Windows.Forms.MenuItem menuFileOpenAsAdmin; - private System.Windows.Forms.MenuItem menuViewOpenPropertiesViewer; - private System.Windows.Forms.MenuItem menuStorageOpenStorage; - private System.Windows.Forms.MenuItem menuRegistryRuntimeClasses; - private System.Windows.Forms.MenuItem menuProcessesSelectProcess; - private System.Windows.Forms.MenuItem menuRegistryRuntimeServers; - private System.Windows.Forms.MenuItem menuItemStorage; - private System.Windows.Forms.MenuItem menuStorageNewStorage; - private System.Windows.Forms.MenuItem menuItemProcessesAllProcesses; - private System.Windows.Forms.MenuItem menuItem2; - private System.Windows.Forms.MenuItem menuFileOpenPowershell; - private System.Windows.Forms.MenuItem menuFileOpen64BitViewer; + } + + #endregion + + private System.Windows.Forms.MainMenu mainMenu; + private System.Windows.Forms.MenuItem menuFile; + private System.Windows.Forms.MenuItem menuFileExit; + private System.Windows.Forms.MenuItem menuRegistry; + private System.Windows.Forms.MenuItem menuViewCLSIDs; + private System.Windows.Forms.MenuItem menuViewCLSIDsByName; + private System.Windows.Forms.MenuItem menuViewProgIDs; + private System.Windows.Forms.MenuItem menuViewCLSIDsByServer; + private System.Windows.Forms.MenuItem menuViewInterfaces; + private System.Windows.Forms.MenuItem menuViewInterfacesByName; + private System.Windows.Forms.MenuItem menuObjectROT; + private System.Windows.Forms.MenuItem menuViewImplementedCategories; + private System.Windows.Forms.MenuItem menuViewPreApproved; + private System.Windows.Forms.MenuItem menuItem1; + private System.Windows.Forms.MenuItem menuObjectCreateInstanceFromCLSID; + private System.Windows.Forms.MenuItem menuObject; + private System.Windows.Forms.MenuItem menuViewCLSIDsByLocalServer; + private System.Windows.Forms.MenuItem menuViewIELowRights; + private System.Windows.Forms.MenuItem menuViewLocalServices; + private System.Windows.Forms.MenuItem menuViewAppIDs; + private System.Windows.Forms.MenuItem menuObjectFromMarshalledStream; + private System.Windows.Forms.MenuItem menuObjectFromSerializedStream; + private System.Windows.Forms.MenuItem menuHelp; + private System.Windows.Forms.MenuItem menuHelpAbout; + private System.Windows.Forms.MenuItem menuRegistryTypeLibraries; + private System.Windows.Forms.MenuItem menuRegistryAppIDsIL; + private System.Windows.Forms.MenuItem menuViewCLSIDsWithSurrogate; + private System.Windows.Forms.MenuItem menuFileOpen32BitViewer; + private System.Windows.Forms.MenuItem menuObjectBindMoniker; + private System.Windows.Forms.MenuItem menuFileOpenDatabase; + private System.Windows.Forms.MenuItem menuFileSaveDatabase; + private System.Windows.Forms.MenuItem menuRegistryMimeTypes; + private System.Windows.Forms.MenuItem menuRegistryAppIDsWithAC; + private System.Windows.Forms.MenuItem menuSecurity; + private System.Windows.Forms.MenuItem menuSecurityDefaultAccess; + private System.Windows.Forms.MenuItem menuSecurityDefaultAccessRestriction; + private System.Windows.Forms.MenuItem menuSecurityDefaultLaunch; + private System.Windows.Forms.MenuItem menuSecurityDefaultLaunchRestriction; + private System.Windows.Forms.MenuItem menuItem4; + private System.Windows.Forms.MenuItem menuItem5; + private System.Windows.Forms.MenuItem menuItem6; + private System.Windows.Forms.MenuItem menuRegistryProperties; + private System.Windows.Forms.MenuItem menuFileOpenMachineOnly; + private System.Windows.Forms.MenuItem menuFileOpenUserOnly; + private System.Windows.Forms.MenuItem menuFileDiff; + private System.Windows.Forms.MenuItem menuObjectFromFile; + private System.Windows.Forms.MenuItem menuObjectParseMoniker; + private System.Windows.Forms.MenuItem menuHexEditor; + private System.Windows.Forms.MenuItem menuHexEditorFromFile; + private System.Windows.Forms.MenuItem menuHexEditorEmpty; + private System.Windows.Forms.MenuItem menuItem7; + private System.Windows.Forms.MenuItem menuItem8; + private System.Windows.Forms.MenuItem menuFileOpenTypeLib; + private System.Windows.Forms.MenuItem menuItem3; + private System.Windows.Forms.MenuItem menuItem9; + private System.Windows.Forms.MenuItem menuRegistryInterfaceProxies; + private System.Windows.Forms.MenuItem menuFileOpenProxyDll; + private System.Windows.Forms.MenuItem menuFileQueryAllInterfaces; + private System.Windows.Forms.MenuItem menuItem10; + private System.Windows.Forms.MenuItem menuFileSaveAsDatabase; + private System.Windows.Forms.MenuItem menuFileSettings; + private System.Windows.Forms.MenuItem menuItem12; + private System.Windows.Forms.MenuItem menuProcesses; + private System.Windows.Forms.MenuItem menuItem13; + private System.Windows.Forms.MenuItem menuProcessesAllProcessesByPid; + private System.Windows.Forms.MenuItem menuProcessesAllProcessesByName; + private System.Windows.Forms.MenuItem menuProcessesAllProcessesByUser; + private System.Windows.Forms.MenuItem menuFileOpenAsAdmin; + private System.Windows.Forms.MenuItem menuViewOpenPropertiesViewer; + private System.Windows.Forms.MenuItem menuStorageOpenStorage; + private System.Windows.Forms.MenuItem menuRegistryRuntimeClasses; + private System.Windows.Forms.MenuItem menuProcessesSelectProcess; + private System.Windows.Forms.MenuItem menuRegistryRuntimeServers; + private System.Windows.Forms.MenuItem menuItemStorage; + private System.Windows.Forms.MenuItem menuStorageNewStorage; + private System.Windows.Forms.MenuItem menuItemProcessesAllProcesses; + private System.Windows.Forms.MenuItem menuItem2; + private System.Windows.Forms.MenuItem menuFileOpenPowershell; + private System.Windows.Forms.MenuItem menuFileOpen64BitViewer; private System.Windows.Forms.MenuItem menuFileOpenARM64Viewer; private System.Windows.Forms.MenuItem menuFileExportInterfaceList; private System.Windows.Forms.MenuItem menuFileSaveDefaultDatabase; @@ -927,6 +967,14 @@ private void InitializeComponent() private System.Windows.Forms.MenuItem menuProcessesOptionsParseStubs; private System.Windows.Forms.MenuItem menuProcessesOptionsParseRegisteredClasses; private System.Windows.Forms.MenuItem menuProcessesOptionsParseActCtx; + + /* Added */ + private System.Windows.Forms.MenuItem menuResolveMethodNamesFromIDA; + private System.Windows.Forms.MenuItem menuResolveMethodNamesFromIDAHard; + private System.Windows.Forms.MenuItem menuResolveMethodDllFix; + private System.Windows.Forms.MenuItem menuGetSequence; + /*Added */ + private System.Windows.Forms.MenuItem menuViewRuntimeInterfaces; private System.Windows.Forms.MenuItem menuViewRuntimeInterfacesTree; private System.Windows.Forms.MenuItem menuItemView; @@ -935,5 +983,5 @@ private void InitializeComponent() private System.Windows.Forms.MenuItem menuViewEnableAutoParsing; private System.Windows.Forms.MenuItem menuViewSaveProxyNamesOnExit; private System.Windows.Forms.MenuItem menuFileImportInteropAssembly; -} - +} + diff --git a/OleViewDotNet/Forms/MainForm.cs b/OleViewDotNet/Forms/MainForm.cs index af8b7832..496cb5fd 100644 --- a/OleViewDotNet/Forms/MainForm.cs +++ b/OleViewDotNet/Forms/MainForm.cs @@ -1,297 +1,302 @@ -// This file is part of OleViewDotNet. -// Copyright (C) James Forshaw 2014 -// -// OleViewDotNet is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// OleViewDotNet 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 General Public License -// along with OleViewDotNet. If not, see . - -using NtApiDotNet; -using OleViewDotNet.Database; -using OleViewDotNet.Interop; -using OleViewDotNet.Processes; -using OleViewDotNet.Proxy; -using OleViewDotNet.Security; -using OleViewDotNet.TypeLib; -using OleViewDotNet.TypeManager; -using OleViewDotNet.Utilities; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices.ComTypes; -using System.Threading.Tasks; -using System.Windows.Forms; -using WeifenLuo.WinFormsUI.Docking; - -namespace OleViewDotNet.Forms; - -internal partial class MainForm : Form -{ - private readonly DockPanel m_dockPanel; - private readonly COMRegistry m_registry; - private PropertyGrid m_property_grid; - - private void UpdateTitle() - { - Text = $"OleView .NET v{AppUtilities.GetVersion()}"; - if (AppUtilities.IsAdministrator()) - { - Text += " - Administrator"; - menuFileOpenAsAdmin.Visible = false; - } - - if (Environment.Is64BitOperatingSystem) - { - if (!Environment.Is64BitProcess) - { - Text += " - 32bit"; - } - else - { - Text += $" - 64bit ({AppUtilities.CurrentArchitecture})"; - } - } - - if (m_registry.FilePath is not null) - { - Text += $" - {m_registry.FilePath}"; - } - } - - public MainForm(COMRegistry registry) - { - m_registry = registry; - InitializeComponent(); +// This file is part of OleViewDotNet. +// Copyright (C) James Forshaw 2014 +// +// OleViewDotNet is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// OleViewDotNet 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 General Public License +// along with OleViewDotNet. If not, see . + +using NtApiDotNet; +using OleViewDotNet.Database; +using OleViewDotNet.Interop; +using OleViewDotNet.Processes; +using OleViewDotNet.Proxy; +using OleViewDotNet.Security; +using OleViewDotNet.TypeLib; +using OleViewDotNet.TypeManager; +using OleViewDotNet.Utilities; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices.ComTypes; +using System.Threading.Tasks; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; + +/* Added */ +using System.Runtime.InteropServices; +/* Added */ + +namespace OleViewDotNet.Forms; + +internal partial class MainForm : Form +{ + private readonly DockPanel m_dockPanel; + private readonly COMRegistry m_registry; + private PropertyGrid m_property_grid; + + private void UpdateTitle() + { + Text = $"OleView .NET v{AppUtilities.GetVersion()}"; + if (AppUtilities.IsAdministrator()) + { + Text += " - Administrator"; + menuFileOpenAsAdmin.Visible = false; + } + + if (Environment.Is64BitOperatingSystem) + { + if (!Environment.Is64BitProcess) + { + Text += " - 32bit"; + } + else + { + Text += $" - 64bit ({AppUtilities.CurrentArchitecture})"; + } + } + + if (m_registry.FilePath is not null) + { + Text += $" - {m_registry.FilePath}"; + } + Text += $" - MSRC Gasan"; + } + + public MainForm(COMRegistry registry) + { + m_registry = registry; + InitializeComponent(); m_dockPanel = new() { ActiveAutoHideContent = null, Dock = DockStyle.Fill, Name = "dockPanel", Theme = new VS2005Theme() - }; - Controls.Add(m_dockPanel); - m_dockPanel.BringToFront(); - CreatePropertyGrid(true); - - if (Environment.Is64BitProcess) - { - bool is_arm64 = NtSystemInfo.EmulationProcessorInformation.ProcessorArchitecture == ProcessorAchitecture.ARM; - bool is_amd64 = AppUtilities.CurrentArchitecture == ProgramArchitecture.X64; - menuFileOpenARM64Viewer.Visible = is_arm64 && is_amd64; - menuFileOpen64BitViewer.Visible = AppUtilities.CurrentArchitecture == ProgramArchitecture.Arm64; - menuFileOpen32BitViewer.Visible = true; - } - else - { - menuFileOpen32BitViewer.Visible = false; - menuFileOpenARM64Viewer.Visible = false; - menuFileOpen64BitViewer.Visible = false; - } - - UpdateTitle(); - } - - private void MainForm_Load(object sender, EventArgs e) - { - HostControl(new RegistryPropertiesControl(m_registry)); - } - - private void menuFileExit_Click(object sender, EventArgs e) - { - Close(); - } - - public void HostControl(Control c) - { - HostControl(c, null); - } - - public void HostControl(Control c, string name) - { - DocumentForm frm = new(c) - { - ShowHint = DockState.Document - }; - frm.Show(m_dockPanel); - if (!string.IsNullOrWhiteSpace(name)) - { - frm.TabText = name; - } - } - - public async Task HostObject(ICOMClassEntry ent, object obj, bool factory) - { - Dictionary props = new(); - - ent ??= new COMCLSIDEntry(m_registry, Guid.Empty, COMServerType.UnknownServer); - props.Add("CLSID", ent.Clsid.FormatGuid()); - props.Add("Name", ent.Name); - props.Add("Server", ent.DefaultServer); - - if (!ent.InterfacesLoaded) - { - await ent.LoadSupportedInterfacesAsync(false, null); - } - - IEnumerable intfs = factory ? ent.FactoryInterfaces : ent.Interfaces; - - ObjectInformation view = new(m_registry, ent, ent.Name, obj, - props, intfs.Select(i => m_registry.MapIidToInterface(i.Iid)).ToArray()); - HostControl(view); - } - - private void OpenView(COMRegistryDisplayMode mode, IEnumerable processes) - { - Cursor currCursor = Cursor.Current; - Cursor.Current = Cursors.WaitCursor; - HostControl(new COMRegistryViewer(m_registry, mode, processes)); - Cursor.Current = currCursor; - } - - private void OpenView(COMRegistryDisplayMode mode) - { - OpenView(mode, null); - } - - private void menuViewCLSIDs_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.CLSIDs); - } - - private void menuViewCLSIDsByName_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.CLSIDsByName); - } - - private void menuViewProgIDs_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.ProgIDs); - } - - private void menuViewCLSIDsByServer_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.CLSIDsByServer); - } - - private void menuViewInterfaces_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.Interfaces); - } - - private void menuViewInterfacesByName_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.InterfacesByName); - } - - private void menuViewROT_Click(object sender, EventArgs e) - { - HostControl(new ROTViewer(m_registry)); - } - - private void menuViewImplementedCategories_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.ImplementedCategories); - } - - private void menuViewPreApproved_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.PreApproved); - } - - public async Task CreateInstanceFromCLSID(Guid clsid, CLSCTX clsctx, bool class_factory) - { - try - { - COMCLSIDEntry ent = null; - Dictionary props = new(); - object comObj = null; - string strObjName = ""; - IEnumerable ints = null; - - if (m_registry.Clsids.ContainsKey(clsid)) - { - ent = m_registry.Clsids[clsid]; - strObjName = ent.Name; - props.Add("CLSID", ent.Clsid.FormatGuid()); - props.Add("Name", ent.Name); - props.Add("Server", ent.DefaultServer); - await ent.LoadSupportedInterfacesAsync(false, null); - - if (class_factory) - { - comObj = ent.CreateClassFactory(); - ints = ent.FactoryInterfaces.Select(i => m_registry.MapIidToInterface(i.Iid)); - } - else - { - comObj = ent.CreateInstanceAsObject(clsctx, null); - ints = ent.Interfaces.Select(i => m_registry.MapIidToInterface(i.Iid)); - } - } - else - { - using var pObj = class_factory ? SafeComObjectHandle.GetClassObject(clsid, clsctx, COMKnownGuids.IID_IUnknown) : - SafeComObjectHandle.CreateInstance(clsid, clsctx, COMKnownGuids.IID_IUnknown); - - ints = m_registry.GetInterfacesForIUnknown(pObj).ToArray(); - comObj = pObj.ToObject(); - strObjName = clsid.FormatGuid(); - props.Add("CLSID", clsid.FormatGuid()); - } - - if (comObj is not null) - { - HostControl(new ObjectInformation(m_registry, ent, strObjName, comObj, props, ints.ToArray())); - } - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - private async void menuViewCreateInstanceFromCLSID_Click(object sender, EventArgs e) - { + }; + Controls.Add(m_dockPanel); + m_dockPanel.BringToFront(); + CreatePropertyGrid(true); + + if (Environment.Is64BitProcess) + { + bool is_arm64 = NtSystemInfo.EmulationProcessorInformation.ProcessorArchitecture == ProcessorAchitecture.ARM; + bool is_amd64 = AppUtilities.CurrentArchitecture == ProgramArchitecture.X64; + menuFileOpenARM64Viewer.Visible = is_arm64 && is_amd64; + menuFileOpen64BitViewer.Visible = AppUtilities.CurrentArchitecture == ProgramArchitecture.Arm64; + menuFileOpen32BitViewer.Visible = true; + } + else + { + menuFileOpen32BitViewer.Visible = false; + menuFileOpenARM64Viewer.Visible = false; + menuFileOpen64BitViewer.Visible = false; + } + + UpdateTitle(); + } + + private void MainForm_Load(object sender, EventArgs e) + { + HostControl(new RegistryPropertiesControl(m_registry)); + } + + private void menuFileExit_Click(object sender, EventArgs e) + { + Close(); + } + + public void HostControl(Control c) + { + HostControl(c, null); + } + + public void HostControl(Control c, string name) + { + DocumentForm frm = new(c) + { + ShowHint = DockState.Document + }; + frm.Show(m_dockPanel); + if (!string.IsNullOrWhiteSpace(name)) + { + frm.TabText = name; + } + } + + public async Task HostObject(ICOMClassEntry ent, object obj, bool factory) + { + Dictionary props = new(); + + ent ??= new COMCLSIDEntry(m_registry, Guid.Empty, COMServerType.UnknownServer); + props.Add("CLSID", ent.Clsid.FormatGuid()); + props.Add("Name", ent.Name); + props.Add("Server", ent.DefaultServer); + + if (!ent.InterfacesLoaded) + { + await ent.LoadSupportedInterfacesAsync(false, null); + } + + IEnumerable intfs = factory ? ent.FactoryInterfaces : ent.Interfaces; + + ObjectInformation view = new(m_registry, ent, ent.Name, obj, + props, intfs.Select(i => m_registry.MapIidToInterface(i.Iid)).ToArray()); + HostControl(view); + } + + private void OpenView(COMRegistryDisplayMode mode, IEnumerable processes) + { + Cursor currCursor = Cursor.Current; + Cursor.Current = Cursors.WaitCursor; + HostControl(new COMRegistryViewer(m_registry, mode, processes)); + Cursor.Current = currCursor; + } + + private void OpenView(COMRegistryDisplayMode mode) + { + OpenView(mode, null); + } + + private void menuViewCLSIDs_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.CLSIDs); + } + + private void menuViewCLSIDsByName_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.CLSIDsByName); + } + + private void menuViewProgIDs_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.ProgIDs); + } + + private void menuViewCLSIDsByServer_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.CLSIDsByServer); + } + + private void menuViewInterfaces_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.Interfaces); + } + + private void menuViewInterfacesByName_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.InterfacesByName); + } + + private void menuViewROT_Click(object sender, EventArgs e) + { + HostControl(new ROTViewer(m_registry)); + } + + private void menuViewImplementedCategories_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.ImplementedCategories); + } + + private void menuViewPreApproved_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.PreApproved); + } + + public async Task CreateInstanceFromCLSID(Guid clsid, CLSCTX clsctx, bool class_factory) + { + try + { + COMCLSIDEntry ent = null; + Dictionary props = new(); + object comObj = null; + string strObjName = ""; + IEnumerable ints = null; + + if (m_registry.Clsids.ContainsKey(clsid)) + { + ent = m_registry.Clsids[clsid]; + strObjName = ent.Name; + props.Add("CLSID", ent.Clsid.FormatGuid()); + props.Add("Name", ent.Name); + props.Add("Server", ent.DefaultServer); + await ent.LoadSupportedInterfacesAsync(false, null); + + if (class_factory) + { + comObj = ent.CreateClassFactory(); + ints = ent.FactoryInterfaces.Select(i => m_registry.MapIidToInterface(i.Iid)); + } + else + { + comObj = ent.CreateInstanceAsObject(clsctx, null); + ints = ent.Interfaces.Select(i => m_registry.MapIidToInterface(i.Iid)); + } + } + else + { + using var pObj = class_factory ? SafeComObjectHandle.GetClassObject(clsid, clsctx, COMKnownGuids.IID_IUnknown) : + SafeComObjectHandle.CreateInstance(clsid, clsctx, COMKnownGuids.IID_IUnknown); + + ints = m_registry.GetInterfacesForIUnknown(pObj).ToArray(); + comObj = pObj.ToObject(); + strObjName = clsid.FormatGuid(); + props.Add("CLSID", clsid.FormatGuid()); + } + + if (comObj is not null) + { + HostControl(new ObjectInformation(m_registry, ent, strObjName, comObj, props, ints.ToArray())); + } + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + private async void menuViewCreateInstanceFromCLSID_Click(object sender, EventArgs e) + { using CreateCLSIDForm frm = new(); if (frm.ShowDialog() == DialogResult.OK) { await CreateInstanceFromCLSID(frm.Clsid, frm.ClsCtx, frm.ClassFactory); - } - } - - private void menuViewCLSIDsByLocalServer_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.CLSIDsByLocalServer); - } - - private void menuViewIELowRights_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.IELowRights); - } - - private void menuViewLocalServices_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.LocalServices); - } - - private void menuViewAppIDs_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.AppIDs); - } - - private async void menuObjectFromMarshalledStream_Click(object sender, EventArgs e) - { + } + } + + private void menuViewCLSIDsByLocalServer_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.CLSIDsByLocalServer); + } + + private void menuViewIELowRights_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.IELowRights); + } + + private void menuViewLocalServices_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.LocalServices); + } + + private void menuViewAppIDs_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.AppIDs); + } + + private async void menuObjectFromMarshalledStream_Click(object sender, EventArgs e) + { using OpenFileDialog dlg = new(); dlg.Filter = "All Files (*.*)|*.*"; @@ -307,42 +312,42 @@ private async void menuObjectFromMarshalledStream_Click(object sender, EventArgs { EntryPoint.ShowError(this, ex); } - } - } - - public async Task OpenObjectInformation(object comObj, string defaultName) - { - if (comObj is not null) - { - COMCLSIDEntry ent = null; - Dictionary props = new(); - string strObjName = ""; - IEnumerable ints = null; - Guid clsid = COMUtilities.GetObjectClass(comObj); - - if (m_registry.Clsids.ContainsKey(clsid)) - { - ent = m_registry.Clsids[clsid]; - strObjName = ent.Name; - props.Add("CLSID", ent.Clsid.FormatGuid()); - props.Add("Name", ent.Name); - props.Add("Server", ent.DefaultServer); - await ent.LoadSupportedInterfacesAsync(false, null); - ints = ent.Interfaces.Select(i => m_registry.MapIidToInterface(i.Iid)); - } - else - { - ints = m_registry.GetInterfacesForObject(comObj).ToArray(); - strObjName = defaultName ?? clsid.FormatGuid(); - props.Add("CLSID", clsid.FormatGuid()); - } - - HostControl(new ObjectInformation(m_registry, ent, strObjName, comObj, props, ints.ToArray())); - } - } - - private async void menuObjectFromSerializedStream_Click(object sender, EventArgs e) - { + } + } + + public async Task OpenObjectInformation(object comObj, string defaultName) + { + if (comObj is not null) + { + COMCLSIDEntry ent = null; + Dictionary props = new(); + string strObjName = ""; + IEnumerable ints = null; + Guid clsid = COMUtilities.GetObjectClass(comObj); + + if (m_registry.Clsids.ContainsKey(clsid)) + { + ent = m_registry.Clsids[clsid]; + strObjName = ent.Name; + props.Add("CLSID", ent.Clsid.FormatGuid()); + props.Add("Name", ent.Name); + props.Add("Server", ent.DefaultServer); + await ent.LoadSupportedInterfacesAsync(false, null); + ints = ent.Interfaces.Select(i => m_registry.MapIidToInterface(i.Iid)); + } + else + { + ints = m_registry.GetInterfacesForObject(comObj).ToArray(); + strObjName = defaultName ?? clsid.FormatGuid(); + props.Add("CLSID", clsid.FormatGuid()); + } + + HostControl(new ObjectInformation(m_registry, ent, strObjName, comObj, props, ints.ToArray())); + } + } + + private async void menuObjectFromSerializedStream_Click(object sender, EventArgs e) + { using OpenFileDialog dlg = new(); dlg.Filter = "All Files (*.*)|*.*"; @@ -358,46 +363,46 @@ private async void menuObjectFromSerializedStream_Click(object sender, EventArgs { EntryPoint.ShowError(this, ex); } - } - } - - private void menuHelpAbout_Click(object sender, EventArgs e) - { + } + } + + private void menuHelpAbout_Click(object sender, EventArgs e) + { using AboutForm frm = new(); - frm.ShowDialog(this); - } - - private void menuRegistryTypeLibs_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.Typelibs); - } - - private void menuRegistryAppIDsIL_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.AppIDsWithIL); - } - - private void menuViewCLSIDsWithSurrogate_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.CLSIDsWithSurrogate); - } - - private void menuFileOpen32BitViewer_Click(object sender, EventArgs e) - { - try - { - AppUtilities.StartArchProcess(ProgramArchitecture.X86, string.Empty); - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - private string _last_moniker = "Specify Moniker"; - - private async Task ParseOrBindMoniker(bool bind) - { + frm.ShowDialog(this); + } + + private void menuRegistryTypeLibs_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.Typelibs); + } + + private void menuRegistryAppIDsIL_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.AppIDsWithIL); + } + + private void menuViewCLSIDsWithSurrogate_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.CLSIDsWithSurrogate); + } + + private void menuFileOpen32BitViewer_Click(object sender, EventArgs e) + { + try + { + AppUtilities.StartArchProcess(ProgramArchitecture.X86, string.Empty); + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + private string _last_moniker = "Specify Moniker"; + + private async Task ParseOrBindMoniker(bool bind) + { using BuildMonikerForm frm = new(_last_moniker); frm.BindMoniker = bind; if (frm.ShowDialog(this) == DialogResult.OK) @@ -415,181 +420,181 @@ private async Task ParseOrBindMoniker(bool bind) { EntryPoint.ShowError(this, ex); } - } - } - - private async void menuObjectBindMoniker_Click(object sender, EventArgs e) - { - await ParseOrBindMoniker(true); - } - - private string GetSaveFileName(bool save) - { - if (save && !string.IsNullOrWhiteSpace(m_registry.FilePath)) - { - return m_registry.FilePath; - } - - using (SaveFileDialog dlg = new()) - { - if (!string.IsNullOrWhiteSpace(m_registry.FilePath)) - { - dlg.FileName = m_registry.FilePath; - } - - dlg.Filter = "OleViewDotNet DB File (*.ovdb)|*.ovdb|All Files (*.*)|*.*"; - if (dlg.ShowDialog(this) == DialogResult.OK) - { - return dlg.FileName; - } - } - - return string.Empty; - } - - private void SaveDatabase(bool save) - { - string filename = GetSaveFileName(save); - if (string.IsNullOrWhiteSpace(filename)) - { - return; - } - - try - { - m_registry.Save(filename); - UpdateTitle(); - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - private void menuFileSaveDatabase_Click(object sender, EventArgs e) - { - SaveDatabase(true); - } - - private void menuFileOpenDatabase_Click(object sender, EventArgs e) - { - using OpenFileDialog dlg = new(); - dlg.Filter = "OleViewDotNet DB File (*.ovdb)|*.ovdb|All Files (*.*)|*.*"; - if (dlg.ShowDialog(this) == DialogResult.OK) - { - LoadRegistry(() => FormUtils.LoadRegistry(this, dlg.FileName)); - } - } - - private void menuRegistryMimeTypes_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.MimeTypes); - } - - private void menuRegistryAppIDsWithAC_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.AppIDsWithAC); - } - - private void menuSecurityDefaultAccess_Click(object sender, EventArgs e) - { - COMSecurity.ViewSecurity(m_registry, "Default Access", m_registry.DefaultAccessPermission, true); - } - - private void menuSecurityDefaultAccessRestriction_Click(object sender, EventArgs e) - { - COMSecurity.ViewSecurity(m_registry, "Default Access Restrictions", m_registry.DefaultAccessRestriction, true); - } - - private void menuSecurityDefaultLaunch_Click(object sender, EventArgs e) - { - COMSecurity.ViewSecurity(m_registry, "Default Launch", m_registry.DefaultLaunchPermission, false); - } - - private void menuSecurityDefaultLaunchRestriction_Click(object sender, EventArgs e) - { - COMSecurity.ViewSecurity(m_registry, "Default Launch Restrictions", m_registry.DefaultLaunchRestriction, false); - } - - public COMRegistry Registry => m_registry; + } + } + + private async void menuObjectBindMoniker_Click(object sender, EventArgs e) + { + await ParseOrBindMoniker(true); + } + + private string GetSaveFileName(bool save) + { + if (save && !string.IsNullOrWhiteSpace(m_registry.FilePath)) + { + return m_registry.FilePath; + } + + using (SaveFileDialog dlg = new()) + { + if (!string.IsNullOrWhiteSpace(m_registry.FilePath)) + { + dlg.FileName = m_registry.FilePath; + } + + dlg.Filter = "OleViewDotNet DB File (*.ovdb)|*.ovdb|All Files (*.*)|*.*"; + if (dlg.ShowDialog(this) == DialogResult.OK) + { + return dlg.FileName; + } + } + + return string.Empty; + } + + private void SaveDatabase(bool save) + { + string filename = GetSaveFileName(save); + if (string.IsNullOrWhiteSpace(filename)) + { + return; + } + + try + { + m_registry.Save(filename); + UpdateTitle(); + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + private void menuFileSaveDatabase_Click(object sender, EventArgs e) + { + SaveDatabase(true); + } + + private void menuFileOpenDatabase_Click(object sender, EventArgs e) + { + using OpenFileDialog dlg = new(); + dlg.Filter = "OleViewDotNet DB File (*.ovdb)|*.ovdb|All Files (*.*)|*.*"; + if (dlg.ShowDialog(this) == DialogResult.OK) + { + LoadRegistry(() => FormUtils.LoadRegistry(this, dlg.FileName)); + } + } + + private void menuRegistryMimeTypes_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.MimeTypes); + } + + private void menuRegistryAppIDsWithAC_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.AppIDsWithAC); + } + + private void menuSecurityDefaultAccess_Click(object sender, EventArgs e) + { + COMSecurity.ViewSecurity(m_registry, "Default Access", m_registry.DefaultAccessPermission, true); + } + + private void menuSecurityDefaultAccessRestriction_Click(object sender, EventArgs e) + { + COMSecurity.ViewSecurity(m_registry, "Default Access Restrictions", m_registry.DefaultAccessRestriction, true); + } + + private void menuSecurityDefaultLaunch_Click(object sender, EventArgs e) + { + COMSecurity.ViewSecurity(m_registry, "Default Launch", m_registry.DefaultLaunchPermission, false); + } + + private void menuSecurityDefaultLaunchRestriction_Click(object sender, EventArgs e) + { + COMSecurity.ViewSecurity(m_registry, "Default Launch Restrictions", m_registry.DefaultLaunchRestriction, false); + } + + public COMRegistry Registry => m_registry; + + private void menuRegistryProperties_Click(object sender, EventArgs e) + { + HostControl(new RegistryPropertiesControl(m_registry)); + } + + private void LoadRegistry(Func loader) + { + try + { + new MainForm(loader()).Show(); + } + catch (OperationCanceledException) + { + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + private void menuFileOpenMachineOnly_Click(object sender, EventArgs e) + { + LoadRegistry(() => FormUtils.LoadRegistry(this, COMRegistryMode.MachineOnly)); + } + + private void menuFileOpenUserOnly_Click(object sender, EventArgs e) + { + LoadRegistry(() => FormUtils.LoadRegistry(this, COMRegistryMode.UserOnly)); + } + + private void menuFileDiff_Click(object sender, EventArgs e) + { + using DiffRegistryForm frm = new(m_registry); + if (frm.ShowDialog(this) == DialogResult.OK) + { + new MainForm(frm.DiffRegistry).Show(); + } + } + + private async void menuObjectFromFile_Click(object sender, EventArgs e) + { + try + { + using OpenFileDialog dlg = new(); + dlg.Filter = "All Files (*.*)|*.*"; + if (dlg.ShowDialog(this) == DialogResult.OK) + { + COMCLSIDEntry entry = m_registry.GetFileClass(dlg.FileName); + if (entry is not null) + { + IPersistFile ps = (IPersistFile)entry.CreateInstanceAsObject(entry.CreateContext, null); + ps.Load(dlg.FileName, (int)STGM.READ); + await HostObject(entry, ps, false); + } + } + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } - private void menuRegistryProperties_Click(object sender, EventArgs e) - { - HostControl(new RegistryPropertiesControl(m_registry)); - } - - private void LoadRegistry(Func loader) - { - try - { - new MainForm(loader()).Show(); - } - catch (OperationCanceledException) - { - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - private void menuFileOpenMachineOnly_Click(object sender, EventArgs e) - { - LoadRegistry(() => FormUtils.LoadRegistry(this, COMRegistryMode.MachineOnly)); - } - - private void menuFileOpenUserOnly_Click(object sender, EventArgs e) - { - LoadRegistry(() => FormUtils.LoadRegistry(this, COMRegistryMode.UserOnly)); - } - - private void menuFileDiff_Click(object sender, EventArgs e) - { - using DiffRegistryForm frm = new(m_registry); - if (frm.ShowDialog(this) == DialogResult.OK) + private async void menuObjectParseMoniker_Click(object sender, EventArgs e) + { + await ParseOrBindMoniker(false); + } + + private void OpenHexEditor(string name, byte[] bytes) + { + ObjectHexEditor editor = new(m_registry, name, bytes); + HostControl(editor); + } + + private void menuHexEditorFromFile_Click(object sender, EventArgs e) + { + try { - new MainForm(frm.DiffRegistry).Show(); - } - } - - private async void menuObjectFromFile_Click(object sender, EventArgs e) - { - try - { - using OpenFileDialog dlg = new(); - dlg.Filter = "All Files (*.*)|*.*"; - if (dlg.ShowDialog(this) == DialogResult.OK) - { - COMCLSIDEntry entry = m_registry.GetFileClass(dlg.FileName); - if (entry is not null) - { - IPersistFile ps = (IPersistFile)entry.CreateInstanceAsObject(entry.CreateContext, null); - ps.Load(dlg.FileName, (int)STGM.READ); - await HostObject(entry, ps, false); - } - } - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - private async void menuObjectParseMoniker_Click(object sender, EventArgs e) - { - await ParseOrBindMoniker(false); - } - - private void OpenHexEditor(string name, byte[] bytes) - { - ObjectHexEditor editor = new(m_registry, name, bytes); - HostControl(editor); - } - - private void menuHexEditorFromFile_Click(object sender, EventArgs e) - { - try - { using OpenFileDialog dlg = new(); dlg.Multiselect = true; dlg.Filter = "All Files (*.*)|*.*"; @@ -600,21 +605,21 @@ private void menuHexEditorFromFile_Click(object sender, EventArgs e) OpenHexEditor(Path.GetFileName(file), File.ReadAllBytes(file)); } - } - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - private void menuHexEditorEmpty_Click(object sender, EventArgs e) - { - OpenHexEditor("Empty", new byte[0]); - } - - private void menuFileOpenTypeLib_Click(object sender, EventArgs e) - { + } + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + private void menuHexEditorEmpty_Click(object sender, EventArgs e) + { + OpenHexEditor("Empty", new byte[0]); + } + + private void menuFileOpenTypeLib_Click(object sender, EventArgs e) + { using OpenFileDialog dlg = new(); dlg.Filter = "TLB Files (*.tlb)|*.tlb|Executable Files (*.exe;*.dll;*.ocx)|*.exe;*.dll;*.ocx|All Files (*.*)|*.*"; if (dlg.ShowDialog(this) == DialogResult.OK) @@ -628,16 +633,16 @@ private void menuFileOpenTypeLib_Click(object sender, EventArgs e) { EntryPoint.ShowError(this, ex); } - } - } - - private void menuRegistryInterfaceProxies_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.ProxyCLSIDs); - } - - private void menuFileOpenProxyDll_Click(object sender, EventArgs e) - { + } + } + + private void menuRegistryInterfaceProxies_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.ProxyCLSIDs); + } + + private void menuFileOpenProxyDll_Click(object sender, EventArgs e) + { using OpenFileDialog dlg = new(); dlg.Filter = "Executable Files (*.dll;*.ocx)|*.dll;*.ocx|All Files (*.*)|*.*"; if (dlg.ShowDialog(this) == DialogResult.OK) @@ -651,155 +656,155 @@ private void menuFileOpenProxyDll_Click(object sender, EventArgs e) { EntryPoint.ShowError(this, ex); } - } - } - - private void menuFileQueryAllInterfaces_Click(object sender, EventArgs e) - { + } + } + + private void menuFileQueryAllInterfaces_Click(object sender, EventArgs e) + { using QueryInterfacesOptionsForm options = new(); if (options.ShowDialog(this) == DialogResult.OK) { FormUtils.QueryAllInterfaces(this, m_registry.Clsids.Values, options.ServerTypes, options.ConcurrentQueries, options.RefreshInterfaces); - } - } - - private void menuFileSaveAsDatabase_Click(object sender, EventArgs e) - { - SaveDatabase(false); - } - - private void menuFileSettings_Click(object sender, EventArgs e) - { + } + } + + private void menuFileSaveAsDatabase_Click(object sender, EventArgs e) + { + SaveDatabase(false); + } + + private void menuFileSettings_Click(object sender, EventArgs e) + { using SettingsForm frm = new(); - frm.ShowDialog(this); - } - - private static bool _configured_symbols = false; - - private void ConfigureSymbols() - { - if (_configured_symbols) - { - return; - } - - _configured_symbols = true; - - if (!ProgramSettings.SymbolsConfigured) - { - if (MessageBox.Show(this, "Symbol support has not been configured, would you like to do that now?", - "Configure Symbols", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) - { + frm.ShowDialog(this); + } + + private static bool _configured_symbols = false; + + private void ConfigureSymbols() + { + if (_configured_symbols) + { + return; + } + + _configured_symbols = true; + + if (!ProgramSettings.SymbolsConfigured) + { + if (MessageBox.Show(this, "Symbol support has not been configured, would you like to do that now?", + "Configure Symbols", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + { using SettingsForm frm = new(); - frm.ShowDialog(this); - } - } - } - - private void LoadProcesses(Func orderby_selector) - { - ConfigureSymbols(); - IEnumerable processes = FormUtils.LoadProcesses(this, m_registry); - if (processes is not null && processes.Any()) - { - OpenView(COMRegistryDisplayMode.Processes, processes.OrderBy(orderby_selector)); - } - } - - internal void LoadIPid(Guid ipid) - { - try - { - ConfigureSymbols(); - var proc = FormUtils.LoadProcesses(new int[] { COMUtilities.GetProcessIdFromIPid(ipid) }, this, m_registry).FirstOrDefault(); - if (proc is not null) - { - COMIPIDEntry ipid_entry = proc.Ipids.Where(e => e.Ipid == ipid).FirstOrDefault(); - if (ipid_entry is not null) - { - HostControl(new PropertiesControl(m_registry, $"IPID: {ipid.FormatGuid()}", ipid_entry)); - } - else - { - throw new Exception("Couldn't find the target IPID in the remote process. Did you configure the Dbghelp and symbol paths correctly in the main settings?"); - } - } - else - { - throw new Exception($"Couldn't load process for IPID: {ipid.FormatGuid()}"); - } - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - internal void LoadProcessByProcessId(int pid) - { - try - { - ConfigureSymbols(); - var processes = FormUtils.LoadProcesses(new int[] { pid }, this, m_registry); - if (!processes.Any()) - { - throw new ArgumentException($"Process {pid} has not initialized COM, or is inaccessible"); - } - - HostControl(new PropertiesControl(m_registry, $"Process {pid}", processes.First())); - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - private void menuProcessesAllProcessesByPid_Click(object sender, EventArgs e) - { - LoadProcesses(p => p.ProcessId); - } - - private void menuProcessesAllProcessesByName_Click(object sender, EventArgs e) - { - LoadProcesses(p => p.Name); - } - - private void menuProcessesAllProcessesByUser_Click(object sender, EventArgs e) - { - LoadProcesses(p => p.User); - } - - private void menuFileOpenAsAdmin_Click(object sender, EventArgs e) - { - try - { + frm.ShowDialog(this); + } + } + } + + private void LoadProcesses(Func orderby_selector) + { + ConfigureSymbols(); + IEnumerable processes = FormUtils.LoadProcesses(this, m_registry); + if (processes is not null && processes.Any()) + { + OpenView(COMRegistryDisplayMode.Processes, processes.OrderBy(orderby_selector)); + } + } + + internal void LoadIPid(Guid ipid) + { + try + { + ConfigureSymbols(); + var proc = FormUtils.LoadProcesses(new int[] { COMUtilities.GetProcessIdFromIPid(ipid) }, this, m_registry).FirstOrDefault(); + if (proc is not null) + { + COMIPIDEntry ipid_entry = proc.Ipids.Where(e => e.Ipid == ipid).FirstOrDefault(); + if (ipid_entry is not null) + { + HostControl(new PropertiesControl(m_registry, $"IPID: {ipid.FormatGuid()}", ipid_entry)); + } + else + { + throw new Exception("Couldn't find the target IPID in the remote process. Did you configure the Dbghelp and symbol paths correctly in the main settings?"); + } + } + else + { + throw new Exception($"Couldn't load process for IPID: {ipid.FormatGuid()}"); + } + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + internal void LoadProcessByProcessId(int pid) + { + try + { + ConfigureSymbols(); + var processes = FormUtils.LoadProcesses(new int[] { pid }, this, m_registry); + if (!processes.Any()) + { + throw new ArgumentException($"Process {pid} has not initialized COM, or is inaccessible"); + } + + HostControl(new PropertiesControl(m_registry, $"Process {pid}", processes.First())); + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + private void menuProcessesAllProcessesByPid_Click(object sender, EventArgs e) + { + LoadProcesses(p => p.ProcessId); + } + + private void menuProcessesAllProcessesByName_Click(object sender, EventArgs e) + { + LoadProcesses(p => p.Name); + } + + private void menuProcessesAllProcessesByUser_Click(object sender, EventArgs e) + { + LoadProcesses(p => p.User); + } + + private void menuFileOpenAsAdmin_Click(object sender, EventArgs e) + { + try + { ProcessStartInfo start_info = new(Assembly.GetEntryAssembly().Location, - $"--arch={AppUtilities.CurrentArchitecture}"); - start_info.UseShellExecute = true; - start_info.Verb = "runas"; - - Process.Start(start_info).Close(); - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - public void UpdatePropertyGrid(object obj) - { - if (m_property_grid is not null && !m_property_grid.IsDisposed) - { - m_property_grid.SelectedObject = obj; - } - } - - public void CreatePropertyGrid(bool autohide) - { - if (m_property_grid is null || m_property_grid.IsDisposed) - { + $"--arch={AppUtilities.CurrentArchitecture}"); + start_info.UseShellExecute = true; + start_info.Verb = "runas"; + + Process.Start(start_info).Close(); + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + public void UpdatePropertyGrid(object obj) + { + if (m_property_grid is not null && !m_property_grid.IsDisposed) + { + m_property_grid.SelectedObject = obj; + } + } + + public void CreatePropertyGrid(bool autohide) + { + if (m_property_grid is null || m_property_grid.IsDisposed) + { m_property_grid = new() { ToolbarVisible = false, @@ -810,34 +815,34 @@ public void CreatePropertyGrid(bool autohide) { TabText = "Object Properties", ShowHint = autohide ? DockState.DockRightAutoHide : DockState.DockRight - }; - frm.Show(m_dockPanel); - } - } - - private void menuViewOpenPropertiesViewer_Click(object sender, EventArgs e) - { - CreatePropertyGrid(false); - } - - private static STGM GetStorageAccess(bool read_only) - { - if (read_only) - { - return STGM.READ | STGM.SHARE_DENY_WRITE; - } - else - { - return STGM.SHARE_EXCLUSIVE | STGM.READWRITE; - } - } - - private const string STORAGE_FILTER = "All Files (*.*)|*.*|Doc Files (*.doc)|*.doc"; - - private void menuStorageOpenStorage_Click(object sender, EventArgs e) - { - try - { + }; + frm.Show(m_dockPanel); + } + } + + private void menuViewOpenPropertiesViewer_Click(object sender, EventArgs e) + { + CreatePropertyGrid(false); + } + + private static STGM GetStorageAccess(bool read_only) + { + if (read_only) + { + return STGM.READ | STGM.SHARE_DENY_WRITE; + } + else + { + return STGM.SHARE_EXCLUSIVE | STGM.READWRITE; + } + } + + private const string STORAGE_FILTER = "All Files (*.*)|*.*|Doc Files (*.doc)|*.doc"; + + private void menuStorageOpenStorage_Click(object sender, EventArgs e) + { + try + { using OpenFileDialog dlg = new(); dlg.ShowReadOnly = true; dlg.ReadOnlyChecked = true; @@ -847,18 +852,18 @@ private void menuStorageOpenStorage_Click(object sender, EventArgs e) IStorage stg = NativeMethods.StgOpenStorage(dlg.FileName, null, GetStorageAccess(dlg.ReadOnlyChecked), IntPtr.Zero, 0); HostControl(new StorageViewer(stg, Path.GetFileName(dlg.FileName), dlg.ReadOnlyChecked)); - } - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - private void menuStorageNewStorage_Click(object sender, EventArgs e) - { - try - { + } + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + private void menuStorageNewStorage_Click(object sender, EventArgs e) + { + try + { using SaveFileDialog dlg = new(); dlg.Filter = STORAGE_FILTER; if (dlg.ShowDialog(this) == DialogResult.OK) @@ -867,117 +872,117 @@ private void menuStorageNewStorage_Click(object sender, EventArgs e) IStorage stg = NativeMethods.StgCreateStorageEx(dlg.FileName, STGM.SHARE_EXCLUSIVE | STGM.READWRITE, STGFMT.Storage, 0, null, IntPtr.Zero, iid); HostControl(new StorageViewer(stg, Path.GetFileName(dlg.FileName), false)); - } - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - private void menuRegistryRuntimeClasses_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.RuntimeClasses); - } - - private void menuProcessesSelectProcess_Click(object sender, EventArgs e) - { + } + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + private void menuRegistryRuntimeClasses_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.RuntimeClasses); + } + + private void menuProcessesSelectProcess_Click(object sender, EventArgs e) + { using SelectProcessForm form = new(ProcessAccessRights.VmRead, false, true); if (form.ShowDialog(this) == DialogResult.OK) { LoadProcessByProcessId(form.SelectedProcess.ProcessId); - } - } - - private void menuRegistryRuntimeServers_Click(object sender, EventArgs e) - { - OpenView(COMRegistryDisplayMode.RuntimeServers); - } - - private void menuFileOpenPowershell_Click(object sender, EventArgs e) - { - try - { - string temp_file = Path.GetTempFileName(); - m_registry.Save(temp_file); - - string startup_script = Path.Combine(AppUtilities.GetAppDirectory(), "Startup-Module.ps1"); - if (!File.Exists(startup_script)) - { - throw new ArgumentException("PowerShell startup script is missing"); - } - - using (Process.Start("powershell.exe", $"-NoExit -ExecutionPolicy Bypass -File \"{startup_script}\" \"{temp_file}\" -DeleteFile")) - { - } - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - private void FocusOnTextBoxFilter() - { - // user hit search so we set the input focus into the first inputbox (which is usually a filter input) - if (m_dockPanel.ActivePane.ActiveContent is not DocumentForm df) return; - - Control[] textBoxFilters = df.Controls.Find("textBoxFilter", true); - if (textBoxFilters.Length != 1) return; - - textBoxFilters[0].Focus(); - } - - private void MainForm_KeyUp(object sender, KeyEventArgs e) - { - if (e.Control && (e.KeyCode == Keys.W)) - { - m_dockPanel.ActivePane.CloseActiveContent(); - return; - } - - if (e.Control && e.Alt && (e.KeyCode == Keys.Left)) - { - m_dockPanel.NavigateDocument(DockPanelHelper.Direction.Left); - return; - } - - - if (e.Control && e.Alt && (e.KeyCode == Keys.Right)) - { - m_dockPanel.NavigateDocument(DockPanelHelper.Direction.Right); - return; - } - - if (e.Control && (e.KeyCode == Keys.F)) - { - FocusOnTextBoxFilter(); - return; - } - } - - private void menuFileOpen64BitViewer_Click(object sender, EventArgs e) - { - try - { - AppUtilities.StartArchProcess(ProgramArchitecture.X64, string.Empty); - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } - } - - private void menuFileOpenARM64Viewer_Click(object sender, EventArgs e) - { - try - { - AppUtilities.StartArchProcess(ProgramArchitecture.Arm64, string.Empty); - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); - } + } + } + + private void menuRegistryRuntimeServers_Click(object sender, EventArgs e) + { + OpenView(COMRegistryDisplayMode.RuntimeServers); + } + + private void menuFileOpenPowershell_Click(object sender, EventArgs e) + { + try + { + string temp_file = Path.GetTempFileName(); + m_registry.Save(temp_file); + + string startup_script = Path.Combine(AppUtilities.GetAppDirectory(), "Startup-Module.ps1"); + if (!File.Exists(startup_script)) + { + throw new ArgumentException("PowerShell startup script is missing"); + } + + using (Process.Start("powershell.exe", $"-NoExit -ExecutionPolicy Bypass -File \"{startup_script}\" \"{temp_file}\" -DeleteFile")) + { + } + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + private void FocusOnTextBoxFilter() + { + // user hit search so we set the input focus into the first inputbox (which is usually a filter input) + if (m_dockPanel.ActivePane.ActiveContent is not DocumentForm df) return; + + Control[] textBoxFilters = df.Controls.Find("textBoxFilter", true); + if (textBoxFilters.Length != 1) return; + + textBoxFilters[0].Focus(); + } + + private void MainForm_KeyUp(object sender, KeyEventArgs e) + { + if (e.Control && (e.KeyCode == Keys.W)) + { + m_dockPanel.ActivePane.CloseActiveContent(); + return; + } + + if (e.Control && e.Alt && (e.KeyCode == Keys.Left)) + { + m_dockPanel.NavigateDocument(DockPanelHelper.Direction.Left); + return; + } + + + if (e.Control && e.Alt && (e.KeyCode == Keys.Right)) + { + m_dockPanel.NavigateDocument(DockPanelHelper.Direction.Right); + return; + } + + if (e.Control && (e.KeyCode == Keys.F)) + { + FocusOnTextBoxFilter(); + return; + } + } + + private void menuFileOpen64BitViewer_Click(object sender, EventArgs e) + { + try + { + AppUtilities.StartArchProcess(ProgramArchitecture.X64, string.Empty); + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } + } + + private void menuFileOpenARM64Viewer_Click(object sender, EventArgs e) + { + try + { + AppUtilities.StartArchProcess(ProgramArchitecture.Arm64, string.Empty); + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); + } } private void menuFileExportInterfaceList_Click(object sender, EventArgs e) @@ -1000,17 +1005,17 @@ private void menuFileExportInterfaceList_Click(object sender, EventArgs e) private void menuFileSaveDefaultDatabase_Click(object sender, EventArgs e) { - try - { - if (m_registry.LoadingMode != COMRegistryMode.Merged) - return; - m_registry.Save(ProgramSettings.GetDefaultDatabasePath(true)); - m_registry.FilePath = null; - UpdateTitle(); - } - catch (Exception ex) - { - EntryPoint.ShowError(this, ex); + try + { + if (m_registry.LoadingMode != COMRegistryMode.Merged) + return; + m_registry.Save(ProgramSettings.GetDefaultDatabasePath(true)); + m_registry.FilePath = null; + UpdateTitle(); + } + catch (Exception ex) + { + EntryPoint.ShowError(this, ex); } } @@ -1067,6 +1072,48 @@ private void menuProcessesOptionsParseActCtx_Click(object sender, EventArgs e) ProgramSettings.ParseActivationContext = !ProgramSettings.ParseActivationContext; } + /* Added */ + + private void menuResolveMethodNamesFromIDA_Click(object sender, EventArgs e) + { + ProgramSettings.ResolveMethodNamesFromIDA = !ProgramSettings.ResolveMethodNamesFromIDA; + } + + private void menuResolveMethodNamesFromIDAHard_Click(object sender, EventArgs e) + { + if (ProgramSettings.ResolveMethodDllFix) + ProgramSettings.ResolveMethodDllFix = !ProgramSettings.ResolveMethodDllFix; + ProgramSettings.ResolveMethodNamesFromIDAHard = !ProgramSettings.ResolveMethodNamesFromIDAHard; + } + + private void menuGetSequence_Click(object sender, EventArgs e) + { + if (!Directory.Exists("interfaces\\sequence")) Directory.CreateDirectory("interfaces\\sequence"); + CallSequenceForm callSequenceForm = new CallSequenceForm(); + callSequenceForm.Show(); + } + + private void menuResolveMethodDllFix_Click(object sender, EventArgs e) + { + if (ProgramSettings.ResolveMethodNamesFromIDAHard) + ProgramSettings.ResolveMethodNamesFromIDAHard = !ProgramSettings.ResolveMethodNamesFromIDAHard; + ProgramSettings.ResolveMethodDllFix = !ProgramSettings.ResolveMethodDllFix; + if (ProgramSettings.ResolveMethodDllFix) + { + DllFixForm dllFixForm = new DllFixForm(); + dllFixForm.ShowDialog(); + } + } + + private void menuProcesses_Popup(object sender, EventArgs e) + { + menuResolveMethodNamesFromIDA.Checked = ProgramSettings.ResolveMethodNamesFromIDA; + menuResolveMethodNamesFromIDAHard.Checked = ProgramSettings.ResolveMethodNamesFromIDAHard; + menuResolveMethodDllFix.Checked = ProgramSettings.ResolveMethodDllFix; + } + + /* Added */ + private void menuProcessesOptions_Popup(object sender, EventArgs e) { menuProcessesOptionsResolveMethodNames.Checked = ProgramSettings.ResolveMethodNames; @@ -1163,4 +1210,4 @@ private void menuFileImportInteropAssembly_Click(object sender, EventArgs e) EntryPoint.ShowError(this, ex); } } -} +} diff --git a/OleViewDotNet/Forms/ResolveMethod.cs b/OleViewDotNet/Forms/ResolveMethod.cs new file mode 100644 index 00000000..da0f9018 --- /dev/null +++ b/OleViewDotNet/Forms/ResolveMethod.cs @@ -0,0 +1,589 @@ +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using System.IO; +using System.Diagnostics; +using System.Text.RegularExpressions; +using System.Runtime.CompilerServices; + +namespace OleViewDotNet.Forms +{ + internal class ResolveMethod + { + public static String IDAPath = null; + public static List banList = null; + + // Find IDA path from Registry(Local Settings\\Software\\Microsoft\\Windows\\Shell\\MuiCache). + // If failed to find, create IDAPathForm to get IDA Path. + public static String GetIDAT() + { + + if (File.Exists("IDAPath")) + { + using (StreamReader reader = new StreamReader("IDAPath")) + { + IDAPath = reader.ReadToEnd(); + } + return IDAPath; + } + + string regKey = "Local Settings\\Software\\Microsoft\\Windows\\Shell\\MuiCache"; + try + { + using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(regKey)) + { + if (key != null) + { + foreach (string valueName in key.GetValueNames()) + { + object valueData = key.GetValue(valueName); + if (valueData is string stringValue && stringValue.Contains("Hex-Rays SA")) + { + String[] parts = valueName.Split('\\'); + String fileName = String.Join("\\", parts, 0, parts.Length - 1) + "\\idat64.exe"; + if (File.Exists(fileName)) + { + IDAPath = fileName; + } + } + } + } + } + } + catch (Exception ex) + { + } + + if (IDAPath == null) + { + MessageBox.Show("Failed to find idat64.exe."); + + IDAPathForm iDAPathForm = new IDAPathForm(); + iDAPathForm.ShowDialog(); + } + + using (StreamWriter writer = new StreamWriter("IDAPath")) + { + writer.Write(IDAPath); + } + + return IDAPath; + } + + // Find service DLL/EXE from Registry. + public static String GetBinaryPath(String serviceName) + { + String regKey = $"SYSTEM\\ControlSet001\\Services\\{serviceName}\\Parameters"; + object value = null; + try + { + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(regKey)) + { + if (key != null) + { + value = key.GetValue("ServiceDLL"); + } + } + if (value == null) + { + regKey = $"SYSTEM\\ControlSet001\\Services\\{serviceName}"; + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(regKey)) + { + if (key != null) + { + value = key.GetValue("ServiceDLL"); + } + } + } + if (value == null) + { + regKey = $"SYSTEM\\ControlSet001\\Services\\{serviceName}"; + using (RegistryKey key = Registry.LocalMachine.OpenSubKey(regKey)) + { + if (key != null) + { + value = key.GetValue("ImagePath"); + } + } + } + } + catch (Exception ex) + { + } + + if (value == null) + { + return null; + } + else + { + String binaryName = value.ToString().ToLower(); + binaryName = binaryName.Replace("%systemroot%", "C:\\Windows"); + binaryName = binaryName.Replace("\"", ""); + binaryName = binaryName.Replace("%programfiles%", "C:\\Program Files"); + binaryName = binaryName.Replace("%windir%", "C:\\Windows"); + binaryName = binaryName.Replace("\n", ""); + + String[] parts = binaryName.Split(' '); + if (parts[parts.Length - 1].EndsWith(".exe") || parts[parts.Length - 1].EndsWith(".dll")) + { + binaryName = String.Join(" ", parts); + } + else + { + binaryName = String.Join(" ", parts, 0, parts.Length - 1); + } + + return binaryName; + } + } + + // Copy service DLL/EXE to DLLs directory. + public static void CopyDLL(String binaryPath) + { + if (!Directory.Exists("DLLs")) Directory.CreateDirectory("DLLs"); + String binaryName = Path.GetFileName(binaryPath); + if (!File.Exists($"DLLs\\{binaryName}")) + { + + File.Copy(binaryPath, $"DLLs\\{binaryName}"); + } + } + + // Create .asm file for DLL/EXE using idat64.exe. + public static bool GenerateAsmFile(String binaryPath) + { + String binaryName = Path.GetFileName(binaryPath); + if (File.Exists($"DLLs\\{binaryName}" + ".asm")) return true; + CopyDLL(binaryPath); + Process process = new Process(); + if (IDAPath == null) process.StartInfo.FileName = GetIDAT(); + process.StartInfo.FileName = IDAPath; + process.StartInfo.Arguments = $"-A -B DLLs\\{binaryName}"; + process.StartInfo.CreateNoWindow = true; + process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + + try + { + process.Start(); + process.WaitForExit(); + int exitCode = process.ExitCode; + } + catch (Exception ex) + { + MessageBox.Show("Failed to resolve interfaces."); + } + process.Dispose(); + return true; + } + + // Get interface name from idl. + public static String GetInterfaceName(String idl) + { + String[] lines = idl.Split('\n'); + if (lines[0].StartsWith("[")) + { + foreach (String line in lines) + { + if (line.StartsWith("interface")) return line.Split(' ')[1]; + } + } + else + { + return lines[0].Split(' ')[2]; + } + return null; + } + + // Get last proc number(Proc{m}) from idl. + public static int GetLastProcNumFromIdl(String idl) + { + String[] lines = idl.Split('\n'); + for (int i = 0; i < lines.Length; i++) + { + if (lines[i].Contains("}")) + { + string pattern = @"(?<=Proc)\d+"; + + Match match = Regex.Match(lines[i - 1], pattern); + if (match.Success) + { + return int.Parse(match.Value); + } + else return -1; + } + } + return -1; + } + + // Get first proc number(Proc{n}) from idl. + public static int GetFirstProcNumFromIdl(String idl) + { + String[] lines = idl.Split('\n'); + for (int i = 0; i < lines.Length; i++) + { + if (lines[i].Contains("HRESULT")) + { + string pattern = @"(?<=Proc)\d+"; + + Match match = Regex.Match(lines[i], pattern); + if (match.Success) + { + return int.Parse(match.Value); + } + else return -1; + } + } + return -1; + } + + // parsing .asm file to find COM vtables and get method names. + // This method will find vtables with interface name. + public static List> GetMethodsFromIDA(String binaryPath, String idl) + { + List> ret = new List>(); + String[] asmLines = null; + String[] idlLines = idl.Split('\n'); + + int firstProcNum = GetFirstProcNumFromIdl(idl); + int lastProcNum = GetLastProcNumFromIdl(idl); + int idlMethodCnt; + if (firstProcNum == -1 || lastProcNum == -1) + { + return ret; + } + else idlMethodCnt = lastProcNum - firstProcNum + 1; + + String binaryName = Path.GetFileName(binaryPath); + String interfaceName = GetInterfaceName(idl); + if (!File.Exists($"DLLs\\{binaryName}.asm")) return ret; + using (StreamReader reader = new StreamReader($"DLLs\\{binaryName}.asm")) + { + String asm = reader.ReadToEnd(); + + if (!asm.Contains("QueryInterface") && !banList.Contains(binaryPath)) + { + using (StreamWriter writer = new StreamWriter("BanList", true)) + { + writer.WriteLine(binaryPath); + } + ResolveMethod.banList.Add(binaryPath); + } + asmLines = asm.Split('\n'); + } + int lineIndex = 0; + while (true) + { + List methods = new List { "QueryInterface", "AddRef", "Release" }; + if (lineIndex >= asmLines.Length) break; + String line = asmLines[lineIndex++]; + + if (line.Contains($"`vftable'{{for `{interfaceName}'}}")) + { + int nowIndex = lineIndex; + bool flag = false; + while (true) + { + line = asmLines[lineIndex++]; + if (line.Contains("?Release")) break; + if (lineIndex > nowIndex + 8) + { + lineIndex = nowIndex; + flag = true; + break; + } + } + if (flag) + { + continue; + } + while (true) + { + nowIndex = lineIndex; + line = asmLines[lineIndex++].Trim(' '); + if (line.Contains("?Release")) continue; + if (line.StartsWith("dq offset ??")) + { + break; + } + else if (line.StartsWith("dq offset ?")) + { + String[] parts; + String className = "", methodName = ""; + try + { + parts = line.Split(new String[] { " ; " }, StringSplitOptions.None)[1]. + Split(new String[] { "::" }, StringSplitOptions.None); + className = String.Join("::", parts, 0, parts.Length - 1); + methodName = line.Split(new String[] { "dq offset ?" }, StringSplitOptions.None)[1].Split('@')[0]; + } + catch (IndexOutOfRangeException ex) + { + methodName = line.Split('?')[1].Split('@')[0]; + } + methods.Add($"/*{className}*/{methodName}"); + } + else + { + break; + } + } + if (methods.Count >= 4 && (methods.Count - (lastProcNum - firstProcNum + 1) - 3) >= 0 && (methods.Count - (lastProcNum - firstProcNum + 1) - 3) <= 1) + { + ret.Add(methods); + } + } + } + return ret; + } + + // Parsing .asm file to find COM vtables and get method names. + // This method will search all vtables, and compare method count, each method's parameter count with idl to find appropriate interface. + public static List> GetMethodsFromCandidates(String binaryPath, String idl) + { + + List> ret = new List>(); + List methodsFromIdl = new List(); + String[] asmLines = null; + String[] idlLines = idl.Split('\n'); + + int firstProcNum = GetFirstProcNumFromIdl(idl); + int lastProcNum = GetLastProcNumFromIdl(idl); + int idlMethodCnt; + if (firstProcNum == -1 || lastProcNum == -1) + { + return ret; + } + else idlMethodCnt = lastProcNum - firstProcNum + 1; + + foreach (String line in idlLines) + { + if (line.Contains("HRESULT")) methodsFromIdl.Add(line); + } + + String binaryName = Path.GetFileName(binaryPath); + String interfaceName = GetInterfaceName(idl); + if (!File.Exists($"DLLs\\{binaryName}.asm")) return ret; + using (StreamReader reader = new StreamReader($"DLLs\\{binaryName}.asm")) + { + asmLines = reader.ReadToEnd().Split('\n'); + } + + int lineIndex = 0; + while (true) + { + List methods = new List { "QueryInterface", "AddRef", "Release" }; + if (lineIndex >= asmLines.Length) break; + String line = asmLines[lineIndex++]; + + if (line.Contains($"`vftable'")) + { + line = asmLines[lineIndex++]; + if (line.Contains("QueryInterface")) + { + int idlIndex = 0; + int startIndex = 3; + int diffCnt = 0; + int nowIndex = lineIndex; + int diffBase = 0; + bool flag = false; + while (true) + { + line = asmLines[lineIndex++]; + if (line.Contains("?Release")) break; + if (lineIndex > nowIndex + 8) + { + lineIndex = nowIndex; + flag = true; + break; + } + } + if (flag) + { + continue; + } + while (true) + { + nowIndex = lineIndex; + line = asmLines[lineIndex++].Trim(' '); + if (line.Contains("?Release")) continue; + if (line.StartsWith("dq offset ??")) + { + lineIndex = nowIndex; + break; + } + else if (line.StartsWith("dq offset ?")) + { + if (startIndex < firstProcNum) + { + startIndex++; + continue; + } + if (idlIndex == methodsFromIdl.Count) + { + flag = true; + break; + } + int pCnt1 = 0, pCnt2 = 0; + try + { + pCnt2 = CountParameters(methodsFromIdl[idlIndex].Trim()); + pCnt1 = CountParameters(line.Split(new String[] { " ; " }, StringSplitOptions.None)[1].Trim()); + } + catch (IndexOutOfRangeException ex) + { + pCnt1 = pCnt2; + } + + if (pCnt1 != pCnt2) + { + if (methodsFromIdl.Count == 1) + { + flag = true; + break; + } + diffCnt++; + if (methodsFromIdl.Count < 10) diffBase = 1; + else diffBase = methodsFromIdl.Count / 10; + if (diffCnt > diffBase) + { + flag = true; + break; + } + } + + String[] parts; + String className = "", methodName = ""; + try + { + parts = line.Split(new String[] { " ; " }, StringSplitOptions.None)[1]. + Split(new String[] { "::" }, StringSplitOptions.None); + className = String.Join("::", parts, 0, parts.Length - 1); + methodName = line.Split(new String[] { "dq offset ?" }, StringSplitOptions.None)[1].Split('@')[0]; + } + catch (IndexOutOfRangeException ex) + { + methodName = line.Split('?')[1].Split('@')[0]; + } + methods.Add($"/*{className}*/{methodName}"); + idlIndex++; + } + else if (line.Contains("purecall")) + { + lineIndex = nowIndex; + break; + } + else + { + lineIndex = nowIndex; + break; + } + } + if (methods.Count - methodsFromIdl.Count - 3 > 1 || methods.Count - methodsFromIdl.Count - 3 < 0) flag = true; + if (methodsFromIdl.Count >= 4 && ((methods.Count - methodsFromIdl.Count - 3) >= 0 && (methods.Count - methodsFromIdl.Count - 3) <= 1)) flag = false; + if (methods.Count == 5 && methods[3].EndsWith("CreateInstance") && methods[4].EndsWith("LockServer")) flag = true; + if (methods.Count >= 20 && ((methods.Count - methodsFromIdl.Count - 3) >= 0 && (methods.Count - methodsFromIdl.Count - 3) <= 5)) flag = true; + if (!flag) + { + ret.Add(methods); + } + } + } + } + return ret; + } + + // Counts parameters from each methods in idl. + public static int CountParameters(string functionDeclaration) + { + if (functionDeclaration.Trim().EndsWith("(void)")) + return 0; + + string functionDefinition = Regex.Replace(functionDeclaration, @"<.*?>", ""); + + Match match = Regex.Match(functionDefinition, @"([\w:~]+|`.*?')\s*\((.*?)\)\s*(?:const)?(?:override)?;?$"); + if (!match.Success) + return 0; + + string functionName = match.Groups[1].Value; + string parameters = match.Groups[2].Value; + + if (string.IsNullOrWhiteSpace(parameters)) + return 0; + + parameters = Regex.Replace(parameters, @"\[([^\]]*)\]", m => m.Groups[0].Value.Replace(",", "")); + + parameters = Regex.Replace(parameters, @"<([^>]*)>", m => m.Groups[0].Value.Replace(",", "")); + + var paramList = parameters.Split(',').Select(p => p.Replace("", ",")).ToList(); + + return paramList.Count(p => !string.IsNullOrWhiteSpace(p)); + } + + // Changes idl's method name from Proc{n} to real method name and returns it. + public static String ConvertMethodName(String idl, List methods) + { + if (methods.Count == 0) return idl + "\n"; + String result = ""; + int index = 3; + String[] lines = idl.Split('\n'); + + String funcStyle; + + if (lines[0][0] == '[') + { + funcStyle = "HRESULT Proc"; + } + else + { + funcStyle = "__stdcall Proc"; + } + foreach (String line in lines) + { + String now = line + "\n"; + if (line.Contains(funcStyle)) + { + if (index == methods.Count) continue; + now = line.Split(new String[] { " Proc" }, StringSplitOptions.None)[0] + " "; + now += methods[index++]; + foreach (String tmp in line.Split('(').Skip(1).ToArray()) + { + now += "(" + tmp; + } + now += "\n"; + } + result += now; + } + return result; + } + + // Initialize banList. BanList is a DLL/EXE list that will not be parsed. + public static void BanListInit() + { + if (!File.Exists("BanList")) + { + String template = "C:\\WINDOWS\\SYSTEM32\\MSASN1.dll\r\nC:\\WINDOWS\\SYSTEM32\\dxcore.dll\r\nC:\\WINDOWS\\SYSTEM32\\twinapi.appcore.dll\r\nC:\\WINDOWS\\SYSTEM32\\wevtapi.dll\r\nC:\\WINDOWS\\SYSTEM32\\winsta.dll\r\nC:\\WINDOWS\\System32\\WINSTA.dll\r\nC:\\WINDOWS\\System32\\profapi.dll\r\nC:\\WINDOWS\\system32\\MSASN1.dll\r\nC:\\WINDOWS\\system32\\ncryptprov.dll\r\nC:\\Windows\\System32\\Microsoft.Bluetooth.Proxy.dll\r\nC:\\Windows\\System32\\SspiCli.dll\r\nC:\\Windows\\System32\\Windows.Security.Authentication.OnlineId.dll\r\nC:\\Windows\\System32\\XmlLite.dll\r\nC:\\Windows\\System32\\msxml6.dll\r\nC:\\Windows\\System32\\vaultcli.dll\r\nc:\\windows\\system32\\BrokerLib.dll\r\nc:\\windows\\system32\\PROPSYS.dll\r\nc:\\windows\\system32\\WMICLNT.dll\r\nc:\\windows\\system32\\fwbase.dll\r\nc:\\windows\\system32\\wlanapi.dll\r\nC:\\WINDOWS\\SYSTEM32\\IPHLPAPI.DLL\r\nC:\\WINDOWS\\SYSTEM32\\bi.dll\r\nC:\\WINDOWS\\SYSTEM32\\capauthz.dll\r\nC:\\WINDOWS\\System32\\CRYPTBASE.DLL\r\nC:\\WINDOWS\\System32\\NTASN1.dll\r\nC:\\WINDOWS\\System32\\SETUPAPI.dll\r\nC:\\WINDOWS\\System32\\SHLWAPI.dll\r\nC:\\WINDOWS\\System32\\SspiCli.dll\r\nC:\\WINDOWS\\System32\\fwpuclnt.dll\r\nC:\\WINDOWS\\System32\\ncrypt.dll\r\nC:\\WINDOWS\\System32\\netutils.dll\r\nC:\\WINDOWS\\System32\\sspicli.dll\r\nC:\\WINDOWS\\System32\\wkscli.dll\r\nC:\\Windows\\System32\\AppXDeploymentClient.dll\r\nc:\\windows\\system32\\WppRecorderUM.dll\r\nc:\\windows\\system32\\netutils.dll\r\nC:\\WINDOWS\\SYSTEM32\\netjoin.dll\r\nC:\\WINDOWS\\SYSTEM32\\netutils.dll\r\nC:\\WINDOWS\\System32\\CRYPTBASE.dll\r\nC:\\WINDOWS\\System32\\DPAPI.DLL\r\nC:\\WINDOWS\\System32\\SHCORE.dll\r\nC:\\WINDOWS\\System32\\SHELL32.dll\r\nC:\\WINDOWS\\System32\\netprofm.dll\r\nC:\\WINDOWS\\system32\\execmodelproxy.dll\r\nC:\\Windows\\System32\\Windows.Networking.Connectivity.dll\r\nC:\\Windows\\System32\\Windows.Web.dll\r\nC:\\Windows\\System32\\iertutil.dll\r\nC:\\Windows\\System32\\msvcp110_win.dll\r\nC:\\Windows\\System32\\netutils.dll\r\nC:\\Windows\\System32\\srvcli.dll\r\nC:\\Windows\\System32\\usermgrproxy.dll\r\nc:\\windows\\system32\\DNSAPI.dll\r\nc:\\windows\\system32\\DSROLE.dll\r\nc:\\windows\\system32\\MobileNetworking.dll\r\nc:\\windows\\system32\\SYSNTFY.dll\r\nc:\\windows\\system32\\WINSTA.dll\r\nc:\\windows\\system32\\WTSAPI32.dll\r\nc:\\windows\\system32\\fwpuclnt.dll\r\nc:\\windows\\system32\\AUTHZ.dll\r\nc:\\windows\\system32\\NTASN1.dll\r\nc:\\windows\\system32\\ncrypt.dll\r\nC:\\WINDOWS\\SYSTEM32\\wlanapi.dll\r\nC:\\WINDOWS\\System32\\DEVOBJ.dll\r\nC:\\WINDOWS\\system32\\ncryptsslp.dll\r\nC:\\WINDOWS\\system32\\schannel.DLL\r\nC:\\WINDOWS\\system32\\sspicli.dll\r\nC:\\Windows\\System32\\taskschd.dll\r\nc:\\windows\\system32\\WINNSI.DLL\r\nC:\\WINDOWS\\SYSTEM32\\SspiCli.dll\r\nC:\\WINDOWS\\SYSTEM32\\profapi.dll\r\nC:\\WINDOWS\\System32\\IMM32.DLL\r\nC:\\WINDOWS\\System32\\coml2.dll\r\nC:\\Windows\\System32\\CapabilityAccessManagerClient.dll\r\nC:\\Windows\\System32\\Windows.StateRepositoryPS.dll\r\nC:\\WINDOWS\\SYSTEM32\\windows.staterepositoryclient.dll\r\nC:\\WINDOWS\\System32\\WINTRUST.dll\r\nC:\\WINDOWS\\system32\\CRYPTBASE.dll\r\nC:\\Windows\\System32\\WinTypes.dll\r\nc:\\windows\\system32\\webio.dll\r\nC:\\WINDOWS\\SYSTEM32\\MobileNetworking.dll\r\nC:\\WINDOWS\\System32\\ADVAPI32.dll\r\nC:\\Windows\\System32\\twinapi.appcore.dll\r\nc:\\windows\\system32\\UMPDC.dll\r\nC:\\WINDOWS\\SYSTEM32\\cryptsp.dll\r\nC:\\Windows\\System32\\OneCoreCommonProxyStub.dll\r\nc:\\windows\\system32\\WINHTTP.dll\r\nc:\\windows\\system32\\profapi.dll\r\nC:\\WINDOWS\\System32\\npmproxy.dll\r\nc:\\windows\\system32\\SspiCli.dll\r\nc:\\windows\\system32\\msvcp110_win.dll\r\nC:\\WINDOWS\\System32\\MSASN1.dll\r\nc:\\windows\\system32\\DEVOBJ.dll\r\nC:\\WINDOWS\\SYSTEM32\\WINSTA.dll\r\nC:\\Windows\\System32\\OneCoreUAPCommonProxyStub.dll\r\nC:\\Windows\\System32\\rasadhlp.dll\r\nC:\\WINDOWS\\SYSTEM32\\windows.staterepositorycore.dll\r\nC:\\WINDOWS\\System32\\shlwapi.dll\r\nC:\\WINDOWS\\system32\\rsaenh.dll\r\nc:\\windows\\system32\\USERENV.dll\r\nC:\\WINDOWS\\SYSTEM32\\DNSAPI.dll\r\nC:\\WINDOWS\\SYSTEM32\\WINNSI.DLL\r\nC:\\WINDOWS\\SYSTEM32\\policymanager.dll\r\nC:\\WINDOWS\\SYSTEM32\\rmclient.dll\r\nC:\\WINDOWS\\SYSTEM32\\windows.storage.dll\r\nC:\\WINDOWS\\SYSTEM32\\dhcpcsvc.DLL\r\nC:\\WINDOWS\\SYSTEM32\\dhcpcsvc6.DLL\r\nC:\\WINDOWS\\SYSTEM32\\gpapi.dll\r\nC:\\WINDOWS\\SYSTEM32\\usermgrcli.dll\r\nC:\\WINDOWS\\SYSTEM32\\wtsapi32.dll\r\nC:\\WINDOWS\\SYSTEM32\\wintypes.dll\r\nC:\\WINDOWS\\System32\\ole32.dll\r\nc:\\windows\\system32\\IPHLPAPI.DLL\r\nC:\\WINDOWS\\SYSTEM32\\UMPDC.dll\r\nC:\\WINDOWS\\SYSTEM32\\ntmarta.dll\r\nC:\\WINDOWS\\system32\\mswsock.dll\r\nC:\\WINDOWS\\System32\\svchost.exe\r\nC:\\WINDOWS\\System32\\CRYPT32.dll\r\nC:\\WINDOWS\\SYSTEM32\\powrprof.dll\r\nC:\\WINDOWS\\System32\\NSI.dll\r\nC:\\WINDOWS\\SYSTEM32\\cfgmgr32.dll\r\nC:\\WINDOWS\\System32\\WS2_32.dll\r\nC:\\WINDOWS\\System32\\shcore.dll\r\nC:\\WINDOWS\\System32\\advapi32.dll\r\nC:\\WINDOWS\\system32\\svchost.exe\r\nC:\\WINDOWS\\System32\\OLEAUT32.dll\r\nC:\\WINDOWS\\System32\\clbcatq.dll\r\nC:\\WINDOWS\\System32\\user32.dll\r\nC:\\WINDOWS\\System32\\GDI32.dll\r\nC:\\WINDOWS\\System32\\gdi32full.dll\r\nC:\\WINDOWS\\System32\\win32u.dll\r\nC:\\WINDOWS\\SYSTEM32\\kernel.appcore.dll\r\nC:\\WINDOWS\\System32\\bcryptPrimitives.dll\r\nC:\\WINDOWS\\SYSTEM32\\ntdll.dll\r\nC:\\WINDOWS\\System32\\KERNEL32.DLL\r\nC:\\WINDOWS\\System32\\KERNELBASE.dll\r\nC:\\WINDOWS\\System32\\RPCRT4.dll\r\nC:\\WINDOWS\\System32\\bcrypt.dll\r\nC:\\WINDOWS\\System32\\combase.dll\r\nC:\\WINDOWS\\System32\\msvcp_win.dll\r\nC:\\WINDOWS\\System32\\msvcrt.dll\r\nC:\\WINDOWS\\System32\\sechost.dll\r\nC:\\WINDOWS\\System32\\ucrtbase.dll\r\nC:\\WINDOWS\\System32\\d3d11.dll\r\nC:\\WINDOWS\\System32\\d2d1.dll\r\nc:\\windows\\system32\\CLIPC.dll\r\nC:\\Windows\\System32\\wuapi.dll\r\nC:\\WINDOWS\\uus\\AMD64\\uusbrain.dll\r\nC:\\Windows\\System32\\wups.dll\r\nC:\\WINDOWS\\SYSTEM32\\gamestreamingext.dll\r\nc:\\windows\\system32\\VERSION.dll\r\nC:\\WINDOWS\\SYSTEM32\\wiatrace.dll\r\nC:\\WINDOWS\\system32\\msv1_0.DLL\r\nC:\\WINDOWS\\system32\\NtlmShared.dll\r\nC:\\WINDOWS\\SYSTEM32\\deviceassociation.dll\r\nC:\\WINDOWS\\SYSTEM32\\webservices.dll\r\nC:\\WINDOWS\\SYSTEM32\\HTTPAPI.dll\r\nC:\\WINDOWS\\System32\\verifier.dll\r\nc:\\windows\\system32\\logoncli.dll\r\nc:\\windows\\system32\\NETAPI32.dll\r\nC:\\WINDOWS\\SYSTEM32\\PeerDist.dll\r\nc:\\windows\\system32\\VirtDisk.dll\r\nc:\\windows\\system32\\SXSHARED.dll\r\nC:\\WINDOWS\\system32\\defragproxy.dll\r\nC:\\WINDOWS\\system32\\ESENT.dll\r\nC:\\Windows\\System32\\TieringEngineProxy.dll\r\nc:\\windows\\system32\\profsvc.dll\r\nC:\\WINDOWS\\System32\\SAMLIB.dll\r\nC:\\WINDOWS\\SYSTEM32\\profext.dll\r\nC:\\WINDOWS\\SYSTEM32\\AcLayers.DLL\r\nC:\\WINDOWS\\SYSTEM32\\HID.DLL\r\nC:\\WINDOWS\\SYSTEM32\\directxdatabasehelper.dll\r\nC:\\Windows\\System32\\PerceptionSimulation\\SixDofControllerManager.ProxyStubs.dll\r\nC:\\Windows\\System32\\PerceptionSimulation\\VirtualDisplayManager.ProxyStubs.dll\r\nC:\\WINDOWS\\system32\\sxproxy.dll\r\nC:\\WINDOWS\\System32\\bcd.dll\r\nC:\\WINDOWS\\System32\\VssTrace.DLL\r\nc:\\windows\\system32\\securityhealthservice.exe\r\nc:\\windows\\system32\\ESENT.dll\r\nc:\\windows\\system32\\dsclient.dll\r\nC:\\Windows\\System32\\WalletProxy.dll\r\nc:\\windows\\system32\\OneX.DLL\r\nc:\\windows\\system32\\eappprxy.dll\r\nc:\\windows\\system32\\WLANSEC.dll\r\nc:\\windows\\system32\\WMI.dll\r\nC:\\WINDOWS\\System32\\wlansvcpal.dll\r\nC:\\WINDOWS\\System32\\TetheringIeProvider.dll\r\nC:\\WINDOWS\\SYSTEM32\\wlgpclnt.dll\r\nC:\\WINDOWS\\system32\\kerberos.DLL\r\nC:\\WINDOWS\\system32\\Kerb3961.dll\r\nC:\\WINDOWS\\SYSTEM32\\SystemEventsBrokerClient.dll\r\nc:\\windows\\system32\\nvagent.dll\r\nc:\\windows\\system32\\NetSetupApi.dll\r\nC:\\WINDOWS\\System32\\vmsifproxystub.dll\r\nc:\\windows\\system32\\lfsvc.dll\r\nC:\\Windows\\System32\\LocationFrameworkPS.dll\r\nC:\\WINDOWS\\system32\\mi.dll\r\nC:\\WINDOWS\\system32\\fveapi.dll\r\nC:\\WINDOWS\\system32\\cscapi.dll\r\nC:\\WINDOWS\\SYSTEM32\\samcli.dll\r\nC:\\WINDOWS\\SYSTEM32\\NCObjAPI.DLL\r\nC:\\WINDOWS\\System32\\EventAggregation.dll\r\nC:\\WINDOWS\\system32\\keepaliveprovider.dll\r\nC:\\WINDOWS\\System32\\winsqlite3.dll\r\nC:\\WINDOWS\\System32\\LINKINFO.dll\r\nC:\\WINDOWS\\system32\\SFC.DLL\r\nC:\\WINDOWS\\system32\\sfc_os.DLL\r\nc:\\windows\\system32\\dsclient.dllc:\\windows\\system32\\wpnuserservice.dll\r\nC:\\Windows\\System32\\StateRepository.Core.dll\r\nc:\\windows\\system32\\wpnuserservice.dll\r\nC:\\WINDOWS\\SYSTEM32\\edputil.dll\r\nC:\\WINDOWS\\system32\\Secur32.dll\r\nC:\\WINDOWS\\SYSTEM32\\bcp47mrm.dll\r\nC:\\WINDOWS\\System32\\TimeBrokerClient.dll\r\nC:\\Windows\\System32\\ShellCommonCommonProxyStub.dll"; + using (StreamWriter writer = new StreamWriter("BanList")) + { + writer.Write(template); + writer.Flush(); + } + } + banList = new List(); + using (StreamReader reader = new StreamReader("BanList")) + { + while (true) + { + String nowLine = reader.ReadLine(); + if (nowLine == null) break; + banList.Add(nowLine); + } + } + } + } +} diff --git a/OleViewDotNet/Forms/ResolvingForm.Designer.cs b/OleViewDotNet/Forms/ResolvingForm.Designer.cs new file mode 100644 index 00000000..da4dce33 --- /dev/null +++ b/OleViewDotNet/Forms/ResolvingForm.Designer.cs @@ -0,0 +1,103 @@ +using System.Windows.Forms; + +namespace OleViewDotNet.Forms +{ + partial class ResolvingForm + { + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.ProgressBar progressBar1; + + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.progressBar1 = new System.Windows.Forms.ProgressBar(); + this.label3 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // label1 + // + this.label1.Font = new System.Drawing.Font("굴림", 12F); + this.label1.Location = new System.Drawing.Point(12, 9); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(479, 31); + this.label1.TabIndex = 0; + this.label1.Text = "Trying to resolve from"; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // label2 + // + this.label2.Font = new System.Drawing.Font("굴림", 10F); + this.label2.Location = new System.Drawing.Point(-1, 78); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(504, 19); + this.label2.TabIndex = 1; + this.label2.Text = "Generating ASM File..."; + this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // progressBar1 + // + this.progressBar1.Location = new System.Drawing.Point(12, 100); + this.progressBar1.Maximum = 10000; + this.progressBar1.Name = "progressBar1"; + this.progressBar1.Size = new System.Drawing.Size(479, 23); + this.progressBar1.Style = System.Windows.Forms.ProgressBarStyle.Continuous; + this.progressBar1.TabIndex = 2; + // + // label3 + // + this.label3.Location = new System.Drawing.Point(15, 52); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(476, 12); + this.label3.TabIndex = 3; + this.label3.Text = "May takes several minutes..."; + this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // ResolvingForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(503, 135); + this.Controls.Add(this.label3); + this.Controls.Add(this.progressBar1); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "ResolvingForm"; + this.Text = "ResolvingForm"; + this.ResumeLayout(false); + + } + + #endregion + + private Label label3; + } +} \ No newline at end of file diff --git a/OleViewDotNet/Forms/ResolvingForm.cs b/OleViewDotNet/Forms/ResolvingForm.cs new file mode 100644 index 00000000..c1afe09b --- /dev/null +++ b/OleViewDotNet/Forms/ResolvingForm.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Threading; + +namespace OleViewDotNet.Forms +{ + + // This form is for ResolveMethod. + public partial class ResolvingForm : Form + { + public bool resolveDone; + public ResolvingForm() + { + InitializeComponent(); + } + + public ResolvingForm(List binaryPath) + { + InitializeComponent(); + this.progressBar1.Step = 10000 / (binaryPath.Count * 3); + this.resolveDone = false; + this.FormClosed += MainFormClosed; + } + + private void MainFormClosed(object sender, FormClosedEventArgs e) + { + resolveDone = true; + } + + public void Update(String label1, String label2) + { + if (label1 != null) + { + if (this.label1.InvokeRequired) this.label1.BeginInvoke(new Action(() => this.label1.Text = label1)); + else this.label1.Text = label1; + } + + if (label2 != null) + { + if (this.label2.InvokeRequired) this.label2.BeginInvoke(new Action(() => this.label2.Text = label2)); + else this.label2.Text = label2; + } + else if (label2 != null) this.label2.Text = label2; + + if (this.progressBar1.InvokeRequired) this.progressBar1.BeginInvoke(new Action(() => this.progressBar1.PerformStep())); + else this.progressBar1.PerformStep(); + } + } +} diff --git a/OleViewDotNet/Forms/ResolvingForm.resx b/OleViewDotNet/Forms/ResolvingForm.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/OleViewDotNet/Forms/ResolvingForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/OleViewDotNet/Forms/SourceCodeViewerControl.Designer.cs b/OleViewDotNet/Forms/SourceCodeViewerControl.Designer.cs index 07f9478b..ca9895c5 100644 --- a/OleViewDotNet/Forms/SourceCodeViewerControl.Designer.cs +++ b/OleViewDotNet/Forms/SourceCodeViewerControl.Designer.cs @@ -177,6 +177,15 @@ private void InitializeComponent() } + /* Added */ + public void ChangeToCpp() + { + this.toolStripMenuItemIDLOutputType.Checked = false; + this.toolStripMenuItemCppOutputType.Checked = true; + this.toolStripMenuItemGenericOutputType.Checked = false; + } + /* Added */ + #endregion private ICSharpCode.TextEditor.TextEditorControl textEditor; diff --git a/OleViewDotNet/Forms/SourceCodeViewerControl.cs b/OleViewDotNet/Forms/SourceCodeViewerControl.cs index def9b6e1..4ba03624 100644 --- a/OleViewDotNet/Forms/SourceCodeViewerControl.cs +++ b/OleViewDotNet/Forms/SourceCodeViewerControl.cs @@ -24,6 +24,15 @@ using System.IO; using System.Windows.Forms; +/* Added */ +using Microsoft.Win32; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.ServiceProcess; +using System.Threading; +using System.Threading.Tasks; +/* Added */ + namespace OleViewDotNet.Forms; internal partial class SourceCodeViewerControl : UserControl @@ -36,6 +45,10 @@ internal partial class SourceCodeViewerControl : UserControl private bool m_interfaces_only; private bool m_hide_parsing_options; + /* Added */ + public bool m_isReally = true; + /* Added */ + private class NdrTextMarker : TextMarker { public INdrNamedObject Tag { get; } @@ -71,6 +84,15 @@ private void SetText(string text, IEnumerable tags) textEditor.Refresh(); } + /* Added */ + // This is for SetText without texteditor's tag. (from oleviewdotnet v1.14) + private void SetText(string text) + { + textEditor.Text = text.TrimEnd(); + textEditor.Refresh(); + } + /* Added */ + internal void SetRegistry(COMRegistry registry) { m_registry = registry; @@ -97,7 +119,14 @@ internal void Format(COMSourceCodeBuilder builder, ICOMSourceCodeFormattable for } } - internal void Format() + /* Added */ + ResolvingForm resolvingForm = null; + + /* Added */ + + + //internal void Format() + internal String Format() { COMSourceCodeBuilder builder = new(m_registry) { @@ -115,10 +144,320 @@ internal void Format() builder.AppendLine(m_selected_obj is null ? "No formattable object selected" : $"'{m_selected_obj}' is not formattable."); + SetText(builder.ToString(), builder.Tags); + return builder.ToString(); + } + /* Added */ + + // below code is for ResolveMethod. + if (ResolveMethod.banList == null) ResolveMethod.BanListInit(); + + if (builder.ToString().StartsWith("ERROR:") || + builder.ToString().Split('\n')[0].StartsWith("struct") || builder.ToString().Split('\n')[1].StartsWith("struct") || + builder.ToString().Split('\n')[0].StartsWith("union") || builder.ToString().Split('\n')[1].StartsWith("union") || + builder.ToString().Split('\n')[0].StartsWith("[switch_type") || builder.ToString().Split('\n')[1].StartsWith("[switch_type") || + builder.ToString().Split('\n')[0].Contains("needs to be parsed")) + { + SetText(builder.ToString(), builder.Tags); + return builder.ToString(); + } + + if (!m_isReally || (!ProgramSettings.ResolveMethodNamesFromIDA && !ProgramSettings.ResolveMethodNamesFromIDAHard) || + GetIid() == "00000001-0000-0000-C000-000000000046") + { + SetText(builder.ToString(), builder.Tags); + return builder.ToString(); + } + + String resultIDL = ""; + + List binaryPath = new List(); + + if (ProgramSettings.ResolveMethodDllFix) + { + binaryPath.Add(ProgramSettings.FixedDll); + } + else + { + String serviceName = GetServiceName(); + if (serviceName == null) + { + resultIDL = "// Resolve Failed. Failed to get service name.\n" + builder.ToString(); + SetText(resultIDL); + return resultIDL; + } + String binary = ResolveMethod.GetBinaryPath(serviceName); + if (binary == null) + { + resultIDL = "// Resolve Failed. Failed to get binary path.\n" + builder.ToString(); + SetText(resultIDL); + return resultIDL; + } + binaryPath.Add(binary); + } + resultIDL = Resolve(builder.ToString(), binaryPath); + + if (resultIDL == null) + { + binaryPath.Clear(); + if (ProgramSettings.ResolveMethodNamesFromIDAHard) + { + + String serviceName = GetServiceName(); + if (serviceName == null) + { + resultIDL = "// Resolve Failed. Failed to get service name.\n" + builder.ToString(); + SetText(resultIDL); + return resultIDL; + } + int pid = GetServicePid(serviceName); + if (pid == -1) + { + resultIDL = "// Resolve Hard Failed. Failed to find service pid.\n" + builder.ToString(); + SetText(resultIDL); + return resultIDL; + } + + Process process = Process.GetProcessById(pid); + if (process == null) + { + MessageBox.Show("process is null?"); + return builder.ToString(); + } + try + { + for (int i = 0; i < process.Modules.Count; i++) + { + bool flag = true; + for (int j = 0; j < ResolveMethod.banList.Count; j++) + { + if (Path.GetFileName(ResolveMethod.banList[j]).ToLower() + == Path.GetFileName(process.Modules[i].FileName).ToLower()) + { + flag = false; + break; + } + } + if (flag) binaryPath.Add(process.Modules[i].FileName); + } + } + catch (System.ComponentModel.Win32Exception) + { + resultIDL = "// Resolve Hard Failed. Access Denied.\n" + builder.ToString(); + SetText(resultIDL); + return resultIDL; + } + resultIDL = Resolve(builder.ToString(), binaryPath); + } + } + + if (resultIDL == null) + { + resultIDL = $"// Resolve Failed.\n"; + resultIDL += builder.ToString(); + } + + SetText(resultIDL); + return resultIDL; + } + + /* Added */ + // Finds method name with ResolveMethod, changes method name from Proc{n} to real method name and returns it. + internal String Resolve(String idl, List binaryPath) + { + resolvingForm = new ResolvingForm(binaryPath); + Thread uiThread = new Thread(StartResolvingForm); + uiThread.Start(); + + List>> candidates = new List>>(); + String resultIDL = ""; + + for (int i = 0; i < binaryPath.Count; i++) + { + if (i < binaryPath.Count && resolvingForm.resolveDone) + { + return null; + } + resolvingForm.Update($"Trying to resolve from {Path.GetFileName(binaryPath[i])} ({i+1}/{binaryPath.Count})", $"Generating ASM File..."); + if (!ResolveMethod.GenerateAsmFile(binaryPath[i])) + { + resolvingForm.Update(null, null); + resolvingForm.Update(null, null); + Application.DoEvents(); + continue; + } + + resolvingForm.Update(null, $"Searching VTables..."); + Application.DoEvents(); + + List> methods = ResolveMethod.GetMethodsFromIDA(binaryPath[i], idl); + List> methods2 = ResolveMethod.GetMethodsFromCandidates(binaryPath[i], idl); + foreach (List method in methods2) methods.Add(method); + + resolvingForm.Update(null, $"Converting Method Names..."); + Application.DoEvents(); + + if (methods.Count > 0) + { + candidates.Add(methods); + resultIDL += $"// {binaryPath[i]}\n"; + for (int j = 0; j < methods.Count; j++) + { + resultIDL += $"// Candidates {j + 1}\n"; + resultIDL += ResolveMethod.ConvertMethodName(idl, methods[j]); + } + } + + } + resolvingForm.Close(); + + if (candidates.Count == 0) + { + resultIDL = null; + } + return resultIDL; + } + + // For UI thread. + internal void StartResolvingForm() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + + Application.Run(resolvingForm); + } + + // Get iid from interface idl. + internal String GetIid() + { + COMSourceCodeBuilder builder = new(m_registry) + { + InterfacesOnly = m_interfaces_only, + HideComments = m_hide_comments, + OutputType = m_output_type + }; + + if (m_formattable_obj?.IsFormattable == true) + { + Format(builder, m_formattable_obj); } - SetText(builder.ToString(), builder.Tags); + else + { + return null; + } + + String now = builder.ToString(); + if (now[0] == '[') + { + String[] nows = now.Split('\n'); + for (int i = 0; i < nows.Length; i++) + { + if (nows[i].Contains("uuid")) + { + return nows[i].Split('(')[1].Split(')')[0]; + } + } + } + else + { + return now.Split('\"')[1]; + } + return null; } + // Get iid by GetIid method and get service name from Registry.(HKEY_CLASSES_ROOT\CLSID) + internal String GetServiceName() + { + string clsid = null; + try + { + using (StreamReader reader = new StreamReader($"interfaces\\iids\\{this.GetIid()}.txt")) + { + clsid = reader.ReadToEnd(); + } + } + catch (Exception e) { return null; } + string regKey = $"CLSID\\{{{clsid}}}"; + String appId = null; + try + { + using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(regKey)) + { + if (key != null) + { + object appIdValue = key.GetValue("AppID"); + if (appIdValue != null) + { + appId = appIdValue.ToString(); + } + } + } + } + catch (Exception ex) + { + return null; + } + + if (appId == null) return null; + regKey = $"AppID\\{appId}"; + try + { + using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(regKey)) + { + if (key != null) + { + object serviceName = key.GetValue("LocalService"); + if (serviceName != null) + { + return serviceName.ToString(); + } + } + } + } + catch (Exception ex) + { + return null; + } + return null; + } + + // Find pid of service. + internal int GetServicePid(String serviceName) + { + + string query = $"SELECT Name,ProcessId FROM Win32_Service WHERE Name LIKE '{serviceName}%'"; + using (var searcher = new System.Management.ManagementObjectSearcher(query)) + { + foreach (var obj in searcher.Get()) + { + try + { + ServiceController service = new ServiceController((String)obj["Name"]); + + if (service.Status == ServiceControllerStatus.Stopped) + { + service.Start(); + service.WaitForStatus(ServiceControllerStatus.Running); + } + } + catch (InvalidOperationException ex) + { + continue; + } + catch (Exception ex) + { + continue; + } + if (searcher.Get().Count == 1) return Convert.ToInt32(obj["ProcessId"]); + if ((String)(obj["Name"]) == serviceName) continue; + return Convert.ToInt32(obj["ProcessId"]); + } + } + return -1; + } + + /* Added */ + internal object SelectedObject { get => m_selected_obj; diff --git a/OleViewDotNet/ProgramSettings.cs b/OleViewDotNet/ProgramSettings.cs index 1548f2f2..a2d10dca 100644 --- a/OleViewDotNet/ProgramSettings.cs +++ b/OleViewDotNet/ProgramSettings.cs @@ -1,25 +1,25 @@ -// This file is part of OleViewDotNet. -// Copyright (C) James Forshaw 2014, 2016 -// -// OleViewDotNet is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// OleViewDotNet 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 General Public License -// along with OleViewDotNet. If not, see . - -using OleViewDotNet.Utilities; -using System; -using System.IO; -using System.Runtime.Serialization; -using System.Xml; - +// This file is part of OleViewDotNet. +// Copyright (C) James Forshaw 2014, 2016 +// +// OleViewDotNet is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// OleViewDotNet 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 General Public License +// along with OleViewDotNet. If not, see . + +using OleViewDotNet.Utilities; +using System; +using System.IO; +using System.Runtime.Serialization; +using System.Xml; + namespace OleViewDotNet; public static class ProgramSettings @@ -58,6 +58,17 @@ private sealed class ConfigFile [DataMember] public bool SaveProxyNamesOnExit { get; set; } + /* Added */ + [DataMember] + public bool ResolveMethodNamesFromIDA { get; set; } + [DataMember] + public bool ResolveMethodNamesFromIDAHard { get; set; } + [DataMember] + public bool ResolveMethodDllFix { get; set; } + [DataMember] + public String FixedDll { get; set; } + /* Added */ + public static ConfigFile Load() { try @@ -79,8 +90,8 @@ public void Save() string data_path = Path.Combine(GetAppDataDirectory()); Directory.CreateDirectory(data_path); XmlWriterSettings settings = new() - { - Indent = true + { + Indent = true }; using XmlWriter writer = XmlWriter.Create(Path.Combine(data_path, "config.xml"), settings); @@ -179,6 +190,37 @@ public static bool ParseActivationContext set => _config.Value.ParseActivationContext = value; } + /* Added */ + // This setting is for ResolveMethod. + public static bool ResolveMethodNamesFromIDA + { + get => _config.Value.ResolveMethodNamesFromIDA; + set => _config.Value.ResolveMethodNamesFromIDA = value; + } + + // This setting is for ResolveMethod(Hard). + // If this setting is enabled, oleviewdotnet will get imported DLL/EXE list from service process and analyze all. + public static bool ResolveMethodNamesFromIDAHard + { + get => _config.Value.ResolveMethodNamesFromIDAHard; + set => _config.Value.ResolveMethodNamesFromIDAHard = value; + } + + // This setting is for ResolveMethod(Fixed). + // If this setting is enabled, oleviewdotnet will analyze fixed DLL/EXE only. + public static bool ResolveMethodDllFix + { + get => _config.Value.ResolveMethodDllFix; + set => _config.Value.ResolveMethodDllFix = value; + } + + public static String FixedDll + { + get => _config.Value.FixedDll; + set => _config.Value.FixedDll = value; + } + /* Added */ + public static bool AlwaysShowSourceCode { get => _config.Value.AlwaysShowSourceCode; @@ -198,19 +240,19 @@ public static bool SaveProxyNamesOnExit } public static void Save() - { + { _config.Value.Save(); } - public static string GetAppDataDirectory() - { + public static string GetAppDataDirectory() + { return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), - "OleViewDotNet", AppUtilities.CurrentArchitecture.ToString()); - } - - public static string GetTypeLibDirectory() - { - return Path.Combine(GetAppDataDirectory(), "typelib"); + "OleViewDotNet", AppUtilities.CurrentArchitecture.ToString()); + } + + public static string GetTypeLibDirectory() + { + return Path.Combine(GetAppDataDirectory(), "typelib"); } public static string GetProxyDirectory() @@ -218,14 +260,14 @@ public static string GetProxyDirectory() return Path.Combine(GetAppDataDirectory(), "proxy"); } - public static string GetDefaultDatabasePath(bool create_directory) - { - string app_data = GetAppDataDirectory(); + public static string GetDefaultDatabasePath(bool create_directory) + { + string app_data = GetAppDataDirectory(); if (create_directory) - { + { Directory.CreateDirectory(app_data); } - return Path.Combine(app_data, "default.db"); + return Path.Combine(app_data, "default.db"); } } \ No newline at end of file From 4d644afc2012a97388ee838d4358190be6e39b13 Mon Sep 17 00:00:00 2001 From: kwakmu18 Date: Sun, 15 Dec 2024 18:42:10 +0900 Subject: [PATCH 2/5] fix language issue fix language issue --- FindInterface/FindInterface.vcxproj.filters | 8 ++++---- FindInterfaceInproc/FindInterfaceInproc.vcxproj.filters | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/FindInterface/FindInterface.vcxproj.filters b/FindInterface/FindInterface.vcxproj.filters index 430de387..9dc07d3b 100644 --- a/FindInterface/FindInterface.vcxproj.filters +++ b/FindInterface/FindInterface.vcxproj.filters @@ -1,22 +1,22 @@  - + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - + {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - 소스 파일 + Source Files \ No newline at end of file diff --git a/FindInterfaceInproc/FindInterfaceInproc.vcxproj.filters b/FindInterfaceInproc/FindInterfaceInproc.vcxproj.filters index 43bdbee0..f22c360c 100644 --- a/FindInterfaceInproc/FindInterfaceInproc.vcxproj.filters +++ b/FindInterfaceInproc/FindInterfaceInproc.vcxproj.filters @@ -1,22 +1,22 @@  - + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - + {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - 소스 파일 + Source Files \ No newline at end of file From 4bae77b4b3eb874f03d21b4659527ca94be8739d Mon Sep 17 00:00:00 2001 From: kwakmu18 Date: Mon, 16 Dec 2024 12:43:39 +0900 Subject: [PATCH 3/5] 20241216 Update [1] fix dll/exe uppercase problem [2] remove #endregion [3] Improving the method to retrieve the service's PID --- OleViewDotNet/Forms/DllFixForm.Designer.cs | 2 - OleViewDotNet/Forms/DllFixForm.cs | 2 +- .../Forms/SourceCodeViewerControl.cs | 42 +++++++++++++++---- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/OleViewDotNet/Forms/DllFixForm.Designer.cs b/OleViewDotNet/Forms/DllFixForm.Designer.cs index 0d928291..f2aaf3ef 100644 --- a/OleViewDotNet/Forms/DllFixForm.Designer.cs +++ b/OleViewDotNet/Forms/DllFixForm.Designer.cs @@ -92,8 +92,6 @@ private void InitializeComponent() } - #endregion - private System.Windows.Forms.Label label1; private System.Windows.Forms.ComboBox comboBox1; private System.Windows.Forms.Label label2; diff --git a/OleViewDotNet/Forms/DllFixForm.cs b/OleViewDotNet/Forms/DllFixForm.cs index 2e919a67..14ce5f11 100644 --- a/OleViewDotNet/Forms/DllFixForm.cs +++ b/OleViewDotNet/Forms/DllFixForm.cs @@ -25,7 +25,7 @@ public DllFixForm() List fileList = new List(); foreach (String fileName in fileNames) { - if (fileName.EndsWith(".dll") || fileName.EndsWith(".exe")) + if (fileName.ToLower().EndsWith(".dll") || fileName.ToLower().EndsWith(".exe")) { fileList.Add(fileName); } diff --git a/OleViewDotNet/Forms/SourceCodeViewerControl.cs b/OleViewDotNet/Forms/SourceCodeViewerControl.cs index 4ba03624..f0d09239 100644 --- a/OleViewDotNet/Forms/SourceCodeViewerControl.cs +++ b/OleViewDotNet/Forms/SourceCodeViewerControl.cs @@ -265,6 +265,7 @@ internal String Format() // Finds method name with ResolveMethod, changes method name from Proc{n} to real method name and returns it. internal String Resolve(String idl, List binaryPath) { + if (binaryPath.Count == 0) return null; resolvingForm = new ResolvingForm(binaryPath); Thread uiThread = new Thread(StartResolvingForm); uiThread.Start(); @@ -425,10 +426,10 @@ internal String GetServiceName() internal int GetServicePid(String serviceName) { - string query = $"SELECT Name,ProcessId FROM Win32_Service WHERE Name LIKE '{serviceName}%'"; - using (var searcher = new System.Management.ManagementObjectSearcher(query)) + string query = $"SELECT Name,ProcessId FROM Win32_Service WHERE Name LIKE '{serviceName}!_%'"; + using (var searcher1 = new System.Management.ManagementObjectSearcher(query)) { - foreach (var obj in searcher.Get()) + foreach (var obj in searcher1.Get()) { try { @@ -440,17 +441,44 @@ internal int GetServicePid(String serviceName) service.WaitForStatus(ServiceControllerStatus.Running); } } - catch (InvalidOperationException ex) + catch (Exception ex) { continue; } + } + using (var searcher2 = new System.Management.ManagementObjectSearcher(query)) { + foreach (var obj in searcher2.Get()) + { + return Convert.ToInt32(obj["ProcessId"]); + } + } + } + query = $"SELECT Name,ProcessId FROM Win32_Service WHERE Name='{serviceName}'"; + using (var searcher1 = new System.Management.ManagementObjectSearcher(query)) + { + foreach (var obj in searcher1.Get()) + { + try + { + ServiceController service = new ServiceController((String)obj["Name"]); + + if (service.Status == ServiceControllerStatus.Stopped) + { + service.Start(); + service.WaitForStatus(ServiceControllerStatus.Running); + } + } catch (Exception ex) { continue; } - if (searcher.Get().Count == 1) return Convert.ToInt32(obj["ProcessId"]); - if ((String)(obj["Name"]) == serviceName) continue; - return Convert.ToInt32(obj["ProcessId"]); + } + using (var searcher2 = new System.Management.ManagementObjectSearcher(query)) + { + foreach (var obj in searcher2.Get()) + { + return Convert.ToInt32(obj["ProcessId"]); + } } } return -1; From 3612d4004c77c9c0e83df1e86d81163f8db62ab0 Mon Sep 17 00:00:00 2001 From: kwakmu18 Date: Tue, 17 Dec 2024 21:15:13 +0900 Subject: [PATCH 4/5] 20241217 Update 20241217 Update Fix Some Issue --- OleViewDotNet/Forms/ResolveMethod.cs | 1 + OleViewDotNet/Forms/ResolvingForm.cs | 16 ++++++++++++++ .../Forms/SourceCodeViewerControl.cs | 22 ++++++++++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/OleViewDotNet/Forms/ResolveMethod.cs b/OleViewDotNet/Forms/ResolveMethod.cs index da0f9018..86b5773b 100644 --- a/OleViewDotNet/Forms/ResolveMethod.cs +++ b/OleViewDotNet/Forms/ResolveMethod.cs @@ -179,6 +179,7 @@ public static bool GenerateAsmFile(String binaryPath) MessageBox.Show("Failed to resolve interfaces."); } process.Dispose(); + File.Delete(binaryName); return true; } diff --git a/OleViewDotNet/Forms/ResolvingForm.cs b/OleViewDotNet/Forms/ResolvingForm.cs index c1afe09b..9c4ea197 100644 --- a/OleViewDotNet/Forms/ResolvingForm.cs +++ b/OleViewDotNet/Forms/ResolvingForm.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using System.Windows.Forms; using System.Threading; +using System.Diagnostics; namespace OleViewDotNet.Forms { @@ -33,6 +34,21 @@ public ResolvingForm(List binaryPath) private void MainFormClosed(object sender, FormClosedEventArgs e) { resolveDone = true; + try + { + Process[] processes = Process.GetProcessesByName("idat64.exe"); + if (processes.Length == 0) return; + foreach (Process process in processes) + { + try + { + process.Kill(); + process.WaitForExit(); + } + catch { } + } + } + catch { } } public void Update(String label1, String label2) diff --git a/OleViewDotNet/Forms/SourceCodeViewerControl.cs b/OleViewDotNet/Forms/SourceCodeViewerControl.cs index f0d09239..ee5a00de 100644 --- a/OleViewDotNet/Forms/SourceCodeViewerControl.cs +++ b/OleViewDotNet/Forms/SourceCodeViewerControl.cs @@ -175,6 +175,12 @@ internal String Format() if (ProgramSettings.ResolveMethodDllFix) { + if (!File.Exists(ProgramSettings.FixedDll)) + { + ProgramSettings.ResolveMethodDllFix = false; + SetText(builder.ToString(), builder.Tags); + return builder.ToString(); + } binaryPath.Add(ProgramSettings.FixedDll); } else @@ -288,6 +294,17 @@ internal String Resolve(String idl, List binaryPath) continue; } + if (resolvingForm.resolveDone) + { + String[] files = Directory.GetFiles("DLLs", binaryPath[i] + "*"); + + foreach (String file in files) + { + File.Delete(file); + } + return null; + } + resolvingForm.Update(null, $"Searching VTables..."); Application.DoEvents(); @@ -426,11 +443,12 @@ internal String GetServiceName() internal int GetServicePid(String serviceName) { - string query = $"SELECT Name,ProcessId FROM Win32_Service WHERE Name LIKE '{serviceName}!_%'"; + string query = $"SELECT Name,ProcessId FROM Win32_Service WHERE Name LIKE '{serviceName}%'"; using (var searcher1 = new System.Management.ManagementObjectSearcher(query)) { foreach (var obj in searcher1.Get()) { + try { ServiceController service = new ServiceController((String)obj["Name"]); @@ -449,6 +467,7 @@ internal int GetServicePid(String serviceName) using (var searcher2 = new System.Management.ManagementObjectSearcher(query)) { foreach (var obj in searcher2.Get()) { + MessageBox.Show($"Name2: {obj["Name"]}, PID1: {obj["ProcessId"]} "); return Convert.ToInt32(obj["ProcessId"]); } } @@ -477,6 +496,7 @@ internal int GetServicePid(String serviceName) { foreach (var obj in searcher2.Get()) { + MessageBox.Show($"Name2: {obj["Name"]}, PID2: {obj["ProcessId"]} "); return Convert.ToInt32(obj["ProcessId"]); } } From 016ca7e2d3b759d79071f3d5486ae99485474470 Mon Sep 17 00:00:00 2001 From: kwakmu18 Date: Wed, 18 Dec 2024 06:31:55 +0900 Subject: [PATCH 5/5] 20241218 Update 20241218 Update Fix Issues --- .../FindInterfaceInproc.vcxproj | 1 + OleViewDotNet/BanList.txt | 214 ++++++++++++++++++ OleViewDotNet/Forms/CallSequenceForm.cs | 92 +++++--- OleViewDotNet/Forms/IDAPathForm.Designer.cs | 2 +- OleViewDotNet/Forms/MainForm.cs | 1 - OleViewDotNet/Forms/ResolveMethod.cs | 48 ++-- OleViewDotNet/Forms/ResolvingForm.cs | 2 +- .../Forms/SourceCodeViewerControl.cs | 7 +- OleViewDotNet/OleViewDotNet.csproj | 8 + OleViewDotNet/ProgramSettings.cs | 8 + 10 files changed, 308 insertions(+), 75 deletions(-) create mode 100644 OleViewDotNet/BanList.txt diff --git a/FindInterfaceInproc/FindInterfaceInproc.vcxproj b/FindInterfaceInproc/FindInterfaceInproc.vcxproj index 603833ee..3bc18d84 100644 --- a/FindInterfaceInproc/FindInterfaceInproc.vcxproj +++ b/FindInterfaceInproc/FindInterfaceInproc.vcxproj @@ -124,6 +124,7 @@ true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true + MultiThreaded Console diff --git a/OleViewDotNet/BanList.txt b/OleViewDotNet/BanList.txt new file mode 100644 index 00000000..0ffff5f4 --- /dev/null +++ b/OleViewDotNet/BanList.txt @@ -0,0 +1,214 @@ +C:\WINDOWS\SYSTEM32\MSASN1.dll +C:\WINDOWS\SYSTEM32\dxcore.dll +C:\WINDOWS\SYSTEM32\twinapi.appcore.dll +C:\WINDOWS\SYSTEM32\wevtapi.dll +C:\WINDOWS\SYSTEM32\winsta.dll +C:\WINDOWS\System32\WINSTA.dll +C:\WINDOWS\System32\profapi.dll +C:\WINDOWS\system32\MSASN1.dll +C:\WINDOWS\system32\ncryptprov.dll +C:\Windows\System32\Microsoft.Bluetooth.Proxy.dll +C:\Windows\System32\SspiCli.dll +C:\Windows\System32\Windows.Security.Authentication.OnlineId.dll +C:\Windows\System32\XmlLite.dll +C:\Windows\System32\msxml6.dll +C:\Windows\System32\vaultcli.dll +c:\windows\system32\BrokerLib.dll +c:\windows\system32\PROPSYS.dll +c:\windows\system32\WMICLNT.dll +c:\windows\system32\fwbase.dll +c:\windows\system32\wlanapi.dll +C:\WINDOWS\SYSTEM32\IPHLPAPI.DLL +C:\WINDOWS\SYSTEM32\bi.dll +C:\WINDOWS\SYSTEM32\capauthz.dll +C:\WINDOWS\System32\CRYPTBASE.DLL +C:\WINDOWS\System32\NTASN1.dll +C:\WINDOWS\System32\SETUPAPI.dll +C:\WINDOWS\System32\SHLWAPI.dll +C:\WINDOWS\System32\SspiCli.dll +C:\WINDOWS\System32\fwpuclnt.dll +C:\WINDOWS\System32\ncrypt.dll +C:\WINDOWS\System32\netutils.dll +C:\WINDOWS\System32\sspicli.dll +C:\WINDOWS\System32\wkscli.dll +C:\Windows\System32\AppXDeploymentClient.dll +c:\windows\system32\WppRecorderUM.dll +c:\windows\system32\netutils.dll +C:\WINDOWS\SYSTEM32\netjoin.dll +C:\WINDOWS\SYSTEM32\netutils.dll +C:\WINDOWS\System32\CRYPTBASE.dll +C:\WINDOWS\System32\DPAPI.DLL +C:\WINDOWS\System32\SHCORE.dll +C:\WINDOWS\System32\SHELL32.dll +C:\WINDOWS\System32\netprofm.dll +C:\WINDOWS\system32\execmodelproxy.dll +C:\Windows\System32\Windows.Networking.Connectivity.dll +C:\Windows\System32\Windows.Web.dll +C:\Windows\System32\iertutil.dll +C:\Windows\System32\msvcp110_win.dll +C:\Windows\System32\netutils.dll +C:\Windows\System32\srvcli.dll +C:\Windows\System32\usermgrproxy.dll +c:\windows\system32\DNSAPI.dll +c:\windows\system32\DSROLE.dll +c:\windows\system32\MobileNetworking.dll +c:\windows\system32\SYSNTFY.dll +c:\windows\system32\WINSTA.dll +c:\windows\system32\WTSAPI32.dll +c:\windows\system32\fwpuclnt.dll +c:\windows\system32\AUTHZ.dll +c:\windows\system32\NTASN1.dll +c:\windows\system32\ncrypt.dll +C:\WINDOWS\SYSTEM32\wlanapi.dll +C:\WINDOWS\System32\DEVOBJ.dll +C:\WINDOWS\system32\ncryptsslp.dll +C:\WINDOWS\system32\schannel.DLL +C:\WINDOWS\system32\sspicli.dll +C:\Windows\System32\taskschd.dll +c:\windows\system32\WINNSI.DLL +C:\WINDOWS\SYSTEM32\SspiCli.dll +C:\WINDOWS\SYSTEM32\profapi.dll +C:\WINDOWS\System32\IMM32.DLL +C:\WINDOWS\System32\coml2.dll +C:\Windows\System32\CapabilityAccessManagerClient.dll +C:\Windows\System32\Windows.StateRepositoryPS.dll +C:\WINDOWS\SYSTEM32\windows.staterepositoryclient.dll +C:\WINDOWS\System32\WINTRUST.dll +C:\WINDOWS\system32\CRYPTBASE.dll +C:\Windows\System32\WinTypes.dll +c:\windows\system32\webio.dll +C:\WINDOWS\SYSTEM32\MobileNetworking.dll +C:\WINDOWS\System32\ADVAPI32.dll +C:\Windows\System32\twinapi.appcore.dll +c:\windows\system32\UMPDC.dll +C:\WINDOWS\SYSTEM32\cryptsp.dll +C:\Windows\System32\OneCoreCommonProxyStub.dll +c:\windows\system32\WINHTTP.dll +c:\windows\system32\profapi.dll +C:\WINDOWS\System32\npmproxy.dll +c:\windows\system32\SspiCli.dll +c:\windows\system32\msvcp110_win.dll +C:\WINDOWS\System32\MSASN1.dll +c:\windows\system32\DEVOBJ.dll +C:\WINDOWS\SYSTEM32\WINSTA.dll +C:\Windows\System32\OneCoreUAPCommonProxyStub.dll +C:\Windows\System32\rasadhlp.dll +C:\WINDOWS\SYSTEM32\windows.staterepositorycore.dll +C:\WINDOWS\System32\shlwapi.dll +C:\WINDOWS\system32\rsaenh.dll +c:\windows\system32\USERENV.dll +C:\WINDOWS\SYSTEM32\DNSAPI.dll +C:\WINDOWS\SYSTEM32\WINNSI.DLL +C:\WINDOWS\SYSTEM32\policymanager.dll +C:\WINDOWS\SYSTEM32\rmclient.dll +C:\WINDOWS\SYSTEM32\windows.storage.dll +C:\WINDOWS\SYSTEM32\dhcpcsvc.DLL +C:\WINDOWS\SYSTEM32\dhcpcsvc6.DLL +C:\WINDOWS\SYSTEM32\gpapi.dll +C:\WINDOWS\SYSTEM32\usermgrcli.dll +C:\WINDOWS\SYSTEM32\wtsapi32.dll +C:\WINDOWS\SYSTEM32\wintypes.dll +C:\WINDOWS\System32\ole32.dll +c:\windows\system32\IPHLPAPI.DLL +C:\WINDOWS\SYSTEM32\UMPDC.dll +C:\WINDOWS\SYSTEM32\ntmarta.dll +C:\WINDOWS\system32\mswsock.dll +C:\WINDOWS\System32\svchost.exe +C:\WINDOWS\System32\CRYPT32.dll +C:\WINDOWS\SYSTEM32\powrprof.dll +C:\WINDOWS\System32\NSI.dll +C:\WINDOWS\SYSTEM32\cfgmgr32.dll +C:\WINDOWS\System32\WS2_32.dll +C:\WINDOWS\System32\shcore.dll +C:\WINDOWS\System32\advapi32.dll +C:\WINDOWS\system32\svchost.exe +C:\WINDOWS\System32\OLEAUT32.dll +C:\WINDOWS\System32\clbcatq.dll +C:\WINDOWS\System32\user32.dll +C:\WINDOWS\System32\GDI32.dll +C:\WINDOWS\System32\gdi32full.dll +C:\WINDOWS\System32\win32u.dll +C:\WINDOWS\SYSTEM32\kernel.appcore.dll +C:\WINDOWS\System32\bcryptPrimitives.dll +C:\WINDOWS\SYSTEM32\ntdll.dll +C:\WINDOWS\System32\KERNEL32.DLL +C:\WINDOWS\System32\KERNELBASE.dll +C:\WINDOWS\System32\RPCRT4.dll +C:\WINDOWS\System32\bcrypt.dll +C:\WINDOWS\System32\combase.dll +C:\WINDOWS\System32\msvcp_win.dll +C:\WINDOWS\System32\msvcrt.dll +C:\WINDOWS\System32\sechost.dll +C:\WINDOWS\System32\ucrtbase.dll +C:\WINDOWS\System32\d3d11.dll +C:\WINDOWS\System32\d2d1.dll +c:\windows\system32\CLIPC.dll +C:\Windows\System32\wuapi.dll +C:\WINDOWS\uus\AMD64\uusbrain.dll +C:\Windows\System32\wups.dll +C:\WINDOWS\SYSTEM32\gamestreamingext.dll +c:\windows\system32\VERSION.dll +C:\WINDOWS\SYSTEM32\wiatrace.dll +C:\WINDOWS\system32\msv1_0.DLL +C:\WINDOWS\system32\NtlmShared.dll +C:\WINDOWS\SYSTEM32\deviceassociation.dll +C:\WINDOWS\SYSTEM32\webservices.dll +C:\WINDOWS\SYSTEM32\HTTPAPI.dll +C:\WINDOWS\System32\verifier.dll +c:\windows\system32\logoncli.dll +c:\windows\system32\NETAPI32.dll +C:\WINDOWS\SYSTEM32\PeerDist.dll +c:\windows\system32\VirtDisk.dll +c:\windows\system32\SXSHARED.dll +C:\WINDOWS\system32\defragproxy.dll +C:\WINDOWS\system32\ESENT.dll +C:\Windows\System32\TieringEngineProxy.dll +c:\windows\system32\profsvc.dll +C:\WINDOWS\System32\SAMLIB.dll +C:\WINDOWS\SYSTEM32\profext.dll +C:\WINDOWS\SYSTEM32\AcLayers.DLL +C:\WINDOWS\SYSTEM32\HID.DLL +C:\WINDOWS\SYSTEM32\directxdatabasehelper.dll +C:\Windows\System32\PerceptionSimulation\SixDofControllerManager.ProxyStubs.dll +C:\Windows\System32\PerceptionSimulation\VirtualDisplayManager.ProxyStubs.dll +C:\WINDOWS\system32\sxproxy.dll +C:\WINDOWS\System32\bcd.dll +C:\WINDOWS\System32\VssTrace.DLL +c:\windows\system32\securityhealthservice.exe +c:\windows\system32\ESENT.dll +c:\windows\system32\dsclient.dll +C:\Windows\System32\WalletProxy.dll +c:\windows\system32\OneX.DLL +c:\windows\system32\eappprxy.dll +c:\windows\system32\WLANSEC.dll +c:\windows\system32\WMI.dll +C:\WINDOWS\System32\wlansvcpal.dll +C:\WINDOWS\System32\TetheringIeProvider.dll +C:\WINDOWS\SYSTEM32\wlgpclnt.dll +C:\WINDOWS\system32\kerberos.DLL +C:\WINDOWS\system32\Kerb3961.dll +C:\WINDOWS\SYSTEM32\SystemEventsBrokerClient.dll +c:\windows\system32\nvagent.dll +c:\windows\system32\NetSetupApi.dll +C:\WINDOWS\System32\vmsifproxystub.dll +c:\windows\system32\lfsvc.dll +C:\Windows\System32\LocationFrameworkPS.dll +C:\WINDOWS\system32\mi.dll +C:\WINDOWS\system32\fveapi.dll +C:\WINDOWS\system32\cscapi.dll +C:\WINDOWS\SYSTEM32\samcli.dll +C:\WINDOWS\SYSTEM32\NCObjAPI.DLL +C:\WINDOWS\System32\EventAggregation.dll +C:\WINDOWS\system32\keepaliveprovider.dll +C:\WINDOWS\System32\winsqlite3.dll +C:\WINDOWS\System32\LINKINFO.dll +C:\WINDOWS\system32\SFC.DLL +C:\WINDOWS\system32\sfc_os.DLL +c:\windows\system32\dsclient.dllc:\windows\system32\wpnuserservice.dll +C:\Windows\System32\StateRepository.Core.dll +c:\windows\system32\wpnuserservice.dll +C:\WINDOWS\SYSTEM32\edputil.dll +C:\WINDOWS\system32\Secur32.dll +C:\WINDOWS\SYSTEM32\bcp47mrm.dll +C:\WINDOWS\System32\TimeBrokerClient.dll +C:\Windows\System32\ShellCommonCommonProxyStub.dll diff --git a/OleViewDotNet/Forms/CallSequenceForm.cs b/OleViewDotNet/Forms/CallSequenceForm.cs index a388b5f3..9720641e 100644 --- a/OleViewDotNet/Forms/CallSequenceForm.cs +++ b/OleViewDotNet/Forms/CallSequenceForm.cs @@ -68,27 +68,19 @@ public CallSequenceForm() String line = lines[i].Trim(); if (line.StartsWith("HRESULT")) { - List parameters = GetParameters(line); - for (int j = 1; j < parameters.Count; j++) + List parameters = GetParameters(line.Substring(line.IndexOf('(') + 1)); + for (int j = 0; j < parameters.Count; j++) { String[] param = parameters[j].Trim().Split(' '); - if (param[0].Contains("out") && !param[param.Length - 2].StartsWith("int") && - !param[param.Length - 2].StartsWith("HSTRING") && !param[param.Length - 2].StartsWith("wchar") && - !param[param.Length - 2].StartsWith("GUID") && !param[param.Length - 2].StartsWith("byte") && - !param[param.Length - 2].StartsWith("__int") && !param[param.Length - 2].StartsWith("uint") && - !param[param.Length - 2].StartsWith("Struct") && !param[param.Length - 2].ToLower().StartsWith("handle") && - !param[param.Length - 2].StartsWith("float") && !param[param.Length - 2].StartsWith("double") && - !param[param.Length - 2].StartsWith("char") && !param[param.Length - 2].StartsWith("HWND") && - !param[param.Length - 2].StartsWith("handle") && !param[param.Length - 2].StartsWith("BSTR") && - !param[param.Length - 2].StartsWith("short") && !param[param.Length - 2].StartsWith("VARIANT")) + if (!param[0].StartsWith("[out") || !param[1].Contains("**")) continue; + if (param[1].Contains("wchar")) continue; + param[1] = param[1].Replace("*", ""); + param[1] = param[1].Replace("", ",").Replace("", " "); + if (!interfaces.Keys.Contains(param[1])) { - param[param.Length - 2] = param[param.Length - 2].Replace("*", ""); - if (!interfaces.Keys.Contains(param[param.Length - 2])) - { - interfaces[param[param.Length - 2]] = new List(); - } - interfaces[interfaceName].Add(param[param.Length - 2]); + interfaces[param[1]] = new List(); } + interfaces[interfaceName].Add(param[1]); } } } @@ -96,31 +88,65 @@ public CallSequenceForm() stringList.Sort(); comboBox1.DataSource = stringList; } + this.Show(); } + static string ReplaceCommasInBrackets(string text) + { + Stack stack = new Stack(); + StringBuilder result = new StringBuilder(); + StringBuilder temp = new StringBuilder(); + + for (int i = 0; i < text.Length; i++) + { + char ch = text[i]; + + if (ch == '[') + { + if (stack.Count > 0) + { + temp.Append(ch); + } + stack.Push(i); + } + else if (ch == ']') + { + if (stack.Count > 1) + { + temp.Append(ch); + } + stack.Pop(); + + if (stack.Count == 0) + { + result.Append("["); + result.Append(temp.ToString().Replace(",", "").Replace(" ","")); + result.Append("]"); + temp.Clear(); + } + } + else if (stack.Count > 0) + { + temp.Append(ch); + } + else + { + result.Append(ch); + } + } + + return result.ToString(); + } + // Get parameters from idl methods. public List GetParameters(string functionDeclaration) { if (functionDeclaration.Trim().EndsWith("(void)")) return new List(); - string functionDefinition = Regex.Replace(functionDeclaration, @"<.*?>", ""); - Match match = Regex.Match(functionDefinition, @"([\w:~]+|`.*?')\s*\((.*?)\)\s*(?:const)?(?:override)?;?$"); - if (!match.Success) - return new List(); - - string functionName = match.Groups[1].Value; - string parameters = match.Groups[2].Value; - - if (string.IsNullOrWhiteSpace(parameters)) - return new List(); - parameters = Regex.Replace(parameters, @"\[([^\]]*)\]", m => m.Groups[0].Value.Replace(",", "")); - - parameters = Regex.Replace(parameters, @"<([^>]*)>", m => m.Groups[0].Value.Replace(",", "")); - var paramList = parameters.Split(',').Select(p => p.Replace("", ",")).ToList(); - paramList.Insert(0, functionName); - return paramList; + String functionDefinition = ReplaceCommasInBrackets(functionDeclaration); + return functionDefinition.Split(',').ToList(); } // Find sequence by Search method and store with Dictionary structure. diff --git a/OleViewDotNet/Forms/IDAPathForm.Designer.cs b/OleViewDotNet/Forms/IDAPathForm.Designer.cs index 11fbe292..ba8bf132 100644 --- a/OleViewDotNet/Forms/IDAPathForm.Designer.cs +++ b/OleViewDotNet/Forms/IDAPathForm.Designer.cs @@ -96,7 +96,7 @@ private void button1_Click(object sender, EventArgs e) String path = textBox1.Text; if (path.EndsWith("idat64.exe") && File.Exists(path)) { - ResolveMethod.IDAPath = path; + ProgramSettings.IDAPath = path; this.Close(); } else diff --git a/OleViewDotNet/Forms/MainForm.cs b/OleViewDotNet/Forms/MainForm.cs index 496cb5fd..d40326f9 100644 --- a/OleViewDotNet/Forms/MainForm.cs +++ b/OleViewDotNet/Forms/MainForm.cs @@ -1090,7 +1090,6 @@ private void menuGetSequence_Click(object sender, EventArgs e) { if (!Directory.Exists("interfaces\\sequence")) Directory.CreateDirectory("interfaces\\sequence"); CallSequenceForm callSequenceForm = new CallSequenceForm(); - callSequenceForm.Show(); } private void menuResolveMethodDllFix_Click(object sender, EventArgs e) diff --git a/OleViewDotNet/Forms/ResolveMethod.cs b/OleViewDotNet/Forms/ResolveMethod.cs index 86b5773b..e2c9629d 100644 --- a/OleViewDotNet/Forms/ResolveMethod.cs +++ b/OleViewDotNet/Forms/ResolveMethod.cs @@ -15,7 +15,6 @@ namespace OleViewDotNet.Forms { internal class ResolveMethod { - public static String IDAPath = null; public static List banList = null; // Find IDA path from Registry(Local Settings\\Software\\Microsoft\\Windows\\Shell\\MuiCache). @@ -23,15 +22,6 @@ internal class ResolveMethod public static String GetIDAT() { - if (File.Exists("IDAPath")) - { - using (StreamReader reader = new StreamReader("IDAPath")) - { - IDAPath = reader.ReadToEnd(); - } - return IDAPath; - } - string regKey = "Local Settings\\Software\\Microsoft\\Windows\\Shell\\MuiCache"; try { @@ -48,7 +38,7 @@ public static String GetIDAT() String fileName = String.Join("\\", parts, 0, parts.Length - 1) + "\\idat64.exe"; if (File.Exists(fileName)) { - IDAPath = fileName; + ProgramSettings.IDAPath = fileName; } } } @@ -59,20 +49,14 @@ public static String GetIDAT() { } - if (IDAPath == null) + if (ProgramSettings.IDAPath == null) { - MessageBox.Show("Failed to find idat64.exe."); IDAPathForm iDAPathForm = new IDAPathForm(); iDAPathForm.ShowDialog(); } - using (StreamWriter writer = new StreamWriter("IDAPath")) - { - writer.Write(IDAPath); - } - - return IDAPath; + return ProgramSettings.IDAPath; } // Find service DLL/EXE from Registry. @@ -159,11 +143,11 @@ public static void CopyDLL(String binaryPath) public static bool GenerateAsmFile(String binaryPath) { String binaryName = Path.GetFileName(binaryPath); - if (File.Exists($"DLLs\\{binaryName}" + ".asm")) return true; + if (File.Exists($"DLLs\\{binaryName}.asm")) return true; CopyDLL(binaryPath); Process process = new Process(); - if (IDAPath == null) process.StartInfo.FileName = GetIDAT(); - process.StartInfo.FileName = IDAPath; + if (ProgramSettings.IDAPath == null || !File.Exists(ProgramSettings.IDAPath)) GetIDAT(); + process.StartInfo.FileName = ProgramSettings.IDAPath; process.StartInfo.Arguments = $"-A -B DLLs\\{binaryName}"; process.StartInfo.CreateNoWindow = true; process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; @@ -177,9 +161,14 @@ public static bool GenerateAsmFile(String binaryPath) catch (Exception ex) { MessageBox.Show("Failed to resolve interfaces."); + process.Dispose(); + File.Delete($"DLLs\\{binaryName}"); + File.Delete($"DLLs\\{binaryName}.i64"); + return false; } process.Dispose(); - File.Delete(binaryName); + File.Delete($"DLLs\\{binaryName}"); + File.Delete($"DLLs\\{binaryName}.i64"); return true; } @@ -269,7 +258,7 @@ public static List> GetMethodsFromIDA(String binaryPath, String idl if (!asm.Contains("QueryInterface") && !banList.Contains(binaryPath)) { - using (StreamWriter writer = new StreamWriter("BanList", true)) + using (StreamWriter writer = new StreamWriter("BanList.txt", true)) { writer.WriteLine(binaryPath); } @@ -566,17 +555,8 @@ public static String ConvertMethodName(String idl, List methods) // Initialize banList. BanList is a DLL/EXE list that will not be parsed. public static void BanListInit() { - if (!File.Exists("BanList")) - { - String template = "C:\\WINDOWS\\SYSTEM32\\MSASN1.dll\r\nC:\\WINDOWS\\SYSTEM32\\dxcore.dll\r\nC:\\WINDOWS\\SYSTEM32\\twinapi.appcore.dll\r\nC:\\WINDOWS\\SYSTEM32\\wevtapi.dll\r\nC:\\WINDOWS\\SYSTEM32\\winsta.dll\r\nC:\\WINDOWS\\System32\\WINSTA.dll\r\nC:\\WINDOWS\\System32\\profapi.dll\r\nC:\\WINDOWS\\system32\\MSASN1.dll\r\nC:\\WINDOWS\\system32\\ncryptprov.dll\r\nC:\\Windows\\System32\\Microsoft.Bluetooth.Proxy.dll\r\nC:\\Windows\\System32\\SspiCli.dll\r\nC:\\Windows\\System32\\Windows.Security.Authentication.OnlineId.dll\r\nC:\\Windows\\System32\\XmlLite.dll\r\nC:\\Windows\\System32\\msxml6.dll\r\nC:\\Windows\\System32\\vaultcli.dll\r\nc:\\windows\\system32\\BrokerLib.dll\r\nc:\\windows\\system32\\PROPSYS.dll\r\nc:\\windows\\system32\\WMICLNT.dll\r\nc:\\windows\\system32\\fwbase.dll\r\nc:\\windows\\system32\\wlanapi.dll\r\nC:\\WINDOWS\\SYSTEM32\\IPHLPAPI.DLL\r\nC:\\WINDOWS\\SYSTEM32\\bi.dll\r\nC:\\WINDOWS\\SYSTEM32\\capauthz.dll\r\nC:\\WINDOWS\\System32\\CRYPTBASE.DLL\r\nC:\\WINDOWS\\System32\\NTASN1.dll\r\nC:\\WINDOWS\\System32\\SETUPAPI.dll\r\nC:\\WINDOWS\\System32\\SHLWAPI.dll\r\nC:\\WINDOWS\\System32\\SspiCli.dll\r\nC:\\WINDOWS\\System32\\fwpuclnt.dll\r\nC:\\WINDOWS\\System32\\ncrypt.dll\r\nC:\\WINDOWS\\System32\\netutils.dll\r\nC:\\WINDOWS\\System32\\sspicli.dll\r\nC:\\WINDOWS\\System32\\wkscli.dll\r\nC:\\Windows\\System32\\AppXDeploymentClient.dll\r\nc:\\windows\\system32\\WppRecorderUM.dll\r\nc:\\windows\\system32\\netutils.dll\r\nC:\\WINDOWS\\SYSTEM32\\netjoin.dll\r\nC:\\WINDOWS\\SYSTEM32\\netutils.dll\r\nC:\\WINDOWS\\System32\\CRYPTBASE.dll\r\nC:\\WINDOWS\\System32\\DPAPI.DLL\r\nC:\\WINDOWS\\System32\\SHCORE.dll\r\nC:\\WINDOWS\\System32\\SHELL32.dll\r\nC:\\WINDOWS\\System32\\netprofm.dll\r\nC:\\WINDOWS\\system32\\execmodelproxy.dll\r\nC:\\Windows\\System32\\Windows.Networking.Connectivity.dll\r\nC:\\Windows\\System32\\Windows.Web.dll\r\nC:\\Windows\\System32\\iertutil.dll\r\nC:\\Windows\\System32\\msvcp110_win.dll\r\nC:\\Windows\\System32\\netutils.dll\r\nC:\\Windows\\System32\\srvcli.dll\r\nC:\\Windows\\System32\\usermgrproxy.dll\r\nc:\\windows\\system32\\DNSAPI.dll\r\nc:\\windows\\system32\\DSROLE.dll\r\nc:\\windows\\system32\\MobileNetworking.dll\r\nc:\\windows\\system32\\SYSNTFY.dll\r\nc:\\windows\\system32\\WINSTA.dll\r\nc:\\windows\\system32\\WTSAPI32.dll\r\nc:\\windows\\system32\\fwpuclnt.dll\r\nc:\\windows\\system32\\AUTHZ.dll\r\nc:\\windows\\system32\\NTASN1.dll\r\nc:\\windows\\system32\\ncrypt.dll\r\nC:\\WINDOWS\\SYSTEM32\\wlanapi.dll\r\nC:\\WINDOWS\\System32\\DEVOBJ.dll\r\nC:\\WINDOWS\\system32\\ncryptsslp.dll\r\nC:\\WINDOWS\\system32\\schannel.DLL\r\nC:\\WINDOWS\\system32\\sspicli.dll\r\nC:\\Windows\\System32\\taskschd.dll\r\nc:\\windows\\system32\\WINNSI.DLL\r\nC:\\WINDOWS\\SYSTEM32\\SspiCli.dll\r\nC:\\WINDOWS\\SYSTEM32\\profapi.dll\r\nC:\\WINDOWS\\System32\\IMM32.DLL\r\nC:\\WINDOWS\\System32\\coml2.dll\r\nC:\\Windows\\System32\\CapabilityAccessManagerClient.dll\r\nC:\\Windows\\System32\\Windows.StateRepositoryPS.dll\r\nC:\\WINDOWS\\SYSTEM32\\windows.staterepositoryclient.dll\r\nC:\\WINDOWS\\System32\\WINTRUST.dll\r\nC:\\WINDOWS\\system32\\CRYPTBASE.dll\r\nC:\\Windows\\System32\\WinTypes.dll\r\nc:\\windows\\system32\\webio.dll\r\nC:\\WINDOWS\\SYSTEM32\\MobileNetworking.dll\r\nC:\\WINDOWS\\System32\\ADVAPI32.dll\r\nC:\\Windows\\System32\\twinapi.appcore.dll\r\nc:\\windows\\system32\\UMPDC.dll\r\nC:\\WINDOWS\\SYSTEM32\\cryptsp.dll\r\nC:\\Windows\\System32\\OneCoreCommonProxyStub.dll\r\nc:\\windows\\system32\\WINHTTP.dll\r\nc:\\windows\\system32\\profapi.dll\r\nC:\\WINDOWS\\System32\\npmproxy.dll\r\nc:\\windows\\system32\\SspiCli.dll\r\nc:\\windows\\system32\\msvcp110_win.dll\r\nC:\\WINDOWS\\System32\\MSASN1.dll\r\nc:\\windows\\system32\\DEVOBJ.dll\r\nC:\\WINDOWS\\SYSTEM32\\WINSTA.dll\r\nC:\\Windows\\System32\\OneCoreUAPCommonProxyStub.dll\r\nC:\\Windows\\System32\\rasadhlp.dll\r\nC:\\WINDOWS\\SYSTEM32\\windows.staterepositorycore.dll\r\nC:\\WINDOWS\\System32\\shlwapi.dll\r\nC:\\WINDOWS\\system32\\rsaenh.dll\r\nc:\\windows\\system32\\USERENV.dll\r\nC:\\WINDOWS\\SYSTEM32\\DNSAPI.dll\r\nC:\\WINDOWS\\SYSTEM32\\WINNSI.DLL\r\nC:\\WINDOWS\\SYSTEM32\\policymanager.dll\r\nC:\\WINDOWS\\SYSTEM32\\rmclient.dll\r\nC:\\WINDOWS\\SYSTEM32\\windows.storage.dll\r\nC:\\WINDOWS\\SYSTEM32\\dhcpcsvc.DLL\r\nC:\\WINDOWS\\SYSTEM32\\dhcpcsvc6.DLL\r\nC:\\WINDOWS\\SYSTEM32\\gpapi.dll\r\nC:\\WINDOWS\\SYSTEM32\\usermgrcli.dll\r\nC:\\WINDOWS\\SYSTEM32\\wtsapi32.dll\r\nC:\\WINDOWS\\SYSTEM32\\wintypes.dll\r\nC:\\WINDOWS\\System32\\ole32.dll\r\nc:\\windows\\system32\\IPHLPAPI.DLL\r\nC:\\WINDOWS\\SYSTEM32\\UMPDC.dll\r\nC:\\WINDOWS\\SYSTEM32\\ntmarta.dll\r\nC:\\WINDOWS\\system32\\mswsock.dll\r\nC:\\WINDOWS\\System32\\svchost.exe\r\nC:\\WINDOWS\\System32\\CRYPT32.dll\r\nC:\\WINDOWS\\SYSTEM32\\powrprof.dll\r\nC:\\WINDOWS\\System32\\NSI.dll\r\nC:\\WINDOWS\\SYSTEM32\\cfgmgr32.dll\r\nC:\\WINDOWS\\System32\\WS2_32.dll\r\nC:\\WINDOWS\\System32\\shcore.dll\r\nC:\\WINDOWS\\System32\\advapi32.dll\r\nC:\\WINDOWS\\system32\\svchost.exe\r\nC:\\WINDOWS\\System32\\OLEAUT32.dll\r\nC:\\WINDOWS\\System32\\clbcatq.dll\r\nC:\\WINDOWS\\System32\\user32.dll\r\nC:\\WINDOWS\\System32\\GDI32.dll\r\nC:\\WINDOWS\\System32\\gdi32full.dll\r\nC:\\WINDOWS\\System32\\win32u.dll\r\nC:\\WINDOWS\\SYSTEM32\\kernel.appcore.dll\r\nC:\\WINDOWS\\System32\\bcryptPrimitives.dll\r\nC:\\WINDOWS\\SYSTEM32\\ntdll.dll\r\nC:\\WINDOWS\\System32\\KERNEL32.DLL\r\nC:\\WINDOWS\\System32\\KERNELBASE.dll\r\nC:\\WINDOWS\\System32\\RPCRT4.dll\r\nC:\\WINDOWS\\System32\\bcrypt.dll\r\nC:\\WINDOWS\\System32\\combase.dll\r\nC:\\WINDOWS\\System32\\msvcp_win.dll\r\nC:\\WINDOWS\\System32\\msvcrt.dll\r\nC:\\WINDOWS\\System32\\sechost.dll\r\nC:\\WINDOWS\\System32\\ucrtbase.dll\r\nC:\\WINDOWS\\System32\\d3d11.dll\r\nC:\\WINDOWS\\System32\\d2d1.dll\r\nc:\\windows\\system32\\CLIPC.dll\r\nC:\\Windows\\System32\\wuapi.dll\r\nC:\\WINDOWS\\uus\\AMD64\\uusbrain.dll\r\nC:\\Windows\\System32\\wups.dll\r\nC:\\WINDOWS\\SYSTEM32\\gamestreamingext.dll\r\nc:\\windows\\system32\\VERSION.dll\r\nC:\\WINDOWS\\SYSTEM32\\wiatrace.dll\r\nC:\\WINDOWS\\system32\\msv1_0.DLL\r\nC:\\WINDOWS\\system32\\NtlmShared.dll\r\nC:\\WINDOWS\\SYSTEM32\\deviceassociation.dll\r\nC:\\WINDOWS\\SYSTEM32\\webservices.dll\r\nC:\\WINDOWS\\SYSTEM32\\HTTPAPI.dll\r\nC:\\WINDOWS\\System32\\verifier.dll\r\nc:\\windows\\system32\\logoncli.dll\r\nc:\\windows\\system32\\NETAPI32.dll\r\nC:\\WINDOWS\\SYSTEM32\\PeerDist.dll\r\nc:\\windows\\system32\\VirtDisk.dll\r\nc:\\windows\\system32\\SXSHARED.dll\r\nC:\\WINDOWS\\system32\\defragproxy.dll\r\nC:\\WINDOWS\\system32\\ESENT.dll\r\nC:\\Windows\\System32\\TieringEngineProxy.dll\r\nc:\\windows\\system32\\profsvc.dll\r\nC:\\WINDOWS\\System32\\SAMLIB.dll\r\nC:\\WINDOWS\\SYSTEM32\\profext.dll\r\nC:\\WINDOWS\\SYSTEM32\\AcLayers.DLL\r\nC:\\WINDOWS\\SYSTEM32\\HID.DLL\r\nC:\\WINDOWS\\SYSTEM32\\directxdatabasehelper.dll\r\nC:\\Windows\\System32\\PerceptionSimulation\\SixDofControllerManager.ProxyStubs.dll\r\nC:\\Windows\\System32\\PerceptionSimulation\\VirtualDisplayManager.ProxyStubs.dll\r\nC:\\WINDOWS\\system32\\sxproxy.dll\r\nC:\\WINDOWS\\System32\\bcd.dll\r\nC:\\WINDOWS\\System32\\VssTrace.DLL\r\nc:\\windows\\system32\\securityhealthservice.exe\r\nc:\\windows\\system32\\ESENT.dll\r\nc:\\windows\\system32\\dsclient.dll\r\nC:\\Windows\\System32\\WalletProxy.dll\r\nc:\\windows\\system32\\OneX.DLL\r\nc:\\windows\\system32\\eappprxy.dll\r\nc:\\windows\\system32\\WLANSEC.dll\r\nc:\\windows\\system32\\WMI.dll\r\nC:\\WINDOWS\\System32\\wlansvcpal.dll\r\nC:\\WINDOWS\\System32\\TetheringIeProvider.dll\r\nC:\\WINDOWS\\SYSTEM32\\wlgpclnt.dll\r\nC:\\WINDOWS\\system32\\kerberos.DLL\r\nC:\\WINDOWS\\system32\\Kerb3961.dll\r\nC:\\WINDOWS\\SYSTEM32\\SystemEventsBrokerClient.dll\r\nc:\\windows\\system32\\nvagent.dll\r\nc:\\windows\\system32\\NetSetupApi.dll\r\nC:\\WINDOWS\\System32\\vmsifproxystub.dll\r\nc:\\windows\\system32\\lfsvc.dll\r\nC:\\Windows\\System32\\LocationFrameworkPS.dll\r\nC:\\WINDOWS\\system32\\mi.dll\r\nC:\\WINDOWS\\system32\\fveapi.dll\r\nC:\\WINDOWS\\system32\\cscapi.dll\r\nC:\\WINDOWS\\SYSTEM32\\samcli.dll\r\nC:\\WINDOWS\\SYSTEM32\\NCObjAPI.DLL\r\nC:\\WINDOWS\\System32\\EventAggregation.dll\r\nC:\\WINDOWS\\system32\\keepaliveprovider.dll\r\nC:\\WINDOWS\\System32\\winsqlite3.dll\r\nC:\\WINDOWS\\System32\\LINKINFO.dll\r\nC:\\WINDOWS\\system32\\SFC.DLL\r\nC:\\WINDOWS\\system32\\sfc_os.DLL\r\nc:\\windows\\system32\\dsclient.dllc:\\windows\\system32\\wpnuserservice.dll\r\nC:\\Windows\\System32\\StateRepository.Core.dll\r\nc:\\windows\\system32\\wpnuserservice.dll\r\nC:\\WINDOWS\\SYSTEM32\\edputil.dll\r\nC:\\WINDOWS\\system32\\Secur32.dll\r\nC:\\WINDOWS\\SYSTEM32\\bcp47mrm.dll\r\nC:\\WINDOWS\\System32\\TimeBrokerClient.dll\r\nC:\\Windows\\System32\\ShellCommonCommonProxyStub.dll"; - using (StreamWriter writer = new StreamWriter("BanList")) - { - writer.Write(template); - writer.Flush(); - } - } banList = new List(); - using (StreamReader reader = new StreamReader("BanList")) + using (StreamReader reader = new StreamReader("BanList.txt")) { while (true) { diff --git a/OleViewDotNet/Forms/ResolvingForm.cs b/OleViewDotNet/Forms/ResolvingForm.cs index 9c4ea197..39022bc9 100644 --- a/OleViewDotNet/Forms/ResolvingForm.cs +++ b/OleViewDotNet/Forms/ResolvingForm.cs @@ -36,7 +36,7 @@ private void MainFormClosed(object sender, FormClosedEventArgs e) resolveDone = true; try { - Process[] processes = Process.GetProcessesByName("idat64.exe"); + Process[] processes = Process.GetProcessesByName("idat64"); if (processes.Length == 0) return; foreach (Process process in processes) { diff --git a/OleViewDotNet/Forms/SourceCodeViewerControl.cs b/OleViewDotNet/Forms/SourceCodeViewerControl.cs index ee5a00de..e9d93847 100644 --- a/OleViewDotNet/Forms/SourceCodeViewerControl.cs +++ b/OleViewDotNet/Forms/SourceCodeViewerControl.cs @@ -227,7 +227,6 @@ internal String Format() Process process = Process.GetProcessById(pid); if (process == null) { - MessageBox.Show("process is null?"); return builder.ToString(); } try @@ -271,6 +270,7 @@ internal String Format() // Finds method name with ResolveMethod, changes method name from Proc{n} to real method name and returns it. internal String Resolve(String idl, List binaryPath) { + if (ProgramSettings.IDAPath == null || !File.Exists(ProgramSettings.IDAPath)) ProgramSettings.IDAPath = ResolveMethod.GetIDAT(); if (binaryPath.Count == 0) return null; resolvingForm = new ResolvingForm(binaryPath); Thread uiThread = new Thread(StartResolvingForm); @@ -296,7 +296,7 @@ internal String Resolve(String idl, List binaryPath) if (resolvingForm.resolveDone) { - String[] files = Directory.GetFiles("DLLs", binaryPath[i] + "*"); + String[] files = Directory.GetFiles("DLLs", Path.GetFileName(binaryPath[i]) + "*"); foreach (String file in files) { @@ -442,7 +442,6 @@ internal String GetServiceName() // Find pid of service. internal int GetServicePid(String serviceName) { - string query = $"SELECT Name,ProcessId FROM Win32_Service WHERE Name LIKE '{serviceName}%'"; using (var searcher1 = new System.Management.ManagementObjectSearcher(query)) { @@ -467,7 +466,6 @@ internal int GetServicePid(String serviceName) using (var searcher2 = new System.Management.ManagementObjectSearcher(query)) { foreach (var obj in searcher2.Get()) { - MessageBox.Show($"Name2: {obj["Name"]}, PID1: {obj["ProcessId"]} "); return Convert.ToInt32(obj["ProcessId"]); } } @@ -496,7 +494,6 @@ internal int GetServicePid(String serviceName) { foreach (var obj in searcher2.Get()) { - MessageBox.Show($"Name2: {obj["Name"]}, PID2: {obj["ProcessId"]} "); return Convert.ToInt32(obj["ProcessId"]); } } diff --git a/OleViewDotNet/OleViewDotNet.csproj b/OleViewDotNet/OleViewDotNet.csproj index 5348a342..57ce3e34 100644 --- a/OleViewDotNet/OleViewDotNet.csproj +++ b/OleViewDotNet/OleViewDotNet.csproj @@ -39,6 +39,11 @@ + + + + + PreserveNewest @@ -46,6 +51,9 @@ Always + + Always + Always diff --git a/OleViewDotNet/ProgramSettings.cs b/OleViewDotNet/ProgramSettings.cs index a2d10dca..15f75b4a 100644 --- a/OleViewDotNet/ProgramSettings.cs +++ b/OleViewDotNet/ProgramSettings.cs @@ -67,6 +67,8 @@ private sealed class ConfigFile public bool ResolveMethodDllFix { get; set; } [DataMember] public String FixedDll { get; set; } + [DataMember] + public String IDAPath { get; set; } /* Added */ public static ConfigFile Load() @@ -219,6 +221,12 @@ public static String FixedDll get => _config.Value.FixedDll; set => _config.Value.FixedDll = value; } + + public static String IDAPath + { + get => _config.Value.IDAPath; + set => _config.Value.IDAPath = value; + } /* Added */ public static bool AlwaysShowSourceCode