Add whole project
This commit is contained in:
parent
c3a8ee9d1c
commit
f557104055
|
@ -0,0 +1 @@
|
|||
/Build
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,34 @@
|
|||
cmake_minimum_required (VERSION 3.0.2)
|
||||
|
||||
project(RpcView)
|
||||
|
||||
set(RPCVIEW_VERSION_MAJOR 0)
|
||||
set(RPCVIEW_VERSION_MINOR 2)
|
||||
set(RPCVIEW_VERSION_RELEASE 0)
|
||||
|
||||
# configure a header file to pass some of the CMake settings to the source code
|
||||
configure_file (
|
||||
"RpcView/RpcViewVersion.h.in"
|
||||
"${PROJECT_BINARY_DIR}/RpcViewVersion.h"
|
||||
)
|
||||
|
||||
# add the binary tree to the search path for include files
|
||||
# so that we will find RpcViewVersion.h
|
||||
include_directories("${PROJECT_BINARY_DIR}")
|
||||
|
||||
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "/W3 /WX /MTd /EHsc /Zi")
|
||||
set(CMAKE_C_FLAGS_DEBUG "/W4 /WX /MTd /EHsc /Zi")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "/W3 /WX /O2 /Oi /Ot /Gy /MT /EHsc /MP")
|
||||
set(CMAKE_C_FLAGS_RELEASE "/W4 /WX /O2 /Oi /Ot /Gy /MT /EHsc /MP")
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "/INCREMENTAL:NO /OPT:REF /OPT:ICF")
|
||||
|
||||
add_definitions(-D_MBCS)
|
||||
|
||||
add_subdirectory(RpcView)
|
||||
add_subdirectory(RpcDecompiler)
|
||||
add_subdirectory(RpcCore)
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef _RPCVIEW_QT_H_
|
||||
#define _RPCVIEW_QT_H_
|
||||
|
||||
#define QT_BUILD_CONFIGURE
|
||||
#define NOMINMAX
|
||||
#include <QtGui/QSortFilterProxyModel>
|
||||
#include <QtGui/QStandardItemModel>
|
||||
#include <QtGui/QDockWidget>
|
||||
#include <QtGui/QLabel>
|
||||
#include <QtGui/QTreeView>
|
||||
#include <QtGui/QGridLayout>
|
||||
#include <QtGui/QGroupBox>
|
||||
#include <QtGui/QDockWidget>
|
||||
#include <QtGui/QTextEdit>
|
||||
#include <QtGui/QLineEdit>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QFormLayout>
|
||||
#include <QtGui/QAbstractItemView>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QMainWindow>
|
||||
#include <QtGui/QStatusBar>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QActionGroup>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QMenuBar>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QTreeWidgetItem>
|
||||
#include <QtGui/QTreeWidget>
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QProcess>
|
||||
#include <QtGui/QSplashScreen>
|
||||
#include <QtGui/QHeaderView>
|
||||
#include <QtGui/QSyntaxHighlighter>
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtGui/QColorDialog>
|
||||
#include <QtGui/QInputDialog>
|
||||
#include <QtGui/QCheckBox>
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QtGui/QStackedWidget>
|
||||
#include <QtGui/QKeyEvent>
|
||||
#include <QtGui/QToolButton>
|
||||
#include <QtGui/QDialogButtonBox>
|
||||
#include <QtCore/QSignalMapper>
|
||||
|
||||
#endif
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,105 @@
|
|||
# RpcView #
|
||||
|
||||
RpcView is a free tool to explore and decompile all RPC functionalities present on a Microsoft system.
|
||||
|
||||
## Compilation ##
|
||||
|
||||
Required elements to compiled the project:
|
||||
|
||||
* Visual Studio (currently Visual Studio 2015 community)
|
||||
* CMake (at least 3.0.2)
|
||||
* Qt4 (currently 4.8.6)
|
||||
|
||||
Before running CMake you have to set the CMAKE_PREFIX_PATH environment variable with the current Qt path, for instance:
|
||||
```
|
||||
set CMAKE_PREFIX_PATH=C:\Qt\4.8.6
|
||||
```
|
||||
Then you can run CMake to produce the project solution.
|
||||
Here is an example to generate the x64 solution with Visual Studio 2053 from the ```RpcView/Build/x64``` directory:
|
||||
|
||||
```cmake
|
||||
cmake -G"Visual Studio 14 2015 Win64" ../../
|
||||
-- The C compiler identification is MSVC 19.0.24215.1
|
||||
-- The CXX compiler identification is MSVC 19.0.24215.1
|
||||
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe
|
||||
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe -- works
|
||||
-- Detecting C compiler ABI info
|
||||
-- Detecting C compiler ABI info - done
|
||||
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe
|
||||
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe -- works
|
||||
-- Detecting CXX compiler ABI info
|
||||
-- Detecting CXX compiler ABI info - done
|
||||
-- Detecting CXX compile features
|
||||
-- Detecting CXX compile features - done
|
||||
[RpcView]
|
||||
-- Looking for Q_WS_X11
|
||||
-- Looking for Q_WS_X11 - not found
|
||||
-- Looking for Q_WS_WIN
|
||||
-- Looking for Q_WS_WIN - found
|
||||
-- Looking for Q_WS_QWS
|
||||
-- Looking for Q_WS_QWS - not found
|
||||
-- Looking for Q_WS_MAC
|
||||
-- Looking for Q_WS_MAC - not found
|
||||
-- Found Qt4: C:/Qt/4.8.6/bin/qmake.exe (found version "4.8.6")
|
||||
-- Target is 64 bits
|
||||
[RpcDecompiler]
|
||||
[RpcCore1_32bits]
|
||||
[RpcCore2_32bits]
|
||||
[RpcCore2_64bits]
|
||||
[RpcCore3_32bits]
|
||||
[RpcCore3_64bits]
|
||||
[RpcCore4_32bits]
|
||||
[RpcCore4_64bits]
|
||||
-- Configuring done
|
||||
-- Generating done
|
||||
-- Build files have been written to: C:/Dev/RpcView/Build/x64
|
||||
```
|
||||
|
||||
To produce the Win32 solution with Visual Studio 2015 from the ```RpcView/Build/x86``` directory:
|
||||
```cmake
|
||||
cmake -G"Visual Studio 14 2015" ../../
|
||||
-- The C compiler identification is MSVC 19.0.24215.1
|
||||
-- The CXX compiler identification is MSVC 19.0.24215.1
|
||||
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/cl.exe
|
||||
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/cl.exe -- works
|
||||
-- Detecting C compiler ABI info
|
||||
-- Detecting C compiler ABI info - done
|
||||
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/cl.exe
|
||||
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/cl.exe -- works
|
||||
-- Detecting CXX compiler ABI info
|
||||
-- Detecting CXX compiler ABI info - done
|
||||
-- Detecting CXX compile features
|
||||
-- Detecting CXX compile features - done
|
||||
[RpcView]
|
||||
-- Looking for Q_WS_X11
|
||||
-- Looking for Q_WS_X11 - not found
|
||||
-- Looking for Q_WS_WIN
|
||||
-- Looking for Q_WS_WIN - found
|
||||
-- Looking for Q_WS_QWS
|
||||
-- Looking for Q_WS_QWS - not found
|
||||
-- Looking for Q_WS_MAC
|
||||
-- Looking for Q_WS_MAC - not found
|
||||
-- Found Qt4: C:/Qt/4.8.6/bin/qmake.exe (found version "4.8.6")
|
||||
-- Target is 32 bits
|
||||
[RpcDecompiler]
|
||||
[RpcCore1_32bits]
|
||||
[RpcCore2_32bits]
|
||||
[RpcCore3_32bits]
|
||||
[RpcCore4_32bits]
|
||||
-- Configuring done
|
||||
-- Generating done
|
||||
-- Build files have been written to: C:/Dev/RpcView/Build/x86
|
||||
```
|
||||
Now you can compile the solution with Visual Studio or CMAKE:
|
||||
|
||||
```
|
||||
cmake --build . --config Release
|
||||
```
|
||||
|
||||
RpcView32 binaries are produced in the ```RpcView/Build/bin/x86``` directory and RpcView64 ones in the ```RpcView/Build/bin/x64```
|
||||
|
||||
## Acknowledgements ##
|
||||
* Jeremy
|
||||
* Julien
|
||||
* Yoanne
|
||||
* Bruno
|
|
@ -0,0 +1,402 @@
|
|||
#include <windows.h>
|
||||
#include <Psapi.h>
|
||||
#include <Tlhelp32.h>
|
||||
#include <conio.h>
|
||||
#include <strsafe.h>
|
||||
#include "Misc.h"
|
||||
#include "RpcCommon.h"
|
||||
#include "ntdll.h"
|
||||
|
||||
#pragma comment(lib,"psapi.lib")
|
||||
#pragma comment(lib,"strsafe.lib")
|
||||
#pragma comment(lib,"Version.lib")
|
||||
|
||||
#define MAX_DRIVE_INDEX 26
|
||||
|
||||
typedef struct _LanguageCodePage_T {
|
||||
WORD wLanguage;
|
||||
WORD wCodePage;
|
||||
} LanguageCodePage_T;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL WINAPI AdjustPrivilege(LPCTSTR lpPrivilegeName,BOOL bEnablePrivilege)
|
||||
{
|
||||
TOKEN_PRIVILEGES TokenPrivilege;
|
||||
LUID Luid;
|
||||
HANDLE hToken = NULL;
|
||||
BOOL bResult=FALSE;
|
||||
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken)) { goto End; }
|
||||
if (!LookupPrivilegeValue(NULL,lpPrivilegeName,&Luid)) {goto End;}
|
||||
TokenPrivilege.PrivilegeCount =1;
|
||||
TokenPrivilege.Privileges[0].Luid=Luid;
|
||||
if (bEnablePrivilege) TokenPrivilege.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
|
||||
else TokenPrivilege.Privileges[0].Attributes=0;
|
||||
if (!AdjustTokenPrivileges(hToken,FALSE,&TokenPrivilege,sizeof(TOKEN_PRIVILEGES),NULL,NULL)) {goto End;}
|
||||
if (GetLastError() == ERROR_SUCCESS) bResult=TRUE;
|
||||
End:
|
||||
if (hToken != NULL) CloseHandle(hToken);
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL WINAPI EnumProcess(EnumProcessCallbackFn_T EnumProcessCallbackFn,void* pCallbackCtxt)
|
||||
{
|
||||
BOOL bResult=FALSE;
|
||||
HANDLE hSnapshot;
|
||||
PROCESSENTRY32W ProcessEntry;
|
||||
BOOL bContinue=TRUE;
|
||||
|
||||
hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
|
||||
if (hSnapshot==NULL) goto End;
|
||||
ProcessEntry.dwSize=sizeof(ProcessEntry);
|
||||
if (!Process32FirstW(hSnapshot,&ProcessEntry)) goto End;
|
||||
do
|
||||
{
|
||||
bResult=EnumProcessCallbackFn(ProcessEntry.th32ProcessID,ProcessEntry.th32ParentProcessID,pCallbackCtxt,&bContinue);
|
||||
if (!bResult) goto End;
|
||||
if (!bContinue) break;
|
||||
|
||||
}while(Process32NextW(hSnapshot,&ProcessEntry));
|
||||
End:
|
||||
if (hSnapshot!=NULL) CloseHandle(hSnapshot);
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL WINAPI GetModuleDescription(WCHAR* pModulePath,WCHAR* pDescription,UINT Bytes)
|
||||
{
|
||||
DWORD dwHandle;
|
||||
DWORD InfoSize;
|
||||
UINT cbTranslate;
|
||||
LanguageCodePage_T* lpTranslate;
|
||||
UINT Size;
|
||||
UINT i;
|
||||
WCHAR SubBlock[MAX_PATH];
|
||||
WCHAR* lpBuffer;
|
||||
BOOL bResult=FALSE;
|
||||
VOID* pData=NULL;
|
||||
//
|
||||
// Read the list of languages and code pages.
|
||||
//
|
||||
InfoSize=GetFileVersionInfoSizeW(pModulePath,&dwHandle);
|
||||
pData=OS_ALLOC(InfoSize);
|
||||
if (pData==NULL) goto End;
|
||||
|
||||
if (!GetFileVersionInfoW(pModulePath,0,InfoSize,pData)) goto End;
|
||||
|
||||
if (!VerQueryValueW(pData, L"\\VarFileInfo\\Translation", (LPVOID*)&lpTranslate,&cbTranslate)) goto End;
|
||||
//
|
||||
// Read the file description for each language and code page.
|
||||
//
|
||||
for(i=0; i < (cbTranslate/sizeof(LanguageCodePage_T)); i++)
|
||||
{
|
||||
StringCbPrintfW(SubBlock,sizeof(SubBlock),L"\\StringFileInfo\\%04x%04x\\FileDescription",lpTranslate[i].wLanguage,lpTranslate[i].wCodePage);
|
||||
//
|
||||
// Retrieve file description for language and code page "i".
|
||||
//
|
||||
if (VerQueryValueW(pData,SubBlock,(LPVOID*)&lpBuffer,&Size))
|
||||
{
|
||||
StringCbPrintfW(pDescription,Bytes,L"%s",lpBuffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
bResult=TRUE;
|
||||
End:
|
||||
if (pData!=NULL) OS_FREE(pData);
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL WINAPI GetLocationInfo(HANDLE hProcess, VOID* pAddress, LocationInfo_T* pLocationInfo)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION MemBasicInfo;
|
||||
DWORD DriveMask;
|
||||
WCHAR DriveIdx;
|
||||
WCHAR NativeLocation[RPC_MAX_LENGTH];
|
||||
WCHAR DeviceName[RPC_MAX_LENGTH];
|
||||
WCHAR* pPath;
|
||||
WCHAR DosDevice[]=L"X:";
|
||||
BOOL bResult=FALSE;
|
||||
|
||||
if (pLocationInfo == NULL) goto End;
|
||||
//
|
||||
// Get Memory location informations
|
||||
//
|
||||
ZeroMemory(pLocationInfo, sizeof(LocationInfo_T));
|
||||
if (!VirtualQueryEx(hProcess, pAddress, &MemBasicInfo, sizeof(MemBasicInfo))) goto End;
|
||||
pLocationInfo->pBaseAddress = MemBasicInfo.BaseAddress;
|
||||
pLocationInfo->State = MemBasicInfo.State;
|
||||
pLocationInfo->Type = MemBasicInfo.Type;
|
||||
pLocationInfo->Size = MemBasicInfo.RegionSize;
|
||||
//
|
||||
// Get the native mapped file name containing the specified address
|
||||
//
|
||||
if (!GetMappedFileNameW(hProcess, pAddress, NativeLocation, _countof(NativeLocation))) goto End;
|
||||
//
|
||||
// Get the correponding Win32 path
|
||||
//
|
||||
DriveMask=GetLogicalDrives();
|
||||
for (DriveIdx=0; DriveIdx < MAX_DRIVE_INDEX; DriveIdx++)
|
||||
{
|
||||
if (DriveMask & (1 << DriveIdx))
|
||||
{
|
||||
DosDevice[0]=L'A'+DriveIdx;
|
||||
if (QueryDosDeviceW(DosDevice,DeviceName,_countof(DeviceName))!=0)
|
||||
{
|
||||
pPath=wcsstr(NativeLocation,DeviceName);
|
||||
if (pPath!=NULL)
|
||||
{
|
||||
StringCbPrintfW(pLocationInfo->Location, sizeof(pLocationInfo->Location), L"%s%s", DosDevice, NativeLocation + wcslen(DeviceName));
|
||||
bResult=TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
End:
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
typedef VOID (WINAPI* RtlGetUnloadEventTraceExFn_T)(
|
||||
_Out_ PULONG *ElementSize,
|
||||
_Out_ PULONG *ElementCount,
|
||||
_Out_ PVOID *EventTrace
|
||||
);
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct _RTL_UNLOAD_EVENT_TRACE {
|
||||
void* BaseAddress; // Base address of dll
|
||||
SIZE_T SizeOfImage; // Size of image
|
||||
ULONG Sequence; // Sequence number for this event
|
||||
ULONG TimeDateStamp; // Time and date of image
|
||||
ULONG CheckSum; // Image checksum
|
||||
WCHAR ImageName[32]; // Image name
|
||||
} RTL_UNLOAD_EVENT_TRACE, *PRTL_UNLOAD_EVENT_TRACE;
|
||||
#pragma pack()
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL WINAPI GetUnloadedLocationInfo(HANDLE hProcess, VOID* pAddress, LocationInfo_T* pLocationInfo)
|
||||
{
|
||||
RtlGetUnloadEventTraceExFn_T RtlGetUnloadEventTraceExFn = NULL;
|
||||
ULONG* pElementSize = NULL;
|
||||
ULONG* pElementCount = NULL;
|
||||
UCHAR* pEventTrace = NULL;
|
||||
RTL_UNLOAD_EVENT_TRACE* pUnloadEventTrace = NULL;
|
||||
ULONG ElementSize = 0;
|
||||
ULONG ElementCount = 0;
|
||||
BOOL bResult = FALSE;
|
||||
ULONG i = 0;
|
||||
|
||||
RtlGetUnloadEventTraceExFn = (RtlGetUnloadEventTraceExFn_T)GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlGetUnloadEventTraceEx");
|
||||
if (RtlGetUnloadEventTraceExFn == NULL) goto End;
|
||||
//
|
||||
// Get addresses of ElementSize, ElementCount and pEventTrace in the ntdll
|
||||
//
|
||||
RtlGetUnloadEventTraceExFn(&pElementSize, &pElementCount, &pEventTrace);
|
||||
//
|
||||
// Read their values in the target process
|
||||
//
|
||||
if (!ReadProcessMemory(hProcess, pElementSize, &ElementSize, sizeof(ElementSize), NULL)) goto End;
|
||||
pUnloadEventTrace = (RTL_UNLOAD_EVENT_TRACE*)OS_ALLOC(ElementSize);
|
||||
if (pUnloadEventTrace == NULL) goto End;
|
||||
if (!ReadProcessMemory(hProcess, pElementCount, &ElementCount, sizeof(ElementCount), NULL)) goto End;
|
||||
if (!ReadProcessMemory(hProcess, pEventTrace, &pEventTrace, sizeof(pEventTrace), NULL)) goto End;
|
||||
//
|
||||
// Look for the unloaded module
|
||||
//
|
||||
for (i = 0; i < ElementCount; i++)
|
||||
{
|
||||
if (!ReadProcessMemory(hProcess, pEventTrace, pUnloadEventTrace, ElementSize, NULL)) goto End;
|
||||
if (pUnloadEventTrace->BaseAddress == NULL) break;
|
||||
if (((SIZE_T)pAddress >= (SIZE_T)pUnloadEventTrace->BaseAddress) &&
|
||||
((SIZE_T)pAddress < ((SIZE_T)pUnloadEventTrace->BaseAddress + pUnloadEventTrace->SizeOfImage)))
|
||||
{
|
||||
pLocationInfo->pBaseAddress = pUnloadEventTrace->BaseAddress;
|
||||
pLocationInfo->Size = pUnloadEventTrace->SizeOfImage;
|
||||
memcpy(pLocationInfo->Location, pUnloadEventTrace->ImageName, sizeof(pLocationInfo->Location));
|
||||
break;
|
||||
}
|
||||
pEventTrace += ElementSize;
|
||||
}
|
||||
End:
|
||||
if (pUnloadEventTrace != NULL) OS_FREE(pUnloadEventTrace);
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
UINT64 WINAPI GetModuleVersion(WCHAR* pModulePath)
|
||||
{
|
||||
DWORD dwHandle;
|
||||
DWORD VersionInfoSize;
|
||||
VS_FIXEDFILEINFO* pFixedFileInfo;
|
||||
LARGE_INTEGER ModuleVersion;
|
||||
UINT Size;
|
||||
VOID* pVersionData = NULL;
|
||||
|
||||
ModuleVersion.QuadPart = 0;
|
||||
VersionInfoSize = GetFileVersionInfoSizeW(pModulePath, &dwHandle);
|
||||
pVersionData = OS_ALLOC( VersionInfoSize );
|
||||
if (pVersionData==NULL) goto End;
|
||||
|
||||
if (!GetFileVersionInfoW(pModulePath, 0, VersionInfoSize, pVersionData)) goto End;
|
||||
|
||||
if (!VerQueryValueW( pVersionData, L"\\", (VOID**)&pFixedFileInfo, &Size )) goto End;
|
||||
ModuleVersion.HighPart = pFixedFileInfo->dwProductVersionMS;
|
||||
ModuleVersion.LowPart = pFixedFileInfo->dwProductVersionLS;
|
||||
End:
|
||||
if (pVersionData!=NULL) OS_FREE(pVersionData);
|
||||
return (ModuleVersion.QuadPart);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL WINAPI GetProcessPebInfo(HANDLE hProcess,WCHAR* pCmdLine,UINT CmdLineLength,WCHAR* pDesktop,UINT DesktopLength)
|
||||
{
|
||||
PROCESS_PARAMETERS ProcessParameters;
|
||||
NTSTATUS Status;
|
||||
PEB Peb;
|
||||
WCHAR TmpBuffer[MAX_PATH];
|
||||
BOOL bResult=FALSE;
|
||||
PROCESS_BASIC_INFORMATION ProcessBasicInfo;
|
||||
//
|
||||
// Get process Basic Info
|
||||
//
|
||||
Status=NtQueryInformationProcess(hProcess,ProcessBasicInformation,&ProcessBasicInfo,sizeof(ProcessBasicInfo),NULL);
|
||||
if (Status != STATUS_SUCCESS) goto End;
|
||||
//
|
||||
// Read the PEB
|
||||
//
|
||||
if (!ReadProcessMemory(hProcess,ProcessBasicInfo.PebBaseAddress,&Peb,sizeof(Peb),NULL)) goto End;
|
||||
//
|
||||
// Read the process parameters
|
||||
//
|
||||
ZeroMemory(&ProcessParameters,sizeof(ProcessParameters));
|
||||
if (!ReadProcessMemory(hProcess,Peb.ProcessParameters,&ProcessParameters,sizeof(ProcessParameters),NULL)) goto End;
|
||||
//
|
||||
// Read the CmdLine
|
||||
//
|
||||
if (!ReadProcessMemory(hProcess,ProcessParameters.CommandLine.Buffer,TmpBuffer,sizeof(TmpBuffer),NULL)) goto End;
|
||||
StringCbPrintfW(pCmdLine,CmdLineLength,L"%s",TmpBuffer);
|
||||
//
|
||||
// Read the Desktop
|
||||
//
|
||||
if (!ReadProcessMemory(hProcess,ProcessParameters.Desktop.Buffer,TmpBuffer,sizeof(TmpBuffer),NULL)) goto End;
|
||||
StringCbPrintfW(pDesktop,DesktopLength,L"%s",TmpBuffer);
|
||||
bResult=TRUE;
|
||||
End:
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL WINAPI GetProcessNameFromPid(DWORD Pid,WCHAR* pName,UINT NameSizeInBytes)
|
||||
{
|
||||
HANDLE hProcessSnapshot = INVALID_HANDLE_VALUE;
|
||||
BOOL bResult = FALSE;
|
||||
PROCESSENTRY32W ProcessEntry;
|
||||
|
||||
hProcessSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
|
||||
if (hProcessSnapshot==INVALID_HANDLE_VALUE) goto End;
|
||||
ProcessEntry.dwSize=sizeof(ProcessEntry);
|
||||
if (!Process32FirstW(hProcessSnapshot,&ProcessEntry)) goto End;
|
||||
do
|
||||
{
|
||||
if (Pid==ProcessEntry.th32ProcessID)
|
||||
{
|
||||
StringCbPrintfW(pName,NameSizeInBytes,L"%s",ProcessEntry.szExeFile);
|
||||
break;
|
||||
}
|
||||
}while( Process32NextW(hProcessSnapshot,&ProcessEntry) );
|
||||
bResult=TRUE;
|
||||
End:
|
||||
if (hProcessSnapshot!=INVALID_HANDLE_VALUE) CloseHandle(hProcessSnapshot);
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL WINAPI GetProcessPath(DWORD Pid, WCHAR* pProcessPath, DWORD ProcessPathLength)
|
||||
{
|
||||
HANDLE hProcess;
|
||||
BOOL bResult = FALSE;
|
||||
DWORD Size;
|
||||
|
||||
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
|
||||
if (hProcess == NULL) goto End;
|
||||
Size = ProcessPathLength;
|
||||
bResult = QueryFullProcessImageNameW(hProcess, 0, pProcessPath, &Size);
|
||||
End:
|
||||
if (hProcess!=NULL) CloseHandle(hProcess);
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL WINAPI GetRegValueData(HKEY hRootKey,WCHAR* pSubkeyName,WCHAR* pValueName,VOID* pData,UINT DataLength)
|
||||
{
|
||||
DWORD Size;
|
||||
HKEY hKey = NULL;
|
||||
BOOL bResult = FALSE;
|
||||
|
||||
if (RegOpenKeyExW(hRootKey,pSubkeyName,0,KEY_READ,&hKey)!=ERROR_SUCCESS) goto End;
|
||||
Size = DataLength;
|
||||
if (RegQueryValueExW(hKey,pValueName,NULL,NULL,(LPBYTE)pData,&Size)!=ERROR_SUCCESS) goto End;
|
||||
bResult=TRUE;
|
||||
End:
|
||||
if (hKey!=NULL) RegCloseKey(hKey);
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL WINAPI GetUserAndDomainName(DWORD Pid, WCHAR* Buffer, ULONG BufferLengthInBytes)
|
||||
{
|
||||
HANDLE hProcess = NULL;
|
||||
HANDLE hToken = NULL;
|
||||
DWORD Bytes;
|
||||
TOKEN_USER* pTokenUser=NULL;
|
||||
WCHAR UserName[RPC_MAX_LENGTH];
|
||||
WCHAR DomainName[RPC_MAX_LENGTH];
|
||||
DWORD dwSize;
|
||||
SID_NAME_USE SidType;
|
||||
BOOL bResult = FALSE;
|
||||
|
||||
hProcess = OpenProcess(PROCESS_VM_OPERATION|PROCESS_QUERY_INFORMATION,FALSE,Pid);
|
||||
if (hProcess==NULL) goto End;
|
||||
|
||||
if (!OpenProcessToken(hProcess,TOKEN_QUERY,&hToken)) goto End;
|
||||
GetTokenInformation(hToken,TokenUser,NULL,0,&Bytes);
|
||||
pTokenUser=(TOKEN_USER*)OS_ALLOC(Bytes);
|
||||
if (pTokenUser==NULL) goto End;
|
||||
if (!GetTokenInformation(hToken,TokenUser,pTokenUser,Bytes,&Bytes)) goto End;
|
||||
dwSize=sizeof(UserName);
|
||||
if (!LookupAccountSidW(NULL,pTokenUser->User.Sid,UserName,&dwSize,DomainName,&dwSize,&SidType)) goto End;
|
||||
StringCbPrintfW(Buffer,BufferLengthInBytes,L"%s\\%s",DomainName,UserName);
|
||||
bResult=TRUE;
|
||||
End:
|
||||
if (pTokenUser!=NULL) OS_FREE(pTokenUser);
|
||||
if (hToken!=NULL) CloseHandle(hToken);
|
||||
if (hProcess!=NULL) CloseHandle(hProcess);
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL WINAPI IsProcessWow64(ULONG Pid)
|
||||
{
|
||||
BOOL bWow64 = FALSE;
|
||||
HANDLE hProcess = NULL;
|
||||
|
||||
hProcess = OpenProcess(PROCESS_VM_OPERATION|PROCESS_QUERY_INFORMATION,FALSE,Pid);
|
||||
if (hProcess==NULL) goto End;
|
||||
IsWow64Process(hProcess,&bWow64);
|
||||
End:
|
||||
if (hProcess!=NULL) CloseHandle(hProcess);
|
||||
return (bWow64);
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef _MISC_H_
|
||||
#define _MISC_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4201)
|
||||
//To represent a version as either 64bits value or x.x.x.x
|
||||
typedef struct _Version_T{
|
||||
union{
|
||||
UINT64 As64BitsValue;
|
||||
struct{
|
||||
USHORT Part1;
|
||||
USHORT Part2;
|
||||
USHORT Part3;
|
||||
USHORT Part4;
|
||||
}As16BitsValues;
|
||||
};
|
||||
}Version_T;
|
||||
#pragma warning(pop)
|
||||
|
||||
typedef struct _LocationInfo_T{
|
||||
WCHAR Location[MAX_PATH];
|
||||
VOID* pBaseAddress;
|
||||
DWORD State;
|
||||
DWORD Type;
|
||||
SIZE_T Size;
|
||||
}LocationInfo_T;
|
||||
|
||||
|
||||
BOOL WINAPI AdjustPrivilege(LPCTSTR lpPrivilegeName,BOOL bEnablePrivilege);
|
||||
BOOL WINAPI GetModuleDescription(WCHAR* pModulePath,WCHAR* pDescription,UINT Bytes);
|
||||
UINT64 WINAPI GetModuleVersion(WCHAR* pModulePath);
|
||||
BOOL WINAPI GetLocationInfo(HANDLE hProcess, VOID* pAddress, LocationInfo_T* pLocationInfo);
|
||||
BOOL WINAPI GetUnloadedLocationInfo(HANDLE hProcess, VOID* pAddress, LocationInfo_T* pLocationInfo);
|
||||
BOOL WINAPI GetProcessNameFromPid(DWORD Pid,WCHAR* pName,UINT NameSizeInBytes);
|
||||
BOOL WINAPI GetProcessPath(DWORD Pid, WCHAR* pProcessPath, DWORD ProcessPathLength);
|
||||
BOOL WINAPI GetProcessPebInfo(HANDLE hProcess,WCHAR* pCmdLine,UINT CmdLineLength,WCHAR* pDesktop,UINT DesktopLength);
|
||||
BOOL WINAPI GetRegValueData(HKEY hRootKey,WCHAR* pSubkeyName,WCHAR* pValueName,VOID* pData,UINT DataLength);
|
||||
BOOL WINAPI GetUserAndDomainName(DWORD Pid, WCHAR* Buffer, ULONG BufferLengthInBytes);
|
||||
BOOL WINAPI IsProcessWow64(ULONG Pid);
|
||||
VOID WINAPI PrintUUID(UUID* pUUID);
|
||||
HANDLE WINAPI KphOpenProcess(_In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_ DWORD dwProcessId);
|
||||
|
||||
typedef BOOL (WINAPI* EnumProcessCallbackFn_T)(DWORD Pid, DWORD Ppid, VOID* pContext, BOOL* pbContinue);
|
||||
BOOL WINAPI EnumProcess(EnumProcessCallbackFn_T EnumProcessCallbackFn, void* pCallbackCtxt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //_MISC_H_
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef _RPC_COMMON_H_
|
||||
#define _RPC_COMMON_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define INVALID_PID_VALUE ((UINT)-1)
|
||||
#define INVALID_PROC_COUNT ((UINT)-1)
|
||||
#define RPC_MAX_LENGTH 260
|
||||
#define INVALID_IF_CALLBACK_ADDRESS 0x400000
|
||||
#define HEX_SIZE_OF_PTR (2*sizeof(void*))
|
||||
|
||||
typedef enum _AddressRepresentation_T{
|
||||
AddressRepresentation_Unknown = 0,
|
||||
AddressRepresentation_Absolute,
|
||||
AddressRepresentation_RVA
|
||||
}AddressRepresentation_T;
|
||||
|
||||
#ifdef _DEBUG
|
||||
//
|
||||
// DEBUG
|
||||
//
|
||||
#ifndef DBG_NEW
|
||||
#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
|
||||
#define new DBG_NEW
|
||||
#endif
|
||||
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <stdlib.h>
|
||||
#include <crtdbg.h>
|
||||
|
||||
#define OS_FREE(pMem) free(pMem)
|
||||
#define OS_ALLOC(Size) calloc(Size,1);
|
||||
#define OS_DEBUG(...) _cprintf(__VA_ARGS__)
|
||||
#define DEBUG_BREAK() __debugbreak()
|
||||
#else
|
||||
//
|
||||
// RELEASE
|
||||
//
|
||||
#define OS_FREE(pMem) HeapFree(GetProcessHeap(), 0, pMem)
|
||||
#define OS_ALLOC(Size) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size)
|
||||
#define OS_DEBUG(...) _cprintf(__VA_ARGS__)
|
||||
#define DEBUG_BREAK()
|
||||
#endif // _DEBUG
|
||||
|
||||
#endif//_RPC_COMMON_H_
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef _RPC_VIEW_H_
|
||||
#define _RPC_VIEW_H_
|
||||
|
||||
#include "RpcCommon.h"
|
||||
#include <Windows.h>
|
||||
|
||||
typedef ULONG RVA_T;
|
||||
|
||||
typedef struct _RpcModuleInfo_T
|
||||
{
|
||||
UINT Pid;
|
||||
UINT64 pModuleBase;
|
||||
}RpcModuleInfo_T;
|
||||
|
||||
typedef VOID* (__fastcall* RpcAllocFn_T)(SIZE_T Size);
|
||||
typedef VOID (__fastcall* RpcFreeFn_T)(VOID* pMem);
|
||||
typedef BOOL (__fastcall* RpcGetProcessDataFn_T)(RpcModuleInfo_T* pRpcModuleInfo, RVA_T rva, VOID* pBuffer, UINT BufferLength);
|
||||
typedef VOID (__cdecl* RpcPrintFn_T)(void* pContext, const char* pTxt);
|
||||
typedef VOID (__cdecl* RpcDebugFn_T)(const char* pFunction, ULONG Line, const char* pFormatString,...);
|
||||
typedef BOOL (__fastcall* RpcGetInterfaceNameFn_T)(GUID* pIfId,UCHAR* pName,ULONG NameLength);
|
||||
|
||||
//Framework helper for decompilation plugin
|
||||
typedef struct _RpcViewHelper_T{
|
||||
void* pContext;
|
||||
RpcAllocFn_T RpcAlloc;
|
||||
RpcFreeFn_T RpcFree;
|
||||
RpcGetProcessDataFn_T RpcGetProcessData;
|
||||
RpcPrintFn_T RpcPrint;
|
||||
RpcDebugFn_T RpcDebug;
|
||||
RpcGetInterfaceNameFn_T RpcGetInterfaceName;
|
||||
}RpcViewHelper_T;
|
||||
|
||||
#endif //_RPC_VIEW_H_
|
|
@ -0,0 +1,25 @@
|
|||
#include "ntdll.h"
|
||||
|
||||
NtQueryInformationProcessFn_T NtQueryInformationProcessFn = NULL;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
NTSTATUS NTAPI NtQueryInformationProcess(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN PROCESSINFOCLASS ProcessInformationClass,
|
||||
OUT PVOID ProcessInformation,
|
||||
IN ULONG ProcessInformationLength,
|
||||
OUT PULONG ReturnLength OPTIONAL
|
||||
)
|
||||
{
|
||||
if (NtQueryInformationProcessFn == NULL)
|
||||
{
|
||||
NtQueryInformationProcessFn = (NtQueryInformationProcessFn_T)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryInformationProcess");
|
||||
}
|
||||
return NtQueryInformationProcessFn(
|
||||
ProcessHandle,
|
||||
ProcessInformationClass,
|
||||
ProcessInformation,
|
||||
ProcessInformationLength,
|
||||
ReturnLength);
|
||||
}
|
|
@ -0,0 +1,351 @@
|
|||
#ifndef _NTDLL_H_
|
||||
#define _NTDLL_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef LONG KPRIORITY;
|
||||
|
||||
typedef struct _UNICODE_STRING{
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWSTR Buffer;
|
||||
}UNICODE_STRING,*PUNICODE_STRING;
|
||||
|
||||
|
||||
typedef VOID (NTAPI* RtlInitUnicodeStringFn_T)(
|
||||
__out PUNICODE_STRING DestinationString,
|
||||
__in_z_opt __drv_aliasesMem PCWSTR SourceString
|
||||
);
|
||||
|
||||
VOID NTAPI RtlInitUnicodeString(
|
||||
__out PUNICODE_STRING DestinationString,
|
||||
__in_z_opt __drv_aliasesMem PCWSTR SourceString
|
||||
);
|
||||
|
||||
|
||||
typedef struct _PROCESS_PARAMETERS {
|
||||
ULONG AllocationSize;
|
||||
ULONG Size;
|
||||
ULONG Flags;
|
||||
ULONG Reserved;
|
||||
ULONG_PTR Console;
|
||||
ULONG ProcessGroup;
|
||||
HANDLE hStdInput;
|
||||
HANDLE hStdOutput;
|
||||
HANDLE hStdError;
|
||||
UNICODE_STRING CurrentDirectoryName;
|
||||
HANDLE CurrentDirectoryHandle;
|
||||
UNICODE_STRING DllPath;
|
||||
UNICODE_STRING ImageFile;
|
||||
UNICODE_STRING CommandLine;
|
||||
PWSTR Environment;
|
||||
ULONG dwX;
|
||||
ULONG dwY;
|
||||
ULONG dwXSize;
|
||||
ULONG dwYSize;
|
||||
ULONG dwXCountChars;
|
||||
ULONG dwYCountChars;
|
||||
ULONG dwFillAttribute;
|
||||
ULONG dwFlags;
|
||||
ULONG wShowWindow;
|
||||
UNICODE_STRING WindowTitle;
|
||||
UNICODE_STRING Desktop;
|
||||
UNICODE_STRING Reserved1;
|
||||
UNICODE_STRING Reserved2;
|
||||
} PROCESS_PARAMETERS, *PPROCESS_PARAMETERS;
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4214)
|
||||
typedef struct _PEB{
|
||||
UCHAR InheritedAddressSpace;
|
||||
UCHAR ReadImageFileExecOptions;
|
||||
UCHAR BeingDebugged;
|
||||
UCHAR ImageUsesLargePages : 1;
|
||||
UCHAR IsProtectedProcess : 1;
|
||||
UCHAR IsLegacyProcess : 1;
|
||||
UCHAR IsImageDynamicallyRelocated : 1;
|
||||
UCHAR SpareBits : 4;
|
||||
VOID* Mutant;
|
||||
VOID* ImageBaseAddress;
|
||||
VOID* Ldr;
|
||||
PROCESS_PARAMETERS* ProcessParameters;
|
||||
}PEB;
|
||||
#pragma warning(pop)
|
||||
|
||||
typedef enum _PROCESSINFOCLASS {
|
||||
ProcessBasicInformation, // 0
|
||||
ProcessQuotaLimits, // 1
|
||||
ProcessIoCounters, // 2
|
||||
ProcessVmCounters, // 3
|
||||
ProcessTimes, // 4
|
||||
ProcessBasePriority, // 5
|
||||
ProcessRaisePriority, // 6
|
||||
ProcessDebugPort, // 7
|
||||
ProcessExceptionPort, // 8
|
||||
ProcessAccessToken, // 9
|
||||
ProcessLdtInformation, // 10
|
||||
ProcessLdtSize, // 11
|
||||
ProcessDefaultHardErrorMode, // 12
|
||||
ProcessIoPortHandlers, // 13
|
||||
ProcessPooledUsageAndLimits, // 14
|
||||
ProcessWorkingSetWatch, // 15
|
||||
ProcessUserModeIOPL, // 16
|
||||
ProcessEnableAlignmentFaultFixup, // 17
|
||||
ProcessPriorityClass, // 18
|
||||
ProcessWx86Information, // 19
|
||||
ProcessHandleCount, // 20
|
||||
ProcessAffinityMask, // 21
|
||||
ProcessPriorityBoost, // 22
|
||||
ProcessDeviceMap, // 23
|
||||
ProcessSessionInformation, // 24
|
||||
ProcessForegroundInformation, // 25
|
||||
ProcessWow64Information // 26
|
||||
} PROCESSINFOCLASS;
|
||||
|
||||
|
||||
typedef NTSTATUS (NTAPI* NtQueryInformationProcessFn_T)(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN PROCESSINFOCLASS ProcessInformationClass,
|
||||
OUT PVOID ProcessInformation,
|
||||
IN ULONG ProcessInformationLength,
|
||||
OUT PULONG ReturnLength OPTIONAL
|
||||
);
|
||||
|
||||
NTSTATUS NTAPI NtQueryInformationProcess(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN PROCESSINFOCLASS ProcessInformationClass,
|
||||
OUT PVOID ProcessInformation,
|
||||
IN ULONG ProcessInformationLength,
|
||||
OUT PULONG ReturnLength OPTIONAL
|
||||
);
|
||||
|
||||
|
||||
#define STATUS_SUCCESS 0
|
||||
|
||||
//
|
||||
// Valid values for the Attributes field
|
||||
//
|
||||
|
||||
#define OBJ_INHERIT 0x00000002L
|
||||
#define OBJ_PERMANENT 0x00000010L
|
||||
#define OBJ_EXCLUSIVE 0x00000020L
|
||||
#define OBJ_CASE_INSENSITIVE 0x00000040L
|
||||
#define OBJ_OPENIF 0x00000080L
|
||||
#define OBJ_OPENLINK 0x00000100L
|
||||
#define OBJ_KERNEL_HANDLE 0x00000200L
|
||||
#define OBJ_FORCE_ACCESS_CHECK 0x00000400L
|
||||
#define OBJ_VALID_ATTRIBUTES 0x000007F2L
|
||||
|
||||
|
||||
typedef struct _PROCESS_BASIC_INFORMATION { // Information Class 0
|
||||
ULONG_PTR ExitStatus;
|
||||
PEB* PebBaseAddress;
|
||||
ULONG_PTR AffinityMask;
|
||||
ULONG_PTR BasePriority;
|
||||
ULONG_PTR UniqueProcessId;
|
||||
ULONG_PTR InheritedFromUniqueProcessId;
|
||||
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
|
||||
|
||||
|
||||
typedef struct _OBJECT_ATTRIBUTES {
|
||||
ULONG Length;
|
||||
HANDLE RootDirectory;
|
||||
PUNICODE_STRING ObjectName;
|
||||
ULONG Attributes;
|
||||
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
|
||||
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
|
||||
} OBJECT_ATTRIBUTES;
|
||||
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
|
||||
typedef CONST OBJECT_ATTRIBUTES *PCOBJECT_ATTRIBUTES;
|
||||
|
||||
//++
|
||||
//
|
||||
// VOID
|
||||
// InitializeObjectAttributes(
|
||||
// __out POBJECT_ATTRIBUTES p,
|
||||
// __in PUNICODE_STRING n,
|
||||
// __in ULONG a,
|
||||
// __in HANDLE r,
|
||||
// __in PSECURITY_DESCRIPTOR s
|
||||
// )
|
||||
//
|
||||
//--
|
||||
|
||||
#define InitializeObjectAttributes( p, n, a, r, s ) { \
|
||||
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
|
||||
(p)->RootDirectory = r; \
|
||||
(p)->Attributes = a; \
|
||||
(p)->ObjectName = n; \
|
||||
(p)->SecurityDescriptor = s; \
|
||||
(p)->SecurityQualityOfService = NULL; \
|
||||
}
|
||||
|
||||
typedef NTSTATUS (NTAPI* NtOpenSectionFn_T)(
|
||||
__out PHANDLE SectionHandle,
|
||||
__in ACCESS_MASK DesiredAccess,
|
||||
__in POBJECT_ATTRIBUTES ObjectAttributes
|
||||
);
|
||||
|
||||
|
||||
NTSTATUS NTAPI NtOpenSection(
|
||||
__out PHANDLE SectionHandle,
|
||||
__in ACCESS_MASK DesiredAccess,
|
||||
__in POBJECT_ATTRIBUTES ObjectAttributes
|
||||
);
|
||||
|
||||
//
|
||||
// Section Information Structures.
|
||||
//
|
||||
|
||||
typedef enum _SECTION_INHERIT {
|
||||
ViewShare = 1,
|
||||
ViewUnmap = 2
|
||||
} SECTION_INHERIT;
|
||||
|
||||
typedef NTSTATUS (NTAPI* NtCreateSectionFn_T)(
|
||||
_Out_ PHANDLE SectionHandle,
|
||||
_In_ ACCESS_MASK DesiredAccess,
|
||||
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
_In_opt_ PLARGE_INTEGER MaximumSize,
|
||||
_In_ ULONG SectionPageProtection,
|
||||
_In_ ULONG AllocationAttributes,
|
||||
_In_opt_ HANDLE FileHandle
|
||||
);
|
||||
|
||||
NTSTATUS NTAPI NtCreateSection(
|
||||
_Out_ PHANDLE SectionHandle,
|
||||
_In_ ACCESS_MASK DesiredAccess,
|
||||
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
_In_opt_ PLARGE_INTEGER MaximumSize,
|
||||
_In_ ULONG SectionPageProtection,
|
||||
_In_ ULONG AllocationAttributes,
|
||||
_In_opt_ HANDLE FileHandle
|
||||
);
|
||||
|
||||
|
||||
typedef NTSTATUS (NTAPI* NtMapViewOfSectionFn_T)(
|
||||
__in HANDLE SectionHandle,
|
||||
__in HANDLE ProcessHandle,
|
||||
__inout PVOID *BaseAddress,
|
||||
__in ULONG_PTR ZeroBits,
|
||||
__in SIZE_T CommitSize,
|
||||
__inout_opt PLARGE_INTEGER SectionOffset,
|
||||
__inout PSIZE_T ViewSize,
|
||||
__in SECTION_INHERIT InheritDisposition,
|
||||
__in ULONG AllocationType,
|
||||
__in ULONG Win32Protect
|
||||
);
|
||||
|
||||
|
||||
NTSTATUS NTAPI NtMapViewOfSection(
|
||||
__in HANDLE SectionHandle,
|
||||
__in HANDLE ProcessHandle,
|
||||
__inout PVOID *BaseAddress,
|
||||
__in ULONG_PTR ZeroBits,
|
||||
__in SIZE_T CommitSize,
|
||||
__inout_opt PLARGE_INTEGER SectionOffset,
|
||||
__inout PSIZE_T ViewSize,
|
||||
__in SECTION_INHERIT InheritDisposition,
|
||||
__in ULONG AllocationType,
|
||||
__in ULONG Win32Protect
|
||||
);
|
||||
|
||||
|
||||
typedef enum THREAD_INFORMATION_CLASS {
|
||||
ThreadBasicInformation,
|
||||
ThreadTimes,
|
||||
ThreadPriority,
|
||||
ThreadBasePriority,
|
||||
ThreadAffinityMask,
|
||||
ThreadImpersonationToken,
|
||||
ThreadDescriptorTableEntry,
|
||||
ThreadEnableAlignmentFaultFixup,
|
||||
ThreadEventPair,
|
||||
ThreadQuerySetWin32StartAddress,
|
||||
ThreadZeroTlsCell,
|
||||
ThreadPerformanceCount,
|
||||
ThreadAmILastThread,
|
||||
ThreadIdealProcessor,
|
||||
ThreadPriorityBoost,
|
||||
ThreadSetTlsArrayAddress,
|
||||
ThreadIsIoPending,
|
||||
ThreadHideFromDebugger
|
||||
} THREAD_INFORMATION_CLASS, *PTHREAD_INFORMATION_CLASS;
|
||||
|
||||
typedef struct {
|
||||
HANDLE UniqueProcess;
|
||||
HANDLE UniqueThread;
|
||||
} CLIENT_ID;
|
||||
|
||||
typedef struct _THREAD_BASIC_INFORMATION {
|
||||
NTSTATUS ExitStatus;
|
||||
PVOID TebBaseAddress;
|
||||
CLIENT_ID ClientId;
|
||||
KAFFINITY AffinityMask;
|
||||
KPRIORITY Priority;
|
||||
KPRIORITY BasePriority;
|
||||
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
|
||||
|
||||
typedef NTSTATUS (NTAPI* NtQueryInformationThreadFn_T)(
|
||||
__in HANDLE ThreadHandle,
|
||||
__in THREAD_INFORMATION_CLASS ThreadInformationClass,
|
||||
__out PVOID ThreadInformation,
|
||||
__in ULONG ThreadInformationLength,
|
||||
__out PULONG ReturnLength OPTIONAL
|
||||
);
|
||||
|
||||
|
||||
NTSTATUS NTAPI NtQueryInformationThread(
|
||||
__in HANDLE ThreadHandle,
|
||||
__in THREAD_INFORMATION_CLASS ThreadInformationClass,
|
||||
__out PVOID ThreadInformation,
|
||||
__in ULONG ThreadInformationLength,
|
||||
__out PULONG ReturnLength OPTIONAL
|
||||
);
|
||||
|
||||
|
||||
typedef NTSTATUS (NTAPI* NtUnmapViewOfSectionFn_T)(
|
||||
__in HANDLE ProcessHandle,
|
||||
__in_opt PVOID BaseAddress
|
||||
);
|
||||
|
||||
NTSTATUS NTAPI NtUnmapViewOfSection(
|
||||
__in HANDLE ProcessHandle,
|
||||
__in_opt PVOID BaseAddress
|
||||
);
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4201)
|
||||
typedef struct _IO_STATUS_BLOCK {
|
||||
union {
|
||||
NTSTATUS Status;
|
||||
PVOID Pointer;
|
||||
};
|
||||
|
||||
ULONG_PTR Information;
|
||||
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
|
||||
#pragma warning(pop)
|
||||
|
||||
#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
|
||||
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
|
||||
#define FILE_NON_DIRECTORY_FILE 0x00000040
|
||||
#define FILE_CREATE_TREE_CONNECTION 0x00000080
|
||||
|
||||
typedef NTSTATUS (NTAPI* NtOpenFileFn_T)(
|
||||
__out PHANDLE FileHandle,
|
||||
__in ACCESS_MASK DesiredAccess,
|
||||
__in POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
__out PIO_STATUS_BLOCK IoStatusBlock,
|
||||
__in ULONG ShareAccess,
|
||||
__in ULONG OpenOptions
|
||||
);
|
||||
|
||||
NTSTATUS NTAPI NtOpenFile(
|
||||
__out PHANDLE FileHandle,
|
||||
__in ACCESS_MASK DesiredAccess,
|
||||
__in POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
__out PIO_STATUS_BLOCK IoStatusBlock,
|
||||
__in ULONG ShareAccess,
|
||||
__in ULONG OpenOptions
|
||||
);
|
||||
#endif //_NTDLL_H_
|
|
@ -0,0 +1,34 @@
|
|||
cmake_minimum_required (VERSION 3.0.2)
|
||||
|
||||
function(AddRpcCore Directory)
|
||||
message("[${Directory}]")
|
||||
add_library(${Directory} SHARED
|
||||
# ComInternals.c
|
||||
RpcCore.c
|
||||
../RpcCommon/ntdll.c
|
||||
../RpcCommon/Misc.c
|
||||
RpcCore.def
|
||||
RpcCoreResource.rc
|
||||
)
|
||||
|
||||
target_include_directories(
|
||||
${Directory} PUBLIC
|
||||
${Directory}
|
||||
)
|
||||
endfunction(AddRpcCore)
|
||||
|
||||
file(GLOB CoreFiles *)
|
||||
foreach(Files ${CoreFiles})
|
||||
if (IS_DIRECTORY ${Files} )
|
||||
|
||||
get_filename_component(Dir ${Files} NAME)
|
||||
|
||||
if(${CMAKE_GENERATOR} MATCHES "Win64")
|
||||
AddRpcCore(${Dir})
|
||||
else(${CMAKE_GENERATOR} MATCHES "Win64")
|
||||
if(${Dir} MATCHES "32bits")
|
||||
AddRpcCore(${Dir})
|
||||
endif(${Dir} MATCHES "32bits")
|
||||
endif(${CMAKE_GENERATOR} MATCHES "Win64")
|
||||
endif (IS_DIRECTORY ${Files} )
|
||||
endforeach(Files)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,2 @@
|
|||
EXPORTS
|
||||
RpcCoreHelper
|
|
@ -0,0 +1,211 @@
|
|||
#ifndef _RPC_CORE_H_
|
||||
#define _RPC_CORE_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define RPC_CORE_EXPORT_SYMBOL "RpcCoreHelper"
|
||||
#define MAX_RPC_INTERFACE_ANNOTATION 64
|
||||
#define MAX_GUID 40
|
||||
#define MAX_CLSID_NAME 128
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Type definitions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define RPC_PROCESS_INFO_DEFAULT 0x0
|
||||
#define RPC_PROCESS_INFO_MISC 0x1
|
||||
#define RPC_PROCESS_INFO_RPC 0x2
|
||||
#define RPC_PROCESS_INFO_ALL (RPC_PROCESS_INFO_MISC | RPC_PROCESS_INFO_RPC)
|
||||
|
||||
typedef enum _RpcProcessType_T{
|
||||
RpcProcessType_UNKNOWN = 0,
|
||||
RpcProcessType_RPC,
|
||||
RpcProcessType_DCOM,
|
||||
RpcProcessType_HYBRID
|
||||
}RpcProcessType_T;
|
||||
|
||||
typedef struct _RpcProcessInfo_T{
|
||||
//Default
|
||||
DWORD Pid;
|
||||
DWORD ParentPid;
|
||||
#ifdef _WIN64
|
||||
BOOL bIsWow64;
|
||||
#endif
|
||||
//Misc
|
||||
WCHAR Name[MAX_PATH];
|
||||
WCHAR Path[MAX_PATH];
|
||||
WCHAR CmdLine[MAX_PATH];
|
||||
WCHAR User[MAX_PATH];
|
||||
WCHAR Desktop[MAX_PATH];
|
||||
DWORD Session;
|
||||
UINT64 Version;
|
||||
HICON hIcon;
|
||||
WCHAR Description[MAX_PATH];
|
||||
FILETIME CreationTime;
|
||||
//Rpc
|
||||
RpcProcessType_T RpcProcessType;
|
||||
DWORD MaxCalls;
|
||||
BOOL bIsServer;
|
||||
BOOL bIsListening;
|
||||
UINT InterfacesCount;
|
||||
UINT EndpointsCount;
|
||||
UINT SspCount;
|
||||
DWORD InCalls;
|
||||
DWORD OutCalls;
|
||||
DWORD InPackets;
|
||||
DWORD OutPackets;
|
||||
//...
|
||||
}RpcProcessInfo_T;
|
||||
|
||||
|
||||
typedef struct _NdrInfo_T{
|
||||
ULONG Version; // NDR version required for the stub.
|
||||
ULONG MIDLVersion; // Version of the MIDL compiler used to compile the .idl file
|
||||
ULONG_PTR mFlags; // Flag describing the attributes of the stub (RPCFLG_HAS_MULTI_SYNTAXES, RPCFLG_HAS_CALLBACK, or RPC_INTERFACE_HAS_PIPES)
|
||||
}NdrInfo_T;
|
||||
|
||||
|
||||
typedef enum _TypeOfStub_T{
|
||||
TypeOfStub_Unknown = 0,
|
||||
TypeOfStub_Interpreted,
|
||||
TypeOfStub_Inlined,
|
||||
TypeOfStub_TypeLib,
|
||||
TypeOfStub_Hybrid
|
||||
}TypeOfStub_T;
|
||||
|
||||
typedef enum _IfType_T{
|
||||
IfType_Unknown = 0,
|
||||
IfType_RPC,
|
||||
IfType_DCOM,
|
||||
IfType_OLE,
|
||||
}IfType_T;
|
||||
|
||||
#define RPC_INTERFACE_INFO_DEFAULT 0x0
|
||||
#define RPC_INTERFACE_INFO_MISC 0x1
|
||||
#define RPC_INTERFACE_INFO_RPC 0x2
|
||||
#define RPC_INTERFACE_INFO_NDR 0x4
|
||||
#define RPC_INTERFACE_INFO_DCOM 0x8
|
||||
#define RPC_INTERFACE_INFO_ALL (RPC_INTERFACE_INFO_MISC | RPC_INTERFACE_INFO_RPC | RPC_INTERFACE_INFO_NDR |RPC_INTERFACE_INFO_DCOM)
|
||||
|
||||
|
||||
typedef struct _RpcInterfaceInfo_T{
|
||||
//Default
|
||||
DWORD Pid;
|
||||
#ifdef _WIN64
|
||||
BOOL bWow64Process;
|
||||
#endif
|
||||
RPC_IF_ID If;
|
||||
RPC_SYNTAX_IDENTIFIER TransfertSyntax;
|
||||
UINT Flags;
|
||||
IfType_T IfType;
|
||||
//Misc
|
||||
WCHAR Name[MAX_PATH];
|
||||
WCHAR Location[MAX_PATH];
|
||||
DWORD LocationState;
|
||||
DWORD LocationType;
|
||||
VOID* pLocationBase;
|
||||
SIZE_T LocationSize;
|
||||
WCHAR Description[MAX_PATH];
|
||||
//RPC
|
||||
BOOL bIsRegistered; //EP mapper
|
||||
UCHAR Annotation[MAX_RPC_INTERFACE_ANNOTATION]; //annotation is natively in UCHAR
|
||||
RPC_IF_CALLBACK_FN* IfCallbackFn; //security callback if any
|
||||
//NDR
|
||||
UINT NumberOfProcedures;
|
||||
NdrInfo_T NdrInfo;
|
||||
TypeOfStub_T TypeOfStub;
|
||||
ULONG* ppProcAddressTable; //Table containing the address of each function
|
||||
USHORT* pFormatStringOffsetTable; //Table containing the offset of each function encoding
|
||||
UCHAR* pProcFormatString; // Midl server info
|
||||
UCHAR* pTypeFormatString; // Midl stub desc
|
||||
VOID* apfnExprEval; // Midl stub desc
|
||||
USHORT* pExprOffset; // Midl stub desc
|
||||
UCHAR* pExprFormatString; // Midl stub desc
|
||||
//DCOM information
|
||||
WCHAR ProxyStubClsid32[MAX_GUID];
|
||||
WCHAR TypeLib[MAX_GUID];
|
||||
WCHAR TypeLibName[MAX_PATH];
|
||||
WCHAR ClsidName[MAX_CLSID_NAME];
|
||||
WCHAR InprocServer32[MAX_PATH];
|
||||
WCHAR TypeLibVersion[20];
|
||||
WCHAR TypeLibPath[MAX_PATH];
|
||||
//...
|
||||
}RpcInterfaceInfo_T;
|
||||
|
||||
|
||||
typedef struct _RpcEndpointInfo_T{
|
||||
WCHAR* pName;
|
||||
WCHAR* pProtocole;
|
||||
//...
|
||||
}RpcEndpointInfo_T;
|
||||
|
||||
|
||||
//Private name: unnamed in PDB file
|
||||
typedef struct _RPC_AUTH_INFO_T{
|
||||
WCHAR* pPrincipalName;
|
||||
ULONG AuthSvc;
|
||||
VOID* pGetKeyFn;
|
||||
VOID* pArg;
|
||||
}RPC_AUTH_INFO_T;
|
||||
|
||||
|
||||
typedef struct _RpcAuthInfo_T{
|
||||
ULONG Capabilities;
|
||||
ULONG Version;
|
||||
WCHAR PrincipalName[MAX_PATH];
|
||||
ULONG AuthSvc;
|
||||
WCHAR Name[MAX_PATH];
|
||||
WCHAR Comment[MAX_PATH];
|
||||
WCHAR DllName[MAX_PATH];
|
||||
VOID* pGetKeyFn;
|
||||
VOID* pArg;
|
||||
}RpcAuthInfo_T;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Callback function type definition
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef BOOL (__fastcall* RpcCoreEnumProcessInterfacesCallbackFn_T)(RpcInterfaceInfo_T* pRpcInterfaceInfo, VOID* pContext, BOOL* pbContinue);
|
||||
typedef BOOL (__fastcall* RpcCoreEnumProcessEndpointsCallbackFn_T)(DWORD Pid, RpcEndpointInfo_T* pRpcEndpointInfo, VOID* pContext, BOOL* pbContinue);
|
||||
typedef BOOL (__fastcall* RpcCoreEnumProcessAuthInfoCallbackFn_T)(DWORD Pid, RpcAuthInfo_T* pRpcAuthInfo, VOID* pContext, BOOL* pbContinue);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Type definitions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef VOID* (__fastcall* RpcCoreInitFn_T)();
|
||||
typedef VOID (__fastcall* RpcCoreUninitFn_T)(VOID* pRpcCoreCtxt);
|
||||
typedef RpcProcessInfo_T* (__fastcall* RpcCoreGetProcessInfoFn_T)(void* pRpcCoreCtxt, DWORD Pid, DWORD Ppid,ULONG ProcessInfoMask);
|
||||
typedef VOID (__fastcall* RpcCoreFreeProcessInfoFn_T)(void* pRpcCoreCtxt, RpcProcessInfo_T* pRpcProcessInfo);
|
||||
typedef RpcInterfaceInfo_T* (__fastcall* RpcCoreGetInterfaceInfoFn_T)(void* pRpcCoreCtxt, DWORD Pid, RPC_IF_ID* pIf,ULONG InterfaceInfoMask);
|
||||
typedef VOID (__fastcall* RpcCoreFreeInterfaceInfoFn_T)(void* pRpcCoreCtxt, RpcInterfaceInfo_T* pRpcInterfaceInfo);
|
||||
typedef BOOL (__fastcall* RpcCoreEnumProcessInterfacesFn_T)(void* pRpcCoreCtxt, DWORD Pid, RpcCoreEnumProcessInterfacesCallbackFn_T RpcCoreEnumProcessInterfacesCallbackFn, void* pCallbackCtxt,ULONG InterfaceInfoMask);
|
||||
typedef BOOL (__fastcall* RpcCoreEnumProcessEndpointsFn_T)(void* pRpcCoreCtxt, DWORD Pid, RpcCoreEnumProcessEndpointsCallbackFn_T RpcCoreEnumProcessEndpointsCallbackFn, void* pCallbackCtxt);
|
||||
typedef BOOL (__fastcall* RpcCoreEnumProcessAuthInfoFn_T)(void* pRpcCoreCtxt, DWORD Pid, RpcCoreEnumProcessAuthInfoCallbackFn_T RpcCoreEnumProcessAuthInfoCallbackFn, void* pCallbackCtxt);
|
||||
|
||||
|
||||
typedef struct _RpcCore_T{
|
||||
UINT64* RuntimeVersion; //the supported version (forx example 0x600011DB04001LL (6.1.7600.16385) for Windows 7 64bits )
|
||||
//const char* pDescription;
|
||||
BOOL bWow64Helper;
|
||||
RpcCoreInitFn_T RpcCoreInitFn;
|
||||
RpcCoreUninitFn_T RpcCoreUninitFn;
|
||||
RpcCoreGetProcessInfoFn_T RpcCoreGetProcessInfoFn;
|
||||
RpcCoreFreeProcessInfoFn_T RpcCoreFreeProcessInfoFn;
|
||||
RpcCoreGetInterfaceInfoFn_T RpcCoreGetInterfaceInfoFn;
|
||||
RpcCoreFreeInterfaceInfoFn_T RpcCoreFreeInterfaceInfoFn;
|
||||
RpcCoreEnumProcessInterfacesFn_T RpcCoreEnumProcessInterfacesFn;
|
||||
RpcCoreEnumProcessEndpointsFn_T RpcCoreEnumProcessEndpointsFn;
|
||||
RpcCoreEnumProcessAuthInfoFn_T RpcCoreEnumProcessAuthInfoFn;
|
||||
}RpcCore_T;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //_RPC_CORE_H_
|
|
@ -0,0 +1,99 @@
|
|||
#ifndef _RPC_INTERNALS_H_
|
||||
#define _RPC_INTERNALS_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <Rpc.h>
|
||||
|
||||
static UINT64 RPC_CORE_RUNTIME_VERSION[] = {
|
||||
0x500010a280884LL, //5.1.2600.2180
|
||||
0x500010a281588LL, //5.1.2600.5512
|
||||
0x500010a281786LL, //5.1.2600.6022
|
||||
0x500010a28194dLL, //5.1.2600.6477
|
||||
0x500020ECE0F77LL //5.2.3790.3959
|
||||
};
|
||||
|
||||
#ifdef _WIN64
|
||||
#define RPC_CORE_IS_WOW64 TRUE
|
||||
#define PTR_T *__ptr32 //WOW64!!!
|
||||
#define ULONG_PTR_T ULONG
|
||||
#else
|
||||
#define RPC_CORE_IS_WOW64 FALSE
|
||||
#define ULONG_PTR_T ULONG_PTR
|
||||
#define PTR_T *
|
||||
#endif
|
||||
|
||||
#include "../RpcInternalsCommon.h"
|
||||
|
||||
#define RPC_ADDRESS_TYPE_DG 0x400000
|
||||
#define RPC_ADDRESS_TYPE_LRPC 0x800000
|
||||
#define RPC_ADDRESS_TYPE_OSF 0x800
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct _RPC_SERVER_T{
|
||||
MUTEX_T MUTEX;
|
||||
ULONG Unk1;
|
||||
ULONG Unk2;
|
||||
BOOL bIsListening;
|
||||
ULONG MinimumCallThreads;
|
||||
ULONG bWait;
|
||||
ULONG OutCalls;
|
||||
ULONG Unk3;
|
||||
ULONG InCalls;
|
||||
SIMPLE_DICT_T AddressDict;
|
||||
ULONG Unk3_;
|
||||
SIMPLE_DICT_T _ProtSeqQueue;
|
||||
ULONG Unk4[4];
|
||||
ULONG OutPackets;
|
||||
ULONG Unk5;
|
||||
MUTEX_T Mutex2;
|
||||
ULONG MaxCalls;
|
||||
VOID PTR_T hEvent;
|
||||
ULONG Unk6[6];
|
||||
SIMPLE_DICT_T InterfaceDict;
|
||||
BOOL ___bIsListening;
|
||||
BOOL bIsListenMaxCallsDefault;
|
||||
ULONG Unk7[6];
|
||||
ULONG InPackets;
|
||||
RPC_FORWARD_FUNCTION PTR_T pRpcForwardFunction;
|
||||
ULONG Unk8[6];
|
||||
SIMPLE_DICT_T AuthenInfoDict;
|
||||
}RPC_SERVER_T, PTR_T PRPC_SERVER_T;
|
||||
|
||||
typedef struct _RPC_INTERFACE_T
|
||||
{
|
||||
RPC_SERVER_T PTR_T pRpcServer;
|
||||
ULONG Flags;
|
||||
ULONG EpMapperFlags;
|
||||
RPC_MGR_EPV PTR_T pMgrEpv;
|
||||
RPC_IF_CALLBACK_FN PTR_T IfCallbackFn;
|
||||
RPC_SERVER_INTERFACE_T RpcServerInterface;
|
||||
ULONG pSyntaxInfo;
|
||||
ULONG pTransfertSyntaxes;
|
||||
ULONG pTransfertSyntaxesCount;
|
||||
ULONG Unk1;
|
||||
ULONG NbTypeManager;
|
||||
ULONG MaxRpcSize;
|
||||
ULONG Unk2;
|
||||
ULONG pUuidVector;
|
||||
SIMPLE_DICT_T RpcInterfaceManagerDict;
|
||||
UCHAR Annotation[MAX_RPC_INTERFACE_ANNOTATION];
|
||||
SIMPLE_DICT_T FwEpDict;
|
||||
ULONG Unk3[6];
|
||||
}RPC_INTERFACE_T, PTR_T PRPC_INTERFACE_T;
|
||||
|
||||
typedef struct _RPC_ADDRESS_T{
|
||||
VOID PTR_T PTR_T pVTable;
|
||||
ULONG Magic;
|
||||
ULONG TypeOfAddress;
|
||||
ULONG ReferenceCounter;
|
||||
WCHAR PTR_T Name;
|
||||
WCHAR PTR_T Protocole;
|
||||
WCHAR PTR_T Address;
|
||||
ULONG bNamed;
|
||||
ULONG EpAddAddressFlag;
|
||||
ULONG unk4[6];
|
||||
MUTEX_T Mutex;
|
||||
}RPC_ADDRESS_T;
|
||||
|
||||
#pragma pack()
|
||||
#endif // _RPC_INTERNALS_H_
|
|
@ -0,0 +1,115 @@
|
|||
#ifndef _RPC_INTERNALS_H_
|
||||
#define _RPC_INTERNALS_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <Rpc.h>
|
||||
|
||||
|
||||
static UINT64 RPC_CORE_RUNTIME_VERSION[] = {
|
||||
0x600011DB04001LL, //6.1.7600.16385
|
||||
0x600011DB1446ALL, //6.1.7601.17514
|
||||
0x600011DB1471DLL, //6.1.7601.18205
|
||||
0x600011DB14864LL, //6.1.7601.18532
|
||||
0x600011DB149E0LL, //6.1.7601.18912
|
||||
0x600011DB149F5LL, //6.1.7601.18933
|
||||
0x600011DB149FBLL, //6.1.7601.18939
|
||||
0x600011DB15B7BLL //6.1.7601.23419
|
||||
};
|
||||
|
||||
#ifdef _WIN64
|
||||
#define RPC_CORE_DESCRIPTION "Windows 7 SP1 64bits Wow64 runtime core"
|
||||
#define RPC_CORE_IS_WOW64 TRUE
|
||||
#define PTR_T *__ptr32 //WOW64!!!
|
||||
#define ULONG_PTR_T ULONG
|
||||
#else
|
||||
#define RPC_CORE_DESCRIPTION "Windows 7 SP1 32bits runtime core"
|
||||
#define RPC_CORE_IS_WOW64 FALSE
|
||||
#define ULONG_PTR_T ULONG_PTR
|
||||
#define PTR_T *
|
||||
#endif
|
||||
|
||||
|
||||
#include "../RpcInternalsCommon.h"
|
||||
|
||||
#define RPC_ADDRESS_TYPE_DG 0x400000
|
||||
#define RPC_ADDRESS_TYPE_LRPC 0x800000
|
||||
#define RPC_ADDRESS_TYPE_OSF 0x800
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct _RPC_SERVER_T {
|
||||
MUTEX_T Mutex;
|
||||
ULONG _bIslistening;
|
||||
ULONG bIsListening;
|
||||
ULONG MinimumCallThreads;
|
||||
ULONG bWait;
|
||||
ULONG OutCalls;
|
||||
ULONG Unk1;
|
||||
ULONG InCalls;
|
||||
SIMPLE_DICT_T AddressDict;
|
||||
ULONG lAvailableCalls;
|
||||
SIMPLE_DICT_T _ProtSeqQueue;
|
||||
ULONG Unk2[4];
|
||||
ULONG OutPackets;
|
||||
MUTEX_T Mutex2;
|
||||
ULONG MaxCalls;
|
||||
VOID PTR_T hEvent;
|
||||
ULONG Unk3[4];
|
||||
SIMPLE_DICT_T InterfaceDict;
|
||||
ULONG __bIslistening;
|
||||
ULONG bIsMaxCalls1234;
|
||||
ULONG Unk4[6];
|
||||
ULONG InPackets;
|
||||
RPC_FORWARD_FUNCTION PTR_T pRpcForwardFunction;
|
||||
ULONG Unk5[6];
|
||||
SIMPLE_DICT_T AuthenInfoDict;
|
||||
}RPC_SERVER_T, PTR_T PRPC_SERVER_T;
|
||||
|
||||
typedef struct _RPC_INTERFACE_T
|
||||
{
|
||||
PRPC_SERVER_T pRpcServer;
|
||||
ULONG Flags;
|
||||
ULONG EpMapperFlags;
|
||||
RPC_MGR_EPV PTR_T pMgrEpv;
|
||||
RPC_IF_CALLBACK_FN PTR_T IfSecurityCallbackFn;
|
||||
RPC_SERVER_INTERFACE_T RpcServerInterface;
|
||||
ULONG unk2[2];
|
||||
BOOL bInterfaceSupportMultipleTransferSyntaxes;
|
||||
ULONG unk3;
|
||||
ULONG NbTypeManager;
|
||||
ULONG MaxRpcSize;
|
||||
UUID_VECTOR PTR_T pUuidVector;
|
||||
SIMPLE_DICT_T RpcInterfaceManagerDict;
|
||||
UCHAR Annotation[MAX_RPC_INTERFACE_ANNOTATION];
|
||||
RPC_IF_CALLBACK_FN PTR_T IfCallbackFn;
|
||||
ULONG CurrentNullManagerCalls;
|
||||
ULONG CurrentAutoListenCalls;
|
||||
ULONG __Field_DC;
|
||||
ULONG unk5;
|
||||
ULONG SecurityCallbackInProgress;
|
||||
ULONG __Field_E8;
|
||||
VOID PTR_T pSecurityEntryHashTable;
|
||||
SIMPLE_DICT_T FwEpDict;
|
||||
ULONG field_10C;
|
||||
}RPC_INTERFACE_T, PTR_T PRPC_INTERFACE_T;
|
||||
|
||||
typedef struct _RPC_ADDRESS_T {
|
||||
VOID PTR_T PTR_T pVTable;
|
||||
ULONG Magic;
|
||||
ULONG TypeOfAddress;
|
||||
ULONG ReferenceCounter;
|
||||
ULONG unk1;
|
||||
WCHAR PTR_T Name;
|
||||
WCHAR PTR_T Protocole;
|
||||
WCHAR PTR_T Address;
|
||||
ULONG bNamed;
|
||||
ULONG EpAddAddressFlag;
|
||||
SIMPLE_DICT_T __LRPCSassociationDict;
|
||||
ULONG unk3[2];
|
||||
ULONG NbActiveCalls;
|
||||
ULONG unk4[4];
|
||||
MUTEX_T Mutex;
|
||||
}RPC_ADDRESS_T;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif // _RPC_INTERNALS_H_
|
|
@ -0,0 +1,119 @@
|
|||
#ifndef _RPC_INTERNALS_H_
|
||||
#define _RPC_INTERNALS_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <Rpc.h>
|
||||
|
||||
static UINT64 RPC_CORE_RUNTIME_VERSION[] = {
|
||||
0x600011DB04001LL, //6.1.7600.16385
|
||||
0x600011DB1446ALL, //6.1.7601.17514
|
||||
0x600011DB1471DLL, //6.1.7601.18205
|
||||
0x600011DB14864LL, //6.1.7601.18532
|
||||
0x600011DB149E0LL, //6.1.7601.18912
|
||||
0x600011DB149F5LL, //6.1.7601.18933
|
||||
0x600011DB149FBLL, //6.1.7601.18939
|
||||
0x600011DB15B7BLL //6.1.7601.23419
|
||||
};
|
||||
|
||||
#define RPC_CORE_DESCRIPTION "Windows 7 SP1 64bits runtime core"
|
||||
#define RPC_CORE_IS_WOW64 FALSE
|
||||
|
||||
#define ULONG_PTR_T ULONG_PTR
|
||||
#define PTR_T *
|
||||
|
||||
#include "../RpcInternalsCommon.h"
|
||||
|
||||
#define RPC_ADDRESS_TYPE_DG 0x400000
|
||||
#define RPC_ADDRESS_TYPE_LRPC 0x800000
|
||||
#define RPC_ADDRESS_TYPE_OSF 0x800
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct _RPC_SERVER_T {
|
||||
MUTEX_T Mutex;
|
||||
ULONG __bIslistening;
|
||||
BOOL bIsListening;
|
||||
ULONG MinimumCallThreads;
|
||||
BOOL Wait;
|
||||
ULONG OutCalls;
|
||||
ULONG Unk1;
|
||||
ULONG InCalls;
|
||||
ULONG Unk2;
|
||||
SIMPLE_DICT_T AddressDict;
|
||||
ULONG lAvailableCalls;
|
||||
ULONG Unk3;
|
||||
SIMPLE_DICT_T _ProtSeqQueue;
|
||||
ULONG Unk4[8];
|
||||
ULONG OutPackets;
|
||||
ULONG Unk5;
|
||||
MUTEX_T Mutex2;
|
||||
ULONG MaxCalls;
|
||||
ULONG Unk6;
|
||||
VOID PTR_T hEvent;
|
||||
ULONG Unk7[4];
|
||||
SIMPLE_DICT_T InterfaceDict;
|
||||
BOOL _bIsListening;
|
||||
BOOL bIsMaxCalls1234;
|
||||
ULONG Unk8[6];
|
||||
ULONG InPackets;
|
||||
ULONG Unk9;
|
||||
RPC_FORWARD_FUNCTION PTR_T pRpcForwardFunction;
|
||||
ULONG Unk10[6];
|
||||
SIMPLE_DICT_T AuthenInfoDict;
|
||||
}RPC_SERVER_T, PTR_T PRPC_SERVER_T;
|
||||
|
||||
|
||||
typedef struct _RPC_INTERFACE_T {
|
||||
PRPC_SERVER_T pRpcServer;
|
||||
ULONG Flags;
|
||||
ULONG EpMapperFlags;
|
||||
RPC_MGR_EPV PTR_T pMgrEpv;
|
||||
RPC_IF_CALLBACK_FN PTR_T IfCallbackFn;
|
||||
RPC_SERVER_INTERFACE_T RpcServerInterface;
|
||||
PMIDL_SYNTAX_INFO pSyntaxInfo;
|
||||
VOID PTR_T pTransfertSyntaxes;
|
||||
ULONG TransfertSyntaxesCount;
|
||||
ULONG __Field_C4;
|
||||
ULONG NbTypeManager;
|
||||
ULONG MaxRpcSize;
|
||||
UUID_VECTOR PTR_T pUuidVector;
|
||||
SIMPLE_DICT_T RpcInterfaceManagerDict;
|
||||
UCHAR Annotation[MAX_RPC_INTERFACE_ANNOTATION];
|
||||
ULONG IsCallSizeLimitReached;
|
||||
ULONG currentNullManagerCalls;
|
||||
ULONG __Field_150;
|
||||
ULONG __Field_154;
|
||||
ULONG bRundownsBlocked;
|
||||
ULONG SecurityCallbackInProgress;
|
||||
ULONG SecurityCacheEntry;
|
||||
ULONG field_164;
|
||||
VOID PTR_T __SecurityCacheEntries;
|
||||
SIMPLE_DICT_T FwEpDict;
|
||||
ULONG __Field_218;
|
||||
ULONG Unk1;
|
||||
}RPC_INTERFACE_T, PTR_T PRPC_INTERFACE_T;
|
||||
|
||||
|
||||
typedef struct _RPC_ADDRESS_T {
|
||||
VOID PTR_T pVtable;
|
||||
ULONG Magic;
|
||||
ULONG TypeOfAddress;
|
||||
ULONG ReferenceCounter;
|
||||
ULONG Unk1[3];
|
||||
WCHAR PTR_T Name;
|
||||
WCHAR PTR_T Protocole;
|
||||
WCHAR PTR_T Address;
|
||||
ULONG bNamed;
|
||||
ULONG EpAddAddressFlag;
|
||||
SIMPLE_DICT_T __LRPCSassociationSimpleDict;
|
||||
ULONG __Field_68;
|
||||
ULONG Unk2;
|
||||
ULONG EpAddOnFlag;
|
||||
ULONG NbActiveCalls;
|
||||
ULONG Unk3[6];
|
||||
MUTEX_T Mutex;
|
||||
}RPC_ADDRESS_T;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif // _RPC_INTERNALS_H_
|
|
@ -0,0 +1,116 @@
|
|||
#ifndef _RPC_INTERNALS_H_
|
||||
#define _RPC_INTERNALS_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <Rpc.h>
|
||||
|
||||
|
||||
static UINT64 RPC_CORE_RUNTIME_VERSION[] = {
|
||||
0x6000223f04000LL, //6.2.9200.16384
|
||||
0x6000223f040eeLL //6.2.9200.16622
|
||||
};
|
||||
|
||||
#ifdef _WIN64
|
||||
#define RPC_CORE_DESCRIPTION "Windows 8 64bits Wow64 runtime core"
|
||||
#define RPC_CORE_IS_WOW64 TRUE
|
||||
#define PTR_T *__ptr32 //WOW64!!!
|
||||
#define ULONG_PTR_T ULONG
|
||||
#else
|
||||
#define RPC_CORE_DESCRIPTION "Windows 8 32bits runtime core"
|
||||
#define RPC_CORE_IS_WOW64 FALSE
|
||||
#define ULONG_PTR_T ULONG_PTR
|
||||
#define PTR_T *
|
||||
#endif
|
||||
|
||||
#include "../RpcInternalsCommon.h"
|
||||
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct _RPC_SERVER_T {
|
||||
MUTEX_T MUTEX;
|
||||
BOOL _bIslistening;
|
||||
BOOL bIsListening;
|
||||
ULONG MinimumCallThreads;
|
||||
BOOL bWait;
|
||||
ULONG OutCalls;
|
||||
ULONG Unk1;
|
||||
ULONG InCalls;
|
||||
SIMPLE_DICT_T AddressDict;
|
||||
ULONG lAvailableCalls;
|
||||
ULONG Unk2[11];
|
||||
ULONG OutPackets;
|
||||
MUTEX_T Mutex2;
|
||||
ULONG MaxCalls;
|
||||
VOID PTR_T hEvent;
|
||||
ULONG Unk4[4];
|
||||
SIMPLE_DICT_T InterfaceDict;
|
||||
BOOL __bIslistening;
|
||||
BOOL bIsMaxCall1234;
|
||||
ULONG Unk5[6];
|
||||
ULONG InPackets;
|
||||
RPC_FORWARD_FUNCTION PTR_T pRpcForwardFunction;
|
||||
ULONG Unk6[6];
|
||||
SIMPLE_DICT_T AuthenInfoDict;
|
||||
LIST_ENTRY_T RpcIfGroupListEntry;
|
||||
ULONG PTR_T __SRWLock;
|
||||
LIST_ENTRY_T __138;
|
||||
}RPC_SERVER_T, PTR_T PRPC_SERVER_T;
|
||||
|
||||
typedef struct _RPC_INTERFACE_T
|
||||
{
|
||||
PRPC_SERVER_T pRpcServer;
|
||||
ULONG Flags;
|
||||
MUTEX_T Mutex;
|
||||
ULONG EpMapperFlags;
|
||||
RPC_MGR_EPV PTR_T pMgrEpv;
|
||||
RPC_IF_CALLBACK_FN PTR_T IfSecurityCallback;
|
||||
RPC_SERVER_INTERFACE_T RpcServerInterface;
|
||||
MIDL_SYNTAX_INFO PTR_T pSyntaxInfo;
|
||||
VOID PTR_T pTransfertSyntaxes;
|
||||
ULONG TransfertSyntaxesCount;
|
||||
ULONG Unk1;
|
||||
ULONG NbTypeManager;
|
||||
ULONG MaxRpcSize;
|
||||
UUID_VECTOR PTR_T pUuidVector;
|
||||
SIMPLE_DICT_T RpcInterfaceManagerDict;
|
||||
UCHAR Annotation[64];
|
||||
RPC_IF_CALLBACK_FN PTR_T IfCallbackFn;
|
||||
ULONG IsCallSizeLimitReached;
|
||||
ULONG currentNullManagerCalls;
|
||||
ULONG currentAutoListenCalls;
|
||||
ULONG Unk2[2];
|
||||
ULONG SecurityCallbackInProgress;
|
||||
ULONG SecurityCacheEntry;
|
||||
ULONG __SecurityCacheEntries[16];
|
||||
SIMPLE_DICT_T FwEpDict;
|
||||
ULONG Unk3[4];
|
||||
}RPC_INTERFACE_T, PTR_T PRPC_INTERFACE_T;
|
||||
|
||||
#define RPC_ADDRESS_TYPE_DG 0x400000
|
||||
#define RPC_ADDRESS_TYPE_LRPC 0x800000
|
||||
#define RPC_ADDRESS_TYPE_OSF 0x800
|
||||
|
||||
typedef struct _RPC_ADDRESS_T {
|
||||
VOID PTR_T PTR_T pVTable;
|
||||
ULONG Magic;
|
||||
ULONG TypeOfAddress;
|
||||
ULONG ReferenceCounter;
|
||||
ULONG Unk1;
|
||||
WCHAR PTR_T Name;
|
||||
WCHAR PTR_T Protocole;
|
||||
WCHAR PTR_T Address;
|
||||
BOOL bNamed;
|
||||
ULONG EpAddAddressFlag;
|
||||
SIMPLE_DICT_T __LRPCSassociationSimpleDict;
|
||||
ULONG __Field_68;
|
||||
ULONG Unk3;
|
||||
ULONG NbActiveCalls;
|
||||
ULONG __Field_74;
|
||||
ULONG Unk4[6];
|
||||
ULONG __Field_90;
|
||||
MUTEX_T Mutex;
|
||||
}RPC_ADDRESS_T;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif // _RPC_INTERNALS_H_
|
|
@ -0,0 +1,117 @@
|
|||
#ifndef _RPC_INTERNALS_H_
|
||||
#define _RPC_INTERNALS_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <Rpc.h>
|
||||
|
||||
static UINT64 RPC_CORE_RUNTIME_VERSION[] = {
|
||||
0x6000223f04000LL, //6.2.9200.16384
|
||||
0x6000223f040eeLL //6.2.9200.16622
|
||||
};
|
||||
|
||||
#define RPC_CORE_DESCRIPTION "Windows 8 64bits runtime core"
|
||||
#define RPC_CORE_IS_WOW64 FALSE
|
||||
|
||||
#define ULONG_PTR_T ULONG_PTR
|
||||
#define PTR_T *
|
||||
|
||||
#include "../RpcInternalsCommon.h"
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct _RPC_SERVER_T {
|
||||
MUTEX_T Mutex;
|
||||
ULONG __bIslistening;
|
||||
ULONG bIsListening;
|
||||
ULONG MinimumCallThreads;
|
||||
ULONG Wait;
|
||||
ULONG OutCalls;
|
||||
ULONG Unk1;
|
||||
ULONG InCalls;
|
||||
ULONG Unk2;
|
||||
SIMPLE_DICT_T AddressDict;
|
||||
ULONG lAvailableCalls;
|
||||
ULONG Unk3;
|
||||
ULONG Unk4[20];
|
||||
ULONG OutPackets;
|
||||
ULONG Unk5;
|
||||
MUTEX_T Mutex2;
|
||||
ULONG MaxCalls;
|
||||
ULONG Unk6;
|
||||
VOID PTR_T hEvent;
|
||||
ULONG Unk7[4];
|
||||
SIMPLE_DICT_T InterfaceDict;
|
||||
ULONG _bIsListening;
|
||||
ULONG bIsMaxCalls1234;
|
||||
ULONG Unk8[6];
|
||||
ULONG InPackets;
|
||||
ULONG Unk9;
|
||||
RPC_FORWARD_FUNCTION PTR_T pRpcForwardFunction;
|
||||
ULONG Unk10[6];
|
||||
SIMPLE_DICT_T AuthenInfoDict;
|
||||
LIST_ENTRY_T RpcIfGroupListEntry;
|
||||
ULONG PTR_T __SRWLock;
|
||||
LIST_ENTRY_T field_1E0;
|
||||
}RPC_SERVER_T, PTR_T PRPC_SERVER_T;
|
||||
|
||||
typedef struct _RPC_INTERFACE_T
|
||||
{
|
||||
PRPC_SERVER_T pRpcServer;
|
||||
ULONG Flags;
|
||||
ULONG Unk1;
|
||||
MUTEX_T Mutex;
|
||||
ULONG EpMapperFlags;
|
||||
ULONG Unk2;
|
||||
RPC_MGR_EPV PTR_T pMgrEpv;
|
||||
RPC_IF_CALLBACK_FN PTR_T IfCallbackFn;
|
||||
RPC_SERVER_INTERFACE_T RpcServerInterface;
|
||||
PMIDL_SYNTAX_INFO pSyntaxInfo;
|
||||
VOID PTR_T pTransfertSyntaxes;
|
||||
ULONG TransfertSyntaxesCount;
|
||||
ULONG __Field_C4;
|
||||
ULONG NbTypeManager;
|
||||
ULONG MaxRpcSize;
|
||||
UUID_VECTOR PTR_T pUuidVector;
|
||||
SIMPLE_DICT_T RpcInterfaceManagerDict;
|
||||
UCHAR Annotation[MAX_RPC_INTERFACE_ANNOTATION];
|
||||
ULONG IsCallSizeLimitReached;
|
||||
ULONG currentNullManagerCalls;
|
||||
ULONG __Field_150;
|
||||
ULONG __Field_154;
|
||||
ULONG __Field_158;
|
||||
ULONG SecurityCallbackInProgress;
|
||||
ULONG SecurityCacheEntry;
|
||||
ULONG field_164;
|
||||
VOID PTR_T __SecurityCacheEntries[16];
|
||||
SIMPLE_DICT_T FwEpDict;
|
||||
ULONG Unk3[6];
|
||||
struct RPCP_INTERFACE_GROUP PTR_T pRpcpInterfaceGroup;
|
||||
}RPC_INTERFACE_T, PTR_T PRPC_INTERFACE_T;
|
||||
|
||||
#define RPC_ADDRESS_TYPE_DG 0x400000
|
||||
#define RPC_ADDRESS_TYPE_LRPC 0x800000
|
||||
#define RPC_ADDRESS_TYPE_OSF 0x800
|
||||
|
||||
typedef struct _RPC_ADDRESS_T {
|
||||
VOID PTR_T pVtable;
|
||||
ULONG Magic;
|
||||
ULONG TypeOfAddress;
|
||||
ULONG ReferenceCounter;
|
||||
ULONG Unk1[3];
|
||||
WCHAR PTR_T Name;
|
||||
WCHAR PTR_T Protocole;
|
||||
WCHAR PTR_T Address;
|
||||
ULONG bNamed;
|
||||
ULONG EpAddAddressFlag;
|
||||
SIMPLE_DICT_T __LRPCSassociationSimpleDict;
|
||||
ULONG __Field_68;
|
||||
ULONG Unk3;
|
||||
ULONG NbActiveCalls;
|
||||
ULONG __Field_74;
|
||||
ULONG Unk4[6];
|
||||
ULONG __Field_90;
|
||||
MUTEX_T Mutex;
|
||||
}RPC_ADDRESS_T;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif // _RPC_INTERNALS_H_
|
|
@ -0,0 +1,129 @@
|
|||
#ifndef _RPC_INTERNALS_H_
|
||||
#define _RPC_INTERNALS_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <Rpc.h>
|
||||
|
||||
|
||||
static UINT64 RPC_CORE_RUNTIME_VERSION[] = {
|
||||
0x6000324D70000LL, //6.3.9431.0000
|
||||
0x6000325804000LL, //6.3.9600.16384
|
||||
0x6000325804340LL, //6.3.9600.17216
|
||||
0x6000325804407LL, //6.3.9600.17415
|
||||
0x60003258045FFLL, //6.3.9600.17919
|
||||
|
||||
0xA000028004000LL, //10.0.10240.16384
|
||||
0xA00002800401CLL, //10.0.10240.16412
|
||||
0xA0000295A0000LL, //10.0.10586.0
|
||||
0xA0000295A0132LL, //10.0.10586.306
|
||||
0xA0000380603E8LL, //10.0.14342.1000
|
||||
0xA000038190000LL, //10.0.14361.0
|
||||
0xA000038390000LL, //10.0.14393.0
|
||||
0xA000038390052LL //10.0.14393.82
|
||||
};
|
||||
|
||||
#ifdef _WIN64
|
||||
#define RPC_CORE_DESCRIPTION "Windows 10 64bits wow64 runtime core"
|
||||
#define RPC_CORE_IS_WOW64 TRUE
|
||||
#define PTR_T *__ptr32 //WOW64!!!
|
||||
#define ULONG_PTR_T ULONG
|
||||
#else
|
||||
#define RPC_CORE_DESCRIPTION "Windows 10 32bits runtime core"
|
||||
#define RPC_CORE_IS_WOW64 FALSE
|
||||
#define ULONG_PTR_T ULONG_PTR
|
||||
#define PTR_T *
|
||||
#endif
|
||||
|
||||
#include "../RpcInternalsCommon.h"
|
||||
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct _RPC_SERVER_T{
|
||||
MUTEX_T MUTEX;
|
||||
BOOL _bIslistening;
|
||||
BOOL bIsListening;
|
||||
ULONG MinimumCallThreads;
|
||||
BOOL bWait;
|
||||
ULONG OutCalls;
|
||||
ULONG Unk1;
|
||||
ULONG InCalls;
|
||||
SIMPLE_DICT_T AddressDict;
|
||||
ULONG lAvailableCalls;
|
||||
SIMPLE_DICT_T _ProtSeqQueue;
|
||||
ULONG Unk2[4];
|
||||
ULONG OutPackets;
|
||||
MUTEX_T Mutex2;
|
||||
ULONG MaxCalls;
|
||||
VOID PTR_T hEvent;
|
||||
ULONG Unk4[4];
|
||||
SIMPLE_DICT_T InterfaceDict;
|
||||
BOOL __bIslistening;
|
||||
BOOL bIsMaxCall1234;
|
||||
ULONG Unk5[6];
|
||||
ULONG InPackets;
|
||||
RPC_FORWARD_FUNCTION PTR_T pRpcForwardFunction;
|
||||
ULONG Unk6[6];
|
||||
SIMPLE_DICT_T AuthenInfoDict;
|
||||
LIST_ENTRY_T RpcIfGroupListEntry;
|
||||
ULONG PTR_T __SRWLock;
|
||||
LIST_ENTRY_T __138;
|
||||
}RPC_SERVER_T, PTR_T PRPC_SERVER_T;
|
||||
|
||||
typedef struct _RPC_INTERFACE_T
|
||||
{
|
||||
PRPC_SERVER_T pRpcServer;
|
||||
ULONG Flags;
|
||||
MUTEX_T Mutex;
|
||||
ULONG EpMapperFlags;
|
||||
RPC_MGR_EPV PTR_T pMgrEpv;
|
||||
RPC_IF_CALLBACK_FN PTR_T IfSecurityCallback;
|
||||
RPC_SERVER_INTERFACE_T RpcServerInterface;
|
||||
MIDL_SYNTAX_INFO PTR_T pSyntaxInfo;
|
||||
VOID PTR_T pTransfertSyntaxes;
|
||||
ULONG TransfertSyntaxesCount;
|
||||
ULONG Unk1;
|
||||
ULONG NbTypeManager;
|
||||
ULONG MaxRpcSize;
|
||||
UUID_VECTOR PTR_T pUuidVector;
|
||||
SIMPLE_DICT_T RpcInterfaceManagerDict;
|
||||
UCHAR Annotation[64];
|
||||
RPC_IF_CALLBACK_FN PTR_T IfCallbackFn;
|
||||
ULONG IsCallSizeLimitReached;
|
||||
ULONG currentNullManagerCalls;
|
||||
ULONG currentAutoListenCalls;
|
||||
ULONG Unk2[2];
|
||||
ULONG SecurityCallbackInProgress;
|
||||
ULONG SecurityCacheEntry;
|
||||
ULONG __SecurityCacheEntries[16];
|
||||
SIMPLE_DICT_T FwEpDict;
|
||||
ULONG Unk3[4];
|
||||
}RPC_INTERFACE_T, PTR_T PRPC_INTERFACE_T;
|
||||
|
||||
#define RPC_ADDRESS_TYPE_DG 0x400000
|
||||
#define RPC_ADDRESS_TYPE_LRPC 0x800000
|
||||
#define RPC_ADDRESS_TYPE_OSF 0x800
|
||||
|
||||
typedef struct _RPC_ADDRESS_T{
|
||||
VOID PTR_T PTR_T pVTable;
|
||||
ULONG Magic;
|
||||
ULONG TypeOfAddress;
|
||||
ULONG ReferenceCounter;
|
||||
ULONG Unk1;
|
||||
WCHAR PTR_T Name;
|
||||
WCHAR PTR_T Protocole;
|
||||
WCHAR PTR_T Address;
|
||||
BOOL bNamed;
|
||||
ULONG EpAddAddressFlag;
|
||||
SIMPLE_DICT_T __LRPCSassociationSimpleDict;
|
||||
ULONG __Field_68;
|
||||
ULONG Unk3;
|
||||
ULONG NbActiveCalls;
|
||||
ULONG __Field_74;
|
||||
ULONG Unk4[6];
|
||||
ULONG __Field_90;
|
||||
MUTEX_T Mutex;
|
||||
}RPC_ADDRESS_T;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif // _RPC_INTERNALS_H_
|
|
@ -0,0 +1,130 @@
|
|||
#ifndef _RPC_INTERNALS_H_
|
||||
#define _RPC_INTERNALS_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <Rpc.h>
|
||||
|
||||
static UINT64 RPC_CORE_RUNTIME_VERSION[] = {
|
||||
0x6000324D70000LL, //6.3.9431.0000
|
||||
0x6000325804000LL, //6.3.9600.16384
|
||||
0x6000325804340LL, //6.3.9600.17216
|
||||
0x6000325804407LL, //6.3.9600.17415
|
||||
0x60003258045FFLL, //6.3.9600.17919
|
||||
|
||||
0xA000028004000LL, //10.0.10240.16384
|
||||
0xA00002800401CLL, //10.0.10240.16412
|
||||
0xA0000295A0000LL, //10.0.10586.0
|
||||
0xA0000295A0132LL, //10.0.10586.306
|
||||
0xA0000380603E8LL, //10.0.14342.1000
|
||||
0xA000038190000LL, //10.0.14361.0
|
||||
0xA000038390000LL, //10.0.14393.0
|
||||
0xA000038390052LL //10.0.14393.82
|
||||
};
|
||||
|
||||
#define RPC_CORE_DESCRIPTION "Windows 10 64bits runtime core"
|
||||
#define RPC_CORE_IS_WOW64 FALSE
|
||||
|
||||
#define ULONG_PTR_T ULONG_PTR
|
||||
#define PTR_T *
|
||||
|
||||
#include "../RpcInternalsCommon.h"
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct _RPC_SERVER_T{
|
||||
MUTEX_T Mutex;
|
||||
ULONG __bIslistening;
|
||||
ULONG bIsListening;
|
||||
ULONG MinimumCallThreads;
|
||||
ULONG Wait;
|
||||
ULONG OutCalls;
|
||||
ULONG Unk1;
|
||||
ULONG InCalls;
|
||||
ULONG Unk2;
|
||||
SIMPLE_DICT_T AddressDict;
|
||||
ULONG lAvailableCalls;
|
||||
ULONG Unk3;
|
||||
SIMPLE_DICT_T _ProtSeqQueue;
|
||||
ULONG Unk4[8];
|
||||
ULONG OutPackets;
|
||||
ULONG Unk5;
|
||||
MUTEX_T Mutex2;
|
||||
ULONG MaxCalls;
|
||||
ULONG Unk6;
|
||||
VOID PTR_T hEvent;
|
||||
ULONG Unk7[4];
|
||||
SIMPLE_DICT_T InterfaceDict;
|
||||
ULONG _bIsListening;
|
||||
ULONG bIsMaxCalls1234;
|
||||
ULONG Unk8[6];
|
||||
ULONG InPackets;
|
||||
ULONG Unk9;
|
||||
RPC_FORWARD_FUNCTION PTR_T pRpcForwardFunction;
|
||||
ULONG Unk10[6];
|
||||
SIMPLE_DICT_T AuthenInfoDict;
|
||||
LIST_ENTRY_T RpcIfGroupListEntry;
|
||||
ULONG PTR_T __SRWLock;
|
||||
LIST_ENTRY_T field_1E0;
|
||||
}RPC_SERVER_T, PTR_T PRPC_SERVER_T;
|
||||
|
||||
typedef struct _RPC_INTERFACE_T
|
||||
{
|
||||
PRPC_SERVER_T pRpcServer;
|
||||
ULONG Flags;
|
||||
ULONG Unk1;
|
||||
MUTEX_T Mutex;
|
||||
ULONG EpMapperFlags;
|
||||
ULONG Unk2;
|
||||
RPC_MGR_EPV PTR_T pMgrEpv;
|
||||
RPC_IF_CALLBACK_FN PTR_T IfCallbackFn;
|
||||
RPC_SERVER_INTERFACE_T RpcServerInterface;
|
||||
PMIDL_SYNTAX_INFO pSyntaxInfo;
|
||||
VOID PTR_T pTransfertSyntaxes;
|
||||
ULONG TransfertSyntaxesCount;
|
||||
ULONG __Field_C4;
|
||||
ULONG NbTypeManager;
|
||||
ULONG MaxRpcSize;
|
||||
UUID_VECTOR PTR_T pUuidVector;
|
||||
SIMPLE_DICT_T RpcInterfaceManagerDict;
|
||||
UCHAR Annotation[MAX_RPC_INTERFACE_ANNOTATION];
|
||||
ULONG IsCallSizeLimitReached;
|
||||
ULONG currentNullManagerCalls;
|
||||
ULONG __Field_150;
|
||||
ULONG __Field_154;
|
||||
ULONG __Field_158;
|
||||
ULONG SecurityCallbackInProgress;
|
||||
ULONG SecurityCacheEntry;
|
||||
ULONG field_164;
|
||||
VOID PTR_T __SecurityCacheEntries[16];
|
||||
SIMPLE_DICT_T FwEpDict;
|
||||
ULONG Unk3[6];
|
||||
struct RPCP_INTERFACE_GROUP PTR_T pRpcpInterfaceGroup;
|
||||
}RPC_INTERFACE_T, PTR_T PRPC_INTERFACE_T;
|
||||
|
||||
#define RPC_ADDRESS_TYPE_DG 0x400000
|
||||
#define RPC_ADDRESS_TYPE_LRPC 0x800000
|
||||
#define RPC_ADDRESS_TYPE_OSF 0x800
|
||||
|
||||
typedef struct _RPC_ADDRESS_T{
|
||||
VOID PTR_T pVtable;
|
||||
ULONG Magic;
|
||||
ULONG TypeOfAddress;
|
||||
ULONG ReferenceCounter;
|
||||
ULONG Unk1[3];
|
||||
WCHAR PTR_T Name;
|
||||
WCHAR PTR_T Protocole;
|
||||
WCHAR PTR_T Address;
|
||||
ULONG bNamed;
|
||||
ULONG EpAddAddressFlag;
|
||||
SIMPLE_DICT_T __LRPCSassociationSimpleDict;
|
||||
ULONG __Field_68;
|
||||
ULONG Unk3;
|
||||
ULONG NbActiveCalls;
|
||||
ULONG __Field_74;
|
||||
ULONG Unk4[6];
|
||||
ULONG __Field_90;
|
||||
MUTEX_T Mutex;
|
||||
}RPC_ADDRESS_T;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif // _RPC_INTERNALS_H_
|
|
@ -0,0 +1,90 @@
|
|||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include <RpcViewVersion.h>
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Français (France) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA)
|
||||
#ifdef _WIN32
|
||||
//LANGUAGE LANG_FRENCH, SUBLANG_FRENCH
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION _RPCVIEW_VERSION_MAJOR_,_RPCVIEW_VERSION_MINOR_,_RPCVIEW_VERSION_RELEASE_,0
|
||||
PRODUCTVERSION _RPCVIEW_VERSION_MAJOR_,_RPCVIEW_VERSION_MINOR_,_RPCVIEW_VERSION_RELEASE_,0
|
||||
FILEFLAGSMASK 0x0L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904e4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "RpcView"
|
||||
VALUE "FileDescription", "RPC runtime analyzer module"
|
||||
VALUE "InternalName", "RpcCore"
|
||||
VALUE "LegalCopyright", "Copyright © 2012-2017 RpcView Team"
|
||||
VALUE "LegalTrademarks", "Copyright (C) 2012-2017 RpcView Team"
|
||||
VALUE "OriginalFilename", "RpcCore.dll"
|
||||
VALUE "ProductName", "RpcCore"
|
||||
VALUE "ProductVersion", _RPCVIEW_PRODUCT_VERSION_
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1252
|
||||
END
|
||||
END
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.\0"
|
||||
END
|
||||
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Français (France) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
#ifndef _RPC_INTERNALS_COMMON_H_
|
||||
#define _RPC_INTERNALS_COMMON_H_
|
||||
|
||||
// Microsoft Remote Procedure Call (RPC) internals
|
||||
// Undocumented structure from rpcrt4.dll
|
||||
//
|
||||
// global pointers :
|
||||
// RPC_SERVER* GlobalRpcServer
|
||||
// RPC_INTERFACE* GlobalManagementInterface
|
||||
// ENDPOINT_MANAGER* EndpointManager
|
||||
// LRPC_SERVER* GlobalLrpcServer
|
||||
// SECURITY_PROVIDER_INFO* ProviderList
|
||||
//
|
||||
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Rpc\
|
||||
// - the "ClientsProtocols" key contains protocole sequence accepted
|
||||
// - the "Extensions" key ???
|
||||
// - the "SecurityService" key contains AuthnSvc constants and the corresponding DLLs
|
||||
// the "InitSecurityInterfaceW" function is called as entry-point to initialize the Authentication service
|
||||
//
|
||||
|
||||
#include <windows.h>
|
||||
#include "..\RpcCommon\ntdll.h"
|
||||
|
||||
#define MAX_RPC_INTERFACE_ANNOTATION 64
|
||||
#define SIMPLE_DICT_SMALL_ARRAY 4
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// From Winnt.h
|
||||
// The following structures are redefined to support Wow64 ptr
|
||||
//
|
||||
struct _RTL_CRITICAL_SECTION_T;
|
||||
|
||||
typedef struct _LIST_ENTRY_T {
|
||||
struct _LIST_ENTRY PTR_T Flink;
|
||||
struct _LIST_ENTRY PTR_T Blink;
|
||||
} LIST_ENTRY_T, *PLIST_ENTRY_T;
|
||||
|
||||
|
||||
typedef struct _RTL_CRITICAL_SECTION_DEBUG_T {
|
||||
WORD Type;
|
||||
WORD CreatorBackTraceIndex;
|
||||
struct _RTL_CRITICAL_SECTION_T PTR_T CriticalSection;
|
||||
LIST_ENTRY_T ProcessLocksList;
|
||||
DWORD EntryCount;
|
||||
DWORD ContentionCount;
|
||||
DWORD Flags;
|
||||
WORD CreatorBackTraceIndexHigh;
|
||||
WORD SpareWORD;
|
||||
} RTL_CRITICAL_SECTION_DEBUG_T, PTR_T PRTL_CRITICAL_SECTION_DEBUG_T;
|
||||
|
||||
typedef struct _RTL_CRITICAL_SECTION_T {
|
||||
PRTL_CRITICAL_SECTION_DEBUG_T DebugInfo;
|
||||
//
|
||||
// The following three fields control entering and exiting the critical
|
||||
// section for the resource
|
||||
//
|
||||
LONG LockCount;
|
||||
LONG RecursionCount;
|
||||
VOID PTR_T OwningThread; // from the thread's ClientId->UniqueThread
|
||||
VOID PTR_T LockSemaphore;
|
||||
VOID PTR_T SpinCount; // force size on 64-bit systems when packed
|
||||
} RTL_CRITICAL_SECTION_T, PTR_T PRTL_CRITICAL_SECTION_T;
|
||||
|
||||
//==============================================================================
|
||||
// From RpcDceP.h
|
||||
//
|
||||
typedef struct _RPC_DISPATCH_TABLE_T{
|
||||
UINT DispatchTableCount;
|
||||
RPC_DISPATCH_FUNCTION PTR_T DispatchTable;
|
||||
ULONG_PTR_T Reserved;
|
||||
} RPC_DISPATCH_TABLE_T, PTR_T PRPC_DISPATCH_TABLE_T;
|
||||
|
||||
typedef struct _RPC_PROTSEQ_ENDPOINT_T{
|
||||
UCHAR PTR_T RpcProtocolSequence;
|
||||
UCHAR PTR_T Endpoint;
|
||||
} RPC_PROTSEQ_ENDPOINT_T, PTR_T PRPC_PROTSEQ_ENDPOINT_T;
|
||||
|
||||
typedef struct _RPC_SERVER_INTERFACE_T{
|
||||
UINT Length;
|
||||
RPC_IF_ID InterfaceId;
|
||||
RPC_IF_ID TransferSyntax;
|
||||
PRPC_DISPATCH_TABLE_T DispatchTable;
|
||||
UINT RpcProtseqEndpointCount;
|
||||
PRPC_PROTSEQ_ENDPOINT_T RpcProtseqEndpoint;
|
||||
RPC_MGR_EPV PTR_T DefaultManagerEpv;
|
||||
void const PTR_T InterpreterInfo;
|
||||
UINT Flags ;
|
||||
} RPC_SERVER_INTERFACE_T, PTR_T PRPC_SERVER_INTERFACE_T;
|
||||
|
||||
|
||||
typedef struct _NDR_EXPR_DESC_T
|
||||
{
|
||||
const unsigned short PTR_T pOffset;
|
||||
const unsigned char PTR_T pFormatExpr;
|
||||
} NDR_EXPR_DESC_T;
|
||||
|
||||
|
||||
/*
|
||||
* MIDL Stub Descriptor
|
||||
*/
|
||||
typedef struct _MIDL_STUB_DESC_T{
|
||||
void PTR_T RpcInterfaceInformation;
|
||||
void PTR_T pfnAllocate;
|
||||
void PTR_T pfnFree;
|
||||
void PTR_T pAutoHandle;
|
||||
const VOID PTR_T apfnNdrRundownRoutines;
|
||||
const VOID PTR_T aGenericBindingRoutinePairs;
|
||||
const VOID PTR_T apfnExprEval;
|
||||
const VOID PTR_T aXmitQuintuple;
|
||||
const unsigned char PTR_T pFormatTypes;
|
||||
int fCheckBounds;
|
||||
/* Ndr library version. */
|
||||
unsigned long Version;
|
||||
VOID PTR_T pMallocFreeStruct;
|
||||
long MIDLVersion;
|
||||
const COMM_FAULT_OFFSETS PTR_T CommFaultOffsets;
|
||||
// New fields for version 3.0+
|
||||
const VOID PTR_T aUserMarshalQuadruple;
|
||||
// Notify routines - added for NT5, MIDL 5.0
|
||||
const VOID PTR_T NotifyRoutineTable;
|
||||
/*
|
||||
* Reserved for future use.
|
||||
*/
|
||||
ULONG_PTR_T mFlags;
|
||||
// International support routines - added for 64bit post NT5
|
||||
const VOID PTR_T CsRoutineTables;
|
||||
void PTR_T ProxyServerInfo;
|
||||
const NDR_EXPR_DESC_T PTR_T pExprInfo;
|
||||
// Fields up to now present in win2000 release.
|
||||
} MIDL_STUB_DESC_T, PTR_T PMIDL_STUB_DESC_T;
|
||||
|
||||
|
||||
/*
|
||||
* Server Interpreter's information strucuture.
|
||||
*/
|
||||
typedef struct _MIDL_SERVER_INFO_T{
|
||||
PMIDL_STUB_DESC_T pStubDesc;
|
||||
const VOID PTR_T PTR_T DispatchTable;
|
||||
const unsigned char PTR_T ProcString;
|
||||
const unsigned short PTR_T FmtStringOffset;
|
||||
const VOID PTR_T PTR_T ThunkTable;
|
||||
RPC_IF_ID PTR_T pTransferSyntax;
|
||||
ULONG_PTR_T nCount;
|
||||
VOID PTR_T pSyntaxInfo;
|
||||
} MIDL_SERVER_INFO_T, PTR_T PMIDL_SERVER_INFO_T;
|
||||
|
||||
//==============================================================================
|
||||
// Common private structures from rpctr4.dll.
|
||||
// These structures seems to be constant on all the runtime versions.
|
||||
//
|
||||
#pragma pack(1)
|
||||
typedef struct _SIMPLE_DICT_T{
|
||||
VOID PTR_T PTR_T pArray;
|
||||
UINT ArraySizeInBytes; //to change : countof array elements
|
||||
UINT NumberOfEntries;
|
||||
VOID PTR_T SmallArray[SIMPLE_DICT_SMALL_ARRAY];
|
||||
}SIMPLE_DICT_T, PTR_T PSIMPLE_DICT_T;
|
||||
|
||||
typedef struct _QUEUE_T{
|
||||
VOID PTR_T Tail;
|
||||
VOID PTR_T Head;
|
||||
ULONG Lentgh;
|
||||
VOID PTR_T SmallArray[SIMPLE_DICT_SMALL_ARRAY];
|
||||
}QUEUE_T;
|
||||
|
||||
typedef struct _MUTEX_T{
|
||||
RTL_CRITICAL_SECTION_T CriticalSection;
|
||||
}MUTEX_T;
|
||||
|
||||
typedef struct _EVENT_T{
|
||||
ULONG hEvent;
|
||||
} EVENT_T;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#define RPC_ADDRESS_TYPE_DG 0x400000
|
||||
#define RPC_ADDRESS_TYPE_LRPC 0x800000
|
||||
#define RPC_ADDRESS_TYPE_OSF 0x800
|
||||
|
||||
#endif //_RPC_INTERNALS_COMMON_H_
|
|
@ -0,0 +1,38 @@
|
|||
cmake_minimum_required (VERSION 3.0.2)
|
||||
|
||||
message("[RpcDecompiler]")
|
||||
|
||||
add_library(RpcDecompiler SHARED
|
||||
internalComplexTypesArrays.cpp
|
||||
internalComplexTypesArrays.h
|
||||
InternalComplexTypesMisc.cpp
|
||||
InternalComplexTypesMisc.h
|
||||
internalComplexTypesPointers.cpp
|
||||
internalComplexTypesPointers.h
|
||||
internalComplexTypesStrings.cpp
|
||||
internalComplexTypesStrings.h
|
||||
internalComplexTypesStructs.cpp
|
||||
internalComplexTypesStructs.h
|
||||
internalComplexTypesUnions.cpp
|
||||
internalComplexTypesUnions.h
|
||||
internalRpcDecompiler.cpp
|
||||
internalRpcDecompiler.h
|
||||
InternalRpcDecompTypeDefs.cpp
|
||||
internalRpcDecompTypeDefs.h
|
||||
internalRpcDecompTypeDefs_LEGACY.h
|
||||
internalRpcDecompTypeDefsNew.h
|
||||
internalRpcUtils.h
|
||||
InternalsRpcUtils.cpp
|
||||
internalTypeTools.cpp
|
||||
internalTypeTools.h
|
||||
RpcDecompiler.cpp
|
||||
RpcDecompiler.h
|
||||
IdlFunction.h
|
||||
IdlFunction.cpp
|
||||
IdlType.h
|
||||
IdlType.cpp
|
||||
IdlInterface.h
|
||||
IdlInterface.cpp
|
||||
RpcDecompilerResource.rc)
|
||||
|
||||
|
|
@ -0,0 +1,447 @@
|
|||
#include "IdlFunction.h"
|
||||
#include <sstream>
|
||||
#include "internalRpcDecompTypeDefsNew.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
// ======================================================================
|
||||
// CONSTRUCTOR
|
||||
// ======================================================================
|
||||
IdlFunction::IdlFunction(unsigned int uProcIdx, IdlInterface* pIdlInterface) :
|
||||
m_uProcIdx(uProcIdx),
|
||||
m_pIdlInterface(pIdlInterface),
|
||||
m_bHasRangeOnConformance(FALSE),
|
||||
m_uOffsetFirstArg(0),
|
||||
m_bDecoded(FALSE)
|
||||
{
|
||||
memset(&m_ProcHeader, 0, sizeof(m_ProcHeader));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// ======================================================================
|
||||
// ACCESSOR
|
||||
// ======================================================================
|
||||
IdlInterface* IdlFunction::getpIdlInterface() const
|
||||
{
|
||||
return m_pIdlInterface;
|
||||
}
|
||||
|
||||
size_t IdlFunction::getNbArguments() const
|
||||
{
|
||||
return (size_t)m_ProcHeader.oifheader.bNumber_of_params;
|
||||
}
|
||||
|
||||
bool IdlFunction::hasRangeOnConformance() const
|
||||
{
|
||||
return m_ProcHeader.win2KextHeader.interpreter_opt_flag2.HasRangeOnConf;
|
||||
}
|
||||
|
||||
const IdlType* IdlFunction::getReturnArg() const
|
||||
{
|
||||
|
||||
for(auto iter= m_listArg.begin(); iter != m_listArg.end(); iter++)
|
||||
{
|
||||
if(iter->isReturnArg() == TRUE)
|
||||
{
|
||||
return &*iter;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
// ======================================================================
|
||||
// OTHER METHODS
|
||||
// ======================================================================
|
||||
DECOMP_STATUS IdlFunction::decode(void* pCtx)
|
||||
{
|
||||
DECOMP_STATUS status = DS_ERR;
|
||||
|
||||
// set function name
|
||||
this->setName(pCtx);
|
||||
|
||||
status = this->decodeProcHeader(pCtx);
|
||||
|
||||
if(status != DS_SUCCESS)
|
||||
{
|
||||
RPC_ERROR_FN("decodeProcHeader failed\n");
|
||||
return DS_ERR_IN_DECODE_PROC_HEADER;
|
||||
}
|
||||
|
||||
status = this->decodeArguments(pCtx);
|
||||
|
||||
if(status != DS_SUCCESS)
|
||||
{
|
||||
RPC_ERROR_FN("decodeArguments failed\n");
|
||||
return DS_ERR_IN_DECODE_PROC_PARAMS;
|
||||
}
|
||||
|
||||
m_bDecoded = TRUE;
|
||||
|
||||
return DS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void IdlFunction::setName(void* pCtx)
|
||||
{
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *)pCtx;
|
||||
std::stringstream ss;
|
||||
|
||||
if (pRpcDecompilerCtxt->pRpcDecompilerInfo->ppProcNameTable == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ss << "Proc" << std::dec << this->m_uProcIdx;
|
||||
|
||||
if (pRpcDecompilerCtxt->pRpcDecompilerInfo->ppProcNameTable[this->m_uProcIdx] == NULL)
|
||||
{
|
||||
m_strFunctionName = ss.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t sz = wcslen(pRpcDecompilerCtxt->pRpcDecompilerInfo->ppProcNameTable[this->m_uProcIdx]) + 1;
|
||||
size_t szConverted = 0;
|
||||
|
||||
char* pTmp = (char*)pRpcDecompilerCtxt->pRpcViewHelper->RpcAlloc((UINT)sz);
|
||||
|
||||
if (pTmp != NULL)
|
||||
{
|
||||
ZeroMemory(pTmp, sz);
|
||||
wcstombs_s(&szConverted, pTmp, sz, pRpcDecompilerCtxt->pRpcDecompilerInfo->ppProcNameTable[this->m_uProcIdx], sz);
|
||||
|
||||
m_strFunctionName = ss.str() + std::string("_") + std::string(pTmp);
|
||||
//
|
||||
// We have to replace all ':' by '_' as MIDL doesn't support it
|
||||
// example: NThreadingLibrary::TWorkItem::NotifyCancel
|
||||
//
|
||||
std::replace(m_strFunctionName.begin(), m_strFunctionName.end(), ':', '_');
|
||||
|
||||
pRpcDecompilerCtxt->pRpcViewHelper->RpcFree(pTmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DECOMP_STATUS IdlFunction::decodeProcHeader(void* pCtx)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *)pCtx;
|
||||
UINT uOffsetInProcFmtString;
|
||||
|
||||
|
||||
if (pRpcDecompilerCtxt == NULL)
|
||||
{
|
||||
return DS_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// get proc offset in type format string
|
||||
uOffsetInProcFmtString = pRpcDecompilerCtxt->pRpcDecompilerInfo->pFormatStringOffsetTable[this->m_uProcIdx];
|
||||
|
||||
// Init ProcHeader
|
||||
memset(&this->m_ProcHeader, 0, sizeof(this->m_ProcHeader));
|
||||
|
||||
//========================================================
|
||||
// Read Oi Header part of header
|
||||
//========================================================
|
||||
|
||||
|
||||
bResult = RPC_GET_PROCESS_DATA2(
|
||||
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + uOffsetInProcFmtString),
|
||||
&(this->m_ProcHeader.oiHeader.beginning),
|
||||
sizeof(this->m_ProcHeader.oiHeader.beginning));
|
||||
|
||||
if (bResult == FALSE)
|
||||
{
|
||||
return DS_ERR_UNABLE_TO_READ_MEMORY;
|
||||
}
|
||||
|
||||
uOffsetInProcFmtString += sizeof(this->m_ProcHeader.oiHeader.beginning);
|
||||
|
||||
// should we read rpc_flags ?
|
||||
if ((this->m_ProcHeader.oiHeader.beginning.bOi_flags & Oi_HAS_RPCFLAGS) == Oi_HAS_RPCFLAGS)
|
||||
{
|
||||
bResult = RPC_GET_PROCESS_DATA2(
|
||||
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + uOffsetInProcFmtString),
|
||||
&(this->m_ProcHeader.oiHeader.dwRpc_flags),
|
||||
sizeof(this->m_ProcHeader.oiHeader.dwRpc_flags));
|
||||
|
||||
if (bResult == FALSE){
|
||||
return DS_ERR_UNABLE_TO_READ_MEMORY;
|
||||
}
|
||||
|
||||
uOffsetInProcFmtString += sizeof(this->m_ProcHeader.oiHeader.dwRpc_flags);
|
||||
}
|
||||
|
||||
// read OiHeader end
|
||||
bResult = RPC_GET_PROCESS_DATA2(
|
||||
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + uOffsetInProcFmtString),
|
||||
&(this->m_ProcHeader.oiHeader.end),
|
||||
sizeof(this->m_ProcHeader.oiHeader.end));
|
||||
|
||||
if (bResult == FALSE){
|
||||
return DS_ERR_UNABLE_TO_READ_MEMORY; ;
|
||||
}
|
||||
|
||||
uOffsetInProcFmtString += sizeof(this->m_ProcHeader.oiHeader.dwRpc_flags);
|
||||
|
||||
|
||||
//========================================================
|
||||
// If necessary read exeplicit_handle_description
|
||||
//========================================================
|
||||
if(this->m_ProcHeader.oiHeader.beginning.bHandle_type == FC_EXPLICIT_HANDLE)
|
||||
{
|
||||
bResult = RPC_GET_PROCESS_DATA2(
|
||||
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + uOffsetInProcFmtString),
|
||||
&(this->m_ProcHeader.explicitHandle),
|
||||
EXPLICIT_HANDLE_MIN_SIZE);
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
return DS_ERR_UNABLE_TO_READ_MEMORY;
|
||||
}
|
||||
|
||||
switch(this->m_ProcHeader.explicitHandle.htype)
|
||||
{
|
||||
case FC_BIND_PRIMITIVE:
|
||||
uOffsetInProcFmtString+= EXPLICIT_HANDLE_PRIMITIVE_SIZE;
|
||||
break;
|
||||
|
||||
case FC_BIND_GENERIC:
|
||||
bResult = RPC_GET_PROCESS_DATA2(
|
||||
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + uOffsetInProcFmtString),
|
||||
&(this->m_ProcHeader.explicitHandle),
|
||||
EXPLICIT_HANDLE_GENERIC_SIZE);
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
return DS_ERR_UNABLE_TO_READ_MEMORY;
|
||||
}
|
||||
|
||||
uOffsetInProcFmtString+= EXPLICIT_HANDLE_GENERIC_SIZE;
|
||||
break;
|
||||
|
||||
case FC_BIND_CONTEXT:
|
||||
bResult = RPC_GET_PROCESS_DATA2(
|
||||
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + uOffsetInProcFmtString),
|
||||
&(this->m_ProcHeader.explicitHandle),
|
||||
EXPLICIT_HANDLE_CONTEXT_SIZE);
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
return DS_ERR_UNABLE_TO_READ_MEMORY;
|
||||
}
|
||||
|
||||
uOffsetInProcFmtString+= EXPLICIT_HANDLE_CONTEXT_SIZE;
|
||||
break;
|
||||
|
||||
default:
|
||||
RPC_ERROR_FN("invalid explicit handle type\n");
|
||||
return DS_ERR_INVALID_DATA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//========================================================
|
||||
// Read Oif header part of header
|
||||
//========================================================
|
||||
|
||||
bResult = RPC_GET_PROCESS_DATA2(
|
||||
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + uOffsetInProcFmtString),
|
||||
&(this->m_ProcHeader.oifheader),
|
||||
sizeof(this->m_ProcHeader.oifheader));
|
||||
|
||||
if (bResult == FALSE){
|
||||
return DS_ERR_UNABLE_TO_READ_MEMORY; ;
|
||||
}
|
||||
|
||||
uOffsetInProcFmtString += sizeof(this->m_ProcHeader.oifheader);
|
||||
|
||||
//========================================================
|
||||
// Read Win32Ext header part of header
|
||||
//========================================================
|
||||
|
||||
// TODO : check under which condition win32Kext header is present
|
||||
bResult = RPC_GET_PROCESS_DATA2(
|
||||
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + uOffsetInProcFmtString),
|
||||
&(this->m_ProcHeader.win2KextHeader.extension_version),
|
||||
sizeof(this->m_ProcHeader.win2KextHeader.extension_version));
|
||||
|
||||
if (bResult == FALSE){
|
||||
return DS_ERR_UNABLE_TO_READ_MEMORY; ;
|
||||
}
|
||||
|
||||
|
||||
switch (this->m_ProcHeader.win2KextHeader.extension_version)
|
||||
{
|
||||
case WIN2K_EXT_HEADER_32B_SIZE:
|
||||
bResult = RPC_GET_PROCESS_DATA2(
|
||||
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + uOffsetInProcFmtString),
|
||||
&(this->m_ProcHeader.win2KextHeader.extension_version),
|
||||
WIN2K_EXT_HEADER_32B_SIZE
|
||||
);
|
||||
|
||||
uOffsetInProcFmtString += WIN2K_EXT_HEADER_32B_SIZE;
|
||||
|
||||
break;
|
||||
case WIN2K_EXT_HEADER_64B_SIZE:
|
||||
bResult = RPC_GET_PROCESS_DATA2(
|
||||
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + uOffsetInProcFmtString),
|
||||
&(this->m_ProcHeader.win2KextHeader.extension_version),
|
||||
WIN2K_EXT_HEADER_64B_SIZE
|
||||
);
|
||||
|
||||
uOffsetInProcFmtString += WIN2K_EXT_HEADER_64B_SIZE;
|
||||
break;
|
||||
|
||||
default:
|
||||
return DS_ERR_INVALID_DATA;
|
||||
}
|
||||
|
||||
m_uOffsetFirstArg = uOffsetInProcFmtString;
|
||||
|
||||
|
||||
return DS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DECOMP_STATUS IdlFunction::decodeArguments(void* pCtx)
|
||||
{
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *)pCtx;
|
||||
UINT uOffsetArg = 0;
|
||||
|
||||
//========================================================
|
||||
// Check arg
|
||||
//========================================================
|
||||
if(pRpcDecompilerCtxt == NULL)
|
||||
{
|
||||
return DS_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// ensure that offset to first arg is properly set
|
||||
if(m_uOffsetFirstArg == 0)
|
||||
{
|
||||
return DS_ERR_FUNCTION_NOT_PROPERLY_INITIALIZED;
|
||||
}
|
||||
|
||||
|
||||
uOffsetArg = m_uOffsetFirstArg;
|
||||
|
||||
for(unsigned int i=0; i<this->getNbArguments(); i++)
|
||||
{
|
||||
DECOMP_STATUS status;
|
||||
IdlType idlArg(this, uOffsetArg);
|
||||
|
||||
status = idlArg.decode(pRpcDecompilerCtxt);
|
||||
|
||||
if(status != DS_SUCCESS)
|
||||
{
|
||||
RPC_ERROR_FN("decode failed\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
m_listArg.push_back(idlArg);
|
||||
|
||||
// TODO : check if this size is constant
|
||||
uOffsetArg += OIF_PARAM_SIZE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return DS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
|
||||
std::ostream& IdlFunction::dump(std::ostream& o) const
|
||||
{
|
||||
const IdlType* pReturnArg = this->getReturnArg();
|
||||
bool bFirst = true;
|
||||
|
||||
|
||||
// =============================================
|
||||
// ensure that function has been correctly decoded
|
||||
// =============================================
|
||||
if(m_bDecoded == FALSE)
|
||||
{
|
||||
o << DEFAULT_FN_PREFIX << m_uProcIdx << "_NotDecoded();" << std::endl;
|
||||
return o;
|
||||
}
|
||||
|
||||
// =============================================
|
||||
// display return argument
|
||||
// =============================================
|
||||
if(pReturnArg == NULL)
|
||||
{
|
||||
o << "void ";
|
||||
}
|
||||
else
|
||||
{
|
||||
o << *pReturnArg;
|
||||
}
|
||||
|
||||
// =============================================
|
||||
// display function name
|
||||
// =============================================
|
||||
o << m_strFunctionName << "(" << std::endl;
|
||||
|
||||
#ifdef _ADD_IMPLICIT_HANDLE
|
||||
// =============================================
|
||||
// display every arguments
|
||||
// =============================================
|
||||
// manage special handle case
|
||||
// sometimes a handle should be add at the beginning
|
||||
// let's check if the first argument start at offset 0
|
||||
for(auto it=m_listArg.begin(); it!=m_listArg.end(); it++)
|
||||
{
|
||||
if(it->getStackOffset() == 0)
|
||||
{
|
||||
bNeedFirstHandle = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(bNeedFirstHandle == true)
|
||||
{
|
||||
o << "\t/*add default handle*/[in] handle_t arg_0";
|
||||
bFirst = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// display every arguments in argList
|
||||
for(auto it=m_listArg.begin(); it!=m_listArg.end(); it++)
|
||||
{
|
||||
if(it->isReturnArg() == false)
|
||||
{
|
||||
if(bFirst)
|
||||
{
|
||||
bFirst = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
o <<", " << std::endl;
|
||||
}
|
||||
|
||||
|
||||
o << "\t" << *it;
|
||||
}
|
||||
}
|
||||
|
||||
o << ");";
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const IdlFunction& idlFunction)
|
||||
{
|
||||
return idlFunction.dump(o);
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
#ifndef _RPC_DECOMP_FUNCTION_
|
||||
#define _RPC_DECOMP_FUNCTION_
|
||||
|
||||
#include <list>
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "IdlType.h"
|
||||
#include "IdlInterface.h"
|
||||
#include "internalRpcDecompTypeDefs.h"
|
||||
|
||||
class IdlType;
|
||||
class IdlInterface;
|
||||
|
||||
//#define _ADD_IMPLICIT_HANDLE
|
||||
#define DEFAULT_FN_PREFIX "_Function_"
|
||||
|
||||
class IdlFunction
|
||||
{
|
||||
private:
|
||||
std::string m_strFunctionName; // function name
|
||||
IdlInterface* m_pIdlInterface; // interface owning function
|
||||
std::list<IdlType> m_listArg; // list of function argument
|
||||
unsigned int m_uProcIdx; // function index in proc interface proc format string
|
||||
BOOL m_bInlined; // TRUE if function is inlined
|
||||
BOOL m_bHasRangeOnConformance; // TRUE if function has range on conformance
|
||||
PROC_HEADER_T m_ProcHeader;
|
||||
UINT m_uOffsetFirstArg; // Offset of first argument in proc format string
|
||||
BOOL m_bDecoded; // BOOL indicating if function has been properly decoded
|
||||
public:
|
||||
|
||||
|
||||
// ======================================================================
|
||||
// CONSTRUCTOR
|
||||
// ======================================================================
|
||||
IdlFunction(unsigned int uProcIdx, IdlInterface* pIdlInterface);
|
||||
|
||||
|
||||
// ======================================================================
|
||||
// ACCESSOR
|
||||
// ======================================================================
|
||||
IdlInterface* getpIdlInterface() const;
|
||||
size_t getNbArguments() const;
|
||||
bool hasRangeOnConformance() const;
|
||||
|
||||
|
||||
const IdlType* getReturnArg() const;
|
||||
|
||||
|
||||
// ======================================================================
|
||||
// OTHER METHODS
|
||||
// ======================================================================
|
||||
DECOMP_STATUS decode(void* pCtx);
|
||||
void setName(void* pCtx);
|
||||
DECOMP_STATUS decodeProcHeader(void* pCtx);
|
||||
DECOMP_STATUS decodeArguments(void* pCtx);
|
||||
std::ostream& dump(std::ostream& o) const;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const IdlFunction& idlFunction);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,229 @@
|
|||
#include "IdlInterface.h"
|
||||
#include "internalRpcDecompiler.h"
|
||||
|
||||
// ======================================================================
|
||||
// CONSTRUCTOR
|
||||
// ======================================================================
|
||||
IdlInterface::IdlInterface(std::string strIfName, RPC_IF_ID& RpcIfId, size_t szNbFunctions):
|
||||
m_strIfName(strIfName),
|
||||
m_szNbFunctions(szNbFunctions),
|
||||
m_vectFunctions(szNbFunctions),
|
||||
m_RpcIfId(RpcIfId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IdlInterface::~IdlInterface()
|
||||
{
|
||||
for(size_t i=0; i<m_vectFunctions.size(); i++)
|
||||
{
|
||||
if(m_vectFunctions[i] != NULL)
|
||||
{
|
||||
delete m_vectFunctions[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ======================================================================
|
||||
// ACCESSOR
|
||||
// ======================================================================
|
||||
std::vector<IdlFunction*> IdlInterface::getIntefaceFunctions()
|
||||
{
|
||||
return m_vectFunctions;
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
// DECODING METHODS
|
||||
// ======================================================================
|
||||
DECOMP_STATUS IdlInterface::decode(void* pCtx)
|
||||
{
|
||||
DECOMP_STATUS dStatus = DS_ERR;
|
||||
DECOMP_STATUS dStatusRet = DS_SUCCESS;
|
||||
|
||||
// check param
|
||||
if(pCtx == NULL)
|
||||
{
|
||||
RPC_ERROR_FN("pCtx NULL pointer\n");
|
||||
return DS_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
|
||||
// decode every functions
|
||||
for(UINT i=0; i<m_szNbFunctions; i++)
|
||||
{
|
||||
dStatus = this->decodeFunction(i, pCtx);
|
||||
|
||||
if(dStatus != DS_SUCCESS)
|
||||
{
|
||||
RPC_ERROR_FN("decodeFunction failed\n");
|
||||
printf("Idx %u\n", i);
|
||||
std::ostringstream ossIf;
|
||||
this->dumpIfInfo(ossIf);
|
||||
printf("%s", ossIf.str().c_str());
|
||||
//DEBUG_BREAK();
|
||||
// don't stop at first failure in order to decompile every possible functions
|
||||
dStatusRet = dStatus;
|
||||
}
|
||||
}
|
||||
|
||||
if(dStatusRet == DS_SUCCESS)
|
||||
{
|
||||
// once every functions is decoded
|
||||
dStatusRet = decodeInterfaceComplexTypes(pCtx);
|
||||
}
|
||||
|
||||
|
||||
return dStatusRet;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DECOMP_STATUS IdlInterface::decodeFunction(UINT uFunctionIdx, void* pCtx)
|
||||
{
|
||||
// check param
|
||||
if(pCtx == NULL)
|
||||
{
|
||||
return DS_ERR_INVALID_PARAM;
|
||||
}
|
||||
if(uFunctionIdx > m_szNbFunctions)
|
||||
{
|
||||
return DS_ERR_INVALID_INDEX;
|
||||
}
|
||||
|
||||
// has function already been decoded
|
||||
if(m_vectFunctions[uFunctionIdx] == NULL)
|
||||
{
|
||||
m_vectFunctions[uFunctionIdx] = new IdlFunction(uFunctionIdx, this);
|
||||
|
||||
return (m_vectFunctions[uFunctionIdx])->decode(pCtx);
|
||||
}
|
||||
else
|
||||
{
|
||||
return DS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DECOMP_STATUS IdlInterface::decodeInterfaceComplexTypes(void* pCtx)
|
||||
{
|
||||
std::list<TypeToDefine> listAllTypesSorted;
|
||||
std::ostringstream ossUseless;
|
||||
|
||||
|
||||
// check param
|
||||
if(pCtx == NULL)
|
||||
{
|
||||
return DS_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// clear string stream content
|
||||
m_ossComplexTypes.flush();
|
||||
|
||||
|
||||
// recursively explore all list in order to get a complete list of types
|
||||
if (getAllTypesSortedInAList(pCtx, m_listProcTypes, listAllTypesSorted, ossUseless) == FALSE)
|
||||
{
|
||||
m_ossComplexTypes<<"[ERROR] unable to get list of all types sorted" << std::endl;
|
||||
return DS_ERR_UNABLE_TO_DECODE_COMPLEX_TYPE;
|
||||
}
|
||||
|
||||
if( dumpTypeList(pCtx, listAllTypesSorted, m_ossComplexTypes) == FALSE)
|
||||
{
|
||||
m_ossComplexTypes<<"[ERROR] unable to dump type list" << std::endl;
|
||||
return DS_ERR_UNABLE_TO_DECODE_COMPLEX_TYPE;
|
||||
}
|
||||
|
||||
|
||||
return DS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
|
||||
std::ostream& IdlInterface::dump(std::ostream& o) const
|
||||
{
|
||||
dumpIfInfo(o);
|
||||
|
||||
o << std::endl;
|
||||
o << "interface "<< m_strIfName << std::endl;
|
||||
o << "{" << std::endl;
|
||||
|
||||
// display complex type
|
||||
|
||||
o << m_ossComplexTypes.str();
|
||||
|
||||
// display functions
|
||||
for(size_t i=0; i< m_szNbFunctions; i++)
|
||||
{
|
||||
o << std::endl;
|
||||
|
||||
if(m_vectFunctions[i] == NULL)
|
||||
{
|
||||
o << "void Opnum"<<i<<"NotDecoded(void)";
|
||||
}
|
||||
else
|
||||
{
|
||||
o << *(m_vectFunctions[i]);
|
||||
}
|
||||
|
||||
o << std::endl;
|
||||
}
|
||||
|
||||
o << "} ";
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define MAX_UUID_STR 40
|
||||
std::ostream& IdlInterface::dumpIfInfo(std::ostream& o) const
|
||||
{
|
||||
char chUuidStr[MAX_UUID_STR] = {0};
|
||||
int res;
|
||||
|
||||
res = sprintf_s(
|
||||
chUuidStr,
|
||||
sizeof(chUuidStr),
|
||||
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
m_RpcIfId.Uuid.Data1,
|
||||
m_RpcIfId.Uuid.Data2,
|
||||
m_RpcIfId.Uuid.Data3,
|
||||
m_RpcIfId.Uuid.Data4[0],
|
||||
m_RpcIfId.Uuid.Data4[1],
|
||||
m_RpcIfId.Uuid.Data4[2],
|
||||
m_RpcIfId.Uuid.Data4[3],
|
||||
m_RpcIfId.Uuid.Data4[4],
|
||||
m_RpcIfId.Uuid.Data4[5],
|
||||
m_RpcIfId.Uuid.Data4[6],
|
||||
m_RpcIfId.Uuid.Data4[7]);
|
||||
|
||||
o << "[" << std::endl;
|
||||
o << "uuid(";
|
||||
|
||||
if(res != -1)
|
||||
{
|
||||
o << std::string(chUuidStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
o << "/* ERROR IN UUID DECODING */";
|
||||
}
|
||||
|
||||
o << ")," << std::endl;
|
||||
o << "version("<< m_RpcIfId.VersMajor <<"."<< m_RpcIfId.VersMinor <<")," << std::endl;
|
||||
o <<"]";
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const IdlInterface& idlInterface)
|
||||
{
|
||||
return idlInterface.dump(o);
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
#ifndef _RPC_DECOMP_INTERFACE_
|
||||
#define _RPC_DECOMP_INTERFACE_
|
||||
|
||||
#include "IdlFunction.h"
|
||||
#include "IdlType.h"
|
||||
#include "internalRpcDecompTypeDefs.h"
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
class IdlFunction;
|
||||
class IdlType;
|
||||
|
||||
|
||||
|
||||
// IdlInterface class definition
|
||||
|
||||
class IdlInterface
|
||||
{
|
||||
friend class IdlType;
|
||||
private:
|
||||
std::string m_strIfName; // Interface name
|
||||
RPC_IF_ID m_RpcIfId; // inteface id
|
||||
std::vector<IdlFunction*> m_vectFunctions; // vector holding pointer to every function defined in interface
|
||||
// this vector will be filled once functions are decompiled
|
||||
|
||||
size_t m_szNbFunctions; // number of functions defined in interface
|
||||
|
||||
std::list<TypeToDefine> m_listProcTypes; // list of complex types (structure / union) found while decompiling functions
|
||||
// once this list is filled it is parsed to produce declaration of these complex types
|
||||
|
||||
std::ostringstream m_ossComplexTypes; // string stream that will contained decoded version of complex types
|
||||
// (once they've all been found and decoded)
|
||||
public:
|
||||
// ======================================================================
|
||||
// CONSTRUCTOR
|
||||
// ======================================================================
|
||||
IdlInterface(std::string strIfName, RPC_IF_ID& RpcIfId, size_t szNbFunctions);
|
||||
~IdlInterface();
|
||||
|
||||
// ======================================================================
|
||||
// ACCESSOR
|
||||
// ======================================================================
|
||||
std::vector<IdlFunction*> getIntefaceFunctions();
|
||||
std::list<TypeToDefine> getListTypeToDefine();
|
||||
|
||||
// ======================================================================
|
||||
// DECODIND METHODS
|
||||
// ======================================================================
|
||||
|
||||
DECOMP_STATUS decode(void* pCtx);
|
||||
DECOMP_STATUS decodeFunction(UINT uFunctionIdx, void* pCtx);
|
||||
DECOMP_STATUS decodeInterfaceComplexTypes(void* pCtx);
|
||||
std::ostream& dump(std::ostream& o) const;
|
||||
std::ostream& dumpIfInfo(std::ostream& o) const;
|
||||
};
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const IdlInterface& idlInterface);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,168 @@
|
|||
#include "IdlType.h"
|
||||
#include "internalRpcDecompiler.h"
|
||||
#include <sstream>
|
||||
|
||||
|
||||
IdlType::IdlType(IdlFunction* pFunction, const UINT m_uOffsetInProcFmt):
|
||||
m_pFunction(pFunction),
|
||||
m_uOffsetInProcFmt(m_uOffsetInProcFmt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ======================================================================
|
||||
// ACCESSOR
|
||||
// ======================================================================
|
||||
unsigned short IdlType::getStackOffset() const
|
||||
{
|
||||
return m_paramDescription.oif_Format.stack_offset;
|
||||
}
|
||||
|
||||
|
||||
DECOMP_STATUS IdlType::decode(const void* pCtx)
|
||||
{
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *)pCtx;
|
||||
BOOL bResult;
|
||||
UINT32 argNbr = 0;
|
||||
ParamDesc ParamDesc;
|
||||
std::ostringstream ossTmp;
|
||||
std::ostringstream oss;
|
||||
|
||||
//========================================================
|
||||
// Check arg
|
||||
//========================================================
|
||||
if(pRpcDecompilerCtxt == NULL)
|
||||
{
|
||||
return DS_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//========================================================
|
||||
// Read param description
|
||||
//========================================================
|
||||
bResult = RPC_GET_PROCESS_DATA2(
|
||||
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + m_uOffsetInProcFmt),
|
||||
&m_paramDescription,
|
||||
sizeof(m_paramDescription)
|
||||
);
|
||||
|
||||
|
||||
|
||||
if(is64B) argNbr = m_paramDescription.oif_Format.stack_offset / VIRTUAL_STACK_OFFSET_GRANULARITY_64B;
|
||||
else argNbr = m_paramDescription.oif_Format.stack_offset / VIRTUAL_STACK_OFFSET_GRANULARITY_32B;
|
||||
|
||||
|
||||
// add param IdlFunctionDesc properties
|
||||
if(m_pFunction->hasRangeOnConformance())
|
||||
{
|
||||
ParamDesc.setHasRangeOnConformance();
|
||||
}
|
||||
|
||||
// fill param desc with ParamAttr
|
||||
ParamDesc.fillWithParamAttr(m_paramDescription.oif_Format.paramAttributes);
|
||||
|
||||
|
||||
|
||||
// TODO : ParamDesc was used in old mode, remove it
|
||||
if(m_paramDescription.oif_Format.paramAttributes.IsReturn == 0)
|
||||
{
|
||||
ossTmp << "arg_" << argNbr;
|
||||
ParamDesc.setParamName(ossTmp.str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// param is base type
|
||||
if(m_paramDescription.oif_Format.paramAttributes.IsBasetype)
|
||||
{
|
||||
bResult = processSimpleType(
|
||||
pRpcDecompilerCtxt,
|
||||
(FC_TYPE)m_paramDescription.oif_Format.paramType.base_type_format_char.type_format_char,
|
||||
ParamDesc,
|
||||
oss);
|
||||
|
||||
if(FALSE == bResult)
|
||||
{
|
||||
RPC_ERROR_FN("processSimpleType failed\n");
|
||||
return DS_ERR_IN_SIMPLE_TYPE;
|
||||
}
|
||||
|
||||
|
||||
} //if(paramToPrint.oif_Format.paramAttributes.IsBasetype)
|
||||
else
|
||||
{
|
||||
ParamDesc.setRva(pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString + m_paramDescription.oif_Format.paramType.other_type_offset);
|
||||
|
||||
bResult = rpcDumpType(
|
||||
pRpcDecompilerCtxt,
|
||||
ParamDesc,
|
||||
m_pFunction->getpIdlInterface()->m_listProcTypes,
|
||||
oss);
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_ERROR_FN("rpcDumpType failed\n");
|
||||
return DS_ERR_IN_SIMPLE_TYPE;
|
||||
}
|
||||
}// !(paramToPrint.oif_Format.paramAttributes.IsBasetype)
|
||||
|
||||
|
||||
m_name = oss.str();
|
||||
|
||||
return DS_SUCCESS;
|
||||
}
|
||||
|
||||
bool IdlType::isReturnArg() const
|
||||
{
|
||||
return (m_paramDescription.oif_Format.paramAttributes.IsReturn != 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::ostream& IdlType::dump(std::ostream& o) const
|
||||
{
|
||||
|
||||
if( (m_paramDescription.oif_Format.paramAttributes.IsReturn) == 0)
|
||||
{
|
||||
|
||||
if(m_paramDescription.oif_Format.paramAttributes.IsIn)
|
||||
{
|
||||
o << "[in]";
|
||||
}
|
||||
|
||||
if(m_paramDescription.oif_Format.paramAttributes.IsOut)
|
||||
{
|
||||
o << "[out]";
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if(m_paramDescription.oif_Format.paramAttributes.IsSimpleRef)
|
||||
{
|
||||
o << "/* simple_ref */";
|
||||
}
|
||||
#endif
|
||||
//
|
||||
// pipe appears to be an invalid attribute for MIDL
|
||||
// see EfsRpc (c681d488-d850-11d0-8c52-00c04fd90f7e) EfsRpcReadFileRaw_Downlevel
|
||||
//
|
||||
/*
|
||||
if(m_paramDescription.oif_Format.paramAttributes.IsPipe)
|
||||
{
|
||||
o << "[pipe]";
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
o << m_name;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const IdlType& idlType)
|
||||
{
|
||||
return idlType.dump(o);
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef _RPC_DECOMP_TYPE_
|
||||
#define _RPC_DECOMP_TYPE_
|
||||
|
||||
#include "IdlFunction.h"
|
||||
#include "internalRpcDecompTypeDefs.h"
|
||||
#include <sstream>
|
||||
|
||||
|
||||
class IdlFunction;
|
||||
|
||||
class IdlType
|
||||
{
|
||||
private:
|
||||
std::string m_name; // Param name
|
||||
IdlFunction* m_pFunction; // pointer to related function
|
||||
UINT m_uOffsetInProcFmt; // offset where param is described in proc format string
|
||||
ProcFormatStringParam_U m_paramDescription; // Parameter description in proc format string
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
// ======================================================================
|
||||
// CONSTRUCTOR
|
||||
// ======================================================================
|
||||
IdlType(IdlFunction* pFunction, const UINT m_uOffsetInProcFmt);
|
||||
|
||||
|
||||
// ======================================================================
|
||||
// ACCESSOR
|
||||
// ======================================================================
|
||||
unsigned short getStackOffset() const;
|
||||
|
||||
|
||||
// ======================================================================
|
||||
// OTHER METHODS
|
||||
// ======================================================================
|
||||
DECOMP_STATUS decode(const void* pCtx);
|
||||
bool isReturnArg() const;
|
||||
std::ostream& dump(std::ostream& o) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const IdlType& idlType);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,955 @@
|
|||
#include "InternalComplexTypesMisc.h"
|
||||
#include "internalRpcDecompiler.h"
|
||||
#include "internalRpcUtils.h"
|
||||
#include <string>
|
||||
|
||||
|
||||
BOOL __fastcall processBindContext(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(listProcTypes);
|
||||
UNREFERENCED_PARAMETER(pType);
|
||||
UNREFERENCED_PARAMETER(pContext);
|
||||
|
||||
oss << "[context_handle] void*";
|
||||
displayPtrLevel(ParamDesc.getuPtrLevel(), oss);
|
||||
oss <<" "<<ParamDesc.getStrTypeName();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall process_FC_BLKHOLE(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
BOOL bResult = TRUE;
|
||||
short wOffsetRange = 0;
|
||||
DWORD dwRangeBegin = 0;
|
||||
DWORD dwRangeEnd = 0;
|
||||
RVA_T pNewType = NULL;
|
||||
BYTE bRead = 0;
|
||||
|
||||
|
||||
pType += sizeof(BYTE) + sizeof(BYTE); // skip FC_TYPE and first BYTE
|
||||
|
||||
//read offset to complex type
|
||||
RPC_GET_PROCESS_DATA(pType,&wOffsetRange,sizeof(wOffsetRange));
|
||||
if(!bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] process_FC_BLKHOLE : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
pNewType = pType + wOffsetRange;
|
||||
pType += sizeof(wOffsetRange);
|
||||
|
||||
// read FC_TYPE at given offset
|
||||
RPC_GET_PROCESS_DATA(pNewType,&bRead,sizeof(bRead));
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] process_FC_BLKHOLE : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// if type is a FC_BIND_CONTEXT range doesn't make sense
|
||||
// todo : check why this happen
|
||||
if((FC_TYPE) bRead != FC_BIND_CONTEXT)
|
||||
{
|
||||
//read range begin
|
||||
RPC_GET_PROCESS_DATA(pType,&dwRangeBegin,sizeof(dwRangeBegin));
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] process_FC_BLKHOLE : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pType += sizeof(dwRangeBegin);
|
||||
|
||||
//read range end
|
||||
RPC_GET_PROCESS_DATA(pType,&dwRangeEnd,sizeof(dwRangeEnd));
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] process_FC_BLKHOLE : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
oss<<"[range("<<dwRangeBegin<<","<<(UINT)dwRangeEnd<<")] ";
|
||||
}
|
||||
|
||||
|
||||
ParamDesc.setRva(pNewType);
|
||||
|
||||
bResult = rpcDumpType(
|
||||
pContext,
|
||||
ParamDesc,
|
||||
listProcTypes,
|
||||
oss);
|
||||
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall getFC_BLKHOLEMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Out_ size_t* pszMemorySize,
|
||||
_In_ BOOL bHasRangeOnConformance)
|
||||
{
|
||||
|
||||
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
BOOL bResult = TRUE;
|
||||
short offsetRange = 0;
|
||||
RVA_T pNewType = NULL;
|
||||
|
||||
pType += sizeof(BYTE) + sizeof(BYTE); // skip FC_TYPE and first BYTE
|
||||
|
||||
//read offset to complex type
|
||||
RPC_GET_PROCESS_DATA(pType,&offsetRange,sizeof(offsetRange));
|
||||
if(!bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] getFC_BLKHOLEMemorySize : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
pNewType = pType + offsetRange;
|
||||
|
||||
bResult = getTypeMemorySize(pContext, pNewType, pszMemorySize, bHasRangeOnConformance);
|
||||
|
||||
|
||||
return bResult;
|
||||
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall processRange(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
BOOL bResult = TRUE;
|
||||
std::ostringstream ossTmp;
|
||||
|
||||
Range_t range;
|
||||
|
||||
UNREFERENCED_PARAMETER(listProcTypes);
|
||||
|
||||
RPC_GET_PROCESS_DATA(pType, &range, sizeof(range));
|
||||
|
||||
if(!bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processRange : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
processSimpleType(
|
||||
pContext,
|
||||
(FC_TYPE)(range.flags_type & 0xF), //type is on lower byte
|
||||
ParamDesc,
|
||||
ossTmp);
|
||||
|
||||
|
||||
if(ParamDesc.getuPtrLevel() != 0)
|
||||
{
|
||||
oss << "/*";
|
||||
}
|
||||
oss << "[range(" << std::dec << range.lowValue << "," << range.highValue<< ")] ";
|
||||
if(ParamDesc.getuPtrLevel() != 0)
|
||||
{
|
||||
oss << "*/";
|
||||
}
|
||||
|
||||
|
||||
oss<<ossTmp.str();
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall getRangeMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Out_ size_t* pszMemorySize)
|
||||
{
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
BOOL bResult = TRUE;
|
||||
Range_t range;
|
||||
|
||||
|
||||
RPC_GET_PROCESS_DATA(pType, &range, sizeof(range));
|
||||
|
||||
if(!bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] getRangeMemorySize : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
(*pszMemorySize) = getSimpleTypeMemorySize((FC_TYPE) (range.flags_type & 0xF));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall ProcessArrayRange(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::ostringstream& temp)
|
||||
{
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
BOOL bResult = TRUE;
|
||||
|
||||
Range_t range;
|
||||
UNREFERENCED_PARAMETER(ParamDesc);
|
||||
|
||||
RPC_GET_PROCESS_DATA(pType, &range, sizeof(range));
|
||||
if(!bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] ProcessArrayRange : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
temp << "/*[range(" << std::dec << range.lowValue << "," << range.highValue<< ")]*/ ";
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
UINT getElementByOffset(std::vector <UINT> v, UINT offset)
|
||||
{
|
||||
for(UINT i=0; i<v.size(); i++)
|
||||
{
|
||||
if(v[i] == offset)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return (UINT)-1;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall processUserMarshal(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
BOOL bResult = TRUE;
|
||||
UserMarshal_t userMarshal;
|
||||
RVA_T pUserMarshalTarget = NULL;
|
||||
std::string strParamNameTmp;
|
||||
|
||||
RPC_GET_PROCESS_DATA(pType, &userMarshal, sizeof(userMarshal));
|
||||
|
||||
if(FALSE == bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processUserMarshal : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
oss << "/* WARNING : user_marshall should be defined in ACF file */ [user_marshall(";
|
||||
|
||||
// compute user marshal target offset
|
||||
pUserMarshalTarget = pType + FIELD_OFFSET(UserMarshal_t, offset_to_the_transmitted_type) + userMarshal.offset_to_the_transmitted_type;
|
||||
ParamDesc.setRva(pUserMarshalTarget);
|
||||
|
||||
strParamNameTmp = ParamDesc.getStrTypeName();
|
||||
ParamDesc.setParamName("");
|
||||
|
||||
if (rpcDumpType(pContext, ParamDesc, listProcTypes, oss) == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processUserMarshal : unable to dump type\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
oss << ")] " << strParamNameTmp;
|
||||
|
||||
// set user_marshal size ??
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall getUserMarshallMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Out_ size_t* pszMemorySize)
|
||||
{
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
BOOL bResult = TRUE;
|
||||
UserMarshal_t userMarshal;
|
||||
|
||||
|
||||
RPC_GET_PROCESS_DATA(pType, &userMarshal, sizeof(userMarshal));
|
||||
|
||||
if(FALSE == bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processUserMarshal : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pszMemorySize = userMarshal.user_type_memory_size;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall processPipe(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
BOOL bResult = TRUE;
|
||||
Pipe_t pipe;
|
||||
RVA_T pPipeTarget = NULL;
|
||||
std::string strParamNameTmp;
|
||||
|
||||
RPC_GET_PROCESS_DATA(pType, &pipe, sizeof(pipe));
|
||||
|
||||
if(FALSE == bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processPipe : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// compute pipe target offset
|
||||
pPipeTarget = pType + FIELD_OFFSET(Pipe_t, offsetToType ) + pipe.offsetToType;
|
||||
ParamDesc.setRva(pPipeTarget);
|
||||
|
||||
|
||||
oss << "pipe ";
|
||||
|
||||
if (rpcDumpType(pContext, ParamDesc, listProcTypes, oss) == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processPipe : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// set pipe size ??
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall getPipeMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Out_ size_t* pszMemorySize,
|
||||
_In_ BOOL bHasRangeOnConformance)
|
||||
{
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
BOOL bResult = TRUE;
|
||||
Pipe_t pipe;
|
||||
RVA_T pPipeTarget = NULL;
|
||||
|
||||
|
||||
RPC_GET_PROCESS_DATA(pType, &pipe, sizeof(pipe));
|
||||
|
||||
if(FALSE == bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] getPipeMemorySize : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// compute pipe target offset
|
||||
pPipeTarget = pType + FIELD_OFFSET(Pipe_t, offsetToType ) + pipe.offsetToType;
|
||||
|
||||
bResult = getTypeMemorySize(pContext, pPipeTarget, pszMemorySize, bHasRangeOnConformance);
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall processCorrelationDescriptor(
|
||||
_In_ VOID* pContext,
|
||||
_In_ ConformanceDescr_T confDesc,
|
||||
_Inout_ std::ostringstream& oss,
|
||||
_Inout_ ParamDesc& paramDesc)
|
||||
{
|
||||
|
||||
BOOL bResult = FALSE;
|
||||
|
||||
oss<<"[";
|
||||
|
||||
// display conformance type
|
||||
switch(confDesc.confType)
|
||||
{
|
||||
case size_is:
|
||||
oss<<"size_is(";
|
||||
break;
|
||||
case switch_is:
|
||||
oss<<"switch_is(";
|
||||
break;
|
||||
case length_is:
|
||||
oss<<"length_is(";
|
||||
break;
|
||||
case byte_count:
|
||||
oss<<"byte_count(";
|
||||
break;
|
||||
default:
|
||||
oss<<"unknow_corr_type(";
|
||||
}
|
||||
|
||||
// Check on which pointer level conformance should be applied
|
||||
{
|
||||
UINT uPtrLevel = paramDesc.getuPtrLevel();
|
||||
|
||||
if(uPtrLevel > 1)
|
||||
{
|
||||
while(--uPtrLevel > 1)
|
||||
{
|
||||
oss << ",";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bResult = processCorrelationDescriptorNaked(pContext, confDesc, oss, paramDesc);
|
||||
|
||||
oss<<")]";
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall processCorrelationDescriptorNaked(
|
||||
_In_ VOID* pContext,
|
||||
_In_ ConformanceDescr_T confDesc,
|
||||
_Inout_ std::ostringstream& oss,
|
||||
_Inout_ ParamDesc& paramDesc)
|
||||
{
|
||||
|
||||
BOOL bResult;
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
|
||||
std::string strCorrelationItem; // string describing X in size_is(X)
|
||||
|
||||
|
||||
// special cases : OperationType == FC_EXPR || OperationType === FC_CALLBACK
|
||||
if(confDesc.corrDesc.correlation_operator == FC_EXPR )
|
||||
{
|
||||
USHORT offset = 0;
|
||||
|
||||
// read offset
|
||||
RPC_GET_PROCESS_DATA(
|
||||
((RVA_T)pRpcDecompilerCtxt->pRpcDecompilerInfo->pExprOffset + confDesc.corrDesc.offset*sizeof(USHORT)),
|
||||
&offset,
|
||||
sizeof(USHORT));
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
oss << "/* ERROR unable to read ExprOffset table */";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
oss << "/* FC_EXPR */";
|
||||
|
||||
bResult = processFcExpr(
|
||||
pContext,
|
||||
pRpcDecompilerCtxt->pRpcDecompilerInfo->pExprFormatString + offset,
|
||||
paramDesc,
|
||||
confDesc,
|
||||
oss);
|
||||
|
||||
return bResult;
|
||||
}
|
||||
if(confDesc.corrDesc.correlation_operator == FC_CALLBACK )
|
||||
{
|
||||
oss << "/*FC_CALLBACK not implemented */";
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// FIRST STEP : according to correlation type correlation item
|
||||
|
||||
// case of a FC_CONSTANT_CONFORMANCE
|
||||
if(confDesc.corrDesc.correlation_type & FC_CONSTANT_CONFORMANCE)
|
||||
{
|
||||
INT32 iSize = ((confDesc.corrDesc.correlation_operator << 16) | confDesc.corrDesc.offset) & 0xFFFFFF;
|
||||
|
||||
oss<<std::dec<<iSize;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// case of a FC_TOP_LEVEL_CONFORMANCE
|
||||
// only used in function definition ?
|
||||
if(confDesc.corrDesc.correlation_type & FC_TOP_LEVEL_CONFORMANCE)
|
||||
{
|
||||
UINT uArgNbr = 0;
|
||||
std::stringstream ss;
|
||||
#ifdef DBG_DECOMP
|
||||
oss <<"/*FC_TOP_LEVEL_CONFORMANCE*/";
|
||||
#endif
|
||||
uArgNbr = confDesc.corrDesc.offset / (VIRTUAL_STACK_OFFSET_GRANULARITY);
|
||||
|
||||
ss<<"arg_"<<std::dec<<uArgNbr;
|
||||
strCorrelationItem = ss.str();
|
||||
}
|
||||
else if(confDesc.corrDesc.correlation_type & FC_POINTER_CONFORMANCE) // case of FC_POINTER_CONFORMANCE
|
||||
{
|
||||
std::stringstream ss;
|
||||
UINT uCorrDescMember;
|
||||
#ifdef DBG_DECOMP
|
||||
oss<<"/*FC_POINTER_CONFORMANCE(" << std::dec << confDesc.corrDesc.offset << ") */" ;
|
||||
#endif
|
||||
// check if vectMemberOffset is correctly filled
|
||||
if(paramDesc.getVectMembersOffset().size() == 0)
|
||||
{
|
||||
oss << " /* ERROR : FC_POINTER_CONFORMANCE but an empty vectMemberOffset has been provided (offset = " <<confDesc.corrDesc.offset<< ") */";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// get corr desc member number according to its offset
|
||||
uCorrDescMember = getElementByOffset(paramDesc.getVectMembersOffset(), confDesc.corrDesc.offset);
|
||||
|
||||
if(uCorrDescMember == -1)
|
||||
{
|
||||
oss << "/* ERROR invalid corrDescMember */";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ss << "StructMember"<<std::dec<<uCorrDescMember;
|
||||
strCorrelationItem = ss.str();
|
||||
}
|
||||
else if(confDesc.corrDesc.correlation_type & FC_POINTER_CONFORMANCE) // case of FC_TOP_LEVEL_MULTID_CONFORMANCE
|
||||
{
|
||||
// currently not implemented
|
||||
oss<<"/*FC_TOP_LEVEL_MULTID_CONFORMANCE not implemented */)]";
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// last remaining case is FC_NORMAL_CONFORMANCE
|
||||
// Onlys used in structure definition ?
|
||||
UINT uCorrDescMemberOffset;
|
||||
UINT uCorrDescMember;
|
||||
std::stringstream ss;
|
||||
#ifdef DBG_DECOMP
|
||||
oss<<"/*FC_NORMAL_CONFORMANCE ("<< std::dec << confDesc.corrDesc.offset<<")*/ ";
|
||||
#endif
|
||||
// check if vectMemberOffset is correctly filled
|
||||
if(paramDesc.getVectMembersOffset().size() == 0)
|
||||
{
|
||||
oss << " /* ERROR : FC_NORMAL_CONFORMANCE but an empty vectMemberOffset has been provided */";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// compute correlation member offset
|
||||
if(paramDesc.getVectMembersOffset().size() <= paramDesc.getuStructMemberNum())
|
||||
{
|
||||
oss << "/* ERROR invalid structMemberNum */";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// get member number according to its offset
|
||||
uCorrDescMemberOffset = paramDesc.getVectMembersOffset()[paramDesc.getuStructMemberNum()] + confDesc.corrDesc.offset;
|
||||
uCorrDescMember = getElementByOffset(paramDesc.getVectMembersOffset(), uCorrDescMemberOffset);
|
||||
|
||||
if(uCorrDescMember == -1)
|
||||
{
|
||||
oss << "/* ERROR invalid corrDescMember || corr desc offset = */" << std::dec << confDesc.corrDesc.offset;
|
||||
return TRUE;
|
||||
//return FALSE
|
||||
}
|
||||
|
||||
ss << "StructMember"<<std::dec<<uCorrDescMember;
|
||||
strCorrelationItem = ss.str();
|
||||
|
||||
}
|
||||
|
||||
// SECOND STEP : display correlation item according to correlation operator
|
||||
switch(confDesc.corrDesc.correlation_operator)
|
||||
{
|
||||
|
||||
case FC_DEREFERENCE:
|
||||
oss << "*" << strCorrelationItem;
|
||||
break;
|
||||
|
||||
case FC_ADD_1:
|
||||
oss << strCorrelationItem << "+1";
|
||||
break;
|
||||
|
||||
case FC_SUB_1:
|
||||
oss << strCorrelationItem << "-1";
|
||||
break;
|
||||
|
||||
case FC_DIV_2:
|
||||
oss << strCorrelationItem << "/2";
|
||||
break;
|
||||
|
||||
case FC_MULT_2:
|
||||
oss << strCorrelationItem << "*2";
|
||||
break;
|
||||
|
||||
case FC_EXPR:
|
||||
oss << "/* FC_EXPR not implemented */";
|
||||
break;
|
||||
|
||||
case FC_CALLBACK:
|
||||
oss << "/* FC_CALLBACK not implemented */";
|
||||
|
||||
default:
|
||||
oss << strCorrelationItem;
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
UINT __fastcall processFcExpr(
|
||||
_In_ VOID* pContext,
|
||||
_Out_ RVA_T pExpr,
|
||||
_In_ ParamDesc& paramDesc,
|
||||
_In_ ConformanceDescr_T confDesc,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
EXPR_OPERATOR operation;
|
||||
EXPR_CONST32 constante32;
|
||||
//EXPR_CONST64 constante64; Not used as of yet. Maybe with NDR64?
|
||||
EXPR_VAR var;
|
||||
UINT32 varNb;
|
||||
BOOL bResult;
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
|
||||
UINT sizeToAdvance = 0;
|
||||
UINT sizeOfExpr = 0;
|
||||
|
||||
RPC_GET_PROCESS_DATA(
|
||||
pExpr,
|
||||
&operation,
|
||||
sizeof(EXPR_OPERATOR)
|
||||
);
|
||||
|
||||
switch(operation.ExprType)
|
||||
{
|
||||
case FC_EXPR_OPER:
|
||||
if(operation.Operator >= OP_UNARY_PLUS && operation.Operator <= OP_UNARY_AND) // Unary operator
|
||||
{
|
||||
oss << getOperatorType(operation);
|
||||
|
||||
pExpr += sizeof(EXPR_OPERATOR);
|
||||
sizeToAdvance += sizeof(EXPR_OPERATOR);
|
||||
|
||||
sizeOfExpr = processFcExpr(pContext, pExpr, paramDesc, confDesc, oss);
|
||||
sizeToAdvance += sizeOfExpr;
|
||||
}else if(operation.Operator >= OP_PLUS && operation.Operator <= OP_LOGICAL_OR) // binary operator
|
||||
{
|
||||
std::string tmpOper = getOperatorType(operation);
|
||||
oss << "(";
|
||||
pExpr += sizeof(EXPR_OPERATOR);
|
||||
sizeToAdvance += sizeof(EXPR_OPERATOR);
|
||||
|
||||
sizeOfExpr = processFcExpr(pContext, pExpr, paramDesc, confDesc, oss);
|
||||
|
||||
pExpr += sizeOfExpr;
|
||||
sizeToAdvance += sizeOfExpr;
|
||||
|
||||
oss <<" "<< tmpOper.c_str()<<" ";
|
||||
|
||||
sizeOfExpr = processFcExpr(pContext, pExpr, paramDesc, confDesc, oss);
|
||||
|
||||
sizeToAdvance += sizeOfExpr;
|
||||
|
||||
oss << ")";
|
||||
}else{ // Ternary operator => (expr ? expr1 : expr2)
|
||||
std::ostringstream tmpIfYes;
|
||||
std::ostringstream tmpIfNo;
|
||||
|
||||
pExpr += sizeof(EXPR_OPERATOR);
|
||||
sizeToAdvance += sizeof(EXPR_OPERATOR);
|
||||
|
||||
sizeOfExpr = processFcExpr(pContext, pExpr, paramDesc, confDesc, tmpIfYes);
|
||||
sizeToAdvance += sizeOfExpr;
|
||||
pExpr += sizeOfExpr;
|
||||
|
||||
sizeOfExpr = processFcExpr(pContext, pExpr, paramDesc,confDesc, tmpIfNo);
|
||||
sizeToAdvance += sizeOfExpr;
|
||||
pExpr += sizeOfExpr;
|
||||
|
||||
oss << "(";
|
||||
|
||||
sizeOfExpr = processFcExpr(pContext, pExpr, paramDesc, confDesc, oss);
|
||||
sizeToAdvance += sizeOfExpr;
|
||||
|
||||
oss << "?";
|
||||
oss << tmpIfYes.str();
|
||||
oss << ":";
|
||||
oss << tmpIfNo.str();
|
||||
oss << ")";
|
||||
}
|
||||
break;
|
||||
case FC_EXPR_VAR:
|
||||
RPC_GET_PROCESS_DATA(pExpr, &var, sizeof(EXPR_VAR));
|
||||
|
||||
if(confDesc.corrDesc.correlation_type & FC_TOP_LEVEL_CONFORMANCE)
|
||||
{
|
||||
varNb = var.Offset / VIRTUAL_STACK_OFFSET_GRANULARITY;
|
||||
oss << "arg_" << std::dec << varNb;
|
||||
}else{
|
||||
INT uCorrDescMemberOffset;
|
||||
INT uCorrDescMember;
|
||||
std::stringstream ss;
|
||||
// get member number according to its offset
|
||||
if(paramDesc.getArrayIsAttributedPointer())
|
||||
{
|
||||
uCorrDescMemberOffset = var.Offset;
|
||||
}else{
|
||||
uCorrDescMemberOffset = paramDesc.getVectMembersOffset()[paramDesc.getuStructMemberNum()] + var.Offset;
|
||||
}
|
||||
uCorrDescMember = getElementByOffset(paramDesc.getVectMembersOffset(), uCorrDescMemberOffset);
|
||||
|
||||
if(uCorrDescMember == -1)
|
||||
{
|
||||
oss << "/* [ERROR] invalid corrDescMember || var offset = " << std::dec << var.Offset << "*/";
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
oss << "StructMember"<<std::dec<<uCorrDescMember;
|
||||
}
|
||||
|
||||
|
||||
sizeToAdvance += sizeof(EXPR_VAR);
|
||||
break;
|
||||
case FC_EXPR_CONST32:
|
||||
|
||||
RPC_GET_PROCESS_DATA(pExpr, &constante32, sizeof(EXPR_CONST32));
|
||||
|
||||
oss << std::dec << constante32.ConstValue;
|
||||
|
||||
sizeToAdvance += sizeof(EXPR_CONST32);
|
||||
break;
|
||||
case FC_EXPR_CONST64:
|
||||
// TODO
|
||||
break;
|
||||
default:
|
||||
oss << "/*[ERROR] unknown expression type */";
|
||||
break;
|
||||
}
|
||||
|
||||
return sizeToAdvance;
|
||||
}
|
||||
|
||||
|
||||
std::string __fastcall getOperatorType(
|
||||
_In_ EXPR_OPERATOR oper)
|
||||
{
|
||||
std::string result;
|
||||
switch(oper.Operator)
|
||||
{
|
||||
|
||||
case OP_UNARY_PLUS:
|
||||
result = "+";
|
||||
break;
|
||||
case OP_UNARY_MINUS:
|
||||
result = "-";
|
||||
break;
|
||||
case OP_UNARY_NOT:
|
||||
result = "!";
|
||||
break;
|
||||
case OP_UNARY_COMPLEMENT:
|
||||
result = "~";
|
||||
break;
|
||||
case OP_UNARY_CAST:
|
||||
switch(oper.CastType)
|
||||
{
|
||||
case FC_SMALL:
|
||||
result = "(byte)" ;
|
||||
break;
|
||||
case FC_USMALL:
|
||||
result = "(char)";
|
||||
break;
|
||||
case FC_USHORT:
|
||||
result = "(unsigned short)";
|
||||
break;
|
||||
case FC_LONG:
|
||||
result = "(long)";
|
||||
break;
|
||||
case FC_ULONG:
|
||||
result = "(unsigned long)";
|
||||
break;
|
||||
default:
|
||||
result = "/* unknown cast type */";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OP_UNARY_INDIRECTION:
|
||||
result = "*";
|
||||
break;
|
||||
case OP_UNARY_AND:
|
||||
result = "&";
|
||||
break;
|
||||
case OP_PLUS:
|
||||
result = "+";
|
||||
break;
|
||||
case OP_MINUS:
|
||||
result = "-";
|
||||
break;
|
||||
case OP_STAR:
|
||||
result = "*";
|
||||
break;
|
||||
case OP_SLASH:
|
||||
result = "/";
|
||||
break;
|
||||
case OP_MOD:
|
||||
result = "%";
|
||||
break;
|
||||
case OP_LEFT_SHIFT:
|
||||
result = "<<";
|
||||
break;
|
||||
case OP_RIGHT_SHIFT:
|
||||
result = ">>";
|
||||
break;
|
||||
case OP_LESS:
|
||||
result = "<";
|
||||
break;
|
||||
case OP_LESS_EQUAL:
|
||||
result = "<=";
|
||||
break;
|
||||
case OP_GREATER_EQUAL:
|
||||
result = ">=";
|
||||
break;
|
||||
case OP_GREATER:
|
||||
result = ">";
|
||||
break;
|
||||
case OP_EQUAL:
|
||||
result = "==";
|
||||
break;
|
||||
case OP_NOT_EQUAL:
|
||||
result = "!=";
|
||||
break;
|
||||
case OP_AND:
|
||||
result = "&";
|
||||
break;
|
||||
case OP_OR:
|
||||
result = "|";
|
||||
break;
|
||||
case OP_XOR:
|
||||
result = "^";
|
||||
break;
|
||||
case OP_LOGICAL_AND:
|
||||
result = "&&";
|
||||
break;
|
||||
case OP_LOGICAL_OR:
|
||||
result = "||";
|
||||
break;
|
||||
case OP_EXPRESSION:
|
||||
break;
|
||||
default:
|
||||
result = "/*[ERROR] unknown operation */" ;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall processTransmitRepresentAs(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listAdditionalTypes,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
BOOL bResult;
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
TransmitRepresentAs_t transmit;
|
||||
|
||||
RPC_GET_PROCESS_DATA(pType, &transmit, sizeof(TransmitRepresentAs_t));
|
||||
|
||||
RVA_T pTransmittedType = pType + sizeof(TransmitRepresentAs_t) + transmit.transmitted_type_offset - sizeof(transmit.transmitted_type_offset);
|
||||
|
||||
oss << "/* data transmitted as */";
|
||||
ParamDesc.setRva(pTransmittedType);
|
||||
if( rpcDumpType(pContext, ParamDesc, listAdditionalTypes, oss) == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN("[ERROR] processTransmitRepresentAs : dump type failed \n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall getTransmitAsRepresentAsMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Out_ size_t* pszMemorySize)
|
||||
{
|
||||
BOOL bResult;
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
TransmitRepresentAs_t transmit;
|
||||
|
||||
RPC_GET_PROCESS_DATA(pType, &transmit, sizeof(TransmitRepresentAs_t));
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN("[ERROR] getTransmitAsRepresentAsMemorySize : unable to get process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// TODO : check if this is this size and not target size that is used for conformance
|
||||
*pszMemorySize = transmit.presented_type_memory_size;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
UINT getCorrelationDescriptorSize(
|
||||
_In_ BOOL bRobustFlagWasSet,
|
||||
_In_ BOOL bHasRangeOnConformance)
|
||||
{
|
||||
|
||||
UINT uSize = 0;
|
||||
|
||||
UNREFERENCED_PARAMETER(bRobustFlagWasSet);
|
||||
|
||||
if(robustFlagWasSet)
|
||||
{
|
||||
uSize = sizeof(CorrelationDescriptorRobust_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
uSize = sizeof(CorrelationDescriptorNonRobust_t);
|
||||
}
|
||||
|
||||
if(bHasRangeOnConformance)
|
||||
{
|
||||
uSize += sizeof(Range_t);
|
||||
}
|
||||
|
||||
return uSize;
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
#ifndef _INTERNAL_COMPLEX_TYPES_MISC_H_
|
||||
#define _INTERNAL_COMPLEX_TYPES_MISC_H_
|
||||
|
||||
#include <sstream>
|
||||
#include <list>
|
||||
#include "internalRpcDecompTypeDefs.h"
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall processBindContext(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall process_FC_BLKHOLE(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall getFC_BLKHOLEMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Out_ size_t* pszMemorySize,
|
||||
_In_ BOOL bHasRangeOnConformance);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall processRange(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall getRangeMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Out_ size_t* pszMemorySize);
|
||||
|
||||
BOOL __fastcall ProcessArrayRange(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::ostringstream& temp);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall processUserMarshal(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall getUserMarshallMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Out_ size_t* pszMemorySize);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall processPipe(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall getPipeMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Out_ size_t* pszMemorySize,
|
||||
_In_ BOOL bHasRangeOnConformance);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall processCorrelationDescriptor(
|
||||
_In_ VOID* pContext,
|
||||
_In_ ConformanceDescr_T confDesc,
|
||||
_Inout_ std::ostringstream& oss,
|
||||
_Inout_ ParamDesc& paramDesc);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall processCorrelationDescriptorNaked(
|
||||
_In_ VOID* pContext,
|
||||
_In_ ConformanceDescr_T confDesc,
|
||||
_Inout_ std::ostringstream& oss,
|
||||
_Inout_ ParamDesc& paramDesc);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
UINT __fastcall processFcExpr(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pExpr,
|
||||
_In_ ParamDesc& paramDesc,
|
||||
_In_ ConformanceDescr_T confDesc,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
std::string __fastcall getOperatorType(
|
||||
_In_ EXPR_OPERATOR oper);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall processTransmitRepresentAs(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listAdditionalTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall getTransmitAsRepresentAsMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Out_ size_t* pszMemorySize);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
UINT getCorrelationDescriptorSize(
|
||||
_In_ BOOL bRobustFlagWasSet,
|
||||
_In_ BOOL bHasRangeOnConformance);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,222 @@
|
|||
#include "internalRpcDecompTypeDefs.h"
|
||||
#include "internalRpcDecompiler.h"
|
||||
#include <sstream>
|
||||
|
||||
// ***********************************************
|
||||
//
|
||||
// class used to describe an idl function
|
||||
//
|
||||
// ***********************************************
|
||||
|
||||
IdlFunctionDesc::IdlFunctionDesc() :
|
||||
m_uNbParam (0),
|
||||
m_bHasRangeOnConformance (FALSE),
|
||||
m_bHasReturn(FALSE)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
IdlFunctionDesc::IdlFunctionDesc(std::string strFunctionName) :
|
||||
m_uNbParam (0),
|
||||
m_bHasRangeOnConformance (FALSE),
|
||||
m_bHasReturn(FALSE),
|
||||
m_strFunctionName(strFunctionName)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
UINT32 IdlFunctionDesc::getNbParam() const
|
||||
{
|
||||
return m_uNbParam;
|
||||
}
|
||||
|
||||
|
||||
VOID IdlFunctionDesc::setNbParam(UINT32 uNbParam)
|
||||
{
|
||||
m_uNbParam = uNbParam;
|
||||
}
|
||||
|
||||
VOID IdlFunctionDesc::setHasReturn(BOOL hasReturn)
|
||||
{
|
||||
m_bHasReturn = hasReturn;
|
||||
}
|
||||
|
||||
VOID IdlFunctionDesc::addParamToList(ParamDesc parameter)
|
||||
{
|
||||
m_listParam.push_back(parameter);
|
||||
}
|
||||
|
||||
std::list<ParamDesc>& IdlFunctionDesc::getParamList()
|
||||
{
|
||||
return m_listParam;
|
||||
}
|
||||
|
||||
BOOL IdlFunctionDesc::hasRangeOnConformance() const
|
||||
{
|
||||
return m_bHasRangeOnConformance;
|
||||
}
|
||||
BOOL IdlFunctionDesc::hasReturn() const
|
||||
{
|
||||
return m_bHasReturn;
|
||||
}
|
||||
|
||||
VOID IdlFunctionDesc::parseWin32ExtHeader(Win2kExt_Header_t* pWin32kExtHeader)
|
||||
{
|
||||
m_bHasRangeOnConformance = pWin32kExtHeader->interpreter_opt_flag2.HasRangeOnConf;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ***********************************************
|
||||
//
|
||||
// class TypeToDefine
|
||||
//
|
||||
// ***********************************************
|
||||
/*TypeToDefine::TypeToDefine()
|
||||
{
|
||||
|
||||
}*/
|
||||
|
||||
TypeToDefine::TypeToDefine(const RVA_T rva, const ParamDesc& paramDesc):
|
||||
m_rva(rva),
|
||||
//m_uOffset(paramDesc.m_uOffset),
|
||||
m_fcType(paramDesc.getFcType()),
|
||||
m_bHasRangeOnConf(paramDesc.hasRangeOnConformance())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool TypeToDefine::operator<( const TypeToDefine& right)
|
||||
{
|
||||
return (this->m_rva < right.m_rva);
|
||||
}
|
||||
bool TypeToDefine::operator== ( const TypeToDefine& right)
|
||||
{
|
||||
return (this->m_rva == right.m_rva);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ***********************************************
|
||||
//
|
||||
// class ParamDesc
|
||||
//
|
||||
// ***********************************************
|
||||
ParamDesc::ParamDesc():
|
||||
m_bString(FALSE),
|
||||
m_bIn(FALSE),
|
||||
m_bUnique(FALSE),
|
||||
m_bOut(FALSE),
|
||||
m_bReturn(FALSE),
|
||||
m_uPtrLevel(0),
|
||||
m_hasRangeOnConformance(FALSE),
|
||||
m_arrayIsAttributedPointer(FALSE),
|
||||
m_uStructMemberNum(0),
|
||||
m_uMemorySize(0),
|
||||
m_fcType(FC_ZERO)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ParamDesc::ParamDesc(std::string strTypeName):
|
||||
m_strTypeName(strTypeName),
|
||||
m_bString(FALSE),
|
||||
m_bIn(FALSE),
|
||||
m_bUnique(FALSE),
|
||||
m_bOut(FALSE),
|
||||
m_bReturn(FALSE),
|
||||
m_arrayIsAttributedPointer(FALSE),
|
||||
m_uPtrLevel(0),
|
||||
m_hasRangeOnConformance(FALSE),
|
||||
m_uStructMemberNum(0),
|
||||
m_uMemorySize(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ParamDesc::ParamDesc(std::string strTypeName, UINT uStructMemberNum, std::vector<UINT> vectMemberOffset):
|
||||
m_strTypeName(strTypeName),
|
||||
m_bString(FALSE),
|
||||
m_bIn(FALSE),
|
||||
m_bUnique(FALSE),
|
||||
m_bOut(FALSE),
|
||||
m_bReturn(FALSE),
|
||||
m_arrayIsAttributedPointer(FALSE),
|
||||
m_uPtrLevel(0),
|
||||
m_hasRangeOnConformance(FALSE),
|
||||
m_uStructMemberNum(uStructMemberNum),
|
||||
m_uMemorySize(0),
|
||||
m_vectMembersOffset(vectMemberOffset)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//ParamDesc::ParamDesc(const TypeToDefine& UnionStructDesc):
|
||||
// m_strTypeName(),
|
||||
// m_bString(FALSE),
|
||||
// m_fcType(UnionStructDesc.getFcType()),
|
||||
// m_bIn(FALSE),
|
||||
// m_bUnique(FALSE),
|
||||
// m_bOut(FALSE),
|
||||
// m_uPtrLevel(0),
|
||||
// m_hasRangeOnConformance(UnionStructDesc.getHasRangeOnConformance()),
|
||||
// m_uStructMemberNum(0),
|
||||
// m_uMemorySize(0)
|
||||
//{
|
||||
//
|
||||
//}
|
||||
|
||||
|
||||
// used for structures/union in order to report properties such
|
||||
// as hasRangeOnConformance on structure/union member
|
||||
void ParamDesc::inheritProperties(_In_ const TypeToDefine& parentTypeDesc)
|
||||
{
|
||||
if(parentTypeDesc.getHasRangeOnConformance())
|
||||
{
|
||||
this->m_hasRangeOnConformance = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ParamDesc::gestDescr(_Inout_ std::string& strDesc)
|
||||
{
|
||||
strDesc = "Todo";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ParamDesc::addConformanceDescr(_In_ ConformanceDescr_T conformanceDescr)
|
||||
{
|
||||
m_listConfDescr.push_back(conformanceDescr);
|
||||
}
|
||||
|
||||
|
||||
LONG ParamDesc::getRelativeOffsetFromFmtString(_In_ RVA_T pFormatString) const
|
||||
{
|
||||
return (LONG)(m_rva - pFormatString);
|
||||
}
|
||||
|
||||
|
||||
void ParamDesc::fillWithParamAttr(_In_ PARAM_ATTRIBUTES paramAttr)
|
||||
{
|
||||
if(paramAttr.IsIn) m_bIn = TRUE;
|
||||
if(paramAttr.IsOut) m_bOut = TRUE;
|
||||
|
||||
// TODO how to handle simple ref ?
|
||||
if(paramAttr.IsSimpleRef) m_uPtrLevel++;
|
||||
//....
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
#include "internalRpcUtils.h"
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
BOOL __fastcall isStandardCharacter(_In_ const WCHAR wc)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
|
||||
if( ((wc >= L'a') &&
|
||||
(wc <= L'z'))
|
||||
|
||||
||
|
||||
|
||||
((wc >= L'A') &&
|
||||
(wc <= L'Z'))
|
||||
|
||||
||
|
||||
|
||||
((wc >= L'0') &&
|
||||
(wc <= L'9')) )
|
||||
{
|
||||
bResult = TRUE;
|
||||
}
|
||||
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
std::string narrow(
|
||||
_In_ const std::wstring& ws)
|
||||
{
|
||||
//std::vector<char> buffer(ws.size());
|
||||
////std::locale loc("english");
|
||||
//std::locale loc;
|
||||
//std::use_facet< std::ctype<wchar_t> > (loc).narrow(ws.data(), ws.data() + ws.size(), '?', &buffer[0]);
|
||||
|
||||
//return std::string(&buffer[0], buffer.size());
|
||||
|
||||
return std::string(ws.begin(), ws.end());
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
VOID displayPtrLevel(
|
||||
_In_ const UINT uPtrLevel,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
for(UINT i=0; i<uPtrLevel; i++)
|
||||
{
|
||||
oss<<"*";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
VOID displayErrorMessage(
|
||||
_Inout_ std::ostringstream& oss,
|
||||
_In_ PCHAR message)
|
||||
{
|
||||
oss<< "/* [ERROR] : "<< message << "*/";
|
||||
}
|
||||
|
|
@ -0,0 +1,911 @@
|
|||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <stdlib.h>
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
#include <sstream>
|
||||
#include <list>
|
||||
//DBG
|
||||
#include <iostream>
|
||||
//DBG
|
||||
|
||||
#include "..\RpcCommon\RpcView.h"
|
||||
#include "internalRpcDecompTypeDefs.h"
|
||||
#include "internalRpcDecompiler.h"
|
||||
#include "RpcDecompiler.h"
|
||||
#include "internalRpcUtils.h"
|
||||
#include "internalTypeTools.h"
|
||||
#include "IdlFunction.h"
|
||||
#include "IdlInterface.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Function declaration
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
VOID* __fastcall RpcDecompilerInit(RpcViewHelper_T* pRpcViewHelper, RpcDecompilerInfo_T* pDecompilerInfo); //returns NULL in case of failure
|
||||
VOID __fastcall RpcDecompilerUninit(VOID* pRpcDecompilerCtxt);
|
||||
|
||||
|
||||
BOOL __fastcall RpcDecompilerPrintAllProcedures(VOID* pRpcDecompilerCtxt);
|
||||
BOOL __fastcall RpcDecompilerPrintProcedure(VOID* pRpcDecompilerCtxt, UINT ProcIndex);
|
||||
BOOL __fastcall RpcDecompilerPrintOneProcedure(VOID* pRpcDecompilerCtxt, UINT ProcIndex, std::list<TypeToDefine>& listProcType, std::ostringstream& ossProc);
|
||||
BOOL __fastcall RpcDecompilerDecodeOneProcedureInlined(VOID* pContext, UINT ProcIndex, IdlFunctionDesc& IdlFunctionDesc, std::list<TypeToDefine>& listProcType);
|
||||
BOOL __fastcall RpcDecompilerPrintOneProcedureInlined(VOID* pContext, UINT ProcOffset, IdlFunctionDesc& IdlFunctionDesc, std::list<TypeToDefine>& listProcType, std::ostringstream& ossProc);
|
||||
BOOL __fastcall RpcDecompilerPrintHiddenFUProcedure(VOID* pRpcDecompilerCtxt, UINT * procOffset, std::list<TypeToDefine>& listProcType, std::ostringstream& ossProc);
|
||||
|
||||
BOOL __fastcall RpcDecompilerPrintAllProceduresNew(VOID* pRpcDecompilerCtxt);
|
||||
|
||||
|
||||
|
||||
VOID __fastcall RpcDecompilerPrintFunctionDbgInfo(VOID* pContext, UINT procIndex, std::ostringstream& oss);
|
||||
|
||||
#pragma comment(lib,"Rpcrt4.lib")
|
||||
|
||||
__declspec(dllexport) RpcDecompilerHelper_T RpcDecompilerHelper=
|
||||
{
|
||||
&RpcDecompilerInit,
|
||||
&RpcDecompilerUninit,
|
||||
&RpcDecompilerPrintProcedure,
|
||||
&RpcDecompilerPrintAllProceduresNew,
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
VOID* __fastcall RpcDecompilerInit(RpcViewHelper_T* pRpcViewHelper, RpcDecompilerInfo_T* pRpcDecompilerInfo)
|
||||
{
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = NULL;
|
||||
|
||||
#ifdef _DEBUG
|
||||
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
|
||||
#endif
|
||||
|
||||
if (pRpcViewHelper == NULL) goto End;
|
||||
if (pRpcDecompilerInfo == NULL) goto End;
|
||||
|
||||
//Alloc the private context
|
||||
pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pRpcViewHelper->RpcAlloc( sizeof(RpcDecompilerCtxt_T) );
|
||||
if (pRpcDecompilerCtxt==NULL) goto End;
|
||||
//Init the private context
|
||||
pRpcDecompilerCtxt->pRpcViewHelper = pRpcViewHelper;
|
||||
pRpcDecompilerCtxt->pRpcDecompilerInfo = pRpcDecompilerInfo;
|
||||
pRpcDecompilerCtxt->pRpcModuleInfo = (RpcModuleInfo_T *) pRpcViewHelper->RpcAlloc( sizeof(RpcModuleInfo_T) );
|
||||
if (pRpcDecompilerCtxt->pRpcModuleInfo == NULL)
|
||||
{
|
||||
goto End;
|
||||
}
|
||||
|
||||
pRpcDecompilerCtxt->pRpcModuleInfo->Pid = pRpcDecompilerCtxt->pRpcDecompilerInfo->Pid;
|
||||
pRpcDecompilerCtxt->pRpcModuleInfo->pModuleBase = pRpcDecompilerCtxt->pRpcDecompilerInfo->pModuleBase;
|
||||
|
||||
|
||||
|
||||
|
||||
// set global var
|
||||
|
||||
// is it a 64 bits application ?
|
||||
is64B = pRpcDecompilerCtxt->pRpcDecompilerInfo->bIs64Bits;
|
||||
|
||||
// robust flags case
|
||||
if( pRpcDecompilerCtxt->pRpcDecompilerInfo->NDRVersion >= NDR_VERSION_5_2 )
|
||||
{
|
||||
robustFlagWasSet = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
robustFlagWasSet = FALSE;
|
||||
}
|
||||
|
||||
RPC_DEBUG_FN((UCHAR*)"\nRpcDecompilerInit\n");
|
||||
End:
|
||||
return (pRpcDecompilerCtxt);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
VOID __fastcall RpcDecompilerUninit(VOID* pContext)
|
||||
{
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T*) pContext;
|
||||
|
||||
if (pRpcDecompilerCtxt == NULL) goto End;
|
||||
if (pRpcDecompilerCtxt->pRpcViewHelper == NULL) goto End;
|
||||
|
||||
//Free the private the context
|
||||
RPC_DEBUG_FN((UCHAR*)"\nRpcDecompilerUninit\n");
|
||||
RPC_FREE_FN(pRpcDecompilerCtxt->pRpcModuleInfo);
|
||||
RPC_FREE_FN( pRpcDecompilerCtxt );
|
||||
|
||||
End:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL __fastcall RpcDecompilerPrintProcedure(VOID* pContext, UINT ProcIndex)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(ProcIndex);
|
||||
UNREFERENCED_PARAMETER(pContext);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall RpcDecompilerDecodeOneProcedureInlined(
|
||||
VOID* pContext,
|
||||
UINT ProcIndex,
|
||||
IdlFunctionDesc& IdlFunctionDesc,
|
||||
std::list<TypeToDefine>& listProcType
|
||||
)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
RpcDecompilerCtxt_T* pRpcDecompilerCtxt = (RpcDecompilerCtxt_T*)pContext;
|
||||
|
||||
inlinedParam param;
|
||||
BOOL noMoreParameter = FALSE;
|
||||
BOOL noMoreParameterBecauseOfReturn = FALSE;
|
||||
UINT nbOfParameters = 0;
|
||||
|
||||
UNREFERENCED_PARAMETER(listProcType);
|
||||
|
||||
RVA_T pData = pRpcDecompilerCtxt->pRpcDecompilerInfo->ppProcFormatInlined[ProcIndex];
|
||||
|
||||
// check if we have an entry defined in ppProcFormatInlined
|
||||
if(pData == NULL)
|
||||
{
|
||||
RPC_DEBUG_FN("no entry defined for this function in ppProcFormatInlined");
|
||||
bResult = FALSE;
|
||||
|
||||
goto END;
|
||||
}
|
||||
|
||||
// Loop over each parameter and add them to the list
|
||||
while(!noMoreParameter && !noMoreParameterBecauseOfReturn)
|
||||
{
|
||||
ParamDesc parameter;
|
||||
RPC_GET_PROCESS_DATA(pData, ¶m, sizeof(param));
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN("Failed to read proc format string in DecodeOneProcedureInlined");
|
||||
}
|
||||
|
||||
// Set parameter flags (in, out)
|
||||
switch(param.baseParam.bFcTypeParamProperties)
|
||||
{
|
||||
case FC_IN_PARAM_BASETYPE:
|
||||
parameter.setFcType((FC_TYPE)param.baseParam.bFcType);
|
||||
case FC_IN_PARAM:
|
||||
parameter.setIsIn();
|
||||
break;
|
||||
case FC_IN_PARAM_NO_FREE_INST:
|
||||
// TODO
|
||||
break;
|
||||
case FC_IN_OUT_PARAM:
|
||||
parameter.setIsIn();
|
||||
parameter.setIsOut();
|
||||
break;
|
||||
case FC_OUT_PARAM:
|
||||
parameter.setIsOut();
|
||||
break;
|
||||
case FC_RETURN_PARAM_BASETYPE:
|
||||
parameter.setFcType((FC_TYPE)param.baseParam.bFcType);
|
||||
case FC_RETURN_PARAM:
|
||||
parameter.setIsReturn();
|
||||
IdlFunctionDesc.setHasReturn(TRUE);
|
||||
noMoreParameterBecauseOfReturn = TRUE;
|
||||
// TODO : check in which case this is true
|
||||
break;
|
||||
// End of parameters
|
||||
case FC_END:
|
||||
case FC_ZERO:
|
||||
noMoreParameter = TRUE;
|
||||
break;
|
||||
default:
|
||||
bResult = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
//No parameter left, dont add anything to the list
|
||||
if(!noMoreParameter)
|
||||
{
|
||||
// Jump to next parameter in the format string
|
||||
if(isSimpleType(parameter.getFcType()))
|
||||
{
|
||||
|
||||
// Parameter type is right after the param description
|
||||
parameter.setRva(pData + FIELD_OFFSET(INLINED_PARAM_BASE_T, bFcType));
|
||||
pData += sizeof(INLINED_PARAM_BASE_T);
|
||||
}else{
|
||||
//FC_TYPE complexType;
|
||||
BYTE bfcType;
|
||||
|
||||
// Type given in the type format string
|
||||
parameter.setRva(pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString + param.complexParam.offset);
|
||||
|
||||
|
||||
RPC_GET_PROCESS_DATA(parameter.getRva(), &bfcType, sizeof(bfcType));
|
||||
parameter.setFcType((FC_TYPE)bfcType);
|
||||
|
||||
pData += sizeof(INLINED_PARAM_COMPLEX_T);
|
||||
}
|
||||
|
||||
IdlFunctionDesc.addParamToList(parameter);
|
||||
nbOfParameters++;
|
||||
}
|
||||
}
|
||||
IdlFunctionDesc.setNbParam(nbOfParameters);
|
||||
|
||||
END:
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL __fastcall RpcDecompilerPrintOneProcedureInlined(
|
||||
VOID* pContext,
|
||||
UINT ProcOffset,
|
||||
IdlFunctionDesc& IdlFunctionDesc,
|
||||
std::list<TypeToDefine>& listProcType,
|
||||
std::ostringstream& ossProc)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
|
||||
UNREFERENCED_PARAMETER(ProcOffset);
|
||||
|
||||
ossProc << "\t";
|
||||
|
||||
if(!IdlFunctionDesc.hasReturn())
|
||||
{
|
||||
ossProc << "void ";
|
||||
}else
|
||||
{
|
||||
for(auto iter = IdlFunctionDesc.getParamList().begin(); iter != IdlFunctionDesc.getParamList().end(); iter++)
|
||||
{
|
||||
if (iter->isReturn())
|
||||
{
|
||||
rpcDumpType(pContext, *iter, listProcType, ossProc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ossProc << IdlFunctionDesc.getFunctionName() << " ";
|
||||
ossProc << "(";
|
||||
UINT32 i = 0;
|
||||
for(auto iter = IdlFunctionDesc.getParamList().begin(); iter != IdlFunctionDesc.getParamList().end(); iter++)
|
||||
{
|
||||
ossProc << std::endl << "\t\t";
|
||||
|
||||
if (!(iter->isReturn()))
|
||||
{
|
||||
if(iter->isIn())
|
||||
{
|
||||
ossProc << "[in]";
|
||||
}
|
||||
if(iter->isOut())
|
||||
{
|
||||
ossProc << "[out]";
|
||||
}
|
||||
|
||||
ossProc << " ";
|
||||
bResult = rpcDumpType(pContext, *iter, listProcType, ossProc);
|
||||
ossProc << " arg_" << i;
|
||||
// If this is not the last parameter (list contains all parameters including returned value)
|
||||
if(i != (IdlFunctionDesc.getNbParam() - 2))
|
||||
{
|
||||
ossProc << ",";
|
||||
}// else nothing to do
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
ossProc << ");\n";
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL __fastcall RpcDecompilerPrintOneProcedure(
|
||||
VOID* pContext,
|
||||
UINT ProcIndex,
|
||||
std::list<TypeToDefine>& listProcType,
|
||||
std::ostringstream& ossProc)
|
||||
{
|
||||
UINT formatStringOffset = 0;
|
||||
UINT paramSizeInBytes = RPC_DECOMPILER_INVALID_PARAM_SIZE;
|
||||
BOOL bResult = FALSE;
|
||||
RpcDecompilerCtxt_T* pRpcDecompilerCtxt = (RpcDecompilerCtxt_T*)pContext;
|
||||
|
||||
UINT paramOffset = 0;
|
||||
UINT numParam = 0;
|
||||
BOOL isReturnParam = FALSE;
|
||||
BOOL nextIsReturnParam = FALSE;
|
||||
UINT dummy;
|
||||
|
||||
IdlFunctionDesc IdlFunctionDesc;
|
||||
|
||||
|
||||
if (pRpcDecompilerCtxt == NULL) goto End;
|
||||
if (pRpcDecompilerCtxt->pRpcViewHelper == NULL) goto End;
|
||||
if (pRpcDecompilerCtxt->pRpcDecompilerInfo == NULL) goto End;
|
||||
if (pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString == NULL) goto End;
|
||||
|
||||
|
||||
if (pRpcDecompilerCtxt->pRpcDecompilerInfo->pFormatStringOffsetTable==NULL)
|
||||
{
|
||||
formatStringOffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
formatStringOffset = pRpcDecompilerCtxt->pRpcDecompilerInfo->pFormatStringOffsetTable[ProcIndex];
|
||||
}
|
||||
|
||||
// carriage return before display function
|
||||
//ossProc << "\t/* Function 0x" << std::hex << ProcIndex<< " */"<< std::endl;
|
||||
ossProc << std::endl;
|
||||
ossProc << "[helpstring(\"RVA: 0x" << std::hex << pRpcDecompilerCtxt->pRpcDecompilerInfo->ppProcAddressTable[ProcIndex] << "\")]" << std::endl;
|
||||
RpcDecompilerPrintFunctionDbgInfo(pContext, ProcIndex, ossProc);
|
||||
|
||||
|
||||
//todo
|
||||
bResult = RpcDecompilerDecodeAndPrintPrototypeReturnType(
|
||||
/* in */ pRpcDecompilerCtxt,
|
||||
/* in */ formatStringOffset,
|
||||
/* out */ ¶mOffset,
|
||||
/* out */ &dummy,
|
||||
/* out */ IdlFunctionDesc,
|
||||
/* in/out */listProcType,
|
||||
/* in/out */ ossProc);
|
||||
|
||||
if (bResult == FALSE) goto End;
|
||||
|
||||
bResult = RpcDecompilerPrintPrototypeName(
|
||||
/* in */ pRpcDecompilerCtxt,
|
||||
/* in */ ProcIndex,
|
||||
/* in/out */ ossProc);
|
||||
|
||||
if (bResult == FALSE) goto End;
|
||||
|
||||
RPC_DEBUG_FN((UCHAR*)"\nRpcDecompilerPrintProcedure: RpcDecompilerPrintPrototypeName returned nbParamToPrint = %d\n", IdlFunctionDesc.getNbParam());
|
||||
|
||||
|
||||
if(IdlFunctionDesc.getNbParam() == 0)
|
||||
{
|
||||
//No parameter to be printed
|
||||
ossProc << " void ";
|
||||
}
|
||||
|
||||
|
||||
//Print each parameter
|
||||
while( (numParam < IdlFunctionDesc.getNbParam()) )
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"\nRpcDecompilerPrintProcedure: numParam = 0x%x on total to print = 0x%x\n", numParam, IdlFunctionDesc.getNbParam());
|
||||
|
||||
bResult = RpcDecompilerGetReturnParamInfo(/* in */ pRpcDecompilerCtxt, /* in */ paramOffset, /* in */ paramDescrOif, /* out */ &isReturnParam);
|
||||
if (bResult == FALSE) goto End;
|
||||
|
||||
if( ! isReturnParam)
|
||||
{
|
||||
//Print the parameter
|
||||
bResult = RpcDecompilerPrintParam(
|
||||
/* in */ pRpcDecompilerCtxt,
|
||||
/* in */ paramOffset,
|
||||
/* in */ paramDescrOif,
|
||||
/* out */ ¶mSizeInBytes,
|
||||
/* in */ IdlFunctionDesc,
|
||||
listProcType,
|
||||
ossProc); //TODO : decompile paramDescrOi...
|
||||
|
||||
if (bResult == FALSE || paramSizeInBytes == RPC_DECOMPILER_INVALID_PARAM_SIZE)
|
||||
{
|
||||
displayErrorMessage(ossProc, "RpcDecompilerPrintOneProcedure : unable to decode param");
|
||||
goto End;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
paramSizeInBytes = OIF_PARAM_SIZE; //TODO : traiter le cas où codage pas OIF
|
||||
}
|
||||
paramOffset += paramSizeInBytes;//paramSizeInBytes;
|
||||
numParam++;
|
||||
RPC_DEBUG_FN((UCHAR*)"\nRpcDecompilerPrintProcedure: paramOffset = %d, numParam = %d\n", paramOffset, numParam);
|
||||
|
||||
//Is there one additionnal parameter to be printed ?
|
||||
if ( (! isReturnParam) && (numParam < IdlFunctionDesc.getNbParam()) )
|
||||
{
|
||||
//The last parameter has been printed because it was not a return parameter
|
||||
//There is still at least 1 parameter to be printed
|
||||
bResult = RpcDecompilerGetReturnParamInfo(/* in */ pRpcDecompilerCtxt, /* in */ paramOffset, /* in */ paramDescrOif, /* out */ &nextIsReturnParam);
|
||||
if (bResult == FALSE) goto End;
|
||||
|
||||
if (! nextIsReturnParam)
|
||||
{
|
||||
//The next parameter will have to be printed because it is not a return parameter
|
||||
ossProc << ", ";
|
||||
}
|
||||
|
||||
}
|
||||
}//while(numParam <= IdlFunctionDesc.getNbParam());
|
||||
|
||||
|
||||
// Print the end of the procedure prototype
|
||||
ossProc<<");"<<std::endl;
|
||||
|
||||
bResult = TRUE;
|
||||
|
||||
End:
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall RpcDecompilerPrintHiddenFUProcedure(VOID* pContext, UINT * procOffset, std::list<TypeToDefine>& listProcType, std::ostringstream& ossProc)
|
||||
{
|
||||
UINT paramSizeInBytes = RPC_DECOMPILER_INVALID_PARAM_SIZE;
|
||||
BOOL bResult = FALSE;
|
||||
RpcDecompilerCtxt_T* pRpcDecompilerCtxt = (RpcDecompilerCtxt_T*)pContext;
|
||||
|
||||
UINT paramOffset = 0;
|
||||
UINT numParam = 0;
|
||||
BOOL isReturnParam = FALSE;
|
||||
BOOL nextIsReturnParam = FALSE;
|
||||
UINT sizeOfProcDescr = 0;
|
||||
|
||||
IdlFunctionDesc IdlFunctionDesc;
|
||||
|
||||
|
||||
if (pRpcDecompilerCtxt == NULL) goto End;
|
||||
if (pRpcDecompilerCtxt->pRpcViewHelper == NULL) goto End;
|
||||
if (pRpcDecompilerCtxt->pRpcDecompilerInfo == NULL) goto End;
|
||||
if (pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString == NULL) goto End;
|
||||
|
||||
RVA_T pFunction = pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + *procOffset;
|
||||
// carriage return before display function
|
||||
//ossProc << "\t/* Function 0x" << std::hex << ProcIndex<< " */"<< std::endl;
|
||||
ossProc << std::endl;
|
||||
//RpcDecompilerPrintFunctionDbgInfo(pContext, *procOffset, ossProc);
|
||||
ossProc << "\t /* Function index : 0x" << std::hex << *procOffset;
|
||||
ossProc << "\t Module Base : 0x" << (unsigned long) pRpcDecompilerCtxt->pRpcDecompilerInfo->pModuleBase;
|
||||
ossProc << "\t RVA of proc in format string : 0x" << (unsigned long) ((UINT64)pFunction - pRpcDecompilerCtxt->pRpcDecompilerInfo->pModuleBase);
|
||||
ossProc << " */"<<std::endl;
|
||||
|
||||
//todo
|
||||
bResult = RpcDecompilerDecodeAndPrintPrototypeReturnType(
|
||||
/* in */ pRpcDecompilerCtxt,
|
||||
/* in */ *procOffset,
|
||||
/* out */ ¶mOffset,
|
||||
/* out */ &sizeOfProcDescr,
|
||||
/* out */ IdlFunctionDesc,
|
||||
/* in/out */listProcType,
|
||||
/* in/out */ ossProc);
|
||||
|
||||
if (bResult == FALSE) goto End;
|
||||
|
||||
ossProc << " _HiddenFunction_" << std::dec << *procOffset << "(";
|
||||
|
||||
// Increment procOffset to read the next procedure description
|
||||
*procOffset += sizeOfProcDescr;
|
||||
|
||||
if (bResult == FALSE) goto End;
|
||||
|
||||
RPC_DEBUG_FN((UCHAR*)"\nRpcDecompilerPrintProcedure: RpcDecompilerPrintPrototypeName returned nbParamToPrint = %d\n", IdlFunctionDesc.getNbParam());
|
||||
|
||||
|
||||
if(IdlFunctionDesc.getNbParam() == 0)
|
||||
{
|
||||
//No parameter to be printed
|
||||
ossProc << " void ";
|
||||
}
|
||||
|
||||
|
||||
//Print each parameter
|
||||
while( (numParam < IdlFunctionDesc.getNbParam()) )
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"\nRpcDecompilerPrintProcedure: numParam = 0x%x on total to print = 0x%x\n", numParam, IdlFunctionDesc.getNbParam());
|
||||
|
||||
bResult = RpcDecompilerGetReturnParamInfo(/* in */ pRpcDecompilerCtxt, /* in */ paramOffset, /* in */ paramDescrOif, /* out */ &isReturnParam);
|
||||
if (bResult == FALSE) goto End;
|
||||
|
||||
if( ! isReturnParam)
|
||||
{
|
||||
//Print the parameter
|
||||
bResult = RpcDecompilerPrintParam(
|
||||
/* in */ pRpcDecompilerCtxt,
|
||||
/* in */ paramOffset,
|
||||
/* in */ paramDescrOif,
|
||||
/* out */ ¶mSizeInBytes,
|
||||
/* in */ IdlFunctionDesc,
|
||||
listProcType,
|
||||
ossProc); //TODO : décompiler paramDescrOi en plus de paramDescrOif
|
||||
|
||||
if (bResult == FALSE || paramSizeInBytes == RPC_DECOMPILER_INVALID_PARAM_SIZE)
|
||||
{
|
||||
displayErrorMessage(ossProc, "RpcDecompilerPrintOneProcedure : unable to decode param");
|
||||
goto End;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
paramSizeInBytes = OIF_PARAM_SIZE; //TODO : traiter le cas où codage pas OIF
|
||||
}
|
||||
paramOffset += paramSizeInBytes;//paramSizeInBytes;
|
||||
numParam++;
|
||||
RPC_DEBUG_FN((UCHAR*)"\nRpcDecompilerPrintProcedure: paramOffset = %d, numParam = %d\n", paramOffset, numParam);
|
||||
|
||||
//Is there one additionnal parameter to be printed ?
|
||||
if ( (! isReturnParam) && (numParam < IdlFunctionDesc.getNbParam()) )
|
||||
{
|
||||
//The last parameter has been printed because it was not a return parameter
|
||||
//There is still at least 1 parameter to be printed
|
||||
bResult = RpcDecompilerGetReturnParamInfo(/* in */ pRpcDecompilerCtxt, /* in */ paramOffset, /* in */ paramDescrOif, /* out */ &nextIsReturnParam);
|
||||
if (bResult == FALSE) goto End;
|
||||
|
||||
if (! nextIsReturnParam)
|
||||
{
|
||||
//The next parameter will have to be printed because it is not a return parameter
|
||||
ossProc << ", ";
|
||||
}
|
||||
|
||||
}
|
||||
}//while(numParam <= IdlFunctionDesc.getNbParam());
|
||||
|
||||
|
||||
// Print the end of the procedure prototype
|
||||
ossProc<<");"<<std::endl;
|
||||
|
||||
bResult = TRUE;
|
||||
|
||||
End:
|
||||
return (bResult);
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
VOID __fastcall RpcDecompilerPrintFunctionDbgInfo(VOID* pContext, UINT procIndex, std::ostringstream& oss)
|
||||
{
|
||||
RpcDecompilerCtxt_T* pRpcDecompilerCtxt = (RpcDecompilerCtxt_T*)pContext;
|
||||
UINT64 moduleBase = pRpcDecompilerCtxt->pRpcDecompilerInfo->pModuleBase;
|
||||
RVA_T rvaFunction = pRpcDecompilerCtxt->pRpcDecompilerInfo->ppProcAddressTable[procIndex];
|
||||
|
||||
oss << "\t /* Function index : 0x" << std::hex << procIndex;
|
||||
oss << "\t Module Base : 0x" << moduleBase;
|
||||
oss << "\t RVA : 0x" << rvaFunction;
|
||||
oss << " */"<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
VOID __fastcall RpcDecompilerPrintProlog(VOID* pContext, std::ostringstream& oss)
|
||||
{
|
||||
UCHAR* pUuidString = NULL;
|
||||
RpcDecompilerCtxt_T* pRpcDecompilerCtxt = (RpcDecompilerCtxt_T*)pContext;
|
||||
|
||||
if (pRpcDecompilerCtxt == NULL) goto End;
|
||||
if (pRpcDecompilerCtxt->pRpcViewHelper == NULL) goto End;
|
||||
if (pRpcDecompilerCtxt->pRpcDecompilerInfo == NULL) goto End;
|
||||
|
||||
|
||||
if ( UuidToStringA(&pRpcDecompilerCtxt->pRpcDecompilerInfo->pIfId->Uuid,&pUuidString) != RPC_S_OK )
|
||||
{
|
||||
goto End;
|
||||
}
|
||||
oss<< "[\nuuid(" << pUuidString;
|
||||
oss<<"),\nversion("<< pRpcDecompilerCtxt->pRpcDecompilerInfo->pIfId->VersMajor;
|
||||
oss<<"."<<pRpcDecompilerCtxt->pRpcDecompilerInfo->pIfId->VersMinor <<"),\n]\n";
|
||||
/*
|
||||
RPC_DEBUG_FN((UCHAR*)"[\nuuid(%s),\nversion(%u.%u),\n]\n",
|
||||
pUuidString,
|
||||
pRpcDecompilerCtxt->pRpcDecompilerInfo->pIfId->SyntaxVersion.MajorVersion,
|
||||
pRpcDecompilerCtxt->pRpcDecompilerInfo->pIfId->SyntaxVersion.MinorVersion
|
||||
);
|
||||
*/
|
||||
|
||||
End:
|
||||
if (pUuidString != NULL) RpcStringFreeA(&pUuidString);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
VOID RpcPrintInformation(VOID* pContext, std::ostringstream& oss)
|
||||
{
|
||||
RpcDecompilerCtxt_T* pRpcDecompilerCtxt = (RpcDecompilerCtxt_T*)pContext;
|
||||
|
||||
if (pRpcDecompilerCtxt == NULL) goto End;
|
||||
if (pRpcDecompilerCtxt->pRpcViewHelper == NULL) goto End;
|
||||
if (pRpcDecompilerCtxt->pRpcDecompilerInfo == NULL) goto End;
|
||||
|
||||
|
||||
//TODO : fonction de lecture de tous les headers de proc pour lister tous les handles et ecrire le fichier ACF
|
||||
oss << "\n/*****************************************************************";
|
||||
oss << "\n * Do not forget to write the ACF file using the following model:";
|
||||
oss << "\n // ACF file header";
|
||||
oss << "\n [";
|
||||
oss << "\n \t// List here the handles and other specific options.\n";
|
||||
oss << "\n ]\n";
|
||||
oss << "\n // ACF file body";
|
||||
//oss << "\n interface "<< narrow(std::wstring(DEFAULT_IF_NAME)) <<"\n {\n }";
|
||||
oss << "\n interface "<< DEFAULT_IF_NAME <<"\n {\n }";
|
||||
oss << "\n\n *";
|
||||
oss << "\n *****************************************************************/\n\n";
|
||||
|
||||
End:;
|
||||
|
||||
}
|
||||
|
||||
BOOL __fastcall RpcDecompilerPrintAllProceduresInlined(VOID* pContext)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(pContext);
|
||||
return FALSE;
|
||||
/* */
|
||||
}
|
||||
|
||||
//#define DBG_BUF_SIZE 512
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL __fastcall RpcDecompilerPrintAllProcedures(VOID* pContext)
|
||||
{
|
||||
|
||||
RpcDecompilerCtxt_T* pRpcDecompilerCtxt = (RpcDecompilerCtxt_T*)pContext;
|
||||
UINT uProcIdx;
|
||||
std::list<TypeToDefine> listProcType;
|
||||
std::ostringstream ossHeader;
|
||||
std::ostringstream ossProc;
|
||||
std::ostringstream ossType;
|
||||
//BYTE dbgBuf[DBG_BUF_SIZE];
|
||||
|
||||
if (pRpcDecompilerCtxt == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (pRpcDecompilerCtxt->pRpcViewHelper == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (pRpcDecompilerCtxt->pRpcDecompilerInfo == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RPC_DEBUG_FN((UCHAR*)"RpcDecompilerPrintAllProcedures\n");
|
||||
if (pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString == NULL)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"Cannot decompile inlined stub!\n");
|
||||
//return FALSE;
|
||||
}
|
||||
|
||||
|
||||
//// <dbg>
|
||||
|
||||
//dump proc index offset :
|
||||
|
||||
//ossHeader << "proc index offset "<<std::endl;
|
||||
|
||||
//for(int i=0; i< pRpcDecompilerCtxt->pRpcDecompilerInfo->NumberOfProcedures; i++)
|
||||
//{
|
||||
// ossHeader<<"proc "<<i<<"offset : "<<pRpcDecompilerCtxt->pRpcDecompilerInfo->pFormatStringOffsetTable[i] << std::endl;
|
||||
//}
|
||||
//
|
||||
//// Dump proc type and proc format string
|
||||
//RPC_GET_PROCESS_DATA(
|
||||
// pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString,
|
||||
// dbgBuf,
|
||||
// DBG_BUF_SIZE
|
||||
// );
|
||||
|
||||
//ossHeader<<"ProcFormatString : "<<std::endl;
|
||||
//for(int i=0; i<DBG_BUF_SIZE; i++)
|
||||
//{
|
||||
|
||||
// ossHeader<<" 0x"<<std::hex<<(int)dbgBuf[i];
|
||||
// if(i % 2 == 0 )
|
||||
// {
|
||||
// ossHeader<<"/* "<<i<<" */";
|
||||
// }
|
||||
|
||||
// ossHeader<<std::endl;
|
||||
//}
|
||||
|
||||
|
||||
//RPC_GET_PROCESS_DATA(
|
||||
// (pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString ),
|
||||
// dbgBuf,
|
||||
// DBG_BUF_SIZE
|
||||
// );
|
||||
|
||||
//ossHeader<<"TypeFormatString : "<<std::endl;
|
||||
//for(int i=0; i<DBG_BUF_SIZE; i++)
|
||||
//{
|
||||
|
||||
// ossHeader<<" 0x"<<std::hex<<(int)dbgBuf[i];
|
||||
// if(i % 2 == 0 )
|
||||
// {
|
||||
// ossHeader<<"/* "<<i<<" */";
|
||||
// }
|
||||
|
||||
// ossHeader<<std::endl;
|
||||
//}
|
||||
//// </end dbg>
|
||||
|
||||
|
||||
RpcPrintInformation(pContext, ossHeader);
|
||||
|
||||
RpcDecompilerPrintProlog(pContext, ossHeader);
|
||||
|
||||
|
||||
// display Interface name
|
||||
|
||||
ossHeader << "\n\ninterface ";
|
||||
// is there a default if name defined ?
|
||||
if(wcslen(pRpcDecompilerCtxt->pRpcDecompilerInfo->InterfaceName) > 0)
|
||||
{
|
||||
size_t szConverted = 0;
|
||||
size_t sz = wcslen(pRpcDecompilerCtxt->pRpcDecompilerInfo->InterfaceName) + 1;
|
||||
char* pTmp = (char*)pRpcDecompilerCtxt->pRpcViewHelper->RpcAlloc(sz);
|
||||
|
||||
if(pTmp != NULL)
|
||||
{
|
||||
ZeroMemory(pTmp, sz);
|
||||
|
||||
wcstombs_s(&szConverted, pTmp, sz, pRpcDecompilerCtxt->pRpcDecompilerInfo->InterfaceName, sz);
|
||||
|
||||
ossHeader << pTmp;
|
||||
pRpcDecompilerCtxt->pRpcViewHelper->RpcFree(pTmp);
|
||||
}
|
||||
|
||||
//ossHeader << narrow(std::wstring(pRpcDecompilerCtxt->pRpcDecompilerInfo->InterfaceName)) <<" \n{\n";
|
||||
|
||||
|
||||
/*RPC_DEBUG_FN((UCHAR*) "[ERROR] an error has occured while decompilating proc : %d \n",uProcIdx);
|
||||
ossProc << "[ERROR] an error has occured while decompilating proc : "<<uProcIdx<<std::endl;
|
||||
RPC_PRINT_FN ((UCHAR*)ossHeader.str().c_str());
|
||||
RPC_PRINT_FN((UCHAR*)ossProc.str().c_str());
|
||||
return FALSE;*/
|
||||
}
|
||||
else
|
||||
{
|
||||
//ossHeader << narrow(std::wstring(DEFAULT_IF_NAME)) <<" \n{\n";
|
||||
ossHeader << DEFAULT_IF_NAME <<" \n{\n";
|
||||
}
|
||||
RPC_DEBUG_FN((UCHAR*)"\ninterface %ls\n{\n", DEFAULT_IF_NAME);
|
||||
//Decompile each type
|
||||
//if ( RpcDecompilerPrintAllTypes(pContext) == FALSE ) goto End;
|
||||
|
||||
// pFormatStringOffsetTable can be (is always?) null for DCOM interfaces
|
||||
// if(pRpcDecompilerCtxt->pRpcDecompilerInfo->pFormatStringOffsetTable != NULL)
|
||||
// {
|
||||
|
||||
//Decompile each proc
|
||||
for(uProcIdx = 0; uProcIdx < pRpcDecompilerCtxt->pRpcDecompilerInfo->NumberOfProcedures; uProcIdx++)
|
||||
{
|
||||
|
||||
// select decompile method
|
||||
//if(pRpcDecompilerCtxt->pRpcDecompilerInfo->pbFunctionInterpreted[uProcIdx] == TRUE)
|
||||
//{
|
||||
// interpreted case
|
||||
if ( RpcDecompilerPrintOneProcedure(pContext, uProcIdx, listProcType, ossProc) == FALSE )
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*) "[ERROR] an error has occured while decompiling proc : %d \n",uProcIdx);
|
||||
ossProc << "[ERROR] an error has occured while decompiling proc : "<<uProcIdx<<std::endl;
|
||||
}
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// std::stringstream ss;
|
||||
// BOOL bResult = FALSE;
|
||||
|
||||
// // TODO : factorize fnname
|
||||
// ss << "_Function_0x" << std::hex << uProcIdx << std::dec;
|
||||
// IdlFunctionDesc idlFnDesc(ss.str());
|
||||
|
||||
|
||||
// // inlined case
|
||||
// ossProc << std::endl << "\t/* Function index 0x" << std::hex << uProcIdx << " inlined : will be done " << std::endl;
|
||||
|
||||
// //bResult = RpcDecompilerDecodeOneProcedureInlined(pContext, uProcIdx, idlFnDesc, listProcType);
|
||||
// //if(bResult == FALSE)
|
||||
// //{
|
||||
// // ossProc << "[ERROR] an error has occured while decompiling inlined proc : 0x" << std::hex << uProcIdx << std::dec << std::endl;
|
||||
// //}
|
||||
|
||||
// //bResult = RpcDecompilerPrintOneProcedureInlined(pContext, uProcIdx, idlFnDesc, listProcType, ossProc);
|
||||
|
||||
// // TO BE FILLED
|
||||
// }/* endif */
|
||||
|
||||
|
||||
}
|
||||
|
||||
// }
|
||||
|
||||
ossProc << "\n\n}\n";
|
||||
|
||||
|
||||
|
||||
// dump type list accorded to saved types offset
|
||||
|
||||
RpcDecompilerPrintAllTypesInList(pContext, listProcType, ossType);
|
||||
|
||||
// and then dump content
|
||||
RPC_PRINT_FN(pRpcDecompilerCtxt->pRpcViewHelper->pContext,(const char*)ossHeader.str().c_str());
|
||||
RPC_PRINT_FN(pRpcDecompilerCtxt->pRpcViewHelper->pContext,(const char*)ossType.str().c_str());
|
||||
RPC_PRINT_FN(pRpcDecompilerCtxt->pRpcViewHelper->pContext,(const char*)ossProc.str().c_str());
|
||||
|
||||
|
||||
return TRUE;
|
||||
}//end RpcDecompilerPrintAllProcedures
|
||||
|
||||
BOOL __fastcall RpcDecompilerPrintAllProceduresNew(VOID* pContext)
|
||||
{
|
||||
RpcDecompilerCtxt_T* pRpcDecompilerCtxt = (RpcDecompilerCtxt_T*)pContext;
|
||||
std::ostringstream ossIf;
|
||||
DECOMP_STATUS status;
|
||||
std::string strIfname;
|
||||
|
||||
if (pRpcDecompilerCtxt == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (pRpcDecompilerCtxt->pRpcViewHelper == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (pRpcDecompilerCtxt->pRpcDecompilerInfo == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString == NULL)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"Cannot decompile inlined stub!\n");
|
||||
//return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// convert interface name to std::string
|
||||
if(wcslen(pRpcDecompilerCtxt->pRpcDecompilerInfo->InterfaceName) == 0)
|
||||
{
|
||||
strIfname = DEFAULT_IF_NAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
strIfname = narrow(std::wstring(pRpcDecompilerCtxt->pRpcDecompilerInfo->InterfaceName));
|
||||
}
|
||||
|
||||
|
||||
// Create idlInterface used to decode interface
|
||||
IdlInterface idlIf(strIfname, *(pRpcDecompilerCtxt->pRpcDecompilerInfo->pIfId), pRpcDecompilerCtxt->pRpcDecompilerInfo->NumberOfProcedures);
|
||||
|
||||
status = idlIf.decode(pContext);
|
||||
|
||||
if(status != DS_SUCCESS)
|
||||
{
|
||||
RPC_ERROR_FN("decompilation failed\n");
|
||||
}
|
||||
ossIf << idlIf;
|
||||
// and then dump content
|
||||
RPC_PRINT_FN(pRpcDecompilerCtxt->pRpcViewHelper->pContext,ossIf.str().c_str());
|
||||
|
||||
return TRUE;
|
||||
}//end RpcDecompilerPrintAllProcedures
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL WINAPI DllMain(HANDLE hInstDLL, DWORD dwReason, LPVOID lpvReserved)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(hInstDLL);
|
||||
UNREFERENCED_PARAMETER(dwReason);
|
||||
UNREFERENCED_PARAMETER(lpvReserved);
|
||||
//nothing to do here!
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,2 @@
|
|||
EXPORTS
|
||||
RpcDecompilerHelper
|
|
@ -0,0 +1,85 @@
|
|||
#ifndef _RPC_DECOMPILER_H_
|
||||
#define _RPC_DECOMPILER_H_
|
||||
|
||||
#include <Rpc.h>
|
||||
#include <Rpcndr.h>
|
||||
|
||||
#include "..\RpcCommon\RpcView.h"
|
||||
|
||||
#define RPC_DECOMPILER_EXPORT_SYMBOL "RpcDecompilerHelper"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Type definitions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
typedef struct _RpcDecompilerInfo_T{
|
||||
UINT Pid;
|
||||
RPC_IF_ID* pIfId;
|
||||
UINT64 pModuleBase;
|
||||
UINT NDRVersion;
|
||||
UINT MIDLVersion;
|
||||
UINT NDRFags;
|
||||
UINT NumberOfProcedures;
|
||||
RVA_T* ppProcAddressTable; //A table containing the address of each function
|
||||
RVA_T* ppDispatchProcAddressTable;
|
||||
USHORT* pFormatStringOffsetTable; //A table containing the FormatStringOffset of each function
|
||||
WCHAR** ppProcNameTable; //A table containing the name of each function if possible or a NULL pointer else
|
||||
RVA_T/*UCHAR* */ pTypeFormatString; //Just a pointer to the type format string: must be read using
|
||||
RVA_T/*UCHAR* */ pProcFormatString;
|
||||
//RVA_T /*VOID* */ pExprInfo; // FC_EXPR : to be removed (replaced by following 2 elements)
|
||||
RVA_T pExprOffset;
|
||||
RVA_T pExprFormatString;
|
||||
RVA_T apfnExprEval; // Callbacks
|
||||
BOOL bIs64Bits;
|
||||
WCHAR InterfaceName[RPC_MAX_LENGTH];
|
||||
RPC_SYNTAX_IDENTIFIER* pSyntaxId;
|
||||
BOOL bIsInlined;
|
||||
RVA_T* ppProcFormatInlined;
|
||||
BOOL* pbFunctionInterpreted; // array containing for every function a boolean indicating if function is interpreted
|
||||
//...
|
||||
}RpcDecompilerInfo_T;
|
||||
|
||||
typedef VOID* (__fastcall* RpcDecompilerInitFn_T)(RpcViewHelper_T* pRpcViewHelper, RpcDecompilerInfo_T* pDecompilerInfo); //returns NULL in case of failure
|
||||
typedef VOID (__fastcall* RpcDecompilerUninitFn_T)(VOID* pRpcDecompilerCtxt);
|
||||
typedef BOOL (__fastcall* RpcDecompilerPrintProcedureFn_T)(VOID* pRpcDecompilerCtxt, UINT ProcIndex);
|
||||
typedef BOOL (__fastcall* RpcDecompilerPrintAllProceduresFn_T)(VOID* pRpcDecompilerCtxt);
|
||||
|
||||
typedef struct _RpcDecompilerHelper_T{
|
||||
RpcDecompilerInitFn_T RpcDecompilerInitFn;
|
||||
RpcDecompilerUninitFn_T RpcDecompilerUninitFn;
|
||||
RpcDecompilerPrintProcedureFn_T RpcDecompilerPrintProcedureFn;
|
||||
RpcDecompilerPrintAllProceduresFn_T RpcDecompilerPrintAllProceduresFn;
|
||||
}RpcDecompilerHelper_T;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// STATUS DECLARATION
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef enum _DECOMP_STATUS
|
||||
{
|
||||
DS_SUCCESS = 0,
|
||||
DS_ERR ,
|
||||
DS_ERR_UNABLE_TO_READ_MEMORY ,
|
||||
DS_ERR_INVALID_DATA ,
|
||||
DS_ERR_INVALID_PARAM ,
|
||||
DS_ERR_FUNCTION_NOT_PROPERLY_INITIALIZED ,
|
||||
DS_ERR_IN_SIMPLE_TYPE ,
|
||||
DS_ERR_IN_COMPLEX_TYPE ,
|
||||
DS_ERR_IN_DECODE_PROC_HEADER ,
|
||||
DS_ERR_IN_DECODE_PROC_PARAMS ,
|
||||
DS_ERR_INVALID_INDEX ,
|
||||
DS_ERR_UNABLE_TO_DECODE_COMPLEX_TYPE ,
|
||||
}DECOMP_STATUS;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif//_RPC_DECOMPILER_H_
|
|
@ -0,0 +1,90 @@
|
|||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include <RpcViewVersion.h>
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Français (France) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA)
|
||||
#ifdef _WIN32
|
||||
//LANGUAGE LANG_FRENCH, SUBLANG_FRENCH
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION _RPCVIEW_VERSION_MAJOR_,_RPCVIEW_VERSION_MINOR_,_RPCVIEW_VERSION_RELEASE_,0
|
||||
PRODUCTVERSION _RPCVIEW_VERSION_MAJOR_,_RPCVIEW_VERSION_MINOR_,_RPCVIEW_VERSION_RELEASE_,0
|
||||
FILEFLAGSMASK 0x0L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904e4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "RpcView"
|
||||
VALUE "FileDescription", "MS RPC decompilation module"
|
||||
VALUE "InternalName", "RpcView"
|
||||
VALUE "LegalCopyright", "Copyright © 2012-2017 RpcView Team"
|
||||
VALUE "LegalTrademarks", "Copyright (C) 2012-2017 RpcView Team"
|
||||
VALUE "OriginalFilename", "RpcDecompiler.dll"
|
||||
VALUE "ProductName", "RpcDecompiler"
|
||||
VALUE "ProductVersion", _RPCVIEW_PRODUCT_VERSION_
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1252
|
||||
END
|
||||
END
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.\0"
|
||||
END
|
||||
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Français (France) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,58 @@
|
|||
|
||||
#ifndef _INTERNAL_COMPLEX_TYPES_ARRAYS_H_
|
||||
#define _INTERNAL_COMPLEX_TYPES_ARRAYS_H_
|
||||
|
||||
#include <sstream>
|
||||
#include <list>
|
||||
#include "internalRpcDecompTypeDefs.h"
|
||||
|
||||
|
||||
|
||||
BOOL __fastcall processFixedSizeArray(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listAdditionalTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
BOOL __fastcall processConformantArray(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listAdditionalTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
BOOL __fastcall processConformantVaryingArray(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listAdditionalTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
BOOL __fastcall processVaryingArray(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listAdditionalTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
BOOL __fastcall processComplexArray(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listAdditionalTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
UINT __fastcall getArrayMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif//_INTERNAL_COMPLEX_TYPES_ARRAYS_H_
|
|
@ -0,0 +1,326 @@
|
|||
#include "..\RpcCommon\RpcView.h"
|
||||
#include "internalComplexTypesPointers.h"
|
||||
#include "internalRpcDecompiler.h"
|
||||
#include "internalRpcDecompTypeDefs.h"
|
||||
#include "internalComplexTypesArrays.h"
|
||||
#include "InternalComplexTypesMisc.h"
|
||||
#include "internalRpcUtils.h"
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
BOOL __fastcall processStandardPointer(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listAdditionalTypes,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
BYTE bRead;
|
||||
BOOL bResult;
|
||||
RVA_T pComplexType = NULL;
|
||||
CommonPtrSimple_t simplePtr;
|
||||
CommonPtrComplex_t complexPtr;
|
||||
|
||||
// set attributes relative to pointer
|
||||
if(ParamDesc.getuPtrLevel() == 0) // pointer attributes seems to be applied only on first pointer level
|
||||
{
|
||||
if(fcType == FC_UP)
|
||||
{
|
||||
oss<<"[unique]";
|
||||
}
|
||||
|
||||
|
||||
if(fcType == FC_RP)
|
||||
{
|
||||
oss<<"[ref]";
|
||||
}
|
||||
|
||||
if(fcType == FC_FP)
|
||||
{
|
||||
oss<<"[ptr]";
|
||||
}
|
||||
|
||||
if(fcType == FC_OP)
|
||||
{
|
||||
oss<<"/*FC_OP*/";
|
||||
}
|
||||
}
|
||||
|
||||
// increment pointer attribute
|
||||
ParamDesc.incPtrLevel();
|
||||
|
||||
|
||||
|
||||
|
||||
// read FC_POINTER_ATTRIBUTE
|
||||
RPC_GET_PROCESS_DATA((pType+1),&bRead,sizeof(bRead));
|
||||
if(!bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processStandardPointer : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
if(bRead & FC_SIMPLE_POINTER) // A pointer to a simple type or nonsized conformant string
|
||||
{
|
||||
|
||||
// read simple ptr
|
||||
RPC_GET_PROCESS_DATA(pType, &simplePtr, sizeof(simplePtr));
|
||||
if(!bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processStandardPointer : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// special case where it's a conformant non sized string
|
||||
if((FC_TYPE)simplePtr.simple_type == FC_C_CSTRING)
|
||||
{
|
||||
oss << "[string] char";
|
||||
displayPtrLevel(ParamDesc.getuPtrLevel(), oss);
|
||||
oss<< " " << ParamDesc.getStrTypeName();
|
||||
}
|
||||
else if((FC_TYPE)simplePtr.simple_type == FC_C_WSTRING)
|
||||
{
|
||||
oss << "[string] wchar_t";
|
||||
displayPtrLevel(ParamDesc.getuPtrLevel(), oss);
|
||||
oss<< " " << ParamDesc.getStrTypeName();
|
||||
}
|
||||
else // simple type
|
||||
{
|
||||
|
||||
|
||||
bResult = processSimpleType(
|
||||
pContext,
|
||||
(FC_TYPE)simplePtr.simple_type,
|
||||
ParamDesc,
|
||||
oss);
|
||||
|
||||
if(!bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processStandardPointer : unable to parsse simple type\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // complex pointer
|
||||
{
|
||||
|
||||
|
||||
RPC_GET_PROCESS_DATA(pType, &complexPtr, sizeof(complexPtr));
|
||||
if(!bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processStandardPointer : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// compute type Offset :
|
||||
pComplexType = pType + sizeof(complexPtr.pointerType) + sizeof(complexPtr.pointer_attributes) + complexPtr.offset_to_complex_description;
|
||||
//ParamDesc.setuOffset((UINT)(pComplexType - pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString)); //TODO : ....
|
||||
ParamDesc.setRva(pComplexType);
|
||||
|
||||
// DEBUG
|
||||
ParamDesc.setArrayIsAttributedPointer();
|
||||
|
||||
// END DEBUG
|
||||
|
||||
bResult = rpcDumpType(
|
||||
pContext,
|
||||
ParamDesc,
|
||||
listAdditionalTypes,
|
||||
oss);
|
||||
|
||||
if(!bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processStandardPointer : unable to dump complex type\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// set Param size in memory
|
||||
// (set done after RpcDump type to override MemorySize of pointeed type)
|
||||
//ParamDesc.setMemorySize(POINTER_SIZE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall processInterfacePointer(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
BOOL bResult;
|
||||
BYTE bRead;
|
||||
GUID ifGuid;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//read firstByte
|
||||
RPC_GET_PROCESS_DATA(++pType,&bRead,sizeof(bRead));
|
||||
if(!bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processInterfacePointer : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(bRead == FC_CONSTANT_IID)
|
||||
{
|
||||
pType++;
|
||||
|
||||
|
||||
// read ifGuid.Data1;
|
||||
RPC_GET_PROCESS_DATA(pType, &ifGuid, sizeof(ifGuid));
|
||||
|
||||
if(!bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processInterfacePointer : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
pType += sizeof(ifGuid);
|
||||
|
||||
|
||||
|
||||
oss<<"interface(";
|
||||
oss<<std::hex<< std::setfill('0') << std::setw(8) <<ifGuid.Data1<<"-";
|
||||
oss<<std::hex<< std::setfill('0') << std::setw(4) <<ifGuid.Data2<<"-";
|
||||
oss<<std::hex<< std::setfill('0') << std::setw(4) <<ifGuid.Data3<<"-";
|
||||
for(int i=0; i<8 ; i++)
|
||||
{
|
||||
oss<<std::hex<<(int)ifGuid.Data4[i];
|
||||
}
|
||||
oss<<")* ";
|
||||
|
||||
}
|
||||
else //FC_PAD-> interface pointer with idd_is()
|
||||
{
|
||||
// TODO
|
||||
oss<<"[iid_is(TODO)] FC_IP ";
|
||||
}
|
||||
|
||||
oss<<ParamDesc.getStrTypeName();
|
||||
|
||||
// set Param size in memory
|
||||
// (set done after RpcDump type to override MemorySize of pointeed type)
|
||||
//ParamDesc.setMemorySize(POINTER_SIZE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall processByteCountPointer(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listAdditionalTypes,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
BOOL bResult = TRUE;
|
||||
short shortOffset;
|
||||
ByteCountHeader_T byteCountHeader;
|
||||
ConformanceDescr_T confDescr;
|
||||
|
||||
|
||||
|
||||
// increment pointer count
|
||||
ParamDesc.incPtrLevel();
|
||||
|
||||
RPC_GET_PROCESS_DATA(pType,&byteCountHeader,sizeof(byteCountHeader));
|
||||
|
||||
if(!bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processByteCountPointer : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pType += sizeof(byteCountHeader);
|
||||
|
||||
// conformance part parsing
|
||||
// byte_count is an acf attributes, so we'll comment it
|
||||
|
||||
oss << "/* ACF attributes : ";
|
||||
confDescr.pType = pType;
|
||||
confDescr.confType = byte_count;
|
||||
|
||||
RPC_GET_PROCESS_DATA(confDescr.pType, &confDescr.corrDesc, sizeof(confDescr.corrDesc));
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processByteCountPointer : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
processCorrelationDescriptor(pContext, confDescr, oss, ParamDesc);
|
||||
oss << "*/ ";
|
||||
|
||||
// skip conformance part
|
||||
pType += getCorrelationDescriptorSize(robustFlagWasSet, ParamDesc.hasRangeOnConformance());
|
||||
|
||||
|
||||
|
||||
// check if it's simple type or complex type
|
||||
if(byteCountHeader.simpleTypeOrPad == FC_PAD)
|
||||
{
|
||||
|
||||
|
||||
// COMPLEX_TYPE
|
||||
// read offset to complex type
|
||||
RPC_GET_PROCESS_DATA(pType,&shortOffset,sizeof(shortOffset));
|
||||
if(!bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processByteCountPointer : unable to read process data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
pType += shortOffset;
|
||||
//ParamDesc.setuOffset((UINT)(pType - pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString));
|
||||
ParamDesc.setRva(pType);
|
||||
|
||||
//dump COMPLEX TYPE
|
||||
bResult = rpcDumpType(
|
||||
pContext,
|
||||
ParamDesc,
|
||||
listAdditionalTypes,
|
||||
oss);
|
||||
|
||||
if(!bResult)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processByteCountPointer : unable to dump embeded type");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// SIMPLE_TYPE
|
||||
if(!processSimpleType(pContext, (FC_TYPE) byteCountHeader.simpleTypeOrPad, ParamDesc, oss))
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processByteCountPointer : unable to dump simple type");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// set Param size in memory
|
||||
// (set done after RpcDump type to override MemorySize of pointeed type)
|
||||
//ParamDesc.setMemorySize(POINTER_SIZE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef _INTERNAL_COMPLEX_TYPES_POINTERS_H_
|
||||
#define _INTERNAL_COMPLEX_TYPES_POINTERS_H_
|
||||
|
||||
#include <sstream>
|
||||
#include <list>
|
||||
#include "internalRpcDecompTypeDefs.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#define POINTER_SIZE_32_BITS 4
|
||||
#define POINTER_SIZE_64_BITS 8
|
||||
#define POINTER_SIZE (is64B?POINTER_SIZE_64_BITS:POINTER_SIZE_32_BITS)
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall processStandardPointer(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall processInterfacePointer(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall processByteCountPointer(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif//_INTERNAL_COMPLEX_TYPES_POINTERS_H_
|
|
@ -0,0 +1,168 @@
|
|||
#include "..\RpcCommon\RpcView.h"
|
||||
#include "internalRpcDecompiler.h"
|
||||
#include "internalRpcDecompTypeDefs.h"
|
||||
#include "internalComplexTypesStrings.h"
|
||||
#include "InternalComplexTypesMisc.h"
|
||||
#include "internalComplexTypesPointers.h"
|
||||
#include "internalRpcUtils.h"
|
||||
|
||||
|
||||
BOOL __fastcall processConformantString(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
|
||||
BOOL bResult = FALSE;
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
BYTE bFC_STRING_SIZED;
|
||||
ConformantSizedStr_t conformantSizedStr;
|
||||
ConformanceDescr_T confDesc;
|
||||
|
||||
oss<<"[string]";
|
||||
|
||||
|
||||
// set Param size in memory
|
||||
//ParamDesc.setMemorySize(POINTER_SIZE);
|
||||
|
||||
|
||||
// check if string contains FC_STRING_SIZED (conformance descriptor)
|
||||
RPC_GET_PROCESS_DATA(pType+1,&bFC_STRING_SIZED,sizeof(bFC_STRING_SIZED));
|
||||
if(!bResult)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(bFC_STRING_SIZED == FC_STRING_SIZED)
|
||||
{
|
||||
// read conformance sized string
|
||||
RPC_GET_PROCESS_DATA(
|
||||
pType,
|
||||
&conformantSizedStr,
|
||||
SIZE_OF_CONFORMANT_SIZED_STR);
|
||||
if(!bResult)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pType += FIELD_OFFSET(ConformantSizedStr_t, conformance_description);
|
||||
|
||||
// build conformance descriptor
|
||||
confDesc.confType = size_is;
|
||||
confDesc.corrDesc = conformantSizedStr.conformance_description.corrDescNonRobust;
|
||||
confDesc.pType = pType ;
|
||||
|
||||
// print correlation desc
|
||||
processCorrelationDescriptor(pContext, confDesc, oss, ParamDesc);
|
||||
|
||||
if(robustFlagWasSet)
|
||||
{
|
||||
pType += sizeof(CorrelationDescriptorRobust_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
pType += sizeof(CorrelationDescriptorNonRobust_t);
|
||||
}
|
||||
|
||||
if(ParamDesc.hasRangeOnConformance())
|
||||
{
|
||||
ProcessArrayRange(pContext, pType, ParamDesc, oss);
|
||||
pType += sizeof(Range_t);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(fcType == FC_C_CSTRING)
|
||||
{
|
||||
oss<<" char";
|
||||
}
|
||||
else // FC_C_WSTRING
|
||||
{
|
||||
oss<<" wchar_t";
|
||||
}
|
||||
|
||||
displayPtrLevel(ParamDesc.getuPtrLevel(), oss);
|
||||
oss << " ";
|
||||
oss<<ParamDesc.getStrTypeName();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall processNonConformantString(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
|
||||
BOOL bResult = FALSE;
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
NonConformantStr_t nonConformantStrRead;
|
||||
|
||||
UNREFERENCED_PARAMETER(fcType);
|
||||
|
||||
// Read NonConformant string structure in order to know its type
|
||||
RPC_GET_PROCESS_DATA(
|
||||
pType,
|
||||
&nonConformantStrRead,
|
||||
sizeof(nonConformantStrRead)
|
||||
);
|
||||
|
||||
oss<<"[string]";
|
||||
|
||||
if(nonConformantStrRead.stringType == FC_CSTRING)
|
||||
{
|
||||
oss<<"char";
|
||||
}
|
||||
else // Type is FC_WSTRING
|
||||
{
|
||||
oss<<" wchar_t";
|
||||
}
|
||||
|
||||
displayPtrLevel(ParamDesc.getuPtrLevel(), oss);
|
||||
oss << " ";
|
||||
oss<<ParamDesc.getStrTypeName()<<"["<<nonConformantStrRead.string_size<<"]";
|
||||
|
||||
|
||||
bResult = TRUE;
|
||||
|
||||
return(bResult);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
BOOL __fastcall processStructureString(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
//NonConfStructStr_t nonConfStructStr; // FC_SSTRING
|
||||
//ConfStructStr_t confStructStr; // FC_C_SSTRING
|
||||
//ConfSizedStructStr_t confSizedStrucStr; // FC_C_SSTRING sized
|
||||
|
||||
UNREFERENCED_PARAMETER(pType);
|
||||
UNREFERENCED_PARAMETER(pContext);
|
||||
|
||||
switch(fcType)
|
||||
{
|
||||
case FC_SSTRING:
|
||||
oss<<"[string] FC_SSTRING /* TO BE COMPLETED */" <<ParamDesc.getStrTypeName();
|
||||
break;
|
||||
|
||||
case FC_C_SSTRING:
|
||||
oss<<"[string] FC_C_SSTRING /* TO BE COMPLETED */ "<<ParamDesc.getStrTypeName();
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef _INTERNAL_COMPLEX_TYPES_STRINGS_H_
|
||||
#define _INTERNAL_COMPLEX_TYPES_STRINGS_H_
|
||||
|
||||
#include <sstream>
|
||||
#include "internalRpcDecompTypeDefs.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
BOOL __fastcall processConformantString(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
BOOL __fastcall processNonConformantString(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
BOOL __fastcall processStructureString(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
|
||||
#endif//_INTERNAL_COMPLEX_TYPES_STRINGS_H_
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,63 @@
|
|||
#ifndef _INTERNAL_COMPLEX_TYPES_STRUCTS_H_
|
||||
#define _INTERNAL_COMPLEX_TYPES_STRUCTS_H_
|
||||
|
||||
#include <sstream>
|
||||
#include <list>
|
||||
|
||||
#define POINTER_LAYOUT_ENTRY_SIZE 4
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall getStructureMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Out_ size_t* pszStructureMemorySize);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall processStructure(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall defineTypeSimpleStruct(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const TypeToDefine& structureDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listAdditionalType,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall defineTypeConformantStructure(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const TypeToDefine& structureDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall defineTypeComplexStruct(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const TypeToDefine& structureDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//BOOL __fastcall defineTypeHardStruct(
|
||||
// _In_ VOID* pContext,
|
||||
// _In_ PBYTE pType,
|
||||
// _In_ const TypeToDefine& structureDesc,
|
||||
// _Out_ std::list<TypeToDefine>& listProcTypes,
|
||||
// _Out_ std::ostringstream& oss);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif//_INTERNAL_COMPLEX_TYPES_STRUCTS_H_
|
|
@ -0,0 +1,619 @@
|
|||
#include <stdio.h>
|
||||
#include "..\RpcCommon\RpcView.h"
|
||||
#include "internalRpcDecompTypeDefs.h"
|
||||
#include "internalComplexTypesUnions.h"
|
||||
#include "InternalComplexTypesMisc.h"
|
||||
#include "internalRpcDecompiler.h"
|
||||
#include "internalTypeTools.h"
|
||||
#include "internalRpcUtils.h"
|
||||
|
||||
|
||||
BOOL __fastcall processNonEncapsulatedUnion(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
|
||||
UNREFERENCED_PARAMETER(fcType);
|
||||
//NonEncapUnionHeader_t nonEncapUnionHeaderToPrint;
|
||||
nonEncapUnion_offsetToSizeAndArmDescription_t offsetToSizeAndArmDescription;
|
||||
UINT16 uMemorySize;
|
||||
|
||||
ConformanceDescr_T confDesc;
|
||||
UINT32 unionOffsetValueToContructTypeName = 0;
|
||||
|
||||
RVA_T pTypeStart;
|
||||
|
||||
|
||||
|
||||
// save pUnionheader to parse it later
|
||||
pTypeStart = pType;
|
||||
|
||||
|
||||
// let's skip union header
|
||||
|
||||
pType += sizeof(NonEncapUnionHeader_t);
|
||||
|
||||
// we'll have to read a switch_is correlation descr
|
||||
confDesc.pType = pType;
|
||||
confDesc.confType = switch_is;
|
||||
|
||||
RPC_GET_PROCESS_DATA(
|
||||
confDesc.pType,
|
||||
&(confDesc.corrDesc),
|
||||
sizeof(confDesc.corrDesc));
|
||||
|
||||
pType += getCorrelationDescriptorSize(robustFlagWasSet, ParamDesc.hasRangeOnConformance());
|
||||
|
||||
|
||||
RPC_GET_PROCESS_DATA(
|
||||
pType,
|
||||
&offsetToSizeAndArmDescription,
|
||||
sizeof(nonEncapUnion_offsetToSizeAndArmDescription_t)
|
||||
);
|
||||
|
||||
|
||||
|
||||
ParamDesc.addConformanceDescr(confDesc);
|
||||
processCorrelationDescriptor(pContext, confDesc, oss, ParamDesc);
|
||||
|
||||
//Calculate the absolute offset where offsetToSizeAndArmDescription points
|
||||
unionOffsetValueToContructTypeName = (UINT32)((pType + offsetToSizeAndArmDescription) - pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString);
|
||||
|
||||
|
||||
|
||||
|
||||
TypeToDefine unionDesc((pType + offsetToSizeAndArmDescription) , ParamDesc);
|
||||
//unionDesc.setuOffset(unionOffsetValueToContructTypeName);
|
||||
unionDesc.setpNonEncapsulatedUnionHeader(pTypeStart);
|
||||
|
||||
listProcTypes.push_back(unionDesc);
|
||||
|
||||
// read union memory size
|
||||
RPC_GET_PROCESS_DATA(
|
||||
pType + offsetToSizeAndArmDescription,
|
||||
&uMemorySize,
|
||||
sizeof(uMemorySize)
|
||||
);
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processNonEncapsulatedUnion : unable to dump complex type");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//ParamDesc.setMemorySize(uMemorySize);
|
||||
|
||||
oss<<"union union_"<< std::dec <<unionOffsetValueToContructTypeName;
|
||||
displayPtrLevel(ParamDesc.getuPtrLevel(), oss);
|
||||
oss<<" "<<ParamDesc.getStrTypeName();
|
||||
|
||||
bResult = TRUE;
|
||||
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall getNonEncapsulatedUnionMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Out_ size_t* pszMemorySize,
|
||||
_In_ BOOL bHasRangeOnConformance)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
nonEncapUnion_offsetToSizeAndArmDescription_t offsetToSizeAndArmDescription;
|
||||
UINT16 uMemorySize;
|
||||
|
||||
|
||||
// let's skip union header and correlation descriptor
|
||||
pType += sizeof(NonEncapUnionHeader_t) + getCorrelationDescriptorSize(robustFlagWasSet, bHasRangeOnConformance);
|
||||
|
||||
|
||||
RPC_GET_PROCESS_DATA(
|
||||
pType,
|
||||
&offsetToSizeAndArmDescription,
|
||||
sizeof(nonEncapUnion_offsetToSizeAndArmDescription_t)
|
||||
);
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] getNonEncapsulatedUnionMemorySize : unable read memory");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// read union memory size
|
||||
RPC_GET_PROCESS_DATA(
|
||||
pType + offsetToSizeAndArmDescription,
|
||||
&uMemorySize,
|
||||
sizeof(uMemorySize)
|
||||
);
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] getNonEncapsulatedUnionMemorySize : unable read memory");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pszMemorySize = uMemorySize;
|
||||
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall processEncapsulatedUnion(
|
||||
_In_ VOID* pContext,
|
||||
_In_ const RVA_T pType,
|
||||
_In_ FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
|
||||
BOOL bResult = FALSE;
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
//TypeToDefine unionDesc;
|
||||
|
||||
EncapUnion_t encapUnion;
|
||||
|
||||
UNREFERENCED_PARAMETER(fcType);
|
||||
|
||||
// get memory size
|
||||
RPC_GET_PROCESS_DATA(
|
||||
pType,
|
||||
&encapUnion,
|
||||
sizeof(encapUnion));
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processEncapsulatedUnion : unable to dump complex type");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// save memory size
|
||||
//ParamDesc.setMemorySize(encapUnion.sizeAndArmDescr.memorySize + ((encapUnion.switchType & ENCAP_UNION_SWITCH_MEMORY_INCREMENT_MASK) >> 0x4));
|
||||
|
||||
|
||||
// store the type in listProcTypes in order to define it later
|
||||
|
||||
// unionDesc.m_uOffset = ParamDesc.m_uOffset;
|
||||
// unionDesc.m_fcType = fcType;
|
||||
TypeToDefine unionDesc(pType, ParamDesc);
|
||||
|
||||
listProcTypes.push_back(unionDesc);
|
||||
|
||||
oss<<"union_"<< std::dec <<ParamDesc.getRelativeOffsetFromFmtString(pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString)<<" ";
|
||||
displayPtrLevel(ParamDesc.getuPtrLevel(), oss);
|
||||
oss<<" "<<ParamDesc.getStrTypeName();
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall getEncapsulatedUnionMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Out_ size_t* pszMemorySize)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
//TypeToDefine unionDesc;
|
||||
|
||||
EncapUnion_t encapUnion;
|
||||
|
||||
// get memory size
|
||||
RPC_GET_PROCESS_DATA(
|
||||
pType,
|
||||
&encapUnion,
|
||||
sizeof(encapUnion));
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR] processEncapsulatedUnion : unable to dump complex type");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// save memory size
|
||||
*pszMemorySize = encapUnion.sizeAndArmDescr.memorySize + ((encapUnion.switchType & ENCAP_UNION_SWITCH_MEMORY_INCREMENT_MASK) >> 0x4);
|
||||
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BOOL __fastcall printEachUnionMember(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const TypeToDefine& unionDesc,
|
||||
_In_ UINT16 unionMemberCount,
|
||||
_In_ BOOL bIsEncapsulatedUnion,
|
||||
_Inout_ std::list<TypeToDefine>& listAdditionalsType,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
ArmXCase_t unionMemberToPrint;
|
||||
DefaultArmDescr_t defaultArmToPrint = 0;
|
||||
|
||||
|
||||
//Print each member of the union + the default member
|
||||
//bResult = PrintEachUnionMember(/* in */ pRpcDecompilerCtxt, /* in */ TypeOffset, /* in */ unionEncapsulatedDescr, /* in */ unionMemberCount, _Out_ oss);
|
||||
//if(bResult == FALSE) goto End;
|
||||
for(int i = 0; i < unionMemberCount; i++)
|
||||
{
|
||||
ParamDesc memberDesc;
|
||||
std::ostringstream ossMemberName;
|
||||
|
||||
|
||||
// each member inherits it properties from the union
|
||||
memberDesc.inheritProperties(unionDesc);
|
||||
|
||||
|
||||
//lire la description du membre courant de l'union
|
||||
RPC_GET_PROCESS_DATA(
|
||||
pType,
|
||||
&unionMemberToPrint,
|
||||
sizeof(ArmXCase_t));
|
||||
|
||||
// set memberDesc info
|
||||
ossMemberName << "unionMember_" << unionMemberToPrint.armCaseValue;
|
||||
memberDesc.setParamName(ossMemberName.str());
|
||||
|
||||
pType += ARM_X_CASE_SIZE;
|
||||
|
||||
if(bIsEncapsulatedUnion)
|
||||
{
|
||||
oss<<"\t\tcase ("<<unionMemberToPrint.armCaseValue<<"):\t";
|
||||
}
|
||||
else
|
||||
{
|
||||
oss<<"\t\t[case("<<unionMemberToPrint.armCaseValue<<")]\t";
|
||||
}
|
||||
|
||||
if( ( unionMemberToPrint.offsetToArmDescription & FC_MAGIC_UNION_BYTE) &&
|
||||
( ((UINT16) unionMemberToPrint.offsetToArmDescription) >= MIN_UNION_SIMPLE_TYPE_ENCODE) &&
|
||||
( ((UINT16) unionMemberToPrint.offsetToArmDescription) <= MAX_UNION_SIMPLE_TYPE_ENCODE)
|
||||
)
|
||||
{//member is a simple type
|
||||
|
||||
bResult = processSimpleType(
|
||||
pContext,
|
||||
(FC_TYPE) (unionMemberToPrint.offsetToArmDescription & FC_MAGIC_UNION_GET_SIMPLE_TYPE),
|
||||
memberDesc,
|
||||
oss);
|
||||
|
||||
if (bResult == FALSE) goto End;
|
||||
|
||||
|
||||
|
||||
}
|
||||
else //member is a complex type
|
||||
{
|
||||
RVA_T pComplexType;
|
||||
|
||||
//member description is localized at the relative offset unionMemberToPrint.offsetToArmDescription
|
||||
//Calculate the absolute offset where unionMemberToPrint.offsetToArmDescription points
|
||||
pComplexType = (pType //(fin du offsetToSizeAndArmDescription courant)
|
||||
- sizeof(unionMemberToPrint.offsetToArmDescription) //base de l'offset à calculer
|
||||
+ unionMemberToPrint.offsetToArmDescription); //ajout de la valeur relative de l'offset contenue dans unionMemberToPrint.offsetToArmDescription
|
||||
|
||||
|
||||
//memberDesc.setuOffset((UINT)(pComplexType - pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString));
|
||||
memberDesc.setRva(pComplexType);
|
||||
|
||||
//rpcDumpType
|
||||
bResult = rpcDumpType(
|
||||
pContext,
|
||||
memberDesc,
|
||||
listAdditionalsType,
|
||||
oss);
|
||||
|
||||
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[printEachUnionMember] : unable to dump complex type");
|
||||
goto End;
|
||||
}
|
||||
}
|
||||
|
||||
oss << ";" << std::endl;
|
||||
|
||||
|
||||
}
|
||||
|
||||
// process default
|
||||
RPC_GET_PROCESS_DATA(
|
||||
pType,
|
||||
&defaultArmToPrint,
|
||||
sizeof(DefaultArmDescr_t));
|
||||
|
||||
|
||||
switch(defaultArmToPrint)
|
||||
{
|
||||
|
||||
|
||||
|
||||
case NO_DEFAULT_ARM_DESCRIPTION:
|
||||
oss<<"\t/* no default member to print for this Union.\n\tAn exception will be raised if the switch_is value does not match any of the cases values */\n";
|
||||
RPC_DEBUG_FN((UCHAR*)"\nPrintTypeUnionNonEncapsulated : no default member to print for this Union");
|
||||
bResult = TRUE;
|
||||
break;
|
||||
|
||||
case EMPTY_DEFAULT_ARM_DESCRIPTION:
|
||||
if(bIsEncapsulatedUnion)
|
||||
{
|
||||
oss<<"\t\tdefault:\n\t\t;"<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
oss<<"\t\t[default]\t;"<<std::endl;
|
||||
}
|
||||
bResult = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
if(bIsEncapsulatedUnion)
|
||||
{
|
||||
oss<<"\tdefault:"<<std::endl<<"\t\t";;
|
||||
}
|
||||
else
|
||||
{
|
||||
oss<<"\t[default]"<<std::endl<<"\t\t";;
|
||||
}
|
||||
bResult = TRUE;
|
||||
|
||||
//print the default member type
|
||||
if( ( defaultArmToPrint & FC_MAGIC_UNION_BYTE ) &&
|
||||
( ((UINT16) defaultArmToPrint) >= MIN_UNION_SIMPLE_TYPE_ENCODE) &&
|
||||
( ((UINT16) defaultArmToPrint) <= MAX_UNION_SIMPLE_TYPE_ENCODE)
|
||||
)
|
||||
{
|
||||
ParamDesc defaultMemberDesc;
|
||||
defaultMemberDesc.setParamName("defaultMember");
|
||||
|
||||
|
||||
|
||||
//default = simple type
|
||||
bResult = processSimpleType(
|
||||
pContext,
|
||||
(FC_TYPE) (defaultArmToPrint & FC_MAGIC_UNION_GET_SIMPLE_TYPE),
|
||||
defaultMemberDesc,
|
||||
oss);
|
||||
|
||||
if (bResult == FALSE) goto End;
|
||||
}
|
||||
else //default = complex type
|
||||
{
|
||||
ParamDesc defaultMemberDesc;
|
||||
|
||||
//member description is localized at the relative offset defaultArmToPrint
|
||||
//Calculate the absolute offset where defaultArmToPrint points
|
||||
pType = (pType //base de l'offset à calculer
|
||||
+ (INT16) defaultArmToPrint); //ajout de la valeur relative de l'offset contenue dans defaultArmToPrint
|
||||
|
||||
defaultMemberDesc.setParamName("defaultMember");
|
||||
//defaultMemberDesc.setuOffset((UINT)(pType - pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString));
|
||||
defaultMemberDesc.setRva(pType);
|
||||
|
||||
|
||||
//rpcDumpType
|
||||
bResult = rpcDumpType(
|
||||
pContext,
|
||||
defaultMemberDesc,
|
||||
listAdditionalsType,
|
||||
oss);
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"\n!!! source = %s ligne = %d - PrintParamOfFieldType returned bResult = %d", __FILE__, __LINE__, bResult);
|
||||
goto End;
|
||||
}
|
||||
}
|
||||
|
||||
oss << ";"<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
bResult = TRUE;
|
||||
|
||||
End:
|
||||
return bResult;
|
||||
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall defineTypeNonEncapsulatedUnion(
|
||||
_In_ VOID* pContext,
|
||||
_In_ const TypeToDefine& unionDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listAdditionalTypes,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
RVA_T pType = unionDesc.getpNonEncapuslatedUnionHeader();
|
||||
FC_TYPE switchType;
|
||||
UnionArmSelector_t unionArmSeltorToPrint;
|
||||
UINT16 unionMemberCount = 0;
|
||||
NonEncapUnionHeader_t nonEncapUnionHeader;
|
||||
//short offsetToSizeAndArmDescr;
|
||||
|
||||
#ifdef DBG_DECOMP
|
||||
|
||||
oss << std::endl;
|
||||
oss << "\t /* FC_NON_ENCAPSULATED_UNION , offset : NO_MORE "; //<< (int)unionStrDesc.getuOffset();
|
||||
oss << ", pType : 0x" << std::hex << (int)unionDesc.getpType() << std::dec << " */";
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// read nonEncapUnionHeader
|
||||
RPC_GET_PROCESS_DATA(
|
||||
pType,
|
||||
&nonEncapUnionHeader,
|
||||
sizeof(nonEncapUnionHeader)
|
||||
);
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[defineTypeNonEncapsulatedUnion] ERROR : unable to get process data");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// display switch type
|
||||
switchType = (FC_TYPE) nonEncapUnionHeader.switchType;
|
||||
|
||||
|
||||
//// skip switch_is_description (already processed by processNonEncapsulatedUnion function)
|
||||
//pType += sizeof(nonEncapUnionHeader);
|
||||
//if(robustFlagWasSet)
|
||||
//{
|
||||
// pType += sizeof(CorrelationDescriptorRobust_t);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// pType += sizeof(CorrelationDescriptorRobust_t);
|
||||
//}
|
||||
|
||||
//// get offset to size_and_arm description
|
||||
//RPC_GET_PROCESS_DATA(
|
||||
// pType,
|
||||
// &offsetToSizeAndArmDescr,
|
||||
// sizeof(offsetToSizeAndArmDescr)
|
||||
//);
|
||||
//
|
||||
|
||||
|
||||
//pType += offsetToSizeAndArmDescr;
|
||||
|
||||
|
||||
|
||||
//pType = pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString + unionStrDesc.getuOffset() + sizeof(INT16);
|
||||
|
||||
pType = unionDesc.getRva();
|
||||
pType += sizeof(INT16); // skip memory size
|
||||
|
||||
|
||||
//Determine the number of member of the union
|
||||
RPC_GET_PROCESS_DATA(
|
||||
pType,
|
||||
&unionArmSeltorToPrint,
|
||||
sizeof(UnionArmSelector_t)
|
||||
);
|
||||
pType += sizeof(UnionArmSelector_t);
|
||||
|
||||
unionMemberCount = unionArmSeltorToPrint & UNION_ARM_SELTOR_NB_UNION_MEMBER_MASK;
|
||||
|
||||
|
||||
//start to print the union
|
||||
oss<<std::endl<<"\ttypedef [switch_type(";
|
||||
bResult = printSimpleType(pRpcDecompilerCtxt, switchType, oss);
|
||||
oss << ")] union union_"<<std::dec << (unionDesc.getRva() - pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString) <<std::endl; // TODO : clean
|
||||
oss << "\t{" << std::endl;
|
||||
|
||||
|
||||
/// print each union member
|
||||
bResult = printEachUnionMember(
|
||||
pContext,
|
||||
pType,
|
||||
unionDesc,
|
||||
unionMemberCount,
|
||||
FALSE, // type is NON encapsulated union
|
||||
listAdditionalTypes,
|
||||
oss);
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[ERROR]defineTypeNonEncapsulatedUnion : unable to print each union member");
|
||||
}
|
||||
|
||||
oss<<"\t} union_"<< (unionDesc.getRva() - pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString) <<";"<<std::endl<<std::endl;
|
||||
|
||||
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
BOOL __fastcall defineTypeEncapsulatedUnion(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const TypeToDefine& unionDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listAdditionalTypes,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
|
||||
EncapUnion_t encapUnionToPrint;
|
||||
UnionArmSelector_t unionArmSeltorToPrint;
|
||||
|
||||
UINT16 unionMemberCount = 0;
|
||||
UINT32 unionOffsetValueToContructTypeName = (UINT32)(pType - pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString);
|
||||
ParamDesc memberDesc;
|
||||
|
||||
RPC_GET_PROCESS_DATA(
|
||||
pType,
|
||||
&encapUnionToPrint,
|
||||
sizeof(EncapUnion_t)
|
||||
);
|
||||
|
||||
if(encapUnionToPrint.unionType != FC_ENCAPSULATED_UNION)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"\nPrintTypeUnionEncapsulated ERROR : unionType != FC_ENCAPSULATED_UNION");
|
||||
bResult = FALSE;
|
||||
goto End;
|
||||
}
|
||||
pType += sizeof(EncapUnion_t);
|
||||
|
||||
//Determine the number of member of the union
|
||||
RPC_GET_PROCESS_DATA(
|
||||
pType,
|
||||
&unionArmSeltorToPrint,
|
||||
sizeof(UnionArmSelector_t)
|
||||
);
|
||||
pType += sizeof(UnionArmSelector_t);
|
||||
|
||||
unionMemberCount = unionArmSeltorToPrint & UNION_ARM_SELTOR_NB_UNION_MEMBER_MASK;
|
||||
|
||||
//start to print the union
|
||||
oss<<"\n\ttypedef union union_"<< std::dec << unionOffsetValueToContructTypeName<<" switch (";
|
||||
|
||||
bResult = printSimpleType(pRpcDecompilerCtxt, (FC_TYPE)(encapUnionToPrint.switchType & ENCAP_UNION_SWITCH_TYPE_TYPE_MASK) , /* in/out */ oss);
|
||||
oss<<" discrim) U"<<unionOffsetValueToContructTypeName<<"_TYPE\n\t{\n";
|
||||
|
||||
/// print each union member
|
||||
bResult = printEachUnionMember(
|
||||
pContext,
|
||||
pType,
|
||||
unionDesc,
|
||||
unionMemberCount,
|
||||
TRUE, // type is encapsulated union
|
||||
listAdditionalTypes,
|
||||
oss);
|
||||
|
||||
if(bResult == FALSE)
|
||||
{
|
||||
RPC_DEBUG_FN((UCHAR*)"[defineTypeNonEncapsulatedUnion] : unable to print each union member");
|
||||
}
|
||||
|
||||
oss<<"\t}union_"<<unionOffsetValueToContructTypeName<<";"<<std::endl<<std::endl;
|
||||
|
||||
|
||||
End:
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
#ifndef _INTERNAL_COMPLEX_TYPES_UNIONS_H_
|
||||
#define _INTERNAL_COMPLEX_TYPES_UNIONS_H_
|
||||
|
||||
#include <sstream>
|
||||
#include "internalRpcDecompTypeDefs.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
BOOL __fastcall processNonEncapsulatedUnion(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
BOOL __fastcall getNonEncapsulatedUnionMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Out_ size_t* pszMemorySize,
|
||||
_In_ BOOL bHasRangeOnConformance);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
BOOL __fastcall processEncapsulatedUnion(
|
||||
_In_ VOID* pContext,
|
||||
_In_ const RVA_T pType,
|
||||
_In_ FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& ParamDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
BOOL __fastcall getEncapsulatedUnionMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Out_ size_t* pszMemorySize);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
BOOL __fastcall defineTypeNonEncapsulatedUnion(
|
||||
_In_ VOID* pContext,
|
||||
_In_ const TypeToDefine& unionDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
BOOL __fastcall defineTypeEncapsulatedUnion(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_In_ const TypeToDefine& unionDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
|
||||
#endif//_INTERNAL_COMPLEX_TYPES_UNIONS_H_
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,10 @@
|
|||
#ifndef _INTERNAL_RPC_DECOMP_TYPE_DEFS_H_NEW_
|
||||
#define _INTERNAL_RPC_DECOMP_TYPE_DEFS_H_NEW_
|
||||
|
||||
#include "internalRpcDecompTypeDefs.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,104 @@
|
|||
#ifndef _INTERNAL_RPC_DECOMPILER_H_
|
||||
#define _INTERNAL_RPC_DECOMPILER_H_
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "internalRpcDecompTypeDefs.h"
|
||||
|
||||
|
||||
//#define DBG_DECOMP
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BOOL __fastcall getAllTypesSortedInAList(
|
||||
_In_ VOID* pContext,
|
||||
_In_ std::list<TypeToDefine> & listTypesToDefine,
|
||||
_Inout_ std::list<TypeToDefine>& listAllTypesSorted,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
BOOL __fastcall dumpTypeList(
|
||||
_In_ VOID* pContext,
|
||||
_In_ std::list<TypeToDefine> & listTypesToDefine,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BOOL __fastcall RpcDecompilerPrintAllTypesInList(
|
||||
_In_ VOID* pContext,
|
||||
_In_ std::list<TypeToDefine> & listProcTypes,
|
||||
_Out_ std::ostringstream& oss);
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BOOL __fastcall RpcDecompilerDecodeAndPrintPrototypeReturnType(
|
||||
_In_ VOID* pContext,
|
||||
_In_ UINT ProcIndex,
|
||||
_Out_ UINT * paramOffset,
|
||||
_Out_ UINT * sizeOfProcDescr,
|
||||
_Inout_ IdlFunctionDesc& IdlFunctionDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcType,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL __fastcall RpcDecompilerPrintPrototypeName(
|
||||
_In_ VOID* pContext,
|
||||
_In_ UINT ProcIndex,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL __fastcall RpcDecompilerGetReturnParamInfo(
|
||||
_In_ VOID* pContext,
|
||||
_In_ UINT paramOffset,
|
||||
_In_ ParamID_E paramDescrFormat,
|
||||
_Out_ BOOL * isReturnParam);
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
DWORD __fastcall getSimpleTypeMemorySize(_In_ FC_TYPE fcType);
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
BOOL __fastcall processSimpleType(
|
||||
_In_ VOID* pContext,
|
||||
_In_ FC_TYPE fcType,
|
||||
_Inout_ ParamDesc& paramDesc,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL __fastcall printSimpleType(
|
||||
_In_ VOID* pContext,
|
||||
_In_ FC_TYPE fcType,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL __fastcall rpcDumpType(
|
||||
_In_ VOID* pContext,
|
||||
_In_ ParamDesc& paramDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL __fastcall getTypeMemorySize(
|
||||
_In_ VOID* pContext,
|
||||
_In_ RVA_T pType,
|
||||
_Out_ size_t* pszMemorySize,
|
||||
_In_ BOOL bHasRangeOnConformance);
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
BOOL __fastcall RpcDecompilerPrintParam(
|
||||
_In_ VOID* pContext,
|
||||
_In_ UINT paramOffset,
|
||||
_In_ ParamID_E paramDescrFormat,
|
||||
_Out_ UINT * paramSizeInBytes,
|
||||
_In_ const IdlFunctionDesc& IdlFunctionDesc,
|
||||
_Inout_ std::list<TypeToDefine>& listProcType,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
#endif//_INTERNAL_RPC_DECOMPILER_H_
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef _RPC_UTILS_
|
||||
#define _RPC_UTILS_
|
||||
|
||||
#include <string>
|
||||
#include <locale>
|
||||
#include <vector>
|
||||
#include <tchar.h>
|
||||
#include "RpcDecompiler.h"
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall isStandardCharacter(_In_ const WCHAR wc);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
std::string narrow(
|
||||
_In_ const std::wstring& ws);
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
VOID displayPtrLevel(
|
||||
_In_ const UINT uPtrLevel,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
VOID displayErrorMessage(
|
||||
_Inout_ std::ostringstream& oss,
|
||||
_In_ PCHAR message);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,180 @@
|
|||
#include "..\RpcCommon\RpcView.h"
|
||||
#include "internalRpcDecompTypeDefs.h"
|
||||
#include "internalTypeTools.h"
|
||||
#include "internalComplexTypesArrays.h"
|
||||
#include "internalComplexTypesPointers.h"
|
||||
#include "internalComplexTypesStrings.h"
|
||||
#include "internalComplexTypesStructs.h"
|
||||
#include "internalComplexTypesUnions.h"
|
||||
#include "internalRpcUtils.h"
|
||||
|
||||
#define DEFAULT_ENUM "\n\
|
||||
/* \n\
|
||||
// this is the default enum referenced by all functions and structures using an enum \n\
|
||||
typedef enum enum32_toDefine_t\n\
|
||||
{\n\
|
||||
value_0 = 0,\n\
|
||||
value_1 = 1,\n\
|
||||
//...\n\
|
||||
}enum32_toDefine_t;\n\
|
||||
*/\n"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void __fastcall printDefaultEnum(
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
|
||||
oss <<DEFAULT_ENUM;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL __fastcall isSimpleType(
|
||||
_In_ FC_TYPE type)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
|
||||
if( type == FC_BYTE ||
|
||||
type == FC_CHAR ||
|
||||
type == FC_SMALL ||
|
||||
type == FC_USMALL ||
|
||||
type == FC_WCHAR ||
|
||||
type == FC_SHORT ||
|
||||
type == FC_USHORT ||
|
||||
type == FC_LONG ||
|
||||
type == FC_ULONG ||
|
||||
type == FC_FLOAT ||
|
||||
type == FC_HYPER ||
|
||||
type == FC_DOUBLE ||
|
||||
type == FC_ENUM16 ||
|
||||
type == FC_ENUM32 ||
|
||||
type == FC_ERROR_STATUS_T ||
|
||||
type == FC_INT3264 ||
|
||||
type == FC_UINT3264 ||
|
||||
type == FC_IGNORE
|
||||
)
|
||||
{
|
||||
bResult = TRUE;
|
||||
}
|
||||
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL __fastcall printType(
|
||||
_In_ VOID* pContext,
|
||||
_In_ TypeToDefine& typeToDefine,
|
||||
_Inout_ std::list<TypeToDefine>& listAdditionalType,
|
||||
_Inout_ std::ostringstream& oss)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
||||
|
||||
RVA_T pType;
|
||||
|
||||
if (pRpcDecompilerCtxt == NULL) return FALSE;
|
||||
if (pRpcDecompilerCtxt->pRpcViewHelper == NULL) return FALSE;
|
||||
|
||||
if(pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString == NULL) return FALSE;
|
||||
|
||||
RPC_DEBUG_FN((UCHAR*)"\n\n******************** printType *********************");
|
||||
|
||||
|
||||
|
||||
pType = typeToDefine.getRva();
|
||||
|
||||
//RPC_GET_PROCESS_DATA(
|
||||
// pType,
|
||||
// &elementType,
|
||||
// sizeof(BYTE)
|
||||
// );
|
||||
|
||||
#ifdef DBG_DECOMP
|
||||
oss << std::endl << "/* pType : 0x"<<std::hex<<(LONGLONG)typeToDefine.getpType() ;
|
||||
if(typeToDefine.getFcType() == FC_NON_ENCAPSULATED_UNION)
|
||||
{
|
||||
oss << " pNonEncapUnionheader : 0x"<<(LONGLONG)typeToDefine.getpNonEncapuslatedUnionHeader();
|
||||
}
|
||||
oss << std::dec<<" */"<< std::endl;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
switch(typeToDefine.getFcType())
|
||||
{
|
||||
//
|
||||
// structures
|
||||
//
|
||||
case FC_STRUCT:
|
||||
bResult = defineTypeSimpleStruct(pContext, pType, typeToDefine, listAdditionalType, oss);
|
||||
//PrintTypeSimpleStructure(pContext, pType, typeOfContainer, listAdditionalType, oss);
|
||||
break;
|
||||
|
||||
case FC_PSTRUCT:
|
||||
#ifdef DBG_DECOMP
|
||||
oss << std::endl << "\t/* process FC_PSTRUCT */" << std::endl;
|
||||
#endif
|
||||
bResult = defineTypeSimpleStruct(pContext, pType, typeToDefine, listAdditionalType, oss);
|
||||
break;
|
||||
|
||||
|
||||
case FC_CSTRUCT:
|
||||
bResult = defineTypeConformantStructure(pContext, pType, typeToDefine, listAdditionalType, oss);
|
||||
//PrintTypeConformantStructure(pContext, pType, typeOfContainer, listAdditionalType, oss);
|
||||
break;
|
||||
|
||||
case FC_CPSTRUCT:
|
||||
oss << std::endl << "\t/* [TO_CHECK] FC_CPSTRUCT */" << std::endl;
|
||||
bResult = defineTypeConformantStructure(pContext, pType, typeToDefine, listAdditionalType, oss);
|
||||
break;
|
||||
|
||||
case FC_CVSTRUCT:
|
||||
oss << std::endl << "\t/* [ERROR] FC_CVSTRUCT are currently not implemented */" << std::endl;
|
||||
break;
|
||||
|
||||
case FC_BOGUS_STRUCT:
|
||||
bResult = defineTypeComplexStruct(pContext, pType, typeToDefine, listAdditionalType, oss);
|
||||
break;
|
||||
|
||||
case FC_HARD_STRUCT:
|
||||
oss << std::endl <<"\t /* FC_HARD_STRUCT processed as a FC_BOGUS_STRUC */ " << std::endl;
|
||||
bResult = defineTypeComplexStruct(pContext, pType, typeToDefine, listAdditionalType, oss);
|
||||
break;
|
||||
//
|
||||
// unions
|
||||
//
|
||||
case FC_ENCAPSULATED_UNION:
|
||||
|
||||
bResult = defineTypeEncapsulatedUnion(
|
||||
pContext,
|
||||
pType,
|
||||
typeToDefine,
|
||||
listAdditionalType,
|
||||
oss);
|
||||
break;
|
||||
|
||||
|
||||
case FC_NON_ENCAPSULATED_UNION:
|
||||
|
||||
bResult = defineTypeNonEncapsulatedUnion(
|
||||
pContext,
|
||||
typeToDefine,
|
||||
listAdditionalType,
|
||||
oss);
|
||||
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
oss << "PrintType : bad type given. Should be Struct or Union only. given type : "<< std::hex << (int)typeToDefine.getFcType() << std::endl;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef _INTERNAL_TYPE_TOOLS_H_
|
||||
#define _INTERNAL_TYPE_TOOLS_H_
|
||||
|
||||
#include <sstream>
|
||||
#include <list>
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
BOOL __fastcall isSimpleType(
|
||||
_In_ FC_TYPE type);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL __fastcall printType(
|
||||
_In_ VOID* pContext,
|
||||
_In_ TypeToDefine& typeToDefine,
|
||||
_Inout_ std::list<TypeToDefine>& listAdditionalType,
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void __fastcall printDefaultEnum(
|
||||
_Inout_ std::ostringstream& oss);
|
||||
|
||||
|
||||
#endif//_INTERNAL_TYPE_TOOLS_H_
|
|
@ -0,0 +1,54 @@
|
|||
cmake_minimum_required (VERSION 3.0.2)
|
||||
|
||||
message("[RpcView]")
|
||||
|
||||
project(RpcView)
|
||||
|
||||
# Find includes in corresponding build directories
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
# Instruct CMake to run moc automatically when needed.
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
# Find the QtWidgets library
|
||||
# set CMAKE_PREFIX_PATH=c:\Qt\4.8.6
|
||||
find_package(Qt4 REQUIRED QtGui QtCore)
|
||||
|
||||
add_executable(
|
||||
RpcView
|
||||
|
||||
"${PROJECT_BINARY_DIR}/../RpcViewVersion.h"
|
||||
DecompilationWidget.cpp
|
||||
EndpointsWidget.cpp
|
||||
FilterWidget.cpp
|
||||
IdlHighlighter.cpp
|
||||
InterfaceInfoWidget.cpp
|
||||
InterfacesWidget.cpp
|
||||
MainWindow.cpp
|
||||
../RpcCommon/Misc.c
|
||||
../RpcCommon/ntdll.c
|
||||
Pdb.c
|
||||
ProceduresWidget.cpp
|
||||
ProcessInfoWidget.cpp
|
||||
ProcessWidget.cpp
|
||||
|
||||
ConfigurationVisitor.cpp
|
||||
EndpointSelectedVisitor.cpp
|
||||
InitViewsVisitor.cpp
|
||||
InterfaceSelectedVisitor.cpp
|
||||
ProcessSelectedVisitor.cpp
|
||||
RefreshVisitor.cpp
|
||||
|
||||
RpcCoreManager.c
|
||||
RpcView.cpp
|
||||
RpcViewResource.rc
|
||||
)
|
||||
|
||||
if(${CMAKE_GENERATOR} MATCHES "Win64")
|
||||
message(STATUS "Target is 64 bits")
|
||||
target_link_libraries(RpcView ../../../Qt/lib/x64/QtGui ../../../Qt/lib/x64/QtCore)
|
||||
target_link_libraries(RpcView Qt4::QtGui Qt4::QtCore)
|
||||
else(${CMAKE_GENERATOR} MATCHES "Win64")
|
||||
message(STATUS "Target is 32 bits")
|
||||
target_link_libraries(RpcView ../../../Qt/lib/x86/QtGui ../../../Qt/lib/x86/QtCore)
|
||||
target_link_libraries(RpcView Qt4::QtGui Qt4::QtCore)
|
||||
endif(${CMAKE_GENERATOR} MATCHES "Win64")
|
|
@ -0,0 +1,144 @@
|
|||
#include "ConfigurationVisitor.h"
|
||||
#include "EndpointsWidget.h"
|
||||
#include "InterfacesWidget.h"
|
||||
#include "InterfaceInfoWidget.h"
|
||||
#include "ProcessWidget.h"
|
||||
#include "ProcessInfoWidget.h"
|
||||
#include "ProceduresWidget.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ConfigurationVisitor_C::ConfigurationVisitor_C(ConfigurationType_T ConfigurationType, QSettings* pSettings)
|
||||
{
|
||||
this->pSettings = pSettings;
|
||||
this->ConfigurationType = ConfigurationType;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ConfigurationVisitor_C::Visit(EndpointsWidget_C* pEndpointsWidget)
|
||||
{
|
||||
switch (ConfigurationType)
|
||||
{
|
||||
case Load:
|
||||
pEndpointsWidget->LoadConfiguration(this->pSettings);
|
||||
break;
|
||||
//--
|
||||
case Save:
|
||||
pEndpointsWidget->SaveConfiguration(this->pSettings);
|
||||
break;
|
||||
//--
|
||||
case UpdateColumns:
|
||||
pEndpointsWidget->UpdateColumnsVisibility();
|
||||
break;
|
||||
//
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ConfigurationVisitor_C::Visit(InterfacesWidget_C* pInterfacesWidget)
|
||||
{
|
||||
switch (ConfigurationType)
|
||||
{
|
||||
case Load:
|
||||
pInterfacesWidget->LoadConfiguration(this->pSettings);
|
||||
break;
|
||||
//--
|
||||
case Save:
|
||||
pInterfacesWidget->SaveConfiguration(this->pSettings);
|
||||
break;
|
||||
//--
|
||||
case UpdateColumns:
|
||||
pInterfacesWidget->UpdateColumnsVisibility();
|
||||
break;
|
||||
//--
|
||||
case AddressRVA:
|
||||
pInterfacesWidget->SetAddressRepresentation(AddressRepresentation_RVA);
|
||||
break;
|
||||
//--
|
||||
case AddressAbsolute:
|
||||
pInterfacesWidget->SetAddressRepresentation(AddressRepresentation_Absolute);
|
||||
break;
|
||||
//--
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ConfigurationVisitor_C::Visit(InterfaceInfoWidget_C* pInterfaceInfoWidget)
|
||||
{
|
||||
switch (ConfigurationType)
|
||||
{
|
||||
case AddressRVA:
|
||||
pInterfaceInfoWidget->SetAddressRepresentation(AddressRepresentation_RVA);
|
||||
break;
|
||||
//--
|
||||
case AddressAbsolute:
|
||||
pInterfaceInfoWidget->SetAddressRepresentation(AddressRepresentation_Absolute);
|
||||
break;
|
||||
//--
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ConfigurationVisitor_C::Visit(ProcessInfoWidget_C* pProcessInfoWidget)
|
||||
{
|
||||
//nothing to do here
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ConfigurationVisitor_C::Visit(ProceduresWidget_C* pProceduresWidget)
|
||||
{
|
||||
switch (ConfigurationType)
|
||||
{
|
||||
case Load:
|
||||
pProceduresWidget->LoadConfiguration(this->pSettings);
|
||||
break;
|
||||
//--
|
||||
case Save:
|
||||
pProceduresWidget->SaveConfiguration(this->pSettings);
|
||||
break;
|
||||
//--
|
||||
case UpdateColumns:
|
||||
pProceduresWidget->UpdateColumnsVisibility();
|
||||
break;
|
||||
//--
|
||||
case AddressRVA:
|
||||
pProceduresWidget->SetAddressRepresentation(AddressRepresentation_RVA);
|
||||
break;
|
||||
//--
|
||||
case AddressAbsolute:
|
||||
pProceduresWidget->SetAddressRepresentation(AddressRepresentation_Absolute);
|
||||
break;
|
||||
//--
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ConfigurationVisitor_C::Visit(ProcessWidget_C* pProcessWidget)
|
||||
{
|
||||
switch (ConfigurationType)
|
||||
{
|
||||
case Load:
|
||||
pProcessWidget->LoadConfiguration(this->pSettings);
|
||||
break;
|
||||
//--
|
||||
case Save:
|
||||
pProcessWidget->SaveConfiguration(this->pSettings);
|
||||
break;
|
||||
//--
|
||||
case UpdateColumns:
|
||||
pProcessWidget->UpdateColumnsVisibility();
|
||||
break;
|
||||
//
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef _CONFIGURATION_VISITOR_H_
|
||||
#define _CONFIGURATION_VISITOR_H_
|
||||
|
||||
#include "../Qt/Qt.h"
|
||||
#include "ViewVisitor.h"
|
||||
#include "ProcessEntry.h"
|
||||
#include "..\RpcCore\RpcCore.h"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class ConfigurationVisitor_C : public ViewVisitor_C
|
||||
{
|
||||
public:
|
||||
typedef enum {
|
||||
Load,
|
||||
Save,
|
||||
UpdateColumns,
|
||||
AddressAbsolute,
|
||||
AddressRVA
|
||||
}ConfigurationType_T;
|
||||
|
||||
ConfigurationVisitor_C(ConfigurationType_T, QSettings*);
|
||||
|
||||
virtual void Visit(EndpointsWidget_C* pEndpointsWidget);
|
||||
virtual void Visit(InterfacesWidget_C* pInterfacesWidget);
|
||||
virtual void Visit(InterfaceInfoWidget_C* pInterfaceInfoWidget);
|
||||
virtual void Visit(ProcessInfoWidget_C* pProcessInfoWidget);
|
||||
virtual void Visit(ProceduresWidget_C* pProceduresWidget);
|
||||
virtual void Visit(ProcessWidget_C* pProcessWidget);
|
||||
|
||||
private:
|
||||
QSettings* pSettings;
|
||||
ConfigurationType_T ConfigurationType;
|
||||
};
|
||||
|
||||
#endif //_CONFIGURATION_VISITOR_H_
|
|
@ -0,0 +1,37 @@
|
|||
#include "DecompilationWidget.h"
|
||||
|
||||
#define TAB_AS_CHARS 4
|
||||
|
||||
static const char WidgetName[] = "Decompilation";
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void DecompilationWidget_C::InsertText(const char* Txt)
|
||||
{
|
||||
/*
|
||||
pTextEdit->moveCursor(QTextCursor::End);
|
||||
pTextEdit->append( QString::fromAscii(Txt) );
|
||||
pTextEdit->ensureCursorVisible();
|
||||
*/
|
||||
pTextEdit->setText( QString::fromAscii(Txt) );
|
||||
pTextEdit->ensureCursorVisible();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
DecompilationWidget_C::DecompilationWidget_C(QWidget *parent) : QDockWidget(WidgetName)
|
||||
{
|
||||
QFont font;
|
||||
|
||||
setObjectName(WidgetName);
|
||||
|
||||
font.setFamily("Courier");
|
||||
font.setFixedPitch(true);
|
||||
|
||||
pTextEdit = new QTextEdit(this);
|
||||
pTextEdit->setLineWrapMode(QTextEdit::NoWrap);
|
||||
pTextEdit->setFont(font);
|
||||
pTextEdit->setTabStopWidth(font.pointSize()*TAB_AS_CHARS);
|
||||
|
||||
pIdlHighlighter = new IdlHighlighter_C(pTextEdit->document());
|
||||
setWidget(pTextEdit);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef _DECOMPILATION_WIDGET_H_
|
||||
#define _DECOMPILATION_WIDGET_H_
|
||||
|
||||
#include "../Qt/Qt.h"
|
||||
#include "IdlHighlighter.h"
|
||||
|
||||
class DecompilationWidget_C : public QDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DecompilationWidget_C(QWidget* pParent);
|
||||
void InsertText(const char* Txt);
|
||||
|
||||
private:
|
||||
IdlHighlighter_C* pIdlHighlighter;
|
||||
QTextEdit* pTextEdit;
|
||||
};
|
||||
|
||||
#endif //_DECOMPILATION_WIDGET_H_
|
|
@ -0,0 +1,102 @@
|
|||
#include "EndpointSelectedVisitor.h"
|
||||
#include "EndpointsWidget.h"
|
||||
#include "InterfacesWidget.h"
|
||||
#include "InterfaceInfoWidget.h"
|
||||
#include "ProcessWidget.h"
|
||||
#include "ProcessInfoWidget.h"
|
||||
#include "ProceduresWidget.h"
|
||||
#include "../RpcCommon/Misc.h"
|
||||
|
||||
|
||||
typedef struct _EnumCtxt_T{
|
||||
ProcessInfoWidget_C* pProcessInfoWidget;
|
||||
}EnumCtxt_T;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
EndpointSelectedVisitor_C::EndpointSelectedVisitor_C(quint32 Pid,RpcCore_T* pRpcCore,void* pRpcCoreCtxt)
|
||||
{
|
||||
this->Pid = Pid;
|
||||
this->pRpcCore = pRpcCore;
|
||||
this->pRpcCoreCtxt = pRpcCoreCtxt;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointSelectedVisitor_C::Visit(EndpointsWidget_C* pEndpointsWidget)
|
||||
{
|
||||
//nothing to do here
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointSelectedVisitor_C::Visit(InterfacesWidget_C* pInterfacesWidget)
|
||||
{
|
||||
//
|
||||
// Apply process filter
|
||||
//
|
||||
pInterfacesWidget->ApplyProcessFilter(Pid);
|
||||
pInterfacesWidget->resizeColumnsToContents();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointSelectedVisitor_C::Visit(InterfaceInfoWidget_C* pInterfaceInfoWidget)
|
||||
{
|
||||
//
|
||||
// if the Pid of the selected endpoint is different from the current
|
||||
// interface one we ave to reset the InterfaceInfoWidget
|
||||
//
|
||||
if (this->Pid != pInterfaceInfoWidget->GetPid())
|
||||
{
|
||||
pInterfaceInfoWidget->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static BOOL __fastcall EnumProcessAuth(DWORD Pid, RpcAuthInfo_T* pRpcAuthInfo, EnumCtxt_T* pEnumCtxt, BOOL* pbContinue)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Pid);
|
||||
UNREFERENCED_PARAMETER(pbContinue);
|
||||
|
||||
pEnumCtxt->pProcessInfoWidget->AddAuthInfo(pRpcAuthInfo);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointSelectedVisitor_C::Visit(ProcessInfoWidget_C* pProcessInfoWidget)
|
||||
{
|
||||
RpcProcessInfo_T* pRpcProcessInfo;
|
||||
EnumCtxt_T EnumCtxt;
|
||||
|
||||
EnumCtxt.pProcessInfoWidget = pProcessInfoWidget;
|
||||
pProcessInfoWidget->reset();
|
||||
|
||||
pRpcProcessInfo = pRpcCore->RpcCoreGetProcessInfoFn( pRpcCoreCtxt, Pid, 0, RPC_PROCESS_INFO_ALL );
|
||||
if (pRpcProcessInfo != NULL)
|
||||
{
|
||||
pProcessInfoWidget->UpdateProcessInfo(pRpcProcessInfo);
|
||||
pRpcCore->RpcCoreFreeProcessInfoFn( pRpcCoreCtxt, pRpcProcessInfo );
|
||||
pRpcCore->RpcCoreEnumProcessAuthInfoFn( pRpcCoreCtxt, Pid, (RpcCoreEnumProcessAuthInfoCallbackFn_T)EnumProcessAuth,&EnumCtxt);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointSelectedVisitor_C::Visit(ProceduresWidget_C* pProceduresWidget)
|
||||
{
|
||||
//
|
||||
// if the Pid of the selected endpoint is different from the current
|
||||
// procedure one we ave to reset the ProcedureWidget
|
||||
//
|
||||
if (this->Pid != pProceduresWidget->GetPid())
|
||||
{
|
||||
pProceduresWidget->reset(this->Pid);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointSelectedVisitor_C::Visit(ProcessWidget_C* pProcessWidget)
|
||||
{
|
||||
pProcessWidget->SelectProcess(Pid);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef _ENDPOINT_SELECTED_VISITOR_H_
|
||||
#define _ENDPOINT_SELECTED_VISITOR_H_
|
||||
|
||||
#include "..\Qt\Qt.h"
|
||||
#include "ViewVisitor.h"
|
||||
#include "..\RpcCore\RpcCore.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class EndpointSelectedVisitor_C : public ViewVisitor_C
|
||||
{
|
||||
private:
|
||||
RpcCore_T* pRpcCore;
|
||||
void* pRpcCoreCtxt;
|
||||
quint32 Pid;
|
||||
public:
|
||||
EndpointSelectedVisitor_C(quint32 Pid,RpcCore_T* pRpcCore,void* pRpcCoreCtxt);
|
||||
virtual void Visit(EndpointsWidget_C* pEndpointsWidget);
|
||||
virtual void Visit(InterfacesWidget_C* pInterfacesWidget);
|
||||
virtual void Visit(InterfaceInfoWidget_C* pInterfaceInfoWidget);
|
||||
virtual void Visit(ProcessInfoWidget_C* pProcessInfoWidget);
|
||||
virtual void Visit(ProceduresWidget_C* pProceduresWidget);
|
||||
virtual void Visit(ProcessWidget_C* pProcessWidget);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,265 @@
|
|||
#include "EndpointsWidget.h"
|
||||
#include "..\RpcCommon\RpcCommon.h"
|
||||
|
||||
|
||||
static const char WidgetName[] = "Endpoints";
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QString EndpointsWidget_C::GetEndpointsWidgetColumnName(Column_T Column)
|
||||
{
|
||||
switch(Column)
|
||||
{
|
||||
case Column_Pid : return (QString("Pid"));
|
||||
case Column_Protocol: return (QString("Protocol"));
|
||||
case Column_Name : return (QString("Name"));
|
||||
default : return (QString("Unknown"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointsWidget_C::EndpointSelected(const QModelIndex& Index)
|
||||
{
|
||||
quint32 Pid;
|
||||
|
||||
Pid = pProxyModel->data(pProxyModel->index(Index.row(), Column_Pid)).toUInt();
|
||||
//
|
||||
// Emit the EndpointSelected signal so that the MainWindow sends
|
||||
// the appropriate visitor
|
||||
//
|
||||
emit EndpointSelected(Pid);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointsWidget_C::ApplyProcessFilter(quint32 Pid)
|
||||
{
|
||||
if (Pid == INVALID_PID_VALUE)
|
||||
{
|
||||
pProxyModel->setFilterRegExp( QRegExp(".*") );
|
||||
}
|
||||
else
|
||||
{
|
||||
pProxyModel->setFilterRegExp( QString("^%1$").arg(Pid) );
|
||||
if (pProxyModel->rowCount() == 0) pProxyModel->setFilterRegExp( QRegExp(".*") );
|
||||
}
|
||||
pFilterWidget->Reset();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG EndpointsWidget_C::GetEndpoints()
|
||||
{
|
||||
return (ULONG)pProxyModel->rowCount();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG EndpointsWidget_C::GetTotalEndpoints()
|
||||
{
|
||||
return (ULONG)pModel->rowCount();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointsWidget_C::SnapEndpoint()
|
||||
{
|
||||
PrivateItemList = pModel->findItems(".*", Qt::MatchRegExp, Column_Name);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointsWidget_C::RemoveUnregisteredEndpoints()
|
||||
{
|
||||
for (auto Iter=PrivateItemList.begin();Iter!=PrivateItemList.end();Iter++)
|
||||
{
|
||||
if (*Iter!=NULL) pModel->removeRow( (*Iter)->row());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool EndpointsWidget_C::IsEndpointsPresent(quint32 Pid, WCHAR* pName,WCHAR* pProtocole)
|
||||
{
|
||||
QList<QStandardItem*> ItemList;
|
||||
bool bResult = false;
|
||||
|
||||
ItemList = pModel->findItems(QString::fromUtf16((const ushort*)pName), Qt::MatchFixedString, Column_Name);
|
||||
if (ItemList.isEmpty()) goto End;
|
||||
|
||||
for (auto Iter=ItemList.begin();Iter!=ItemList.end();Iter++)
|
||||
{
|
||||
if (*Iter!=NULL)
|
||||
{
|
||||
if (pModel->data(pModel->index((*Iter)->row(), Column_Protocol)).toString() == QString::fromUtf16((const ushort*)pProtocole))
|
||||
{
|
||||
PrivateItemList.removeOne(*Iter);
|
||||
|
||||
bResult = true;
|
||||
goto End;
|
||||
}
|
||||
}
|
||||
}
|
||||
End:
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointsWidget_C::SaveConfiguration(QSettings* pSettings)
|
||||
{
|
||||
pSettings->setValue("Endpoints/geometry",pEndpoints->header()->saveState());
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointsWidget_C::LoadConfiguration(QSettings* pSettings)
|
||||
{
|
||||
pEndpoints->header()->restoreState( pSettings->value("Endpoints/geometry").toByteArray() );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointsWidget_C::resizeColumnsToContents()
|
||||
{
|
||||
int Index;
|
||||
|
||||
for (Index = 0; Index < Column_Last; Index++)
|
||||
{
|
||||
pEndpoints->resizeColumnToContents(Index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool EndpointsWidget_C::AddEndpoint(quint32 Pid, RpcEndpointInfo_T* pRpcEndpointInfo)
|
||||
{
|
||||
int Index;
|
||||
|
||||
Index = pModel->rowCount();
|
||||
pModel->setRowCount(Index+1);
|
||||
pModel->setData(pModel->index(Index, EndpointsWidget_C::Column_Pid), Pid);
|
||||
pModel->setData(pModel->index(Index, EndpointsWidget_C::Column_Protocol), QString::fromUtf16((const ushort*)pRpcEndpointInfo->pProtocole));
|
||||
pModel->setData(pModel->index(Index, EndpointsWidget_C::Column_Name), QString::fromUtf16((const ushort*)pRpcEndpointInfo->pName));
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointsWidget_C::AcceptVisitor(ViewVisitor_C* pVisitor)
|
||||
{
|
||||
pVisitor->Visit(this);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointsWidget_C::UpdateUserFilter()
|
||||
{
|
||||
if (pFilterWidget->GetText()!="") ApplyUserFilter( pFilterWidget->GetText() );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointsWidget_C::ApplyUserFilter(const QString & FilterText)
|
||||
{
|
||||
QRegExp FilterRegExp;
|
||||
|
||||
FilterRegExp.setPattern( FilterText );
|
||||
FilterRegExp.setCaseSensitivity( Qt::CaseInsensitive );
|
||||
|
||||
pProxyModel->setFilterKeyColumn(-1); //filter all columns: UGLY Qt
|
||||
pProxyModel->setFilterRegExp( FilterRegExp );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointsWidget_C::CreateColumnsSelectionWidget()
|
||||
{
|
||||
pColumnsSelectionWidget = new QGroupBox(WidgetName,this);
|
||||
QVBoxLayout* pLayout = new QVBoxLayout(pColumnsSelectionWidget);
|
||||
|
||||
for (int i = 0; i < Column_Last; i++)
|
||||
{
|
||||
CheckBoxArray[i] = new QCheckBox(GetEndpointsWidgetColumnName((Column_T)i),this);
|
||||
pLayout->addWidget(CheckBoxArray[i]);
|
||||
}
|
||||
pColumnsSelectionWidget->setLayout(pLayout);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QWidget* EndpointsWidget_C::GetColumnsSelectionWidget()
|
||||
{
|
||||
for (int i = 0; i < Column_Last; i++)
|
||||
{
|
||||
CheckBoxArray[i]->setChecked(!pEndpoints->header()->isSectionHidden(i));
|
||||
}
|
||||
return pColumnsSelectionWidget;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void EndpointsWidget_C::UpdateColumnsVisibility()
|
||||
{
|
||||
for (int i = 0; i < Column_Last; i++)
|
||||
{
|
||||
pEndpoints->header()->setSectionHidden(i, !CheckBoxArray[i]->isChecked());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
EndpointsWidget_C::EndpointsWidget_C(QWidget* pParent):QDockWidget(WidgetName)
|
||||
{
|
||||
QGridLayout* pGridLayout;
|
||||
QGroupBox* pGroupBox;
|
||||
|
||||
setObjectName(WidgetName);
|
||||
|
||||
pGroupBox = new QGroupBox(this);
|
||||
pGridLayout = new QGridLayout;
|
||||
|
||||
pProxyModel = new QSortFilterProxyModel(this);
|
||||
pProxyModel->setDynamicSortFilter(true);
|
||||
pProxyModel->setFilterKeyColumn(Column_Pid);
|
||||
pProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
|
||||
pModel = new QStandardItemModel(0, Column_Last, this);
|
||||
|
||||
for (uint i = 0; i<Column_Last; i++)
|
||||
{
|
||||
pModel->setHeaderData(i, Qt::Horizontal, GetEndpointsWidgetColumnName( (EndpointsWidget_C::Column_T)i ) );
|
||||
}
|
||||
|
||||
pEndpoints = new QTreeView;
|
||||
pEndpoints->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
pEndpoints->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
pEndpoints->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
pEndpoints->setRootIsDecorated(false);
|
||||
pEndpoints->setSortingEnabled(true);
|
||||
pEndpoints->setAlternatingRowColors(true);
|
||||
pEndpoints->setAnimated(true);
|
||||
pEndpoints->setModel(pProxyModel);
|
||||
pEndpoints->sortByColumn(Column_Protocol, Qt::AscendingOrder);
|
||||
pEndpoints->header()->installEventFilter(pParent);
|
||||
|
||||
pProxyModel->setSourceModel(pModel);
|
||||
|
||||
connect( pEndpoints, SIGNAL(pressed(const QModelIndex&)), this, SLOT(EndpointSelected(const QModelIndex&)));
|
||||
connect( pEndpoints, SIGNAL(activated(const QModelIndex&)), this, SLOT(EndpointSelected(const QModelIndex&)));
|
||||
connect( this, SIGNAL(EndpointSelected(quint32)), pParent, SLOT(EndpointSelected(quint32)) );
|
||||
//
|
||||
// Add user filtering (CTL+F) support
|
||||
//
|
||||
pFilterWidget = new FilterWidget_C(this);
|
||||
|
||||
pGridLayout->addWidget(pEndpoints,0,0);
|
||||
pGridLayout->addWidget(pFilterWidget,1,0);
|
||||
pGroupBox->setLayout(pGridLayout);
|
||||
setWidget(pGroupBox);
|
||||
//
|
||||
// Create the Widget for column selection
|
||||
//
|
||||
CreateColumnsSelectionWidget();
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
#ifndef _ENDPOINTS_WIDGET_H_
|
||||
#define _ENDPOINTS_WIDGET_H_
|
||||
|
||||
#include "..\Qt\Qt.h"
|
||||
#include "..\RpcCore\RpcCore.h"
|
||||
#include "FilterWidget.h"
|
||||
#include "View.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class EndpointsWidget_C : public QDockWidget, public View_I
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EndpointsWidget_C(QWidget* pParent);
|
||||
|
||||
virtual void AcceptVisitor(ViewVisitor_C* pVisitor);
|
||||
void ApplyProcessFilter(quint32 Pid);
|
||||
ULONG GetEndpoints();
|
||||
ULONG GetTotalEndpoints();
|
||||
bool IsEndpointsPresent(quint32 Pid, WCHAR* pName,WCHAR* pProtocol);
|
||||
void RemoveUnregisteredEndpoints();
|
||||
void SnapEndpoint();
|
||||
void resizeColumnsToContents();
|
||||
bool AddEndpoint(quint32 Pid, RpcEndpointInfo_T* pRpcEndpointInfo);
|
||||
void UpdateUserFilter();
|
||||
void SaveConfiguration(QSettings*);
|
||||
void LoadConfiguration(QSettings*);
|
||||
QWidget* GetColumnsSelectionWidget();
|
||||
void UpdateColumnsVisibility();
|
||||
void CreateColumnsSelectionWidget();
|
||||
|
||||
public slots:
|
||||
void ApplyUserFilter(const QString &);
|
||||
|
||||
private slots:
|
||||
void EndpointSelected(const QModelIndex&);
|
||||
|
||||
signals:
|
||||
void EndpointSelected(quint32 Pid);
|
||||
|
||||
private:
|
||||
|
||||
typedef enum{
|
||||
Column_Pid,
|
||||
Column_Protocol,
|
||||
Column_Name,
|
||||
Column_Last
|
||||
}Column_T;
|
||||
|
||||
FilterWidget_C* pFilterWidget;
|
||||
QTreeView* pEndpoints;
|
||||
QSortFilterProxyModel* pProxyModel;
|
||||
QStandardItemModel* pModel;
|
||||
QList<QStandardItem*> PrivateItemList;
|
||||
//--
|
||||
QGroupBox* pColumnsSelectionWidget;
|
||||
QCheckBox* CheckBoxArray[Column_Last];
|
||||
|
||||
QString GetEndpointsWidgetColumnName(Column_T Column);
|
||||
};
|
||||
|
||||
#endif// _ENDPOINTS_WIDGET_H_
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef _EULA_DIALOG_H_
|
||||
#define _EULA_DIALOG_H_
|
||||
|
||||
#include "..\Qt\Qt.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class EulaDialog_C : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EulaDialog_C();
|
||||
|
||||
private:
|
||||
QGridLayout* pGridLayout;
|
||||
QTextEdit* pTextEdit;
|
||||
QPushButton* pAccept;
|
||||
QPushButton* pDecline;
|
||||
};
|
||||
|
||||
#endif// _EULA_DIALOG_H_
|
|
@ -0,0 +1,63 @@
|
|||
#include "FilterWidget.h"
|
||||
#include "RpcViewResource.h"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void FilterWidget_C::Show()
|
||||
{
|
||||
this->show();
|
||||
pUserFilter->setFocus();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void FilterWidget_C::Reset()
|
||||
{
|
||||
pUserFilter->clear();
|
||||
this->hide();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
const QString FilterWidget_C::GetText()
|
||||
{
|
||||
return ( pUserFilter->text() );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void FilterWidget_C::Hide()
|
||||
{
|
||||
this->hide();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
FilterWidget_C::FilterWidget_C(QWidget* pParent)
|
||||
{
|
||||
QAction* pFindAction = new QAction(this);
|
||||
QAction* pEchapAction = new QAction(this);
|
||||
QLabel* pFilterLabel = new QLabel("Filter: ",this);
|
||||
|
||||
pFindAction->setShortcut(QKeySequence::Find);
|
||||
pFindAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
||||
pParent->addAction( pFindAction );
|
||||
|
||||
pEchapAction->setShortcut(QKeySequence(tr("Esc")));
|
||||
pEchapAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
||||
pParent->addAction( pEchapAction );
|
||||
|
||||
connect( pFindAction, SIGNAL(triggered(bool)), this, SLOT(Show()));
|
||||
connect( pEchapAction, SIGNAL(triggered(bool)), this, SLOT(Hide()));
|
||||
|
||||
QGridLayout* pFilterLayout = new QGridLayout(this);
|
||||
|
||||
pUserFilter = new QLineEdit(this);
|
||||
pMatchingItems = new QLabel(this);
|
||||
pFilterLayout->addWidget(pFilterLabel, 0, 0);
|
||||
pFilterLayout->addWidget(pUserFilter,0,1);
|
||||
this->setLayout(pFilterLayout);
|
||||
this->Reset();
|
||||
|
||||
connect( pUserFilter, SIGNAL(textEdited(const QString &)), pParent, SLOT(ApplyUserFilter(const QString &)) );
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef _FILTER_WIDGET_H_
|
||||
#define _FILTER_WIDGET_H_
|
||||
|
||||
#include "..\Qt\Qt.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class FilterWidget_C : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FilterWidget_C(QWidget* pParent);
|
||||
void Reset();
|
||||
const QString GetText();
|
||||
|
||||
private slots:
|
||||
void Hide();
|
||||
void Show();
|
||||
|
||||
private:
|
||||
QLineEdit* pUserFilter;
|
||||
QLabel* pMatchingItems;
|
||||
};
|
||||
|
||||
|
||||
#endif //_FILTER_WIDGET_H_
|
|
@ -0,0 +1,96 @@
|
|||
#include "IdlHighlighter.h"
|
||||
|
||||
//
|
||||
// REMARK: This code comes from Qt example.
|
||||
// It should be updated to really comply with the IDL syntax
|
||||
//
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
IdlHighlighter_C::IdlHighlighter_C(QTextDocument *parent) : QSyntaxHighlighter(parent)
|
||||
{
|
||||
HighlightingRule rule;
|
||||
|
||||
keywordFormat.setForeground(Qt::darkBlue);
|
||||
keywordFormat.setFontWeight(QFont::Bold);
|
||||
QStringList keywordPatterns;
|
||||
keywordPatterns << "\\bchar\\b" << "\\bclass\\b" << "\\bconst\\b"
|
||||
<< "\\bdouble\\b" << "\\benum\\b" << "\\bexplicit\\b"
|
||||
<< "\\bfriend\\b" << "\\binline\\b" << "\\bint\\b"
|
||||
<< "\\blong\\b" << "\\bnamespace\\b" << "\\boperator\\b"
|
||||
<< "\\bprivate\\b" << "\\bprotected\\b" << "\\bpublic\\b"
|
||||
<< "\\bshort\\b" << "\\bsignals\\b" << "\\bsigned\\b"
|
||||
<< "\\bslots\\b" << "\\bstatic\\b" << "\\bstruct\\b"
|
||||
<< "\\btemplate\\b" << "\\btypedef\\b" << "\\btypename\\b"
|
||||
<< "\\bunion\\b" << "\\bunsigned\\b" << "\\bvirtual\\b"
|
||||
<< "\\bvoid\\b" << "\\bvolatile\\b";
|
||||
foreach (const QString &pattern, keywordPatterns)
|
||||
{
|
||||
rule.pattern = QRegExp(pattern);
|
||||
rule.format = keywordFormat;
|
||||
highlightingRules.append(rule);
|
||||
}
|
||||
|
||||
classFormat.setFontWeight(QFont::Bold);
|
||||
classFormat.setForeground(Qt::darkMagenta);
|
||||
rule.pattern = QRegExp("\\bQ[A-Za-z]+\\b");
|
||||
rule.format = classFormat;
|
||||
highlightingRules.append(rule);
|
||||
|
||||
singleLineCommentFormat.setForeground(Qt::red);
|
||||
rule.pattern = QRegExp("//[^\n]*");
|
||||
rule.format = singleLineCommentFormat;
|
||||
highlightingRules.append(rule);
|
||||
|
||||
multiLineCommentFormat.setForeground(Qt::red);
|
||||
|
||||
quotationFormat.setForeground(Qt::darkGreen);
|
||||
rule.pattern = QRegExp("\".*\"");
|
||||
rule.format = quotationFormat;
|
||||
highlightingRules.append(rule);
|
||||
|
||||
functionFormat.setFontItalic(true);
|
||||
functionFormat.setForeground(Qt::blue);
|
||||
rule.pattern = QRegExp("\\b[A-Za-z0-9_]+(?=\\()");
|
||||
rule.format = functionFormat;
|
||||
highlightingRules.append(rule);
|
||||
|
||||
commentStartExpression = QRegExp("/\\*");
|
||||
commentEndExpression = QRegExp("\\*/");
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void IdlHighlighter_C::highlightBlock(const QString &text)
|
||||
{
|
||||
foreach (const HighlightingRule &rule, highlightingRules)
|
||||
{
|
||||
QRegExp expression(rule.pattern);
|
||||
int index = expression.indexIn(text);
|
||||
while (index >= 0) {
|
||||
int length = expression.matchedLength();
|
||||
setFormat(index, length, rule.format);
|
||||
index = expression.indexIn(text, index + length);
|
||||
}
|
||||
}
|
||||
setCurrentBlockState(0);
|
||||
|
||||
int startIndex = 0;
|
||||
if (previousBlockState() != 1)
|
||||
startIndex = commentStartExpression.indexIn(text);
|
||||
|
||||
while (startIndex >= 0)
|
||||
{
|
||||
int endIndex = commentEndExpression.indexIn(text, startIndex);
|
||||
int commentLength;
|
||||
if (endIndex == -1)
|
||||
{
|
||||
setCurrentBlockState(1);
|
||||
commentLength = text.length() - startIndex;
|
||||
} else
|
||||
{
|
||||
commentLength = endIndex - startIndex + commentEndExpression.matchedLength();
|
||||
}
|
||||
setFormat(startIndex, commentLength, multiLineCommentFormat);
|
||||
startIndex = commentStartExpression.indexIn(text, startIndex + commentLength);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef _IDL_HIGHLIGHTER_H_
|
||||
#define _IDL_HIGHLIGHTER_H_
|
||||
|
||||
#include "../Qt/Qt.h"
|
||||
|
||||
class IdlHighlighter_C : public QSyntaxHighlighter
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
IdlHighlighter_C(QTextDocument *parent = 0);
|
||||
|
||||
protected:
|
||||
void highlightBlock(const QString &text);
|
||||
|
||||
private:
|
||||
struct HighlightingRule
|
||||
{
|
||||
QRegExp pattern;
|
||||
QTextCharFormat format;
|
||||
};
|
||||
QVector<HighlightingRule> highlightingRules;
|
||||
|
||||
QRegExp commentStartExpression;
|
||||
QRegExp commentEndExpression;
|
||||
|
||||
QTextCharFormat keywordFormat;
|
||||
QTextCharFormat classFormat;
|
||||
QTextCharFormat singleLineCommentFormat;
|
||||
QTextCharFormat multiLineCommentFormat;
|
||||
QTextCharFormat quotationFormat;
|
||||
QTextCharFormat functionFormat;
|
||||
};
|
||||
|
||||
#endif //_IDL_HIGHLIGHTER_H_
|
|
@ -0,0 +1,181 @@
|
|||
#include "InitViewsVisitor.h"
|
||||
#include "EndpointsWidget.h"
|
||||
#include "InterfacesWidget.h"
|
||||
#include "InterfaceInfoWidget.h"
|
||||
#include "ProcessWidget.h"
|
||||
#include "ProcessInfoWidget.h"
|
||||
#include "ProceduresWidget.h"
|
||||
#include "../RpcCommon/Misc.h"
|
||||
|
||||
|
||||
typedef struct _EnumCtxt_T{
|
||||
InitViewsVisitor_C* pInitViewsVisitor;
|
||||
EndpointsWidget_C* pEndpointsWidget;
|
||||
InterfacesWidget_C* pInterfacesWidget;
|
||||
}EnumCtxt_T;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static BOOL WINAPI EnumProc(DWORD Pid, DWORD Ppid, EnumCtxt_T* pEnumCtxt, BOOL* pbContinue)
|
||||
{
|
||||
ProcessEntry_C* pProcessEntry = new ProcessEntry_C(Ppid,Pid);
|
||||
|
||||
pEnumCtxt->pInitViewsVisitor->ProcessVector.push_back(pProcessEntry);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
InitViewsVisitor_C::InitViewsVisitor_C(RpcCore_T* pRpcCore,void** ppRpcCoreCtxt)
|
||||
{
|
||||
EnumCtxt_T EnumCtxt;
|
||||
|
||||
this->pRpcCore= pRpcCore;
|
||||
|
||||
this->NbOfInterfaces = 0;
|
||||
this->pRpcCoreCtxt = pRpcCore->RpcCoreInitFn();
|
||||
if (this->pRpcCoreCtxt==NULL) goto End;
|
||||
*ppRpcCoreCtxt = this->pRpcCoreCtxt;
|
||||
|
||||
EnumCtxt.pInitViewsVisitor = this;
|
||||
EnumProcess( (EnumProcessCallbackFn_T)&EnumProc, &EnumCtxt );
|
||||
End:
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
InitViewsVisitor_C::~InitViewsVisitor_C()
|
||||
{
|
||||
for (UINT32 i = 0; i < ProcessVector.size(); i++)
|
||||
{
|
||||
delete ProcessVector[i];
|
||||
}
|
||||
ProcessVector.clear();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static BOOL __fastcall EnumEndpoints(DWORD Pid, RpcEndpointInfo_T* pRpcEndpointInfo, EnumCtxt_T* pEnumCtxt, BOOL* pbContinue)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(pbContinue);
|
||||
|
||||
pEnumCtxt->pEndpointsWidget->AddEndpoint(Pid, pRpcEndpointInfo );
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InitViewsVisitor_C::Visit(EndpointsWidget_C* pEndpointsWidget)
|
||||
{
|
||||
EnumCtxt_T EnumCtxt;
|
||||
std::vector<ProcessEntry_C*>::iterator Iter;
|
||||
|
||||
EnumCtxt.pInitViewsVisitor = this;
|
||||
EnumCtxt.pEndpointsWidget = pEndpointsWidget;
|
||||
|
||||
for (Iter=ProcessVector.begin();Iter!=ProcessVector.end();Iter++)
|
||||
{
|
||||
if (*Iter!=NULL)
|
||||
{
|
||||
pRpcCore->RpcCoreEnumProcessEndpointsFn(
|
||||
pRpcCoreCtxt,
|
||||
(*Iter)->Pid,
|
||||
(RpcCoreEnumProcessEndpointsCallbackFn_T) &EnumEndpoints,
|
||||
&EnumCtxt);
|
||||
}
|
||||
}
|
||||
NbOfEndpoints = pEndpointsWidget->GetEndpoints();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static BOOL __fastcall EnumInterfaces(RpcInterfaceInfo_T* pRpcInterfaceInfo, EnumCtxt_T* pEnumCtxt, BOOL* pbContinue)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(pbContinue);
|
||||
|
||||
pEnumCtxt->pInterfacesWidget->AddInterfaces(pRpcInterfaceInfo);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InitViewsVisitor_C::Visit(InterfacesWidget_C* pInterfacesWidget)
|
||||
{
|
||||
EnumCtxt_T EnumCtxt;
|
||||
std::vector<ProcessEntry_C*>::iterator Iter;
|
||||
|
||||
EnumCtxt.pInitViewsVisitor = this;
|
||||
EnumCtxt.pInterfacesWidget = pInterfacesWidget;
|
||||
for (Iter=ProcessVector.begin();Iter!=ProcessVector.end();Iter++)
|
||||
{
|
||||
if (*Iter!=NULL)
|
||||
{
|
||||
pRpcCore->RpcCoreEnumProcessInterfacesFn(
|
||||
pRpcCoreCtxt,
|
||||
(*Iter)->Pid,
|
||||
(RpcCoreEnumProcessInterfacesCallbackFn_T) &EnumInterfaces,
|
||||
&EnumCtxt,
|
||||
RPC_INTERFACE_INFO_ALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InitViewsVisitor_C::Visit(InterfaceInfoWidget_C* pInterfaceInfoWidget)
|
||||
{
|
||||
//nothing to do here
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InitViewsVisitor_C::Visit(ProcessInfoWidget_C* pProcessInfoWidget)
|
||||
{
|
||||
//nothing to do here
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InitViewsVisitor_C::Visit(ProceduresWidget_C* pProceduresWidget)
|
||||
{
|
||||
//nothing to do here
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InitViewsVisitor_C::Visit(ProcessWidget_C* pProcessWidget)
|
||||
{
|
||||
std::vector<ProcessEntry_C*>::iterator Iter;
|
||||
RpcProcessInfo_T* pRpcProcessInfo = NULL;
|
||||
|
||||
for (Iter=ProcessVector.begin();Iter!=ProcessVector.end();Iter++)
|
||||
{
|
||||
if (*Iter!=NULL)
|
||||
{
|
||||
pRpcProcessInfo = pRpcCore->RpcCoreGetProcessInfoFn(pRpcCoreCtxt,(*Iter)->Pid,(*Iter)->Ppid,RPC_PROCESS_INFO_ALL);
|
||||
if (pRpcProcessInfo!=NULL)
|
||||
{
|
||||
pProcessWidget->AddProcess(pRpcProcessInfo);
|
||||
this->NbOfInterfaces+=pRpcProcessInfo->InterfacesCount;
|
||||
pRpcCore->RpcCoreFreeProcessInfoFn(pRpcCoreCtxt,pRpcProcessInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
pProcessWidget->resizeColumnsToContents();
|
||||
NbOfProcesses=pProcessWidget->GetProcesses();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG InitViewsVisitor_C::GetEndpoints()
|
||||
{
|
||||
return (this->NbOfEndpoints);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG InitViewsVisitor_C::GetInterfaces()
|
||||
{
|
||||
return (this->NbOfInterfaces);
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef _INIT_VIEWS_VISITOR_H_
|
||||
#define _INIT_VIEWS_VISITOR_H_
|
||||
|
||||
#include "ViewVisitor.h"
|
||||
#include "..\RpcCore\RpcCore.h"
|
||||
#include "ProcessEntry.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class InitViewsVisitor_C : public ViewVisitor_C
|
||||
{
|
||||
private:
|
||||
RpcCore_T* pRpcCore;
|
||||
VOID* pRpcCoreCtxt;
|
||||
ULONG NbOfEndpoints;
|
||||
ULONG NbOfProcesses;
|
||||
ULONG NbOfInterfaces;
|
||||
|
||||
public:
|
||||
ULONG GetEndpoints();
|
||||
ULONG GetInterfaces();
|
||||
public:
|
||||
std::vector <ProcessEntry_C*> ProcessVector;
|
||||
|
||||
InitViewsVisitor_C(RpcCore_T* pRpcCore,void** ppRpcCoreCtxt);
|
||||
~InitViewsVisitor_C();
|
||||
virtual void Visit(EndpointsWidget_C* pEndpointsWidget);
|
||||
virtual void Visit(InterfacesWidget_C* pInterfacesWidget);
|
||||
virtual void Visit(InterfaceInfoWidget_C* pInterfaceInfoWidget);
|
||||
virtual void Visit(ProcessInfoWidget_C* pProcessInfoWidget);
|
||||
virtual void Visit(ProceduresWidget_C* pProceduresWidget);
|
||||
virtual void Visit(ProcessWidget_C* pProcessWidget);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,309 @@
|
|||
#include "InterfaceInfoWidget.h"
|
||||
#include "..\RpcCommon\RpcCommon.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
extern QString GetInterfaceFlagsString(quint32 Flags);
|
||||
|
||||
static const char WidgetName[] = "Interface Properties";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QString GetInterfaceNdrFlagsString(quint32 Flags)
|
||||
{
|
||||
QString FlagsString;
|
||||
|
||||
if (Flags & RPCFLG_HAS_MULTI_SYNTAXES) FlagsString.append("RPCFLG_HAS_MULTI_SYNTAXES\n");
|
||||
if (Flags & RPCFLG_HAS_CALLBACK) FlagsString.append("RPCFLG_HAS_CALLBACK\n");
|
||||
if (Flags & RPC_INTERFACE_HAS_PIPES) FlagsString.append("RPC_INTERFACE_HAS_PIPES\n");
|
||||
return (FlagsString);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfaceInfoWidget_C::Reset()
|
||||
{
|
||||
pTabWidget->setTabEnabled(pTabWidget->indexOf(pMainWidget),false);
|
||||
pTabWidget->setTabEnabled(pTabWidget->indexOf(pRpcWidget),false);
|
||||
pTabWidget->setTabEnabled(pTabWidget->indexOf(pNdrWidget),false);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
UINT InterfaceInfoWidget_C::GetPid()
|
||||
{
|
||||
return (this->Pid);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfaceInfoWidget_C::UpdateInterfaceInfo(RpcInterfaceInfo_T* pRpcInterfaceInfo, WCHAR* pIfCallbackName)
|
||||
{
|
||||
WCHAR* pUuidString = NULL;
|
||||
WCHAR* pTransfertSyntaxString = NULL;
|
||||
bool bEnable;
|
||||
|
||||
if (pRpcInterfaceInfo==NULL) goto End;
|
||||
this->Pid = pRpcInterfaceInfo->Pid;
|
||||
|
||||
if ( UuidToStringW(&pRpcInterfaceInfo->If.Uuid,(RPC_WSTR*)&pUuidString)!=RPC_S_OK ) goto End;
|
||||
if ( UuidToStringW(&pRpcInterfaceInfo->TransfertSyntax.SyntaxGUID,(RPC_WSTR*)&pTransfertSyntaxString)!=RPC_S_OK ) goto End;
|
||||
|
||||
pTabWidget->setTabEnabled(pTabWidget->indexOf(pMainWidget),true);
|
||||
pUuid->setText( QString::fromUtf16((const ushort*)pUuidString) );
|
||||
//
|
||||
// Only Rpc interfaces have versions
|
||||
//
|
||||
if (pRpcInterfaceInfo->IfType==IfType_RPC)
|
||||
{
|
||||
pVersion->setText( QString("%1.%2").arg(pRpcInterfaceInfo->If.VersMajor).arg(pRpcInterfaceInfo->If.VersMinor) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pVersion->clear();
|
||||
}
|
||||
pName->setText( QString::fromUtf16((const ushort*)pRpcInterfaceInfo->Name) );
|
||||
|
||||
if (pRpcInterfaceInfo->IfType!=IfType_RPC)
|
||||
{
|
||||
pTabWidget->setTabEnabled(pTabWidget->indexOf(pRpcWidget),false);
|
||||
}
|
||||
else
|
||||
{
|
||||
pTabWidget->setTabEnabled(pTabWidget->indexOf(pRpcWidget),true);
|
||||
}
|
||||
|
||||
if ( (pIfCallbackName==NULL) || (*pIfCallbackName==0) ) bEnable=false;
|
||||
else bEnable=true;
|
||||
pCallbackName->setEnabled(bEnable);
|
||||
pCallbackName->setText( QString::fromUtf16((const ushort*)pIfCallbackName) );
|
||||
|
||||
if (pRpcInterfaceInfo->TypeOfStub==TypeOfStub_TypeLib)
|
||||
{
|
||||
pTabWidget->setTabEnabled(pTabWidget->indexOf(pNdrWidget),false);
|
||||
}
|
||||
else
|
||||
{
|
||||
pTabWidget->setTabEnabled(pTabWidget->indexOf(pNdrWidget),true);
|
||||
}
|
||||
|
||||
if (pRpcInterfaceInfo->NumberOfProcedures==INVALID_PROC_COUNT) pProcCount->setText( "Unknown" );
|
||||
else pProcCount->setText( QString("%1").arg(pRpcInterfaceInfo->NumberOfProcedures) );
|
||||
|
||||
switch(pRpcInterfaceInfo->TypeOfStub)
|
||||
{
|
||||
case TypeOfStub_Interpreted:pStub->setText("Interpreted"); break;
|
||||
case TypeOfStub_Inlined: pStub->setText("Inlined"); break;
|
||||
case TypeOfStub_TypeLib: pStub->setText("TypeLib"); break;
|
||||
case TypeOfStub_Hybrid: pStub->setText("Hybrid"); break;
|
||||
default: pStub->setText("Unknown"); break;
|
||||
}
|
||||
|
||||
if (pRpcInterfaceInfo->Location[0]==0) bEnable=false;
|
||||
else bEnable=true;
|
||||
pLocation->setEnabled(bEnable);
|
||||
pLocation->setText( QString::fromUtf16((const ushort*)pRpcInterfaceInfo->Location) );
|
||||
pLocation->setCursorPosition(0);
|
||||
|
||||
Base = (quintptr)pRpcInterfaceInfo->pLocationBase;
|
||||
IfCallback = (quintptr)pRpcInterfaceInfo->IfCallbackFn;
|
||||
TypeFormatString = (quintptr)pRpcInterfaceInfo->pTypeFormatString;
|
||||
ProcFormatString = (quintptr)pRpcInterfaceInfo->pProcFormatString;
|
||||
ExpressionEvaluation = (quintptr)pRpcInterfaceInfo->apfnExprEval;
|
||||
|
||||
pBase->setText(QString("0x%1").arg(Base, HEX_SIZE_OF_PTR, 16, QLatin1Char('0')));
|
||||
SetAddressRepresentation(this->AddressRepresentation);
|
||||
//
|
||||
// Even if Location state is actually a mask, we consider it as 2 separte values
|
||||
//
|
||||
if (pRpcInterfaceInfo->LocationState == MEM_FREE) pState->setText("MEM_FREE");
|
||||
else if (pRpcInterfaceInfo->LocationState == MEM_COMMIT) pState->setText("MEM_COMMIT");
|
||||
|
||||
if (pRpcInterfaceInfo->Annotation[0]==0) bEnable=false;
|
||||
else bEnable=true;
|
||||
|
||||
pAnnotation->setEnabled(bEnable);
|
||||
pAnnotation->setText( QString::fromLatin1((const char*)pRpcInterfaceInfo->Annotation) );
|
||||
pAnnotation->setCursorPosition(0);
|
||||
|
||||
if (!pRpcInterfaceInfo->bIsRegistered)
|
||||
{
|
||||
pEpMapper->setEnabled(false);
|
||||
pEpMapper->setText( "" );
|
||||
}
|
||||
else
|
||||
{
|
||||
pEpMapper->setEnabled(true);
|
||||
pEpMapper->setText( "Registered" );
|
||||
}
|
||||
|
||||
pTransfertSyntax->setText( QString::fromUtf16((const ushort*)pTransfertSyntaxString).append(" V%1.%2").arg(pRpcInterfaceInfo->TransfertSyntax.SyntaxVersion.MajorVersion).arg(pRpcInterfaceInfo->TransfertSyntax.SyntaxVersion.MinorVersion) );
|
||||
pNdrVersion->setText( QString("0x%1").arg(pRpcInterfaceInfo->NdrInfo.Version,0,16) );
|
||||
pMidlVersion->setText( QString("0x%1").arg(pRpcInterfaceInfo->NdrInfo.MIDLVersion,0,16) );
|
||||
pNdrFlags->setText( GetInterfaceNdrFlagsString(pRpcInterfaceInfo->NdrInfo.mFlags) );
|
||||
|
||||
if (pRpcInterfaceInfo->Flags==0) bEnable=false;
|
||||
else bEnable=true;
|
||||
|
||||
pFlags->setEnabled(bEnable);
|
||||
pFlags->setText( GetInterfaceFlagsString(pRpcInterfaceInfo->Flags) );
|
||||
|
||||
if (pRpcInterfaceInfo->Description[0]==0) bEnable=false;
|
||||
else bEnable=true;
|
||||
|
||||
pDescription->setEnabled(bEnable);
|
||||
pDescription->setText( QString::fromUtf16((const ushort*)pRpcInterfaceInfo->Description) );
|
||||
End:
|
||||
if (pUuidString!=NULL) RpcStringFreeW((RPC_WSTR*)&pUuidString);
|
||||
if (pTransfertSyntaxString!=NULL) RpcStringFreeW((RPC_WSTR*)&pTransfertSyntaxString);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfaceInfoWidget_C::SetAddressRepresentation(AddressRepresentation_T AddressRepresentation)
|
||||
{
|
||||
this->AddressRepresentation = AddressRepresentation;
|
||||
|
||||
pCallbackAddress->setText("");
|
||||
pTypeFormatString->setText("");
|
||||
pProcFormatString->setText("");
|
||||
pExpressionEvaluation->setText("");
|
||||
switch (AddressRepresentation)
|
||||
{
|
||||
case AddressRepresentation_RVA:
|
||||
if ((IfCallback != 0) && (IfCallback!=INVALID_IF_CALLBACK_ADDRESS)) pCallbackAddress->setText(QString("+0x%1").arg(IfCallback - Base, 8, 16, QLatin1Char('0')));
|
||||
if (TypeFormatString != 0) pTypeFormatString->setText(QString("+0x%1").arg(TypeFormatString - Base, 8, 16, QLatin1Char('0')));
|
||||
if (ProcFormatString != 0) pProcFormatString->setText(QString("+0x%1").arg(ProcFormatString - Base, 8, 16, QLatin1Char('0')));
|
||||
if (ExpressionEvaluation != 0) pExpressionEvaluation->setText(QString("+0x%1").arg(ExpressionEvaluation - Base, 8, 16, QLatin1Char('0')));
|
||||
break;
|
||||
//--
|
||||
case AddressRepresentation_Absolute:
|
||||
if ((IfCallback != 0) && (IfCallback != INVALID_IF_CALLBACK_ADDRESS))pCallbackAddress->setText(QString("0x%1").arg(IfCallback, HEX_SIZE_OF_PTR, 16, QLatin1Char('0')));
|
||||
if (TypeFormatString != 0) pTypeFormatString->setText(QString("0x%1").arg(TypeFormatString, HEX_SIZE_OF_PTR, 16, QLatin1Char('0')));
|
||||
if (ProcFormatString != 0) pProcFormatString->setText(QString("0x%1").arg(ProcFormatString, HEX_SIZE_OF_PTR, 16, QLatin1Char('0')));
|
||||
if (ExpressionEvaluation != 0) pExpressionEvaluation->setText(QString("0x%1").arg(ExpressionEvaluation, HEX_SIZE_OF_PTR, 16, QLatin1Char('0')));
|
||||
break;
|
||||
//--
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfaceInfoWidget_C::AcceptVisitor(ViewVisitor_C* pVisitor)
|
||||
{
|
||||
pVisitor->Visit(this);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
InterfaceInfoWidget_C::InterfaceInfoWidget_C(QWidget* pParent):QDockWidget(WidgetName)
|
||||
{
|
||||
this->Pid = 0;
|
||||
|
||||
setObjectName(WidgetName);
|
||||
|
||||
pTabWidget = new QTabWidget(this);
|
||||
pTabWidget->setMovable(true);
|
||||
setWidget(pTabWidget);
|
||||
//
|
||||
// Creates the main properties tab
|
||||
//
|
||||
pMainWidget = new QWidget(this);
|
||||
QFormLayout* pMainLayout = new QFormLayout;
|
||||
|
||||
pUuid = new QLineEdit(this);
|
||||
pVersion = new QLabel(this);
|
||||
pName = new QLineEdit(this);
|
||||
pLocation = new QLineEdit(this);
|
||||
pBase = new QLabel(this);
|
||||
pState = new QLabel(this);
|
||||
pStub = new QLabel(this);
|
||||
pProcCount = new QLabel("0",this);
|
||||
pDescription = new QTextEdit(this);
|
||||
|
||||
pUuid->setReadOnly(true);
|
||||
pName->setReadOnly(true);
|
||||
pLocation->setEnabled(false);
|
||||
pLocation->setReadOnly(true);
|
||||
pDescription->setReadOnly(true);
|
||||
pDescription->setMinimumHeight(20);
|
||||
|
||||
pMainLayout->addRow("Uuid:", pUuid);
|
||||
pMainLayout->addRow("Version:", pVersion);
|
||||
pMainLayout->addRow("Name:", pName);
|
||||
pMainLayout->addRow("Location:", pLocation);
|
||||
pMainLayout->addRow("Base:", pBase);
|
||||
pMainLayout->addRow("State:", pState);
|
||||
pMainLayout->addRow("Stub:", pStub);
|
||||
pMainLayout->addRow("Procedures:", pProcCount);
|
||||
pMainLayout->addRow("Description:", pDescription);
|
||||
|
||||
pMainWidget->setLayout(pMainLayout);
|
||||
pTabWidget->addTab(pMainWidget,"Main");
|
||||
//
|
||||
// Creates the RPC tab
|
||||
//
|
||||
pRpcWidget = new QWidget(this);
|
||||
QFormLayout* pRpcLayout = new QFormLayout;
|
||||
|
||||
pCallbackName = new QLineEdit(this);
|
||||
pCallbackAddress= new QLineEdit(this);
|
||||
pEpMapper = new QLabel(this);
|
||||
pFlags = new QTextEdit(this);
|
||||
pAnnotation = new QLineEdit(this);
|
||||
|
||||
pFlags->setReadOnly(true);
|
||||
pFlags->setMinimumHeight(20);
|
||||
pCallbackName->setReadOnly(true);
|
||||
pCallbackAddress->setReadOnly(true);
|
||||
pAnnotation->setEnabled(false);
|
||||
pAnnotation->setReadOnly(true);
|
||||
|
||||
pRpcLayout->addRow("Callback Name:", pCallbackName);
|
||||
pRpcLayout->addRow("Callback Addr:", pCallbackAddress);
|
||||
pRpcLayout->addRow("EpMapper:", pEpMapper);
|
||||
pRpcLayout->addRow("Annotation:", pAnnotation);
|
||||
pRpcLayout->addRow("Flags:", pFlags);
|
||||
|
||||
pRpcWidget->setLayout(pRpcLayout);
|
||||
pTabWidget->addTab(pRpcWidget,"RPC");
|
||||
//
|
||||
// Creates the NDR tab
|
||||
//
|
||||
pNdrWidget = new QWidget(this);
|
||||
QFormLayout* pNdrLayout = new QFormLayout;
|
||||
|
||||
pTransfertSyntax = new QLineEdit(this);
|
||||
pNdrVersion = new QLabel("0",this);
|
||||
pMidlVersion = new QLabel("0",this);
|
||||
pNdrFlags = new QTextEdit(this);
|
||||
pTypeFormatString = new QLineEdit(this);
|
||||
pProcFormatString = new QLineEdit(this);
|
||||
pExpressionEvaluation = new QLineEdit(this);
|
||||
|
||||
pTransfertSyntax->setReadOnly(true);
|
||||
pNdrFlags->setReadOnly(true);
|
||||
pNdrFlags->setMinimumHeight(20);
|
||||
pTypeFormatString->setReadOnly(true);
|
||||
pProcFormatString->setReadOnly(true);
|
||||
pExpressionEvaluation->setReadOnly(true);
|
||||
|
||||
pNdrLayout->addRow("Syntax:", pTransfertSyntax);
|
||||
pNdrLayout->addRow("NDR Version:", pNdrVersion);
|
||||
pNdrLayout->addRow("MIDL Version:", pMidlVersion);
|
||||
pNdrLayout->addRow("NDR Flags:", pNdrFlags);
|
||||
pNdrLayout->addRow("TypeFormatString:", pTypeFormatString);
|
||||
pNdrLayout->addRow("ProcFormatString:", pProcFormatString);
|
||||
pNdrLayout->addRow("ExpressionEvaluation:", pExpressionEvaluation);
|
||||
|
||||
pNdrWidget->setLayout(pNdrLayout);
|
||||
pTabWidget->addTab(pNdrWidget, "NDR");
|
||||
//
|
||||
// By default: all tabs are disable
|
||||
//
|
||||
pTabWidget->setTabEnabled(pTabWidget->indexOf(pMainWidget),false);
|
||||
pTabWidget->setTabEnabled(pTabWidget->indexOf(pRpcWidget),false);
|
||||
pTabWidget->setTabEnabled(pTabWidget->indexOf(pNdrWidget),false);
|
||||
//
|
||||
this->AddressRepresentation = AddressRepresentation_Absolute;
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
#ifndef _INTERFACE_INFO_WIDGET_H_
|
||||
#define _INTERFACE_INFO_WIDGET_H_
|
||||
|
||||
#include "..\Qt\Qt.h"
|
||||
#include "..\RpcCore\RpcCore.h"
|
||||
#include "..\RpcCommon\RpcCommon.h"
|
||||
#include "View.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class InterfaceInfoWidget_C : public QDockWidget, public View_I
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InterfaceInfoWidget_C(QWidget* pParent);
|
||||
virtual void AcceptVisitor(ViewVisitor_C* pVisitor);
|
||||
|
||||
UINT GetPid();
|
||||
void Reset();
|
||||
void UpdateInterfaceInfo(RpcInterfaceInfo_T* pRpcInterfaceInfo, WCHAR* pCallbackName);
|
||||
void SetAddressRepresentation(AddressRepresentation_T AddressRepresentation);
|
||||
private:
|
||||
UINT Pid;
|
||||
AddressRepresentation_T AddressRepresentation;
|
||||
quintptr Base;
|
||||
quintptr IfCallback;
|
||||
quintptr TypeFormatString;
|
||||
quintptr ProcFormatString;
|
||||
quintptr ExpressionEvaluation;
|
||||
//Global
|
||||
QTabWidget* pTabWidget;
|
||||
//Main
|
||||
QWidget* pMainWidget;
|
||||
QLineEdit* pUuid;
|
||||
QLabel* pVersion;
|
||||
QLineEdit* pName;
|
||||
QLineEdit* pLocation;
|
||||
QLabel* pBase;
|
||||
QLabel* pState;
|
||||
QLabel* pStub;
|
||||
QLabel* pProcCount;
|
||||
QTextEdit* pDescription;
|
||||
//RPC
|
||||
QWidget* pRpcWidget;
|
||||
QLineEdit* pCallbackName;
|
||||
QLineEdit* pCallbackAddress;
|
||||
QLabel* pEpMapper;
|
||||
QLineEdit* pAnnotation;
|
||||
QTextEdit* pFlags;
|
||||
//NDR
|
||||
QWidget* pNdrWidget;
|
||||
QLineEdit* pTransfertSyntax;
|
||||
QLabel* pNdrVersion;
|
||||
QLabel* pMidlVersion;
|
||||
QTextEdit* pNdrFlags;
|
||||
QLineEdit* pTypeFormatString;
|
||||
QLineEdit* pProcFormatString;
|
||||
QLineEdit* pExpressionEvaluation;
|
||||
};
|
||||
|
||||
#endif// _INTERFACE_INFO_WIDGET_H_
|
|
@ -0,0 +1,185 @@
|
|||
#include "InterfaceSelectedVisitor.h"
|
||||
#include "EndpointsWidget.h"
|
||||
#include "InterfacesWidget.h"
|
||||
#include "InterfaceInfoWidget.h"
|
||||
#include "ProcessWidget.h"
|
||||
#include "ProcessInfoWidget.h"
|
||||
#include "ProceduresWidget.h"
|
||||
#include "../RpcCommon/Misc.h"
|
||||
#include "Pdb.h"
|
||||
#include <Dbghelp.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
InterfaceSelectedVisitor_C::InterfaceSelectedVisitor_C(quint32 Pid, RPC_IF_ID* pIf,RpcCore_T* pRpcCore,void* pRpcCoreCtxt)
|
||||
{
|
||||
this->Pid = Pid;
|
||||
this->pIf = pIf;
|
||||
this->pRpcCore = pRpcCore;
|
||||
this->pRpcCoreCtxt = pRpcCoreCtxt;
|
||||
|
||||
this->pRpcInterfaceInfo = pRpcCore->RpcCoreGetInterfaceInfoFn( pRpcCoreCtxt, Pid, pIf, RPC_INTERFACE_INFO_ALL );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
InterfaceSelectedVisitor_C::~InterfaceSelectedVisitor_C()
|
||||
{
|
||||
if (pRpcInterfaceInfo != NULL)
|
||||
{
|
||||
pRpcCore->RpcCoreFreeInterfaceInfoFn(pRpcCoreCtxt, pRpcInterfaceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfaceSelectedVisitor_C::Visit(EndpointsWidget_C* pEndpointsWidget)
|
||||
{
|
||||
pEndpointsWidget->ApplyProcessFilter(this->Pid);
|
||||
pEndpointsWidget->resizeColumnsToContents();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfaceSelectedVisitor_C::Visit(InterfacesWidget_C* pInterfacesWidget)
|
||||
{
|
||||
//nothing todo
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfaceSelectedVisitor_C::Visit(InterfaceInfoWidget_C* pInterfaceInfoWidget)
|
||||
{
|
||||
HANDLE hProcess = NULL;
|
||||
WCHAR SymbolName[RPC_MAX_LENGTH];
|
||||
void* hPdb;
|
||||
|
||||
if (pRpcInterfaceInfo==NULL) goto End;
|
||||
//
|
||||
// Get the callback name
|
||||
//
|
||||
SymbolName[0]=0;
|
||||
if (pRpcInterfaceInfo->pLocationBase!=NULL)
|
||||
{
|
||||
hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,Pid);
|
||||
if (hProcess==NULL) goto End;
|
||||
|
||||
hPdb = PdbInit(hProcess, pRpcInterfaceInfo->pLocationBase, pRpcInterfaceInfo->LocationSize);
|
||||
if (hPdb!=NULL)
|
||||
{
|
||||
PdbGetSymbolName(hPdb,pRpcInterfaceInfo->IfCallbackFn, SymbolName, sizeof(SymbolName));
|
||||
PdbUninit(hPdb);
|
||||
}
|
||||
}
|
||||
//
|
||||
// Update the view
|
||||
//
|
||||
pInterfaceInfoWidget->UpdateInterfaceInfo( pRpcInterfaceInfo, SymbolName );
|
||||
End:
|
||||
if (hProcess!=NULL) CloseHandle(hProcess);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
typedef struct _EnumCtxt_T{
|
||||
ProcessInfoWidget_C* pProcessInfoWidget;
|
||||
}EnumCtxt_T;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static BOOL __fastcall EnumProcessAuth(DWORD Pid, RpcAuthInfo_T* pRpcAuthInfo, EnumCtxt_T* pEnumCtxt, BOOL* pbContinue)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Pid);
|
||||
UNREFERENCED_PARAMETER(pbContinue);
|
||||
|
||||
pEnumCtxt->pProcessInfoWidget->AddAuthInfo(pRpcAuthInfo);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfaceSelectedVisitor_C::Visit(ProcessInfoWidget_C* pProcessInfoWidget)
|
||||
{
|
||||
RpcProcessInfo_T* pRpcProcessInfo;
|
||||
EnumCtxt_T EnumCtxt;
|
||||
|
||||
EnumCtxt.pProcessInfoWidget = pProcessInfoWidget;
|
||||
pProcessInfoWidget->reset();
|
||||
pRpcProcessInfo = pRpcCore->RpcCoreGetProcessInfoFn( pRpcCoreCtxt, Pid, 0, RPC_PROCESS_INFO_ALL );
|
||||
if (pRpcProcessInfo!=NULL)
|
||||
{
|
||||
pProcessInfoWidget->UpdateProcessInfo(pRpcProcessInfo);
|
||||
pRpcCore->RpcCoreFreeProcessInfoFn( pRpcCoreCtxt, pRpcProcessInfo );
|
||||
pRpcCore->RpcCoreEnumProcessAuthInfoFn( pRpcCoreCtxt, Pid, (RpcCoreEnumProcessAuthInfoCallbackFn_T)EnumProcessAuth,&EnumCtxt);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfaceSelectedVisitor_C::Visit(ProceduresWidget_C* pProceduresWidget)
|
||||
{
|
||||
HANDLE hProcess = NULL;
|
||||
WCHAR SymbolName[RPC_MAX_LENGTH];
|
||||
ULONG ProcIdx;
|
||||
VOID* ProcFormat = NULL;
|
||||
LPCWSTR pProcName = NULL;
|
||||
VOID* hPdb = NULL;
|
||||
UCHAR* ProcAddress = NULL;
|
||||
|
||||
if (pRpcInterfaceInfo==NULL) goto End;
|
||||
pProceduresWidget->reset(pRpcInterfaceInfo->Pid);
|
||||
|
||||
switch(pRpcInterfaceInfo->IfType)
|
||||
{
|
||||
//
|
||||
// Get proc names from pdb files if present
|
||||
//
|
||||
case IfType_RPC:
|
||||
if (pRpcInterfaceInfo->pLocationBase==NULL) goto End;
|
||||
|
||||
hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,Pid);
|
||||
if (hProcess==NULL) goto End;
|
||||
|
||||
hPdb = PdbInit(hProcess, pRpcInterfaceInfo->pLocationBase, pRpcInterfaceInfo->LocationSize);
|
||||
for(ProcIdx=0;ProcIdx<pRpcInterfaceInfo->NumberOfProcedures;ProcIdx++)
|
||||
{
|
||||
if (pRpcInterfaceInfo->ppProcAddressTable!=NULL)
|
||||
{
|
||||
SymbolName[0]=0;
|
||||
if (hPdb!=NULL)
|
||||
{
|
||||
PdbGetSymbolName(hPdb, (UCHAR*)pRpcInterfaceInfo->pLocationBase + pRpcInterfaceInfo->ppProcAddressTable[ProcIdx], SymbolName, sizeof(SymbolName));
|
||||
}
|
||||
if ( (pRpcInterfaceInfo->pFormatStringOffsetTable==NULL)||
|
||||
(pRpcInterfaceInfo->pProcFormatString==NULL))
|
||||
{
|
||||
ProcFormat=NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcFormat=pRpcInterfaceInfo->pProcFormatString + pRpcInterfaceInfo->pFormatStringOffsetTable[ProcIdx];
|
||||
}
|
||||
pProceduresWidget->AddProcedure(
|
||||
ProcIdx,
|
||||
SymbolName,
|
||||
pRpcInterfaceInfo->pLocationBase,
|
||||
pRpcInterfaceInfo->ppProcAddressTable[ProcIdx],
|
||||
ProcFormat
|
||||
);
|
||||
}
|
||||
}
|
||||
PdbUninit(hPdb);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
pProceduresWidget->resizeColumnsToContents();
|
||||
End:
|
||||
if (hProcess!=NULL) CloseHandle(hProcess);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfaceSelectedVisitor_C::Visit(ProcessWidget_C* pProcessWidget)
|
||||
{
|
||||
pProcessWidget->SelectProcess(Pid);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef _INTERFACE_SELECTED_VISITOR_H_
|
||||
#define _INTERFACE_SELECTED_VISITOR_H_
|
||||
|
||||
#include "../Qt/Qt.h"
|
||||
#include "ViewVisitor.h"
|
||||
#include "..\RpcCore\RpcCore.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class InterfaceSelectedVisitor_C : public ViewVisitor_C
|
||||
{
|
||||
private:
|
||||
quint32 Pid;
|
||||
RPC_IF_ID* pIf;
|
||||
RpcCore_T* pRpcCore;
|
||||
VOID* pRpcCoreCtxt;
|
||||
RpcInterfaceInfo_T* pRpcInterfaceInfo;
|
||||
public:
|
||||
InterfaceSelectedVisitor_C(quint32 Pid, RPC_IF_ID* pIf,RpcCore_T* pRpcCore,void* pRpcCoreCtxt);
|
||||
~InterfaceSelectedVisitor_C();
|
||||
virtual void Visit(EndpointsWidget_C* pEndpointsWidget);
|
||||
virtual void Visit(InterfacesWidget_C* pInterfacesWidget);
|
||||
virtual void Visit(InterfaceInfoWidget_C* pInterfaceInfoWidget);
|
||||
virtual void Visit(ProcessInfoWidget_C* pProcessInfoWidget);
|
||||
virtual void Visit(ProceduresWidget_C* pProceduresWidget);
|
||||
virtual void Visit(ProcessWidget_C* pProcessWidget);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,489 @@
|
|||
#include <conio.h>
|
||||
#include "InterfacesWidget.h"
|
||||
#include "..\RpcCommon\RpcCommon.h"
|
||||
|
||||
static const char WidgetName[] = "Interfaces";
|
||||
|
||||
//8a885d04-1ceb-11c9-9fe8-08002b104860 V2.0
|
||||
RPC_SYNTAX_IDENTIFIER DceRpcSyntaxUuid =
|
||||
{
|
||||
{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},
|
||||
{2,0}
|
||||
};
|
||||
|
||||
//71710533-beba-4937-8319-b5dbef9ccc36 V1.0
|
||||
RPC_SYNTAX_IDENTIFIER Ndr64SyntaxUuid =
|
||||
{
|
||||
{0x71710533,0xbeba,0x4937,{0x83,0x19,0xb5,0xdb,0xef,0x9c,0xcc,0x36}},
|
||||
{1,0}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QString InterfacesWidget_C::GetColumName(Column_T Column)
|
||||
{
|
||||
switch(Column)
|
||||
{
|
||||
case Column_Uuid : return (QString("Uuid"));
|
||||
case Column_Pid : return (QString("Pid"));
|
||||
case Column_Version : return (QString("Ver"));
|
||||
case Column_Flags : return (QString("Flags"));
|
||||
case Column_Name : return (QString("Name"));
|
||||
case Column_Base : return (QString("Base"));
|
||||
case Column_Location : return (QString("Location"));
|
||||
case Column_Description : return (QString("Description"));
|
||||
case Column_NumberOfProcedures : return (QString("Procs"));
|
||||
case Column_IfType : return (QString("Type"));
|
||||
case Column_IsRegistered : return (QString("EpMapper"));
|
||||
case Column_Annotation : return (QString("Annotation"));
|
||||
case Column_HasMarshallingInfo : return (QString("Stub"));
|
||||
case Column_IfCallbackFn : return (QString("Callback"));
|
||||
case Column_TransfertSyntax : return (QString("Syntax"));
|
||||
default : return (QString("Unknown"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfacesWidget_C::InterfaceSelected(const QModelIndex& Index)
|
||||
{
|
||||
QStringList PidStringList;
|
||||
QStringList VersionStringList;
|
||||
RPC_IF_ID RpcIfId;
|
||||
UCHAR* pUuidStringA;
|
||||
|
||||
QString& PidString = pProxyModel->data( pProxyModel->index(Index.row(), Column_Pid) ).toString();
|
||||
pUuidStringA = (UCHAR*)pProxyModel->data( pProxyModel->index(Index.row(), Column_Uuid) ).toString().toLatin1().data();
|
||||
QString& VersionString = pProxyModel->data( pProxyModel->index(Index.row(), Column_Version) ).toString();
|
||||
VersionStringList = VersionString.split(".", QString::SkipEmptyParts, Qt::CaseSensitive);
|
||||
|
||||
if (VersionStringList.isEmpty())
|
||||
{
|
||||
RpcIfId.VersMajor = 0;
|
||||
RpcIfId.VersMinor = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
RpcIfId.VersMajor= VersionStringList.at(0).toUShort();
|
||||
RpcIfId.VersMinor= VersionStringList.at(1).toUShort();
|
||||
}
|
||||
|
||||
UuidFromStringA( pUuidStringA, &RpcIfId.Uuid);
|
||||
|
||||
if (QApplication::mouseButtons() & Qt::RightButton)
|
||||
{
|
||||
QMenu myMenu;
|
||||
|
||||
QAction* pActionDecompile = myMenu.addAction("Decompile");
|
||||
QAction* selectedItem = myMenu.exec(QCursor::pos());
|
||||
if (selectedItem == pActionDecompile)
|
||||
{
|
||||
emit SigDecompileInterface(PidString.toUInt(), &RpcIfId);
|
||||
delete selectedItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete selectedItem;
|
||||
delete pActionDecompile;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Select the interface
|
||||
emit InterfaceSelected(PidString.toUInt(), &RpcIfId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfacesWidget_C::ApplyProcessFilter(quint32 Pid)
|
||||
{
|
||||
pProxyModel->setFilterRegExp( QString("^%1$").arg(Pid) );
|
||||
if (pProxyModel->rowCount() == 0) pProxyModel->setFilterRegExp( QRegExp(".*") );
|
||||
|
||||
pFilterWidget->Reset();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfacesWidget_C::SnapInterfaces()
|
||||
{
|
||||
PrivateItemList = pModel->findItems(".*", Qt::MatchRegExp, Column_Uuid);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfacesWidget_C::RemoveUnregisteredInterfaces()
|
||||
{
|
||||
for (auto Iter=PrivateItemList.begin();Iter!=PrivateItemList.end();Iter++)
|
||||
{
|
||||
if (*Iter!=NULL) pModel->removeRow( (*Iter)->row());
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool InterfacesWidget_C::IsInterfacePresent(quint32 Pid, RPC_IF_ID* pIfId)
|
||||
{
|
||||
QList<QStandardItem*> ItemList;
|
||||
UCHAR* pUuidString = NULL;
|
||||
bool bResult = false;
|
||||
|
||||
if ( UuidToStringA(&pIfId->Uuid,&pUuidString)!=RPC_S_OK ) goto End;
|
||||
|
||||
ItemList = pModel->findItems(QString::fromAscii((const char*)pUuidString), Qt::MatchFixedString, Column_Uuid);
|
||||
if (ItemList.isEmpty()) goto End;
|
||||
|
||||
for (auto Iter=ItemList.begin();Iter!=ItemList.end();Iter++)
|
||||
{
|
||||
if (*Iter!=NULL)
|
||||
{
|
||||
if (pModel->data(pModel->index((*Iter)->row(), Column_Pid)).toUInt() == Pid)
|
||||
{
|
||||
PrivateItemList.removeOne(*Iter);
|
||||
|
||||
bResult = true;
|
||||
goto End;
|
||||
}
|
||||
}
|
||||
}
|
||||
End:
|
||||
RpcStringFreeA(&pUuidString);
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfacesWidget_C::UpdateUserFilter()
|
||||
{
|
||||
if (pFilterWidget->GetText()!="") ApplyUserFilter( pFilterWidget->GetText() );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfacesWidget_C::ApplyUserFilter(const QString & FilterText)
|
||||
{
|
||||
QRegExp FilterRegExp;
|
||||
|
||||
FilterRegExp.setPattern( FilterText );
|
||||
FilterRegExp.setCaseSensitivity( Qt::CaseInsensitive );
|
||||
|
||||
pProxyModel->setFilterKeyColumn(-1);
|
||||
pProxyModel->setFilterRegExp( FilterRegExp );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfacesWidget_C::ShowUserFilter()
|
||||
{
|
||||
pFilterWidget->show();
|
||||
pUserFilter->setFocus();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfacesWidget_C::HideUserFilter()
|
||||
{
|
||||
pFilterWidget->hide();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG InterfacesWidget_C::GetInterfaces()
|
||||
{
|
||||
return (pProxyModel->rowCount());
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG InterfacesWidget_C::GetTotalInterfaces()
|
||||
{
|
||||
return (pModel->rowCount());
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfacesWidget_C::resizeColumnsToContents()
|
||||
{
|
||||
int Index;
|
||||
|
||||
for( Index=0; Index < Column_Last; Index++)
|
||||
{
|
||||
pInterfaces->resizeColumnToContents(Index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QString GetInterfaceFlagsString(quint32 Flags)
|
||||
{
|
||||
QString FlagsString;
|
||||
|
||||
if (Flags & RPC_IF_AUTOLISTEN) FlagsString.append("RPC_IF_AUTOLISTEN\n");
|
||||
if (Flags & RPC_IF_OLE) FlagsString.append("RPC_IF_OLE\n");
|
||||
if (Flags & RPC_IF_ALLOW_UNKNOWN_AUTHORITY) FlagsString.append("RPC_IF_ALLOW_UNKNOWN_AUTHORITY\n");
|
||||
if (Flags & RPC_IF_ALLOW_SECURE_ONLY) FlagsString.append("RPC_IF_ALLOW_SECURE_ONLY\n");
|
||||
if (Flags & RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH) FlagsString.append("RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH\n");
|
||||
if (Flags & RPC_IF_ALLOW_LOCAL_ONLY) FlagsString.append("RPC_IF_ALLOW_LOCAL_ONLY\n");
|
||||
if (Flags & RPC_IF_SEC_NO_CACHE) FlagsString.append("RPC_IF_SEC_NO_CACHE\n");
|
||||
if (Flags & RPC_IF_SEC_CACHE_PER_PROC) FlagsString.append("RPC_IF_SEC_CACHE_PER_PROC\n");
|
||||
if (Flags & RPC_IF_ASYNC_CALLBACK) FlagsString.append("RPC_IF_ASYNC_CALLBACK\n");
|
||||
return (FlagsString);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfacesWidget_C::SetRowColor(int Index, const QColor& Color)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<Column_Last;i++)
|
||||
{
|
||||
pModel->setData(pModel->index(Index,i), QBrush(Color), Qt::BackgroundRole);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool InterfacesWidget_C::AddInterfaces(RpcInterfaceInfo_T* pRpcInterfaceInfo)
|
||||
{
|
||||
int Index;
|
||||
QString PidString;
|
||||
WCHAR* pUuidString = NULL;
|
||||
WCHAR* pTransfertSyntaxString = NULL;
|
||||
WCHAR* pTypeW = NULL;
|
||||
WCHAR* pStubW = NULL;
|
||||
|
||||
if (pRpcInterfaceInfo==NULL) goto End;
|
||||
|
||||
//=====
|
||||
if (pRpcInterfaceInfo->IfType!=IfType_RPC) goto End; //NO DCOM!!!!
|
||||
//====
|
||||
|
||||
if ( UuidToStringW(&pRpcInterfaceInfo->If.Uuid,(RPC_WSTR*)&pUuidString)!=RPC_S_OK ) goto End;
|
||||
Index = pModel->rowCount();
|
||||
pModel->setRowCount(Index+1);
|
||||
pModel->setData(pModel->index(Index, Column_Pid), QString("%1").arg(pRpcInterfaceInfo->Pid) );
|
||||
pModel->setData(pModel->index(Index, Column_Uuid), QString::fromUtf16((const ushort*)pUuidString));
|
||||
|
||||
pModel->setData(pModel->index(Index, Column_Flags), QString("0x%1").arg(pRpcInterfaceInfo->Flags,0,16));
|
||||
pModel->setData(pModel->index(Index, Column_Flags), GetInterfaceFlagsString(pRpcInterfaceInfo->Flags), Qt::ToolTipRole );
|
||||
|
||||
pModel->setData(pModel->index(Index, Column_Name), QString::fromUtf16((const ushort*)pRpcInterfaceInfo->Name));
|
||||
pModel->setData(pModel->index(Index, Column_Base), QString("0x%1").arg((quintptr)pRpcInterfaceInfo->pLocationBase, 16, 16, QLatin1Char('0')));
|
||||
pModel->setData(pModel->index(Index, Column_Base), (quintptr)pRpcInterfaceInfo->pLocationBase, Qt::UserRole);
|
||||
pModel->setData(pModel->index(Index, Column_Location), QString::fromUtf16((const ushort*)pRpcInterfaceInfo->Location));
|
||||
pModel->setData(pModel->index(Index, Column_Description), QString::fromUtf16((const ushort*)pRpcInterfaceInfo->Description));
|
||||
|
||||
if (pRpcInterfaceInfo->NumberOfProcedures==INVALID_PROC_COUNT) pModel->setData(pModel->index(Index, Column_NumberOfProcedures), 0);
|
||||
else pModel->setData(pModel->index(Index, Column_NumberOfProcedures), pRpcInterfaceInfo->NumberOfProcedures);
|
||||
|
||||
switch(pRpcInterfaceInfo->IfType)
|
||||
{
|
||||
case IfType_RPC:
|
||||
//Only RPC interfaces have versions
|
||||
pTypeW = L"RPC";
|
||||
pModel->setData(pModel->index(Index, Column_Version), QString("%1.%2").arg(pRpcInterfaceInfo->If.VersMajor).arg(pRpcInterfaceInfo->If.VersMinor));
|
||||
break;
|
||||
|
||||
case IfType_OLE:
|
||||
pTypeW = L"OLE";
|
||||
if (pRpcInterfaceInfo->TypeOfStub==TypeOfStub_TypeLib) SetRowColor(Index,QColor(255, 200, 255, 180));
|
||||
else SetRowColor(Index,QColor(255, 255, 200, 180));
|
||||
break;
|
||||
case IfType_DCOM:
|
||||
pTypeW = L"DCOM";
|
||||
SetRowColor(Index,QColor(200, 200, 255, 180));
|
||||
break;
|
||||
}
|
||||
|
||||
pModel->setData(pModel->index(Index, Column_IfType), QString::fromUtf16((const ushort*)pTypeW));
|
||||
if (!pRpcInterfaceInfo->bIsRegistered)
|
||||
{
|
||||
pModel->setData(pModel->index(Index, Column_IsRegistered), "");
|
||||
}
|
||||
else
|
||||
{
|
||||
pModel->setData(pModel->index(Index, Column_IsRegistered), QString("Registered"));
|
||||
}
|
||||
pModel->setData(pModel->index(Index, Column_Annotation), QString::fromLatin1((const char*)pRpcInterfaceInfo->Annotation));
|
||||
switch(pRpcInterfaceInfo->TypeOfStub)
|
||||
{
|
||||
case TypeOfStub_Interpreted:pStubW = L"Interpreted"; break;
|
||||
case TypeOfStub_Inlined: pStubW = L"Inlined"; break;
|
||||
case TypeOfStub_TypeLib: pStubW = L"TypeLib"; break;
|
||||
case TypeOfStub_Hybrid: pStubW = L"Hybrid"; break;
|
||||
default: pStubW = NULL; break;
|
||||
}
|
||||
pModel->setData(pModel->index(Index, Column_HasMarshallingInfo), QString::fromUtf16((const ushort*)pStubW));
|
||||
if ((pRpcInterfaceInfo->IfCallbackFn != 0) && (pRpcInterfaceInfo->IfCallbackFn != (RPC_IF_CALLBACK_FN*)INVALID_IF_CALLBACK_ADDRESS))
|
||||
{
|
||||
pModel->setData(pModel->index(Index, Column_IfCallbackFn), QString("0x%1").arg((quintptr)pRpcInterfaceInfo->IfCallbackFn, 16, 16, QLatin1Char('0')));
|
||||
pModel->setData(pModel->index(Index, Column_IfCallbackFn), (quintptr)pRpcInterfaceInfo->IfCallbackFn,Qt::UserRole);
|
||||
}
|
||||
|
||||
if (pRpcInterfaceInfo->bIsRegistered) SetRowColor(Index,QColor(200, 255, 200, 180));
|
||||
if (pRpcInterfaceInfo->LocationState & MEM_FREE) SetRowColor(Index, QColor(200, 200, 200, 180));
|
||||
|
||||
if (!memcmp(&pRpcInterfaceInfo->TransfertSyntax,&DceRpcSyntaxUuid,sizeof(DceRpcSyntaxUuid)))
|
||||
pModel->setData(pModel->index(Index, Column_TransfertSyntax), QString::fromAscii("DCE"));
|
||||
else if (!memcmp(&pRpcInterfaceInfo->TransfertSyntax,&Ndr64SyntaxUuid,sizeof(Ndr64SyntaxUuid)))
|
||||
pModel->setData(pModel->index(Index, Column_TransfertSyntax), QString::fromUtf16((const ushort*)L"NDR64"));
|
||||
else
|
||||
pModel->setData(pModel->index(Index, Column_TransfertSyntax), QString::fromUtf16((const ushort*)L"unknown"));
|
||||
|
||||
End:
|
||||
if (pUuidString!=NULL) RpcStringFreeW((RPC_WSTR*)&pUuidString);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfacesWidget_C::AcceptVisitor(ViewVisitor_C* pVisitor)
|
||||
{
|
||||
pVisitor->Visit(this);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfacesWidget_C::SaveConfiguration(QSettings* pSettings)
|
||||
{
|
||||
pSettings->setValue("Interfaces/geometry",pInterfaces->header()->saveState());
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfacesWidget_C::LoadConfiguration(QSettings* pSettings)
|
||||
{
|
||||
pInterfaces->header()->restoreState( pSettings->value("Interfaces/geometry").toByteArray() );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfacesWidget_C::CreateColumnsSelectionWidget()
|
||||
{
|
||||
pColumnsSelectionWidget = new QGroupBox(WidgetName,this);
|
||||
QVBoxLayout* pLayout = new QVBoxLayout(pColumnsSelectionWidget);
|
||||
|
||||
for (int i = 0; i < Column_Last; i++)
|
||||
{
|
||||
ColumnsCheckBoxArray[i] = new QCheckBox(GetColumName((Column_T)i), pColumnsSelectionWidget);
|
||||
pLayout->addWidget(ColumnsCheckBoxArray[i]);
|
||||
}
|
||||
pLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
|
||||
pColumnsSelectionWidget->setLayout(pLayout);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QWidget* InterfacesWidget_C::GetColumnsSelectionWidget()
|
||||
{
|
||||
for (int i = 0; i < Column_Last; i++)
|
||||
{
|
||||
ColumnsCheckBoxArray[i]->setChecked(!pInterfaces->header()->isSectionHidden(i));
|
||||
}
|
||||
return pColumnsSelectionWidget;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfacesWidget_C::UpdateColumnsVisibility()
|
||||
{
|
||||
for (int i = 0; i < Column_Last; i++)
|
||||
{
|
||||
pInterfaces->header()->setSectionHidden(i, !ColumnsCheckBoxArray[i]->isChecked());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void InterfacesWidget_C::SetAddressRepresentation(AddressRepresentation_T AddressRepresentation)
|
||||
{
|
||||
switch (AddressRepresentation)
|
||||
{
|
||||
case AddressRepresentation_RVA:
|
||||
for (int i = 0; i < pModel->rowCount(); i++)
|
||||
{
|
||||
pModel->setData(pModel->index(i, Column_IfCallbackFn), "");
|
||||
quintptr IfCallback = pModel->data(pModel->index(i, Column_IfCallbackFn), Qt::UserRole).toULongLong();
|
||||
if ((IfCallback != 0) && (IfCallback != INVALID_IF_CALLBACK_ADDRESS))
|
||||
{
|
||||
quintptr Base = pModel->data(pModel->index(i, Column_Base), Qt::UserRole).toULongLong();
|
||||
pModel->setData(pModel->index(i, Column_IfCallbackFn), QString("+0x%1").arg(IfCallback - Base, 8, 16, QLatin1Char('0')));
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--
|
||||
case AddressRepresentation_Absolute:
|
||||
for (int i = 0; i < pModel->rowCount(); i++)
|
||||
{
|
||||
pModel->setData(pModel->index(i, Column_IfCallbackFn), "");
|
||||
quintptr IfCallback = pModel->data(pModel->index(i, Column_IfCallbackFn), Qt::UserRole).toULongLong();
|
||||
if ((IfCallback != 0) && (IfCallback != INVALID_IF_CALLBACK_ADDRESS))
|
||||
{
|
||||
pModel->setData(pModel->index(i, Column_IfCallbackFn), QString("0x%1").arg(IfCallback, HEX_SIZE_OF_PTR, 16, QLatin1Char('0')));
|
||||
}
|
||||
}
|
||||
break;
|
||||
//--
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
InterfacesWidget_C::InterfacesWidget_C(QWidget* pParent):QDockWidget(WidgetName)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
QGridLayout* pGridLayout;
|
||||
QGroupBox* pGroupBox;
|
||||
|
||||
pGroupBox = new QGroupBox(this);
|
||||
pGridLayout = new QGridLayout(pGroupBox);
|
||||
|
||||
setObjectName(WidgetName);
|
||||
|
||||
pProxyModel = new QSortFilterProxyModel(this);
|
||||
pProxyModel->setDynamicSortFilter(true);
|
||||
pProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
|
||||
pModel = new QStandardItemModel(0, Column_Last, this);
|
||||
|
||||
for(i=0;i<Column_Last;i++)
|
||||
{
|
||||
pModel->setHeaderData(i, Qt::Horizontal, GetColumName( (Column_T)i ) );
|
||||
}
|
||||
|
||||
pInterfaces = new QTreeView(this);
|
||||
pInterfaces->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
pInterfaces->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
pInterfaces->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
pInterfaces->setRootIsDecorated(false);
|
||||
pInterfaces->setSortingEnabled(true);
|
||||
pInterfaces->setAnimated(true);
|
||||
pInterfaces->setModel(pProxyModel);
|
||||
pInterfaces->sortByColumn(Column_Uuid, Qt::AscendingOrder);
|
||||
pInterfaces->header()->installEventFilter(pParent);
|
||||
|
||||
pProxyModel->setSourceModel(pModel);
|
||||
|
||||
connect( pInterfaces, SIGNAL(pressed(const QModelIndex&)), this, SLOT(InterfaceSelected(const QModelIndex&)));
|
||||
connect( pInterfaces, SIGNAL(activated(const QModelIndex&)), this, SLOT(InterfaceSelected(const QModelIndex&)));
|
||||
connect( this, SIGNAL(InterfaceSelected(quint32, RPC_IF_ID*)), pParent, SLOT(InterfaceSelected(quint32, RPC_IF_ID*)) );
|
||||
connect( this, SIGNAL(SigDecompileInterface(quint32, RPC_IF_ID*)), pParent, SLOT(SlotDecompileInterface(quint32, RPC_IF_ID*)) );
|
||||
//
|
||||
// Add user filtering (CTL+F) support
|
||||
//
|
||||
pFilterWidget = new FilterWidget_C(this);
|
||||
|
||||
pGridLayout->addWidget(pInterfaces,0,0);
|
||||
pGridLayout->addWidget(pFilterWidget,1,0);
|
||||
pGroupBox->setLayout(pGridLayout);
|
||||
setWidget(pGroupBox);
|
||||
//
|
||||
// Create the widgets for column selection
|
||||
//
|
||||
CreateColumnsSelectionWidget();
|
||||
AddressRepresentation = AddressRepresentation_Absolute;
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
#ifndef _INTERFACES_WIDGET_H_
|
||||
#define _INTERFACES_WIDGET_H_
|
||||
|
||||
#include "..\Qt\Qt.h"
|
||||
#include "..\RpcCore\RpcCore.h"
|
||||
#include "FilterWidget.h"
|
||||
#include "View.h"
|
||||
#include "..\RpcCommon\RpcCommon.h"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class InterfacesWidget_C : public QDockWidget, public View_I
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
typedef enum{
|
||||
Column_Pid,
|
||||
Column_Uuid,
|
||||
Column_Version,
|
||||
Column_IfType,
|
||||
Column_NumberOfProcedures,
|
||||
Column_HasMarshallingInfo,
|
||||
Column_IfCallbackFn,
|
||||
Column_Name,
|
||||
Column_Base,
|
||||
Column_Location,
|
||||
Column_Flags,
|
||||
Column_Description,
|
||||
Column_IsRegistered,
|
||||
Column_Annotation,
|
||||
Column_TransfertSyntax,
|
||||
Column_Last //Must be the last one
|
||||
}Column_T;
|
||||
|
||||
InterfacesWidget_C(QWidget* pParent);
|
||||
virtual void AcceptVisitor(ViewVisitor_C* pVisitor);
|
||||
ULONG GetInterfaces();
|
||||
ULONG GetTotalInterfaces();
|
||||
bool IsInterfacePresent(quint32 Pid, RPC_IF_ID* pIfIp);
|
||||
void RemoveUnregisteredInterfaces();
|
||||
void SnapInterfaces();
|
||||
void SaveConfiguration(QSettings*);
|
||||
void LoadConfiguration(QSettings*);
|
||||
void UpdateUserFilter();
|
||||
QWidget* GetColumnsSelectionWidget();
|
||||
void UpdateColumnsVisibility();
|
||||
void CreateColumnsSelectionWidget();
|
||||
|
||||
void ApplyProcessFilter(quint32 Pid);
|
||||
void resizeColumnsToContents();
|
||||
bool AddInterfaces(RpcInterfaceInfo_T* pRpcInterfaceInfo);
|
||||
void SetAddressRepresentation(AddressRepresentation_T AddressRepresentation);
|
||||
|
||||
public slots:
|
||||
void ApplyUserFilter(const QString &);
|
||||
|
||||
private slots:
|
||||
void InterfaceSelected(const QModelIndex& Index);
|
||||
void SetRowColor(int Index,const QColor& Color);
|
||||
void ShowUserFilter();
|
||||
void HideUserFilter();
|
||||
|
||||
signals:
|
||||
void InterfaceSelected(quint32 Pid, RPC_IF_ID* pIf);
|
||||
void SigDecompileInterface(quint32 Pid, RPC_IF_ID* pIf);
|
||||
|
||||
private:
|
||||
FilterWidget_C* pFilterWidget;
|
||||
QTreeView* pInterfaces;
|
||||
QSortFilterProxyModel* pProxyModel;
|
||||
QStandardItemModel* pModel;
|
||||
QLineEdit* pUserFilter;
|
||||
QLabel* pMatchingItems;
|
||||
QList<QStandardItem*> PrivateItemList;
|
||||
QGroupBox* pColumnsSelectionWidget;
|
||||
QCheckBox* ColumnsCheckBoxArray[Column_Last];
|
||||
QWidget* pColorSelectionWidget;
|
||||
QSignalMapper* SignalMapper;
|
||||
AddressRepresentation_T AddressRepresentation;
|
||||
|
||||
QString GetColumName(Column_T Column);
|
||||
};
|
||||
|
||||
#endif// _INTERFACES_WIDGET_H_
|
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
|
@ -0,0 +1,803 @@
|
|||
#include "MainWindow.h"
|
||||
#include "RpcViewResource.h"
|
||||
#include "../RpcCommon/Misc.h"
|
||||
#include <Psapi.h>
|
||||
#include <Shlobj.h>
|
||||
#include <Dbghelp.h>
|
||||
#include <strsafe.h>
|
||||
#include <conio.h>
|
||||
|
||||
#include "ConfigurationVisitor.h"
|
||||
#include "ProcessSelectedVisitor.h"
|
||||
#include "EndpointSelectedVisitor.h"
|
||||
#include "InterfaceSelectedVisitor.h"
|
||||
#include "InitViewsVisitor.h"
|
||||
#include "RefreshVisitor.h"
|
||||
|
||||
#define FAST_REFRESH_SPEED 500
|
||||
#define NORMAL_REFRESH_SPEED 1000
|
||||
#define BELOW_NORMAL_REFRESH_SPEED 2000
|
||||
#define SLOW_REFRESH_SPEED 5000
|
||||
#define VERY_SLOW_REFRESH_SPEED 10000
|
||||
#define SHELL_EXECUTE_SUCCESS ((HINSTANCE)42) // According to the doc, welcome the 16-bit compatibilty
|
||||
|
||||
|
||||
extern ULONG NTAPI DecompilerExceptionFilter(EXCEPTION_POINTERS* pExceptionPointers);
|
||||
extern HMODULE NTAPI LoadDecompilerEngine(RpcDecompilerHelper_T** ppRpcDecompilerHelper);
|
||||
extern void NTAPI InitDecompilerInfo(_In_ RpcInterfaceInfo_T* pRpcInterfaceInfo, _Out_ RpcDecompilerInfo_T* pRpcDecompilerInfo);
|
||||
extern void NTAPI UninitDecompilerInfo(RpcDecompilerInfo_T* pRpcDecompilerInfo);
|
||||
|
||||
static const char WidgetName[] = "RpcView";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::InterfaceSelected(quint32 Pid, RPC_IF_ID* pIf)
|
||||
{
|
||||
CHAR SymbolPath;
|
||||
|
||||
if (GetEnvironmentVariableA("RpcViewSymbolPath",&SymbolPath,sizeof(SymbolPath))==0)
|
||||
{
|
||||
StatusBar.showMessage("Symbol path not configured.");
|
||||
}
|
||||
|
||||
InterfaceSelectedVisitor_C InterfaceSelectedVisitor(
|
||||
Pid,
|
||||
pIf,
|
||||
pRpcCore,
|
||||
pRpcCoreCtxt
|
||||
);
|
||||
|
||||
this->SendVisitor(InterfaceSelectedVisitor);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::EndpointSelected(quint32 Pid)
|
||||
{
|
||||
EndpointSelectedVisitor_C EndpointSelectedVisitor(
|
||||
Pid,
|
||||
pRpcCore,
|
||||
pRpcCoreCtxt
|
||||
);
|
||||
this->SendVisitor(EndpointSelectedVisitor);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::ProcessSelected(quint32 Pid)
|
||||
{
|
||||
ProcessSelectedVisitor_C ProcessSelectedVisitor(
|
||||
Pid,
|
||||
pRpcCore,
|
||||
pRpcCoreCtxt
|
||||
);
|
||||
this->SendVisitor(ProcessSelectedVisitor);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::InitColumnsDialog()
|
||||
{
|
||||
ColumnsDialog = new QDialog(this);
|
||||
ColumnsVLayout = new QVBoxLayout(ColumnsDialog);
|
||||
ColumnsHLayout = new QHBoxLayout();
|
||||
ColumnsVLayout1 = new QVBoxLayout();
|
||||
ColumnsButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
|
||||
pProcessColumns = pProcessWidget->GetColumnsSelectionWidget();
|
||||
pEndpointsColumns = pEndpointsWidget->GetColumnsSelectionWidget();
|
||||
pInterfacesColumns = pInterfacesWidget->GetColumnsSelectionWidget();
|
||||
pProceduresColumns = pProceduresWidget->GetColumnsSelectionWidget();
|
||||
|
||||
ColumnsHLayout->addWidget(pProcessColumns);
|
||||
ColumnsVLayout1->addWidget(pEndpointsColumns);
|
||||
ColumnsVLayout1->addWidget(pProceduresColumns);
|
||||
ColumnsHLayout->addLayout(ColumnsVLayout1);
|
||||
ColumnsHLayout->addWidget(pInterfacesColumns);
|
||||
|
||||
ColumnsVLayout->addLayout(ColumnsHLayout);
|
||||
ColumnsVLayout->addWidget(ColumnsButtonBox);
|
||||
|
||||
connect(ColumnsButtonBox, SIGNAL(rejected()), ColumnsDialog, SLOT(reject()));
|
||||
connect(ColumnsButtonBox, SIGNAL(accepted()), ColumnsDialog, SLOT(accept()));
|
||||
connect(ColumnsDialog, SIGNAL(accepted()), this, SLOT(UpdateColumns()));
|
||||
|
||||
ColumnsDialog->setWindowTitle("Select Columns");
|
||||
ColumnsDialog->setLayout(ColumnsVLayout);
|
||||
ColumnsDialog->setMaximumSize(0, 0);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::ShowColumnsDialog()
|
||||
{
|
||||
pProcessColumns = pProcessWidget->GetColumnsSelectionWidget();
|
||||
pEndpointsColumns = pEndpointsWidget->GetColumnsSelectionWidget();
|
||||
pInterfacesColumns = pInterfacesWidget->GetColumnsSelectionWidget();
|
||||
pProceduresColumns = pProceduresWidget->GetColumnsSelectionWidget();
|
||||
|
||||
ColumnsDialog->exec();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::UpdateColumns()
|
||||
{
|
||||
ConfigurationVisitor_C ConfigurationVisitor(ConfigurationVisitor_C::UpdateColumns, NULL);
|
||||
SendVisitor(ConfigurationVisitor);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool MainWindow_C::eventFilter(QObject* pObject, QEvent* pEvent)
|
||||
{
|
||||
if (pEvent->type() == QEvent::ContextMenu)
|
||||
{
|
||||
QPoint& position = QCursor::pos();
|
||||
//
|
||||
// Show the context menu associatd to columns
|
||||
//
|
||||
QMenu ColumnsMenu;
|
||||
|
||||
QAction* pActionSelectColumns = ColumnsMenu.addAction("Select Columns...");
|
||||
QAction* pActionFitAll = ColumnsMenu.addAction("Size All Columns to fit");
|
||||
//
|
||||
QAction* selectedItem = ColumnsMenu.exec(position);
|
||||
if (selectedItem == pActionFitAll)
|
||||
{
|
||||
delete pActionSelectColumns;
|
||||
static_cast<QHeaderView*>(pObject)->resizeSections(QHeaderView::ResizeToContents);
|
||||
|
||||
}
|
||||
else if (selectedItem == pActionSelectColumns)
|
||||
{
|
||||
delete pActionFitAll;
|
||||
ShowColumnsDialog();
|
||||
}
|
||||
if (selectedItem != NULL) delete selectedItem;
|
||||
}
|
||||
return QWidget::eventFilter(pObject, pEvent);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
VOID* __fastcall RpcAlloc(SIZE_T Size)
|
||||
{
|
||||
return OS_ALLOC(Size);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
VOID __fastcall RpcFree(VOID* pMem)
|
||||
{
|
||||
OS_FREE(pMem);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL __fastcall RpcGetProcessData(RpcModuleInfo_T* pRpcModuleInfo, RVA_T Rva, VOID* pBuffer, UINT BufferLength)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
HANDLE hProcess = NULL;
|
||||
VOID* pAddress = NULL;
|
||||
|
||||
if (pRpcModuleInfo == NULL) goto End;
|
||||
pAddress = (VOID*)(pRpcModuleInfo->pModuleBase + Rva);
|
||||
|
||||
hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, pRpcModuleInfo->Pid);
|
||||
if (hProcess == NULL) goto End;
|
||||
bResult = ReadProcessMemory(hProcess, pAddress, pBuffer, BufferLength, NULL);
|
||||
End:
|
||||
if (hProcess != NULL) CloseHandle(hProcess);
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
VOID __cdecl RpcPrint(void* pContext, const char* pTxt)
|
||||
{
|
||||
DecompilationWidget_C* pDecompilationWidget = (DecompilationWidget_C*)pContext;
|
||||
pDecompilationWidget->InsertText(pTxt);
|
||||
#ifdef _DEBUG
|
||||
printf("%s\n", pTxt);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
VOID __cdecl RpcDebug(const char* pFunction, ULONG Line, const char* pFormatString, ...)
|
||||
{
|
||||
va_list Arg;
|
||||
va_start(Arg, pFormatString);
|
||||
|
||||
_vcprintf(pFormatString, Arg);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL __fastcall RpcGetInterfaceName(GUID* pUuid, UCHAR* pName, ULONG NameLength)
|
||||
{
|
||||
HKEY hKey = NULL;
|
||||
ULONG DataLength;
|
||||
UCHAR SubKeyName[MAX_PATH];
|
||||
RPC_CSTR pUuidString = NULL;
|
||||
BOOL bResult = FALSE;
|
||||
|
||||
if (UuidToStringA(pUuid, &pUuidString) != RPC_S_OK) goto End;
|
||||
StringCbPrintfA((STRSAFE_LPSTR)SubKeyName, sizeof(SubKeyName), "Interface\\{%s}", pUuidString);
|
||||
|
||||
if (RegOpenKeyExA(HKEY_CLASSES_ROOT, (LPCSTR)SubKeyName, 0, KEY_READ, &hKey) != ERROR_SUCCESS) goto End;
|
||||
DataLength = NameLength;
|
||||
if (RegQueryValueExA(hKey, NULL, NULL, NULL, pName, &DataLength) != ERROR_SUCCESS) goto End;
|
||||
|
||||
bResult = TRUE;
|
||||
End:
|
||||
if (hKey != NULL) RegCloseKey(hKey);
|
||||
if (pUuidString != NULL) RpcStringFreeA(&pUuidString);
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::SlotDecompileInterface(quint32 Pid, RPC_IF_ID* pIf)
|
||||
{
|
||||
RpcDecompilerInfo_T RpcDecompilerInfo;
|
||||
void* pDecompilerCtxt = NULL;
|
||||
RpcInterfaceInfo_T* pRpcInterfaceInfo = NULL;
|
||||
RpcDecompilerHelper_T* pRpcDecompilerHelper = NULL;
|
||||
HMODULE hDecompiler = NULL;
|
||||
|
||||
ZeroMemory(&RpcDecompilerInfo, sizeof(RpcDecompilerInfo));
|
||||
//
|
||||
// Get the decompiler
|
||||
//
|
||||
hDecompiler = LoadDecompilerEngine(&pRpcDecompilerHelper);
|
||||
if (hDecompiler==NULL) goto End;
|
||||
//
|
||||
// Get the Interface info
|
||||
//
|
||||
pRpcInterfaceInfo = pRpcCore->RpcCoreGetInterfaceInfoFn( pRpcCoreCtxt, Pid, pIf, RPC_INTERFACE_INFO_ALL );
|
||||
if (pRpcInterfaceInfo == NULL) goto End;
|
||||
InitDecompilerInfo(pRpcInterfaceInfo, &RpcDecompilerInfo);
|
||||
__try{
|
||||
RpcViewHelper_T LocalRpcViewHelper = {
|
||||
this->pDecompilationWidget,
|
||||
&RpcAlloc,
|
||||
&RpcFree,
|
||||
&RpcGetProcessData,
|
||||
&RpcPrint,
|
||||
&RpcDebug,
|
||||
&RpcGetInterfaceName
|
||||
};
|
||||
pDecompilerCtxt = pRpcDecompilerHelper->RpcDecompilerInitFn(&LocalRpcViewHelper, &RpcDecompilerInfo);
|
||||
if (pDecompilerCtxt!=NULL)
|
||||
{
|
||||
pRpcDecompilerHelper->RpcDecompilerPrintAllProceduresFn( pDecompilerCtxt );
|
||||
pRpcDecompilerHelper->RpcDecompilerUninitFn(pDecompilerCtxt);
|
||||
}
|
||||
}__except( DecompilerExceptionFilter(GetExceptionInformation()) )
|
||||
{
|
||||
//Failure
|
||||
goto End;
|
||||
}
|
||||
End:
|
||||
UninitDecompilerInfo(&RpcDecompilerInfo);
|
||||
if (hDecompiler!=NULL) FreeLibrary(hDecompiler);
|
||||
if (pRpcInterfaceInfo!=NULL)
|
||||
{
|
||||
pRpcCore->RpcCoreFreeInterfaceInfoFn(pRpcCoreCtxt,pRpcInterfaceInfo);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::ViewDetailsForAllProcesses()
|
||||
{
|
||||
HINSTANCE hInstance;
|
||||
UCHAR FilePath[MAX_PATH];
|
||||
|
||||
GetModuleFileNameA(NULL,(LPSTR)FilePath,_countof(FilePath));
|
||||
hInstance = ShellExecuteA(NULL, "runas", (LPCSTR)FilePath, 0, 0, SW_SHOWNORMAL);
|
||||
if ( hInstance == SHELL_EXECUTE_SUCCESS)
|
||||
{
|
||||
Exit();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::About()
|
||||
{
|
||||
Version_T Version;
|
||||
QString AboutText;
|
||||
HMODULE hDecompiler;
|
||||
RpcDecompilerHelper_T* pRpcDecompilerHelper = NULL;
|
||||
LocationInfo_T LocationInfo;
|
||||
|
||||
AboutText.append("RpcView");
|
||||
|
||||
if (!GetLocationInfo(GetCurrentProcess(), GetModuleHandle(NULL), &LocationInfo)) goto End;
|
||||
Version.As64BitsValue = GetModuleVersion(LocationInfo.Location);
|
||||
|
||||
AboutText.append( QString(" v%4.%3.%2.%1\n\n").arg(Version.As16BitsValues.Part1).arg(Version.As16BitsValues.Part2).arg(Version.As16BitsValues.Part3).arg(Version.As16BitsValues.Part4) );
|
||||
/*
|
||||
Version.As64BitsValue = pRpcCoreNativeHelper->RuntimeVersion;
|
||||
AboutText.append(" - ");
|
||||
AboutText.append(pRpcCoreNativeHelper->pDescription);
|
||||
AboutText.append( QString(" for v%4.%3.%2.%1\n").arg(Version.As16BitsValues.Part1).arg(Version.As16BitsValues.Part2).arg(Version.As16BitsValues.Part3).arg(Version.As16BitsValues.Part4) );
|
||||
Version.As64BitsValue = pRpcCoreNativeHelper->RuntimeVersion;
|
||||
#ifdef _WIN64
|
||||
Version.As64BitsValue = pRpcCoreWow64Helper->RuntimeVersion;
|
||||
AboutText.append(" - ");
|
||||
AboutText.append(pRpcCoreWow64Helper->pDescription);
|
||||
AboutText.append( QString(" for v%4.%3.%2.%1\n").arg(Version.As16BitsValues.Part1).arg(Version.As16BitsValues.Part2).arg(Version.As16BitsValues.Part3).arg(Version.As16BitsValues.Part4) );
|
||||
Version.As64BitsValue = pRpcCoreWow64Helper->RuntimeVersion;
|
||||
#endif
|
||||
*/
|
||||
hDecompiler = LoadDecompilerEngine(&pRpcDecompilerHelper);
|
||||
if (hDecompiler==NULL) goto End;
|
||||
|
||||
if (!GetLocationInfo(GetCurrentProcess(), hDecompiler, &LocationInfo)) goto End;
|
||||
Version.As64BitsValue = GetModuleVersion(LocationInfo.Location);
|
||||
FreeLibrary(hDecompiler);
|
||||
|
||||
AboutText.append(" - Decompiler engine");
|
||||
AboutText.append( QString(" v%4.%3.%2.%1\n").arg(Version.As16BitsValues.Part1).arg(Version.As16BitsValues.Part2).arg(Version.As16BitsValues.Part3).arg(Version.As16BitsValues.Part4) );
|
||||
|
||||
End:
|
||||
QMessageBox::about(
|
||||
this,
|
||||
"About RpcView",
|
||||
AboutText
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::Help()
|
||||
{
|
||||
QMessageBox::information(
|
||||
this,
|
||||
"RpcView Help",
|
||||
"RpcView presents a complete view of RPC interfaces on a system.\n"
|
||||
"See http://rpcview.org"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::SendVisitor(ViewVisitor_C& Visitor)
|
||||
{
|
||||
//
|
||||
// todo: a vector of elements (maybe a view factory???)
|
||||
//
|
||||
pProcessWidget->AcceptVisitor(&Visitor);
|
||||
pEndpointsWidget->AcceptVisitor(&Visitor);
|
||||
pInterfacesWidget->AcceptVisitor(&Visitor);
|
||||
pProceduresWidget->AcceptVisitor(&Visitor);
|
||||
|
||||
pInterfaceInfoWidget->AcceptVisitor(&Visitor);
|
||||
pProcessInfoWidget->AcceptVisitor(&Visitor);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
Exit();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::Exit()
|
||||
{
|
||||
pSettings->setValue("MainWindow/windowState", saveState());
|
||||
pSettings->setValue("MainWindow/geometry", saveGeometry());
|
||||
pSettings->setValue("RefreshSpeed", this->RefreshSpeedInMs);
|
||||
pSettings->setValue("AddressRepresentation", this->AddressRepresentation);
|
||||
|
||||
ConfigurationVisitor_C ConfigurationVisitor(ConfigurationVisitor_C::Save, pSettings);
|
||||
SendVisitor(ConfigurationVisitor);
|
||||
//
|
||||
// Uninit the RpcCore
|
||||
//
|
||||
pRpcCore->RpcCoreUninitFn(pRpcCoreCtxt);
|
||||
delete this;
|
||||
#ifdef _DEBUG
|
||||
_CrtDumpMemoryLeaks();
|
||||
#endif
|
||||
ExitProcess(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::RefreshViews()
|
||||
{
|
||||
RefreshVisitor_C RefreshVisitor(
|
||||
pRpcCore,
|
||||
pRpcCoreCtxt
|
||||
);
|
||||
|
||||
SendVisitor(RefreshVisitor);
|
||||
|
||||
pEndpointsCountLabel->setText( QString("Endpoints: %1/%2").arg(RefreshVisitor.GetEndpoints()).arg(RefreshVisitor.GetTotalEndpoints()) );
|
||||
pProcessesCountLabel->setText( QString("Processes: %1/%2").arg(RefreshVisitor.GetProcesses()).arg(RefreshVisitor.GetTotalProcesses()) );
|
||||
pInterfacesCountLabel->setText( QString("Interfaces: %1/%2").arg(RefreshVisitor.GetInterfaces()).arg(RefreshVisitor.GetTotalInterfaces()) );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::ConfigureSymbols()
|
||||
{
|
||||
bool bOk;
|
||||
QString Txt;
|
||||
QString CurrentSymbolsPath;
|
||||
QString NewSymbolsPath;
|
||||
|
||||
CurrentSymbolsPath = pSettings->value("SymbolsPath").toString();
|
||||
|
||||
NewSymbolsPath = QInputDialog::getText(
|
||||
this,
|
||||
"Configure Symbols",
|
||||
"RpcView uses symbols to resolve function names when displaying RPC procedures names.\n\nIf you do not require that information you do not need to configure symbols",
|
||||
QLineEdit::Normal,
|
||||
CurrentSymbolsPath,
|
||||
&bOk
|
||||
);
|
||||
if ( bOk && !NewSymbolsPath.isEmpty() )
|
||||
{
|
||||
pSettings->setValue("SymbolsPath",NewSymbolsPath);
|
||||
SetEnvironmentVariableA("RpcViewSymbolPath",NewSymbolsPath.toAscii());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::SetUpdateSpeedAsFast()
|
||||
{
|
||||
this->RefreshSpeedInMs = FAST_REFRESH_SPEED;
|
||||
pRefreshTimer->setInterval(this->RefreshSpeedInMs);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::SetUpdateSpeedAsNormal()
|
||||
{
|
||||
this->RefreshSpeedInMs = NORMAL_REFRESH_SPEED;
|
||||
pRefreshTimer->setInterval(this->RefreshSpeedInMs);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::SetUpdateSpeedAsBelowNormal()
|
||||
{
|
||||
this->RefreshSpeedInMs = BELOW_NORMAL_REFRESH_SPEED;
|
||||
pRefreshTimer->setInterval(this->RefreshSpeedInMs);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::SetUpdateSpeedAsSlow()
|
||||
{
|
||||
this->RefreshSpeedInMs = SLOW_REFRESH_SPEED;
|
||||
pRefreshTimer->setInterval(this->RefreshSpeedInMs);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::SetUpdateSpeedAsVerySlow()
|
||||
{
|
||||
this->RefreshSpeedInMs = VERY_SLOW_REFRESH_SPEED;
|
||||
pRefreshTimer->setInterval(this->RefreshSpeedInMs);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::InvokeFindShortcut()
|
||||
{
|
||||
QKeyEvent FindEvent(QKeyEvent::KeyPress, Qt::Key_F, Qt::ControlModifier);
|
||||
QApplication::sendEvent(this, &FindEvent);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::FilterProcesses()
|
||||
{
|
||||
pProcessWidget->setFocus(Qt::ActiveWindowFocusReason);
|
||||
InvokeFindShortcut();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::FilterEndpoints()
|
||||
{
|
||||
pEndpointsWidget->setFocus(Qt::ActiveWindowFocusReason);
|
||||
InvokeFindShortcut();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::FilterInterfaces()
|
||||
{
|
||||
pInterfacesWidget->setFocus(Qt::ActiveWindowFocusReason);
|
||||
InvokeFindShortcut();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::SetAbsolute()
|
||||
{
|
||||
this->AddressRepresentation = AddressRepresentation_Absolute;
|
||||
|
||||
ConfigurationVisitor_C ConfigurationVisitor(ConfigurationVisitor_C::AddressAbsolute, NULL);
|
||||
SendVisitor(ConfigurationVisitor);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::SetRVA()
|
||||
{
|
||||
this->AddressRepresentation = AddressRepresentation_RVA;
|
||||
|
||||
ConfigurationVisitor_C ConfigurationVisitor(ConfigurationVisitor_C::AddressRVA, NULL);
|
||||
SendVisitor(ConfigurationVisitor);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::SetupMenu()
|
||||
{
|
||||
HICON hUacIcon;
|
||||
QMenuBar* pMenuBar = new QMenuBar(this);
|
||||
//
|
||||
// File
|
||||
//
|
||||
QMenu* pMenuFile = pMenuBar->addMenu("&File");
|
||||
QAction* pActionAllProcessesDetails = pMenuFile->addAction("Show &Details for All Processes",this,SLOT(ViewDetailsForAllProcesses()));
|
||||
QAction* pActionFileExit = pMenuFile->addAction("E&xit",this,SLOT(Exit()));
|
||||
//
|
||||
// Option
|
||||
//
|
||||
QMenu* pMenuOptions = pMenuBar->addMenu("&Options");
|
||||
QAction* pActionConfigureSymbols = pMenuOptions->addAction("Configure Sym&bols",this,SLOT(ConfigureSymbols()));
|
||||
QMenu* pSubMenupdateSpeed = pMenuOptions->addMenu("&Refresh Speed");
|
||||
QAction* pActionRefresh = pMenuOptions->addAction("Refresh &Now", this, SLOT(RefreshViews()));
|
||||
QAction* pActionViewSelectColumns = pMenuOptions->addAction("Select Col&umns", this, SLOT(ShowColumnsDialog()));
|
||||
QMenu* pSubMenuAddress = pMenuOptions->addMenu("&Address");
|
||||
pActionRefresh->setShortcut(Qt::Key_F5);
|
||||
|
||||
pAddressAbsolute = pSubMenuAddress->addAction("Absolute", this, SLOT(SetAbsolute()));
|
||||
pAddressRva = pSubMenuAddress->addAction("RVA", this, SLOT(SetRVA()));
|
||||
QActionGroup* pAddressGroup = new QActionGroup(this);
|
||||
|
||||
pAddressGroup->addAction(pAddressAbsolute);
|
||||
pAddressGroup->addAction(pAddressRva);
|
||||
|
||||
pAddressAbsolute->setCheckable(true);
|
||||
pAddressRva->setCheckable(true);
|
||||
|
||||
pActionSpeedFast = pSubMenupdateSpeed->addAction(".5 seconds", this, SLOT(SetUpdateSpeedAsFast()));
|
||||
pActionSpeedNormal = pSubMenupdateSpeed->addAction("1 second", this, SLOT(SetUpdateSpeedAsNormal()));
|
||||
pActionSpeedBelowNormal = pSubMenupdateSpeed->addAction("2 seconds", this, SLOT(SetUpdateSpeedAsBelowNormal()));
|
||||
pActionSpeedSlow = pSubMenupdateSpeed->addAction("5 seconds", this, SLOT(SetUpdateSpeedAsSlow()));
|
||||
pActionSpeedVerySlow = pSubMenupdateSpeed->addAction("10 seconds", this, SLOT(SetUpdateSpeedAsVerySlow()));
|
||||
|
||||
pActionSpeedFast->setCheckable(true);
|
||||
pActionSpeedNormal->setCheckable(true);
|
||||
pActionSpeedBelowNormal->setCheckable(true);
|
||||
pActionSpeedSlow->setCheckable(true);
|
||||
pActionSpeedVerySlow->setCheckable(true);
|
||||
|
||||
QActionGroup* pSpeedActionGroup = new QActionGroup(this);
|
||||
|
||||
pSpeedActionGroup->addAction(pActionSpeedFast);
|
||||
pSpeedActionGroup->addAction(pActionSpeedNormal);
|
||||
pSpeedActionGroup->addAction(pActionSpeedBelowNormal);
|
||||
pSpeedActionGroup->addAction(pActionSpeedSlow);
|
||||
pSpeedActionGroup->addAction(pActionSpeedVerySlow);
|
||||
//
|
||||
// View
|
||||
//
|
||||
QMenu* pMenuView = pMenuBar->addMenu("&View");
|
||||
pMenuView->addAction(pInterfacesWidget->toggleViewAction());
|
||||
pMenuView->addAction(pEndpointsWidget->toggleViewAction());
|
||||
pMenuView->addAction(pProceduresWidget->toggleViewAction());
|
||||
pMenuView->addAction(pProcessInfoWidget->toggleViewAction());
|
||||
pMenuView->addAction(pInterfaceInfoWidget->toggleViewAction());
|
||||
pMenuView->addAction(pDecompilationWidget->toggleViewAction());
|
||||
|
||||
pInterfacesWidget->toggleViewAction()->setText("&Interfaces");
|
||||
pEndpointsWidget->toggleViewAction()->setText("&Endpoints");
|
||||
pProceduresWidget->toggleViewAction()->setText("&Procedures");
|
||||
pProcessInfoWidget->toggleViewAction()->setText("Proce&ss Properties");
|
||||
pInterfaceInfoWidget->toggleViewAction()->setText("Inter&faces Properties");
|
||||
pDecompilationWidget->toggleViewAction()->setText("&Decompilation");
|
||||
//
|
||||
// Filter
|
||||
//
|
||||
QMenu* pMenuFilter = pMenuBar->addMenu("Fil&ter");
|
||||
QAction* pActionFilterProcesses = pMenuFilter->addAction("&Process", this, SLOT(FilterProcesses()));
|
||||
QAction* pActionFilterEndpoints = pMenuFilter->addAction("&Endpoints", this, SLOT(FilterEndpoints()));
|
||||
QAction* pActionFilterInterfaces = pMenuFilter->addAction("&Interfaces", this, SLOT(FilterInterfaces()));
|
||||
//
|
||||
// Help
|
||||
//
|
||||
QMenu* pMenuHelp = pMenuBar->addMenu("&Help");
|
||||
QAction* pActionHelp = pMenuHelp->addAction("&Help...", this, SLOT(Help()));
|
||||
pActionHelp->setShortcut(Qt::Key_F1);
|
||||
//--
|
||||
pMenuHelp->addSeparator();
|
||||
//--
|
||||
QAction* pActionAbout = pMenuHelp->addAction("&About", this, SLOT(About()));
|
||||
pActionAboutQt = pMenuHelp->addAction("About &Qt", qApp, SLOT(aboutQt()));
|
||||
|
||||
if (IsUserAnAdmin()) pActionAllProcessesDetails->setEnabled(false);
|
||||
|
||||
hUacIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(ID_UAC_ICON));
|
||||
if (hUacIcon!=NULL)
|
||||
{
|
||||
pActionAllProcessesDetails->setIcon(QPixmap::fromWinHICON(hUacIcon));
|
||||
DestroyIcon(hUacIcon);
|
||||
}
|
||||
setMenuBar(pMenuBar);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::InitMenuRefreshSpeed()
|
||||
{
|
||||
switch(RefreshSpeedInMs)
|
||||
{
|
||||
case FAST_REFRESH_SPEED : pActionSpeedFast->setChecked(true); break;
|
||||
case NORMAL_REFRESH_SPEED : pActionSpeedNormal->setChecked(true); break;
|
||||
case BELOW_NORMAL_REFRESH_SPEED : pActionSpeedBelowNormal->setChecked(true); break;
|
||||
case SLOW_REFRESH_SPEED : pActionSpeedSlow->setChecked(true); break;
|
||||
case VERY_SLOW_REFRESH_SPEED : pActionSpeedVerySlow->setChecked(true); break;
|
||||
//--
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow_C::InitMenuAddressRepresentation()
|
||||
{
|
||||
switch (AddressRepresentation)
|
||||
{
|
||||
case AddressRepresentation_Absolute : pAddressAbsolute->setChecked(true); break;
|
||||
case AddressRepresentation_RVA : pAddressRva->setChecked(true); break;
|
||||
//--
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
MainWindow_C::MainWindow_C(RpcCore_T* pRpcCore)
|
||||
{
|
||||
setObjectName(WidgetName); //required to save the window geometry/state
|
||||
setWindowTitle(WidgetName);
|
||||
//
|
||||
// Inits Helpers: RpcCore and RpcDecompiler
|
||||
//
|
||||
this->pRpcCore = pRpcCore;
|
||||
|
||||
setDockOptions(
|
||||
QMainWindow::AllowNestedDocks|
|
||||
QMainWindow::AllowTabbedDocks|
|
||||
QMainWindow::AnimatedDocks
|
||||
);
|
||||
//
|
||||
// Creates all the views
|
||||
//
|
||||
pInterfacesWidget = new InterfacesWidget_C(this);
|
||||
pProceduresWidget = new ProceduresWidget_C(this);
|
||||
pInterfaceInfoWidget= new InterfaceInfoWidget_C(this);
|
||||
pProcessWidget = new ProcessWidget_C(this);
|
||||
pProcessInfoWidget = new ProcessInfoWidget_C(this);
|
||||
pEndpointsWidget = new EndpointsWidget_C(this);
|
||||
pDecompilationWidget= new DecompilationWidget_C(this);
|
||||
//
|
||||
// Add the Process view as the main one
|
||||
//
|
||||
setCentralWidget(pProcessWidget);
|
||||
//
|
||||
// All other views are optional DockWidgets:
|
||||
//
|
||||
addDockWidget(Qt::RightDockWidgetArea, pProcessInfoWidget);
|
||||
addDockWidget(Qt::RightDockWidgetArea, pInterfaceInfoWidget);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, pInterfacesWidget);
|
||||
addDockWidget(Qt::LeftDockWidgetArea, pEndpointsWidget);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, pProceduresWidget);
|
||||
addDockWidget(Qt::LeftDockWidgetArea, pDecompilationWidget);
|
||||
//
|
||||
// Create the menu
|
||||
//
|
||||
SetupMenu();
|
||||
|
||||
pProcessesCountLabel = new QLabel("Processes: -",this);
|
||||
pInterfacesCountLabel = new QLabel("Interfaces: -",this);
|
||||
pEndpointsCountLabel = new QLabel("Enpoints: -",this);
|
||||
|
||||
StatusBar.showMessage("Ready.");
|
||||
|
||||
StatusBar.addPermanentWidget(pEndpointsCountLabel);
|
||||
StatusBar.addPermanentWidget(pInterfacesCountLabel);
|
||||
StatusBar.addPermanentWidget(pProcessesCountLabel);
|
||||
|
||||
setStatusBar(&StatusBar);
|
||||
|
||||
HANDLE hIcon = LoadImageA(GetModuleHandle(NULL), MAKEINTRESOURCE(ID_MAIN_ICON), IMAGE_ICON, 0, 0, 0);
|
||||
|
||||
QFont font("Helvetica", 20, QFont::Bold);
|
||||
#ifndef _DEBUG
|
||||
QSplashScreen SplashScreen(QPixmap::fromWinHICON((HICON)hIcon),Qt::WindowStaysOnTopHint);
|
||||
SplashScreen.showMessage(QString("RpcView"), Qt::AlignCenter, QColor(Qt::lightGray));
|
||||
SplashScreen.setFont(font);
|
||||
SplashScreen.show();
|
||||
#endif
|
||||
//
|
||||
// Init all the views
|
||||
//
|
||||
InitViewsVisitor_C InitViewsVisitor(
|
||||
pRpcCore,
|
||||
&pRpcCoreCtxt
|
||||
);
|
||||
SendVisitor(InitViewsVisitor);
|
||||
//
|
||||
// Restore saved settings
|
||||
//
|
||||
pSettings = new QSettings(RPC_VIEW_ORGANIZATION_NAME, RPC_VIEW_APPLICATION_NAME,this);
|
||||
|
||||
QVariant RefreshSpeedValue;
|
||||
|
||||
RefreshSpeedValue = pSettings->value("RefreshSpeed");
|
||||
if (RefreshSpeedValue.isNull())
|
||||
{
|
||||
this->RefreshSpeedInMs = NORMAL_REFRESH_SPEED;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->RefreshSpeedInMs = RefreshSpeedValue.toUInt();
|
||||
}
|
||||
InitMenuRefreshSpeed();
|
||||
|
||||
QVariant AddressRepresentationValue;
|
||||
|
||||
AddressRepresentationValue = pSettings->value("AddressRepresentation");
|
||||
if (AddressRepresentationValue.isNull())
|
||||
{
|
||||
this->AddressRepresentation = AddressRepresentation_Absolute;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->AddressRepresentation = (AddressRepresentation_T)AddressRepresentationValue.toUInt();
|
||||
}
|
||||
InitMenuAddressRepresentation();
|
||||
show();
|
||||
|
||||
restoreGeometry( pSettings->value("MainWindow/geometry").toByteArray() );
|
||||
restoreState( pSettings->value("MainWindow/windowState").toByteArray() );
|
||||
ConfigurationVisitor_C ConfigurationVisitor(ConfigurationVisitor_C::Load,pSettings);
|
||||
SendVisitor(ConfigurationVisitor);
|
||||
if (AddressRepresentation == AddressRepresentation_RVA)
|
||||
{
|
||||
ConfigurationVisitor_C ConfigurationVisitor(ConfigurationVisitor_C::AddressRVA, pSettings);
|
||||
SendVisitor(ConfigurationVisitor);
|
||||
}
|
||||
|
||||
SetEnvironmentVariableA( "RpcViewSymbolPath",pSettings->value("SymbolsPath").toByteArray() );
|
||||
|
||||
pInterfacesCountLabel->setText( QString("Interfaces: %1").arg(InitViewsVisitor.GetInterfaces()) );
|
||||
pEndpointsCountLabel->setText( QString("Endpoints: %1").arg(InitViewsVisitor.GetEndpoints()) );
|
||||
//
|
||||
// Start auto refresh
|
||||
//
|
||||
pRefreshTimer = new QTimer(this);
|
||||
connect(pRefreshTimer, SIGNAL(timeout()), this, SLOT(RefreshViews()));
|
||||
pRefreshTimer->start(this->RefreshSpeedInMs);
|
||||
|
||||
InitColumnsDialog();
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
#ifndef _MAIN_WINDOW_H_
|
||||
#define _MAIN_WINDOW_H_
|
||||
|
||||
#include "..\Qt\Qt.h"
|
||||
|
||||
#include "..\RpcCommon\RpcView.h"
|
||||
#include "ProcessWidget.h"
|
||||
#include "ProcessInfoWidget.h"
|
||||
#include "EndpointsWidget.h"
|
||||
#include "InterfacesWidget.h"
|
||||
#include "InterfaceInfoWidget.h"
|
||||
#include "ProceduresWidget.h"
|
||||
#include "DecompilationWidget.h"
|
||||
#include "..\RpcCore\RpcCore.h"
|
||||
#include "..\RpcDecompiler\RpcDecompiler.h"
|
||||
#include "ViewVisitor.h"
|
||||
|
||||
#define RPC_VIEW_ORGANIZATION_NAME "RpcView Team"
|
||||
#define RPC_VIEW_APPLICATION_NAME "RpcView"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class MainWindow_C : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow_C(RpcCore_T* pRpcCore);
|
||||
|
||||
public slots:
|
||||
void ConfigureSymbols();
|
||||
void ProcessSelected(quint32 Pid);
|
||||
void EndpointSelected(quint32 Pid);
|
||||
void InterfaceSelected(quint32 Pid, RPC_IF_ID* pIf);
|
||||
void SlotDecompileInterface(quint32, RPC_IF_ID*);
|
||||
void SetAbsolute();
|
||||
void SetRVA();
|
||||
void Exit();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
private slots:
|
||||
void About();
|
||||
void Help();
|
||||
void RefreshViews();
|
||||
void ViewDetailsForAllProcesses();
|
||||
//--
|
||||
void SetUpdateSpeedAsFast();
|
||||
void SetUpdateSpeedAsNormal();
|
||||
void SetUpdateSpeedAsBelowNormal();
|
||||
void SetUpdateSpeedAsSlow();
|
||||
void SetUpdateSpeedAsVerySlow();
|
||||
void ShowColumnsDialog();
|
||||
void UpdateColumns();
|
||||
//--
|
||||
void FilterProcesses();
|
||||
void FilterEndpoints();
|
||||
void FilterInterfaces();
|
||||
|
||||
private:
|
||||
void* pRpcCoreCtxt;
|
||||
RpcCore_T* pRpcCore;
|
||||
AddressRepresentation_T AddressRepresentation;
|
||||
|
||||
QStatusBar StatusBar;
|
||||
ProcessWidget_C* pProcessWidget;
|
||||
ProcessInfoWidget_C* pProcessInfoWidget;
|
||||
ProceduresWidget_C* pProceduresWidget;
|
||||
EndpointsWidget_C* pEndpointsWidget;
|
||||
InterfacesWidget_C* pInterfacesWidget;
|
||||
InterfaceInfoWidget_C* pInterfaceInfoWidget;
|
||||
DecompilationWidget_C* pDecompilationWidget;
|
||||
|
||||
QLabel* pProcessesCountLabel;
|
||||
QLabel* pInterfacesCountLabel;
|
||||
QLabel* pEndpointsCountLabel;
|
||||
|
||||
QAction* pActionViewInterfaces;
|
||||
QAction* pActionViewEndpoints;
|
||||
QAction* pActionViewProcedures;
|
||||
QAction* pActionViewInterfaceInfo;
|
||||
QAction* pActionViewProcessInfo;
|
||||
QAction* pActionAboutQt;
|
||||
QAction* pActionSpeedFast;
|
||||
QAction* pActionSpeedNormal;
|
||||
QAction* pActionSpeedBelowNormal;
|
||||
QAction* pActionSpeedSlow;
|
||||
QAction* pActionSpeedVerySlow;
|
||||
QAction* pAddressAbsolute;
|
||||
QAction* pAddressRva;
|
||||
|
||||
QSettings* pSettings;
|
||||
QTimer* pRefreshTimer ;
|
||||
//--
|
||||
uint RefreshSpeedInMs;
|
||||
//--
|
||||
// Columns Dialog
|
||||
QDialog* ColumnsDialog;
|
||||
QVBoxLayout* ColumnsVLayout;
|
||||
QHBoxLayout* ColumnsHLayout;
|
||||
QVBoxLayout* ColumnsVLayout1;
|
||||
QDialogButtonBox* ColumnsButtonBox;
|
||||
QWidget* pProcessColumns;
|
||||
QWidget* pEndpointsColumns;
|
||||
QWidget* pInterfacesColumns;
|
||||
QWidget* pProceduresColumns;
|
||||
|
||||
|
||||
void SendVisitor(ViewVisitor_C& pVisitor);
|
||||
void InitMenuRefreshSpeed();
|
||||
void InitMenuAddressRepresentation();
|
||||
void InitColumnsDialog();
|
||||
void SetupMenu();
|
||||
void InvokeFindShortcut();
|
||||
bool eventFilter(QObject* pObject, QEvent* pEvent);
|
||||
};
|
||||
|
||||
#endif// _PROCESS_LOGGER_WINDOW_H_
|
|
@ -0,0 +1,194 @@
|
|||
#include "Pdb.h"
|
||||
#include <conio.h>
|
||||
#include <Strsafe.h>
|
||||
#include <Dbghelp.h>
|
||||
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <stdlib.h>
|
||||
#include <crtdbg.h>
|
||||
|
||||
#define RSDS_SIGNATURE 'SDSR'
|
||||
#define PDB_MAX_SYMBOL_SIZE 1000
|
||||
|
||||
//Only for PDB2.0 format!
|
||||
struct CV_INFO_PDB20{
|
||||
DWORD CvSignature;
|
||||
DWORD Offset;
|
||||
DWORD Signature;
|
||||
DWORD Age;
|
||||
BYTE PdbFileName[MAX_PATH];
|
||||
};
|
||||
|
||||
//Only for PDB7.0 format!
|
||||
typedef struct _CV_INFO_PDB70{
|
||||
DWORD CvSignature;
|
||||
GUID Signature;
|
||||
DWORD Age;
|
||||
BYTE PdbFileName[MAX_PATH];
|
||||
} CV_INFO_PDB70;
|
||||
|
||||
|
||||
typedef struct _PdbCtxt_T{
|
||||
HANDLE hProcess;
|
||||
void* pModuleBase;
|
||||
ULONG ModuleSize;
|
||||
}PdbCtxt_T;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL WINAPI GetModulePdbInfo(HANDLE hProcess, VOID* pModuleBase, CV_INFO_PDB70* pPdb70Info)
|
||||
{
|
||||
UCHAR* pBase = (UCHAR*)pModuleBase;
|
||||
IMAGE_DOS_HEADER ImageDosHeader;
|
||||
IMAGE_NT_HEADERS ImageNtHeaders;
|
||||
IMAGE_DEBUG_DIRECTORY ImageDebugDirectory;
|
||||
BOOL bResult = FALSE;
|
||||
#ifdef _WIN64
|
||||
BOOL bWow64;
|
||||
IMAGE_NT_HEADERS32 ImageNtHeaders32;
|
||||
|
||||
if (hProcess==NULL) hProcess = GetCurrentProcess();
|
||||
|
||||
if (!IsWow64Process(hProcess, &bWow64)) goto End;
|
||||
if (bWow64==TRUE)
|
||||
{
|
||||
if (!ReadProcessMemory(hProcess, pModuleBase, &ImageDosHeader, sizeof(ImageDosHeader), NULL)) goto End;
|
||||
if (!ReadProcessMemory(hProcess, pBase + ImageDosHeader.e_lfanew, &ImageNtHeaders32, sizeof(ImageNtHeaders32), NULL)) goto End;
|
||||
if (!ReadProcessMemory(hProcess, pBase + ImageNtHeaders32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress, &ImageDebugDirectory, sizeof(ImageDebugDirectory), NULL)) goto End;
|
||||
if (!ReadProcessMemory(hProcess, pBase + ImageDebugDirectory.AddressOfRawData, pPdb70Info, sizeof(*pPdb70Info), NULL)) goto End;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (!ReadProcessMemory(hProcess, pModuleBase, &ImageDosHeader, sizeof(ImageDosHeader), NULL)) goto End;
|
||||
if (!ReadProcessMemory(hProcess, pBase + ImageDosHeader.e_lfanew, &ImageNtHeaders, sizeof(ImageNtHeaders), NULL)) goto End;
|
||||
if (!ReadProcessMemory(hProcess, pBase + ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress, &ImageDebugDirectory, sizeof(ImageDebugDirectory), NULL)) goto End;
|
||||
if (!ReadProcessMemory(hProcess, pBase + ImageDebugDirectory.AddressOfRawData, pPdb70Info, sizeof(*pPdb70Info), NULL)) goto End;
|
||||
}
|
||||
if (pPdb70Info->CvSignature != RSDS_SIGNATURE )
|
||||
{
|
||||
_cprintf("Invalid CvSignature");
|
||||
goto End;
|
||||
}
|
||||
bResult = TRUE;
|
||||
End:
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL WINAPI GetPdbFilePath(HANDLE hProcess, VOID* pModuleBase, UCHAR* pPdbPath, UINT PdbPathSize)
|
||||
{
|
||||
CV_INFO_PDB70 Pdb70Info;
|
||||
CHAR SymbolPath[MAX_PATH];
|
||||
BOOL bResult = FALSE;
|
||||
|
||||
if (!GetModulePdbInfo(hProcess, pModuleBase, &Pdb70Info)) goto End;
|
||||
/*
|
||||
if (!SymFindFileInPath(hProcess, "c:\\symbols\\", Pdb70Info.PdbFileName, &Pdb70Info.Signature, Pdb70Info.Age, 0, SSRVOPT_GUIDPTR, pPdbPath, NULL, NULL))
|
||||
{
|
||||
printf("SymFindFileInPath failed %u\n", GetLastError());
|
||||
goto End;
|
||||
}
|
||||
*/
|
||||
if (strchr((char*)Pdb70Info.PdbFileName, '\\') != NULL)
|
||||
{
|
||||
StringCbPrintfA((STRSAFE_LPSTR)pPdbPath, PdbPathSize, "%hs", Pdb70Info.PdbFileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetEnvironmentVariableA("RpcViewSymbolPath", SymbolPath, sizeof(SymbolPath)) == 0) goto End;
|
||||
StringCbPrintfA((STRSAFE_LPSTR)pPdbPath, PdbPathSize, "%s\\%s\\%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%X\\%s",
|
||||
SymbolPath,
|
||||
Pdb70Info.PdbFileName,
|
||||
Pdb70Info.Signature.Data1,
|
||||
Pdb70Info.Signature.Data2,
|
||||
Pdb70Info.Signature.Data3,
|
||||
Pdb70Info.Signature.Data4[0],
|
||||
Pdb70Info.Signature.Data4[1],
|
||||
Pdb70Info.Signature.Data4[2],
|
||||
Pdb70Info.Signature.Data4[3],
|
||||
Pdb70Info.Signature.Data4[4],
|
||||
Pdb70Info.Signature.Data4[5],
|
||||
Pdb70Info.Signature.Data4[6],
|
||||
Pdb70Info.Signature.Data4[7],
|
||||
Pdb70Info.Age,
|
||||
Pdb70Info.PdbFileName
|
||||
);
|
||||
}
|
||||
//printf("pdb path: %s\n",pPdbPath);
|
||||
bResult = TRUE;
|
||||
End:
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
__checkReturn void* WINAPI PdbInit(__in HANDLE hProcess, __in VOID* pModuleBase, __in UINT ModuleSize)
|
||||
{
|
||||
UCHAR PdbPath[MAX_PATH];
|
||||
PdbCtxt_T* pPdbCtxt = NULL;
|
||||
|
||||
if (!SymInitialize(hProcess, NULL, FALSE)) goto End;
|
||||
if (!GetPdbFilePath(hProcess, pModuleBase, PdbPath, sizeof(PdbPath))) goto End;
|
||||
if (!SymLoadModule64(hProcess, NULL, (STRSAFE_LPCSTR)PdbPath, NULL,(DWORD64) pModuleBase, ModuleSize))
|
||||
{
|
||||
printf("SymLoadModule64 failed\n");
|
||||
SymCleanup(hProcess);
|
||||
goto End;
|
||||
}
|
||||
//
|
||||
// All is ok, so we can allocate and init the PDB private context
|
||||
//
|
||||
pPdbCtxt = (PdbCtxt_T*)malloc(sizeof(PdbCtxt_T));
|
||||
if (pPdbCtxt!=NULL)
|
||||
{
|
||||
ZeroMemory(pPdbCtxt, sizeof(PdbCtxt_T));
|
||||
|
||||
pPdbCtxt->hProcess = hProcess;
|
||||
pPdbCtxt->ModuleSize = ModuleSize;
|
||||
pPdbCtxt->pModuleBase = pModuleBase;
|
||||
}
|
||||
End:
|
||||
return (pPdbCtxt);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
__checkReturn BOOL WINAPI PdbGetSymbolName(__in void* hCtxt, __in VOID* pSymbol, __out WCHAR* pName, __in UINT NameLength)
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
IMAGEHLP_SYMBOL64* pSymbolInfo = NULL;
|
||||
DWORD64 dwDisp = 0;
|
||||
PdbCtxt_T* pPdbCtxt = (PdbCtxt_T*)hCtxt;
|
||||
|
||||
if (pPdbCtxt==NULL) goto End;
|
||||
|
||||
pSymbolInfo=(IMAGEHLP_SYMBOL64*)malloc( PDB_MAX_SYMBOL_SIZE );
|
||||
if (pSymbolInfo==NULL) goto End;
|
||||
ZeroMemory(pSymbolInfo, PDB_MAX_SYMBOL_SIZE);
|
||||
|
||||
pSymbolInfo->MaxNameLength = NameLength;
|
||||
pSymbolInfo->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
|
||||
|
||||
bResult = SymGetSymFromAddr64( pPdbCtxt->hProcess, (DWORD64)pSymbol, &dwDisp, pSymbolInfo);
|
||||
if (!bResult) goto End;
|
||||
if (dwDisp!=0) goto End;
|
||||
StringCbPrintfW(pName,NameLength,L"%S",pSymbolInfo->Name);
|
||||
End:
|
||||
if (pSymbolInfo!=NULL) free(pSymbolInfo);
|
||||
return (bResult);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void WINAPI PdbUninit(__in void* hCtxt)
|
||||
{
|
||||
PdbCtxt_T* pPdbCtxt = (PdbCtxt_T*)hCtxt;
|
||||
|
||||
if (pPdbCtxt==NULL) goto End;
|
||||
SymUnloadModule64(pPdbCtxt->hProcess,(DWORD64)pPdbCtxt->pModuleBase);
|
||||
free(pPdbCtxt);
|
||||
End:
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef _PDB_H_
|
||||
#define _PDB_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
EXTERN_C __checkReturn void* WINAPI PdbInit(__in HANDLE hProcess, __in VOID* pModuleBase, __in UINT ModuleSize);
|
||||
EXTERN_C __checkReturn BOOL WINAPI PdbGetSymbolName(__in void* pPdbCtxt, __in VOID* pSymbol, __out WCHAR* pName, __in UINT NameLength);
|
||||
EXTERN_C void WINAPI PdbUninit(__in void* pPdbCtxt);
|
||||
|
||||
#endif // _PDB_H_
|
|
@ -0,0 +1,226 @@
|
|||
#include "ProceduresWidget.h"
|
||||
#include "..\..\RpcCommon\RpcCommon.h"
|
||||
|
||||
static const char WidgetName[] = "Procedures";
|
||||
static const char ConfigPath[] = "Procedures/geometry";
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QString GetProceduresWidgetColumName(ProceduresWigetColumn_T ProceduresWigetColumn)
|
||||
{
|
||||
switch(ProceduresWigetColumn)
|
||||
{
|
||||
case ProceduresWigetColumn_Index : return (QString("Index"));
|
||||
case ProceduresWigetColumn_Name : return (QString("Name"));
|
||||
case ProceduresWigetColumn_Address : return (QString("Address"));
|
||||
case ProceduresWigetColumn_FormatString : return (QString("Format"));
|
||||
default: return (QString("Unknown"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProceduresWidget_C::reset(ULONG Pid)
|
||||
{
|
||||
this->Pid = Pid;
|
||||
pProcedures->clear();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProceduresWidget_C::resizeColumnsToContents()
|
||||
{
|
||||
int Index;
|
||||
|
||||
for( Index=0; Index < ProceduresWigetColumn_Last; Index++)
|
||||
{
|
||||
pProcedures->resizeColumnToContents(Index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool ProceduresWidget_C::AddProcedure(quint32 ProcIdx, WCHAR* pSymbolName, VOID* pBase, ULONG Rva, VOID* pProcFormatString)
|
||||
{
|
||||
QTreeWidgetItem* pProcedure;
|
||||
|
||||
pCurrentIntefaceBase = pBase;
|
||||
pProcedure = new QTreeWidgetItem;
|
||||
|
||||
pProcedure->setData(ProceduresWigetColumn_Index, Qt::DisplayRole, ProcIdx );
|
||||
pProcedure->setData(ProceduresWigetColumn_Name, Qt::DisplayRole, QString::fromUtf16((const ushort*)pSymbolName));
|
||||
pProcedure->setData(ProceduresWigetColumn_Address, Qt::UserRole, (quintptr)pBase + (quint32)Rva);
|
||||
|
||||
if (pProcFormatString == NULL)
|
||||
{
|
||||
pProcedure->setData(ProceduresWigetColumn_FormatString, Qt::DisplayRole, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
pProcedure->setData(ProceduresWigetColumn_FormatString, Qt::UserRole, (quintptr)pProcFormatString);
|
||||
}
|
||||
|
||||
switch (AddressRepresentation)
|
||||
{
|
||||
case AddressRepresentation_Absolute:
|
||||
pProcedure->setData(ProceduresWigetColumn_Address, Qt::DisplayRole, QString("0x%1").arg((quintptr)pBase + Rva, 16, 16, QLatin1Char('0')));
|
||||
pProcedure->setData(ProceduresWigetColumn_FormatString, Qt::DisplayRole, QString("0x%1").arg((quintptr)pProcFormatString, 16, 16, QLatin1Char('0')));
|
||||
break;
|
||||
//--
|
||||
case AddressRepresentation_RVA:
|
||||
pProcedure->setData(ProceduresWigetColumn_Address, Qt::DisplayRole, QString("+0x%1").arg((quintptr)Rva, 8, 16, QLatin1Char('0')));
|
||||
pProcedure->setData(ProceduresWigetColumn_FormatString, Qt::DisplayRole, QString("+0x%1").arg((quintptr)pProcFormatString - (quintptr)pBase, 8, 16, QLatin1Char('0')));
|
||||
break;
|
||||
//--
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
pProcedures->addTopLevelItem(pProcedure);
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProceduresWidget_C::SetAddressRepresentation(AddressRepresentation_T AddressRepresentation)
|
||||
{
|
||||
QTreeWidgetItem* pProcedure;
|
||||
quintptr AbsoluteAddr;
|
||||
|
||||
this->AddressRepresentation = AddressRepresentation;
|
||||
|
||||
switch (AddressRepresentation)
|
||||
{
|
||||
case AddressRepresentation_RVA:
|
||||
for (int i = 0; i < pProcedures->topLevelItemCount(); i++)
|
||||
{
|
||||
pProcedure = pProcedures->topLevelItem(i);
|
||||
AbsoluteAddr = pProcedure->data(ProceduresWigetColumn_Address, Qt::UserRole).toULongLong();
|
||||
pProcedure->setData(ProceduresWigetColumn_Address, Qt::DisplayRole, QString("+0x%1").arg(AbsoluteAddr - (quintptr)pCurrentIntefaceBase, 8, 16, QLatin1Char('0')));
|
||||
AbsoluteAddr = pProcedure->data(ProceduresWigetColumn_FormatString, Qt::UserRole).toULongLong();
|
||||
pProcedure->setData(ProceduresWigetColumn_FormatString, Qt::DisplayRole, QString("+0x%1").arg(AbsoluteAddr - (quintptr)pCurrentIntefaceBase, 8, 16, QLatin1Char('0')));
|
||||
}
|
||||
break;
|
||||
//--
|
||||
case AddressRepresentation_Absolute:
|
||||
for (int i = 0; i < pProcedures->topLevelItemCount(); i++)
|
||||
{
|
||||
pProcedure = pProcedures->topLevelItem(i);
|
||||
AbsoluteAddr = pProcedure->data(ProceduresWigetColumn_Address, Qt::UserRole).toULongLong();
|
||||
pProcedure->setData(ProceduresWigetColumn_Address, Qt::DisplayRole, QString("0x%1").arg(AbsoluteAddr, HEX_SIZE_OF_PTR, 16, QLatin1Char('0')));
|
||||
AbsoluteAddr = pProcedure->data(ProceduresWigetColumn_FormatString, Qt::UserRole).toULongLong();
|
||||
pProcedure->setData(ProceduresWigetColumn_FormatString, Qt::DisplayRole, QString("0x%1").arg(AbsoluteAddr, HEX_SIZE_OF_PTR, 16, QLatin1Char('0')));
|
||||
}
|
||||
break;
|
||||
//--
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProceduresWidget_C::AcceptVisitor(ViewVisitor_C* pVisitor)
|
||||
{
|
||||
pVisitor->Visit(this);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
UINT ProceduresWidget_C::GetPid()
|
||||
{
|
||||
return (this->Pid);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProceduresWidget_C::SaveConfiguration(QSettings* pSettings)
|
||||
{
|
||||
pSettings->setValue(ConfigPath, pProcedures->header()->saveState());
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProceduresWidget_C::LoadConfiguration(QSettings* pSettings)
|
||||
{
|
||||
pProcedures->header()->restoreState(pSettings->value(ConfigPath).toByteArray());
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProceduresWidget_C::CreateColumnsSelectionWidget()
|
||||
{
|
||||
pColumnsSelectionWidget = new QGroupBox(WidgetName,this);
|
||||
QVBoxLayout* pLayout = new QVBoxLayout(pColumnsSelectionWidget);
|
||||
|
||||
for (int i = 0; i < ProceduresWigetColumn_Last; i++)
|
||||
{
|
||||
CheckBoxArray[i] = new QCheckBox(GetProceduresWidgetColumName((ProceduresWigetColumn_T)i), pColumnsSelectionWidget);
|
||||
pLayout->addWidget(CheckBoxArray[i]);
|
||||
}
|
||||
pLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
|
||||
pColumnsSelectionWidget->setLayout(pLayout);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QWidget* ProceduresWidget_C::GetColumnsSelectionWidget()
|
||||
{
|
||||
for (int i = 0; i < ProceduresWigetColumn_Last; i++)
|
||||
{
|
||||
CheckBoxArray[i]->setChecked(!pProcedures->header()->isSectionHidden(i));
|
||||
}
|
||||
return pColumnsSelectionWidget;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProceduresWidget_C::UpdateColumnsVisibility()
|
||||
{
|
||||
for (int i = 0; i < ProceduresWigetColumn_Last; i++)
|
||||
{
|
||||
pProcedures->header()->setSectionHidden(i, !CheckBoxArray[i]->isChecked());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ProceduresWidget_C::ProceduresWidget_C(QWidget* pParent):QDockWidget(WidgetName)
|
||||
{
|
||||
UINT Idx;
|
||||
QGridLayout* pGridLayout;
|
||||
QGroupBox* pGroupBox;
|
||||
|
||||
this->Pid = 0;
|
||||
|
||||
setObjectName(WidgetName);
|
||||
|
||||
pProcedures = new QTreeWidget(this);
|
||||
pGridLayout = new QGridLayout();
|
||||
pGroupBox = new QGroupBox();
|
||||
|
||||
QTreeWidgetItem* pHeaderItem = pProcedures->headerItem();
|
||||
for (Idx = 0; Idx < ProceduresWigetColumn_Last; Idx++)
|
||||
{
|
||||
pHeaderItem->setText( Idx, GetProceduresWidgetColumName((ProceduresWigetColumn_T)Idx) );
|
||||
}
|
||||
|
||||
pProcedures->setColumnCount(ProceduresWigetColumn_Last);
|
||||
pProcedures->setSortingEnabled(true);
|
||||
pProcedures->sortByColumn(-1);
|
||||
pProcedures->setAnimated(true);
|
||||
pProcedures->expandAll();
|
||||
pProcedures->setAlternatingRowColors(true);
|
||||
pProcedures->setRootIsDecorated(false);
|
||||
pProcedures->setMouseTracking(true);
|
||||
pProcedures->header()->installEventFilter(pParent);
|
||||
|
||||
pGridLayout->addWidget(pProcedures,0,0);
|
||||
pGroupBox->setLayout(pGridLayout);
|
||||
setWidget(pGroupBox);
|
||||
AddressRepresentation = AddressRepresentation_Absolute;
|
||||
//
|
||||
// Create the Widget for column selection
|
||||
//
|
||||
CreateColumnsSelectionWidget();
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef _PROCEDURES_WIDGET_H_
|
||||
#define _PROCEDURES_WIDGET_H_
|
||||
|
||||
#include "..\Qt\Qt.h"
|
||||
#include "..\RpcCore\RpcCore.h"
|
||||
#include "View.h"
|
||||
#include "..\..\RpcCommon\\RpcCommon.h"
|
||||
|
||||
typedef enum _ProceduresWigetColumn_T{
|
||||
ProceduresWigetColumn_Index,
|
||||
ProceduresWigetColumn_Name,
|
||||
ProceduresWigetColumn_Address,
|
||||
ProceduresWigetColumn_FormatString,
|
||||
//...
|
||||
ProceduresWigetColumn_Last
|
||||
}ProceduresWigetColumn_T;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class ProceduresWidget_C : public QDockWidget, public View_I
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ProceduresWidget_C(QWidget* pParent);
|
||||
virtual void AcceptVisitor(ViewVisitor_C* pVisitor);
|
||||
|
||||
void resizeColumnsToContents();
|
||||
void reset(ULONG Pid);
|
||||
UINT GetPid();
|
||||
QWidget* GetColumnsSelectionWidget();
|
||||
void UpdateColumnsVisibility();
|
||||
void SaveConfiguration(QSettings*);
|
||||
void LoadConfiguration(QSettings*);
|
||||
void SetAddressRepresentation(AddressRepresentation_T AddressRepresentation);
|
||||
public slots:
|
||||
bool AddProcedure(quint32 ProcIdx, WCHAR* pSymbolName, VOID* pBase, ULONG Rva, VOID* pProcFormatString);
|
||||
|
||||
private:
|
||||
UINT Pid;
|
||||
QTreeWidget* pProcedures;
|
||||
QGroupBox* pColumnsSelectionWidget;
|
||||
QCheckBox* CheckBoxArray[ProceduresWigetColumn_Last];
|
||||
void* pCurrentIntefaceBase;
|
||||
AddressRepresentation_T AddressRepresentation;
|
||||
void CreateColumnsSelectionWidget();
|
||||
};
|
||||
|
||||
#endif// _PROCEDURES_WIDGET_H_
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef _PROCESS_ENTRY_H_
|
||||
#define _PROCESS_ENTRY_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class ProcessEntry_C
|
||||
{
|
||||
public:
|
||||
ProcessEntry_C(ULONG Ppid, ULONG Pid)
|
||||
{
|
||||
this->Ppid=Ppid;
|
||||
this->Pid = Pid;
|
||||
}
|
||||
ULONG Ppid;
|
||||
ULONG Pid;
|
||||
};
|
||||
|
||||
#endif //_PROCESS_ENTRY_H_
|
|
@ -0,0 +1,279 @@
|
|||
#include "ProcessInfoWidget.h"
|
||||
#include "../RpcCore/RpcCore.h"
|
||||
#include "../RpcCommon/Misc.h"
|
||||
|
||||
static const char WidgetName[] = "Processes Properties";
|
||||
|
||||
typedef enum _AuthInfoColumn_T{
|
||||
AuthInfoColumn_AuthSvc,
|
||||
AuthInfoColumn_Name,
|
||||
AuthInfoColumn_Comment,
|
||||
AuthInfoColumn_PrincipalName,
|
||||
//...
|
||||
AuthInfoColumn_Last
|
||||
}AuthInfoColumn_T;
|
||||
|
||||
|
||||
typedef enum _ProcessInfoTab_T{
|
||||
ProcessInfoTab_Image,
|
||||
ProcessInfoTab_RPC,
|
||||
ProcessInfoTab_SSP
|
||||
}ProcessInfoTab_T;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QString GetProcessInfoTabName(ProcessInfoTab_T ProcessInfoTab)
|
||||
{
|
||||
switch(ProcessInfoTab)
|
||||
{
|
||||
case ProcessInfoTab_Image : return QString("Image");
|
||||
case ProcessInfoTab_RPC : return QString("RPC");
|
||||
case ProcessInfoTab_SSP : return QString("SSP");
|
||||
default:return QString("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QString GetAuthInfoColumnName(AuthInfoColumn_T AuthInfoColumn)
|
||||
{
|
||||
switch(AuthInfoColumn)
|
||||
{
|
||||
case AuthInfoColumn_AuthSvc: return QString("Id");
|
||||
case AuthInfoColumn_Name: return QString("Name");
|
||||
case AuthInfoColumn_Comment: return QString("Comment");
|
||||
case AuthInfoColumn_PrincipalName: return QString("PrincName");
|
||||
default:return QString("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool ProcessInfoWidget_C::AddAuthInfo(RpcAuthInfo_T* pRpcAuthInfo)
|
||||
{
|
||||
int Index;
|
||||
|
||||
Index = pModel->rowCount();
|
||||
pModel->setRowCount(Index+1);
|
||||
pModel->setData(pModel->index(Index, AuthInfoColumn_AuthSvc), (quint32)pRpcAuthInfo->AuthSvc );
|
||||
pModel->setData(pModel->index(Index, AuthInfoColumn_Name), QString::fromUtf16((const ushort*)pRpcAuthInfo->Name));
|
||||
pModel->setData(pModel->index(Index, AuthInfoColumn_Comment), QString::fromUtf16((const ushort*)pRpcAuthInfo->Comment));
|
||||
pModel->setData(pModel->index(Index, AuthInfoColumn_PrincipalName), QString::fromUtf16((const ushort*)pRpcAuthInfo->PrincipalName));
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessInfoWidget_C::reset()
|
||||
{
|
||||
pModel->setRowCount(0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessInfoWidget_C::resizeColumnsToContents()
|
||||
{
|
||||
int Index;
|
||||
|
||||
for( Index=0; Index < AuthInfoColumn_Last; Index++)
|
||||
{
|
||||
pAuthTreeView->resizeColumnToContents(Index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG ProcessInfoWidget_C::GetPid()
|
||||
{
|
||||
return (this->Pid);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessInfoWidget_C::UpdateProcessInfo(RpcProcessInfo_T* pRpcProcessInfo)
|
||||
{
|
||||
Version_T Version;
|
||||
bool bEnable;
|
||||
|
||||
if (pRpcProcessInfo==NULL) return;
|
||||
|
||||
this->Pid = pRpcProcessInfo->Pid;
|
||||
|
||||
pTabWidget->setTabEnabled(pTabWidget->indexOf(pImageWidget),true);
|
||||
pTabWidget->setTabEnabled(pTabWidget->indexOf(pRpcWidget),pRpcProcessInfo->bIsServer);
|
||||
|
||||
if (pRpcProcessInfo->SspCount != 0) pTabWidget->setTabEnabled(pTabWidget->indexOf(pAuthTreeView),true);
|
||||
else pTabWidget->setTabEnabled(pTabWidget->indexOf(pAuthTreeView),false);
|
||||
|
||||
Version.As64BitsValue = pRpcProcessInfo->Version;
|
||||
|
||||
if ( pRpcProcessInfo->Path[0] == 0) bEnable=false;
|
||||
else bEnable=true;
|
||||
pPath->setEnabled(bEnable);
|
||||
pPath->setText( QString::fromUtf16((const ushort*)pRpcProcessInfo->Path) );
|
||||
pPath->setToolTip( pPath->text() );
|
||||
pPath->setCursorPosition(0);
|
||||
|
||||
if ( pRpcProcessInfo->CmdLine[0] == 0) bEnable=false;
|
||||
else bEnable=true;
|
||||
pCmdLine->setEnabled(bEnable);
|
||||
pCmdLine->setText( QString::fromUtf16((const ushort*)pRpcProcessInfo->CmdLine) );
|
||||
pCmdLine->setToolTip( pCmdLine->text() );
|
||||
pCmdLine->setCursorPosition(0);
|
||||
|
||||
if (pRpcProcessInfo->hIcon!=NULL)
|
||||
{
|
||||
pIconLabel->setPixmap( QPixmap::fromWinHICON( pRpcProcessInfo->hIcon ) );
|
||||
pIconLabel->show();
|
||||
DestroyIcon( pRpcProcessInfo->hIcon );
|
||||
}
|
||||
else
|
||||
{
|
||||
pIconLabel->hide();
|
||||
}
|
||||
|
||||
if ( pRpcProcessInfo->User[0] == 0) bEnable=false;
|
||||
else bEnable=true;
|
||||
pUser->setEnabled(bEnable);
|
||||
pUser->setText( QString::fromUtf16((const ushort*)pRpcProcessInfo->User) );
|
||||
pCmdLine->setCursorPosition(0);
|
||||
|
||||
pInterfaces->setText( QString("%1").arg(pRpcProcessInfo->InterfacesCount) );
|
||||
pEndpoints->setText( QString("%1").arg(pRpcProcessInfo->EndpointsCount) );
|
||||
if (pRpcProcessInfo->MaxCalls==RPC_C_LISTEN_MAX_CALLS_DEFAULT) pMaxCall->setText( "Default" );
|
||||
else pMaxCall->setText( QString("%1").arg(pRpcProcessInfo->MaxCalls) );
|
||||
/*
|
||||
if (pRpcProcessInfo->bIsListening) pState->setText( "Listening" );
|
||||
else pState->setText( "Stopped" );
|
||||
*/
|
||||
pName->setText( QString::fromUtf16((const ushort*)pRpcProcessInfo->Description) );
|
||||
if (pRpcProcessInfo->Desktop[0] == NULL) bEnable=false;
|
||||
else bEnable=true;
|
||||
pDesktop->setEnabled(bEnable);
|
||||
pDesktop->setText( QString::fromUtf16((const ushort*)pRpcProcessInfo->Desktop) );
|
||||
pDesktop->setCursorPosition(0);
|
||||
|
||||
pInCalls->setText( QString("%1").arg(pRpcProcessInfo->InCalls) );
|
||||
pOutCalls->setText( QString("%1").arg(pRpcProcessInfo->OutCalls) );
|
||||
pInPackets->setText( QString("%1").arg(pRpcProcessInfo->InPackets) );
|
||||
pOutPackets->setText( QString("%1").arg(pRpcProcessInfo->OutPackets) );
|
||||
|
||||
if (Version.As64BitsValue==0) pVersion->setText("Unknown");
|
||||
else pVersion->setText( QString("%4.%3.%2.%1").arg(Version.As16BitsValues.Part1).arg(Version.As16BitsValues.Part2).arg(Version.As16BitsValues.Part3).arg(Version.As16BitsValues.Part4) );
|
||||
#ifdef _WIN64
|
||||
if (pRpcProcessInfo->bIsWow64) pImage->setText( QString("32-bits") );
|
||||
else pImage->setText( QString("64-bits") );
|
||||
#else
|
||||
pImage->setText( QString("32-bits") );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessInfoWidget_C::AcceptVisitor(ViewVisitor_C* pVisitor)
|
||||
{
|
||||
pVisitor->Visit(this);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ProcessInfoWidget_C::ProcessInfoWidget_C(QWidget* pParent):QDockWidget(WidgetName)
|
||||
{
|
||||
setObjectName(WidgetName);
|
||||
|
||||
pTabWidget = new QTabWidget(this);
|
||||
pTabWidget->setMovable(true);
|
||||
setWidget(pTabWidget);
|
||||
//
|
||||
// Creates the Image properties tab
|
||||
//
|
||||
QFormLayout* pImageLayout = new QFormLayout;
|
||||
pImageWidget = new QWidget(this);
|
||||
pIconLabel = new QLabel(this);
|
||||
pVersion = new QLabel(this);
|
||||
pName = new QLineEdit(this);
|
||||
pUser = new QLineEdit(this);
|
||||
pCmdLine = new QLineEdit(this);
|
||||
pPath = new QLineEdit(this);
|
||||
pDesktop = new QLineEdit(this);
|
||||
pImage = new QLabel(this);
|
||||
|
||||
pName->setFrame(false);
|
||||
pName->setReadOnly(true);
|
||||
pImageLayout->addRow(pIconLabel, pName);
|
||||
pImageLayout->addRow("Version:", pVersion);
|
||||
pImageLayout->addRow("Path:", pPath);
|
||||
pPath->setReadOnly(true);
|
||||
pPath->setEnabled(false);
|
||||
pImageLayout->addRow("CmdLine:", pCmdLine);
|
||||
pCmdLine->setReadOnly(true);
|
||||
pCmdLine->setEnabled(false);
|
||||
pImageLayout->addRow("User:", pUser);
|
||||
pUser->setReadOnly(true);
|
||||
pUser->setEnabled(false);
|
||||
pImageLayout->addRow("Desktop:", pDesktop);
|
||||
pDesktop->setReadOnly(true);
|
||||
pDesktop->setEnabled(false);
|
||||
pImageLayout->addRow("Image:", pImage);
|
||||
|
||||
pImageWidget->setLayout(pImageLayout);
|
||||
pTabWidget->insertTab(ProcessInfoTab_Image,pImageWidget,GetProcessInfoTabName(ProcessInfoTab_Image));
|
||||
//
|
||||
// Creates the RPC properties tab
|
||||
//
|
||||
pRpcWidget = new QWidget(this);
|
||||
QFormLayout* pRpcLayout = new QFormLayout;
|
||||
//pState = new QLabel(this);
|
||||
pMaxCall = new QLabel(this);
|
||||
pEndpoints = new QLabel(this);
|
||||
pInterfaces = new QLabel(this);
|
||||
pInCalls = new QLabel(this);
|
||||
pOutCalls = new QLabel(this);
|
||||
pInPackets = new QLabel(this);
|
||||
pOutPackets = new QLabel(this);
|
||||
|
||||
pRpcLayout->addRow("Interfaces:", pInterfaces);
|
||||
pRpcLayout->addRow("Endpoints:", pEndpoints);
|
||||
//pRpcLayout->addRow("State:", pState);
|
||||
pRpcLayout->addRow("MaxCalls:", pMaxCall);
|
||||
|
||||
pRpcLayout->addRow("In Calls:", pInCalls);
|
||||
pRpcLayout->addRow("Out Calls:", pOutCalls);
|
||||
pRpcLayout->addRow("In Packets:", pInPackets);
|
||||
pRpcLayout->addRow("Out Packets:", pOutPackets);
|
||||
|
||||
pRpcWidget->setLayout(pRpcLayout);
|
||||
pTabWidget->insertTab(ProcessInfoTab_RPC,pRpcWidget,GetProcessInfoTabName(ProcessInfoTab_RPC));
|
||||
//
|
||||
// Creates the Security package properties tab
|
||||
//
|
||||
pProxyModel = new QSortFilterProxyModel;
|
||||
pProxyModel->setDynamicSortFilter(true);
|
||||
pProxyModel->setFilterKeyColumn(AuthInfoColumn_AuthSvc);
|
||||
pProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
|
||||
pModel = new QStandardItemModel(0, AuthInfoColumn_Last, this);
|
||||
|
||||
for(int i=0;i<AuthInfoColumn_Last;i++)
|
||||
{
|
||||
pModel->setHeaderData(i, Qt::Horizontal, GetAuthInfoColumnName( (AuthInfoColumn_T)i ) );
|
||||
}
|
||||
|
||||
pAuthTreeView = new QTreeView;
|
||||
pAuthTreeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
pAuthTreeView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
pAuthTreeView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
pAuthTreeView->setRootIsDecorated(false);
|
||||
pAuthTreeView->setSortingEnabled(true);
|
||||
pAuthTreeView->setAnimated(true);
|
||||
pAuthTreeView->setModel(pProxyModel);
|
||||
pAuthTreeView->sortByColumn(AuthInfoColumn_AuthSvc, Qt::AscendingOrder);
|
||||
|
||||
pProxyModel->setSourceModel(pModel);
|
||||
pTabWidget->insertTab(ProcessInfoTab_SSP,pAuthTreeView,GetProcessInfoTabName(ProcessInfoTab_SSP));
|
||||
//
|
||||
// By default: all tabs are disable
|
||||
//
|
||||
pTabWidget->setTabEnabled(pTabWidget->indexOf(pImageWidget),false);
|
||||
pTabWidget->setTabEnabled(pTabWidget->indexOf(pRpcWidget),false);
|
||||
pTabWidget->setTabEnabled(pTabWidget->indexOf(pAuthTreeView),false);
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
#ifndef _PROCESS_INFO_WIDGET_H_
|
||||
#define _PROCESS_INFO_WIDGET_H_
|
||||
|
||||
#include "..\Qt\Qt.h"
|
||||
#include "..\RpcCore\RpcCore.h"
|
||||
#include "View.h"
|
||||
|
||||
/*
|
||||
///GLOBAL///
|
||||
- Name
|
||||
- Path
|
||||
- CmdLine
|
||||
- Current Directory
|
||||
- Image 32/64 bits
|
||||
- Description
|
||||
- Icon
|
||||
- Version
|
||||
- Signed or not
|
||||
- Parent
|
||||
- User
|
||||
...
|
||||
|
||||
///RPC///
|
||||
- Authentication-Service & principal name (PROVIDER_INFO)
|
||||
- number of interfaces
|
||||
- number of endpoints
|
||||
- max call
|
||||
- is listening
|
||||
- GetKeyFn and its Arg (see RpcServerRegisterAuthInfo)
|
||||
...
|
||||
*/
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class ProcessInfoWidget_C : public QDockWidget, public View_I
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ProcessInfoWidget_C(QWidget* pParent);
|
||||
virtual void AcceptVisitor(ViewVisitor_C* pVisitor);
|
||||
|
||||
bool AddAuthInfo(RpcAuthInfo_T* pRpcAuthInfo);
|
||||
void UpdateProcessInfo(RpcProcessInfo_T* pRpcProcessInfo);
|
||||
void resizeColumnsToContents();
|
||||
void reset();
|
||||
ULONG GetPid();
|
||||
private:
|
||||
QLabel* pIconLabel;
|
||||
QLineEdit* pCmdLine;
|
||||
QLineEdit* pPath;
|
||||
QLineEdit* pUser;
|
||||
QLineEdit* pDesktop;
|
||||
QLineEdit* pName;
|
||||
QLabel* pImage;
|
||||
QLabel* pEndpoints;
|
||||
QLabel* pInterfaces;
|
||||
QLabel* pMaxCall;
|
||||
//QLabel* pState;
|
||||
QLabel* pVersion;
|
||||
QSortFilterProxyModel* pProxyModel;
|
||||
QStandardItemModel* pModel;
|
||||
|
||||
QTabWidget* pTabWidget;
|
||||
//tabs
|
||||
QWidget* pImageWidget;
|
||||
QWidget* pRpcWidget;
|
||||
QTreeView* pAuthTreeView;
|
||||
|
||||
QLabel* pInCalls;
|
||||
QLabel* pOutCalls;
|
||||
QLabel* pInPackets;
|
||||
QLabel* pOutPackets;
|
||||
|
||||
ULONG Pid;
|
||||
};
|
||||
|
||||
#endif// _PROCESS_INFO_WIDGET_H_
|
|
@ -0,0 +1,117 @@
|
|||
#include "ProcessSelectedVisitor.h"
|
||||
#include "EndpointsWidget.h"
|
||||
#include "InterfacesWidget.h"
|
||||
#include "InterfaceInfoWidget.h"
|
||||
#include "ProcessWidget.h"
|
||||
#include "ProcessInfoWidget.h"
|
||||
#include "ProceduresWidget.h"
|
||||
#include "../RpcCommon/Misc.h"
|
||||
|
||||
typedef struct _EnumCtxt_T{
|
||||
ProcessInfoWidget_C* pProcessInfoWidget;
|
||||
}EnumCtxt_T;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ProcessSelectedVisitor_C::ProcessSelectedVisitor_C(quint32 Pid,RpcCore_T* pRpcCore,void* pRpcCoreCtxt)
|
||||
{
|
||||
this->Pid = Pid;
|
||||
this->pRpcCore = pRpcCore;
|
||||
this->pRpcCoreCtxt = pRpcCoreCtxt;
|
||||
|
||||
pRpcProcessInfo = pRpcCore->RpcCoreGetProcessInfoFn(pRpcCoreCtxt, Pid, INVALID_PID_VALUE, RPC_PROCESS_INFO_ALL);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ProcessSelectedVisitor_C::~ProcessSelectedVisitor_C()
|
||||
{
|
||||
pRpcCore->RpcCoreFreeProcessInfoFn(pRpcCoreCtxt, pRpcProcessInfo);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessSelectedVisitor_C::Visit(EndpointsWidget_C* pEndpointsWidget)
|
||||
{
|
||||
//Apply process filter
|
||||
pEndpointsWidget->ApplyProcessFilter(Pid);
|
||||
this->NbOfEndpoints = pEndpointsWidget->GetEndpoints();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessSelectedVisitor_C::Visit(InterfacesWidget_C* pInterfacesWidget)
|
||||
{
|
||||
//Apply process filter
|
||||
pInterfacesWidget->ApplyProcessFilter(Pid);
|
||||
this->NbOfInterfaces = pInterfacesWidget->GetInterfaces();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessSelectedVisitor_C::Visit(InterfaceInfoWidget_C* pInterfaceInfoWidget)
|
||||
{
|
||||
if (this->Pid!=pInterfaceInfoWidget->GetPid())
|
||||
{
|
||||
pInterfaceInfoWidget->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
BOOL __fastcall EnumProcessAuth(DWORD Pid, RpcAuthInfo_T* pRpcAuthInfo, EnumCtxt_T* pEnumCtxt, BOOL* pbContinue)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Pid);
|
||||
UNREFERENCED_PARAMETER(pbContinue);
|
||||
|
||||
pEnumCtxt->pProcessInfoWidget->AddAuthInfo(pRpcAuthInfo);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessSelectedVisitor_C::Visit(ProcessInfoWidget_C* pProcessInfoWidget)
|
||||
{
|
||||
EnumCtxt_T EnumCtxt;
|
||||
|
||||
EnumCtxt.pProcessInfoWidget = pProcessInfoWidget;
|
||||
|
||||
pProcessInfoWidget->UpdateProcessInfo( pRpcProcessInfo );
|
||||
pProcessInfoWidget->reset(); //for authinfo
|
||||
pRpcCore->RpcCoreEnumProcessAuthInfoFn(pRpcCoreCtxt, pRpcProcessInfo->Pid,(RpcCoreEnumProcessAuthInfoCallbackFn_T)&EnumProcessAuth,&EnumCtxt);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessSelectedVisitor_C::Visit(ProceduresWidget_C* pProceduresWidget)
|
||||
{
|
||||
if (pProceduresWidget->GetPid() != this->Pid )
|
||||
{
|
||||
pProceduresWidget->reset(this->Pid);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessSelectedVisitor_C::Visit(ProcessWidget_C* pProcessWidget)
|
||||
{
|
||||
this->NbOfProcesses = pProcessWidget->GetProcesses();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG ProcessSelectedVisitor_C::GetEndpoints()
|
||||
{
|
||||
return (this->NbOfEndpoints);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG ProcessSelectedVisitor_C::GetInterfaces()
|
||||
{
|
||||
return (this->NbOfInterfaces);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG ProcessSelectedVisitor_C::GetProcesses()
|
||||
{
|
||||
return (this->NbOfProcesses);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef _PROCESS_SELECTED_VISITOR_H_
|
||||
#define _PROCESS_SELECTED_VISITOR_H_
|
||||
|
||||
#include "../Qt/Qt.h"
|
||||
#include "ViewVisitor.h"
|
||||
#include "..\RpcCore\RpcCore.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class ProcessSelectedVisitor_C : public ViewVisitor_C
|
||||
{
|
||||
private:
|
||||
RpcProcessInfo_T* pRpcProcessInfo;
|
||||
RpcCore_T* pRpcCore;
|
||||
void* pRpcCoreCtxt;
|
||||
ULONG NbOfEndpoints;
|
||||
ULONG NbOfProcesses;
|
||||
ULONG NbOfInterfaces;
|
||||
quint32 Pid;
|
||||
public:
|
||||
ProcessSelectedVisitor_C(quint32 Pid,RpcCore_T* pRpcCore,void* pRpcCoreCtxt);
|
||||
ProcessSelectedVisitor_C::~ProcessSelectedVisitor_C();
|
||||
ULONG GetEndpoints();
|
||||
ULONG GetInterfaces();
|
||||
ULONG GetProcesses();
|
||||
virtual void Visit(EndpointsWidget_C* pEndpointsWidget);
|
||||
virtual void Visit(InterfacesWidget_C* pInterfacesWidget);
|
||||
virtual void Visit(InterfaceInfoWidget_C* pInterfaceInfoWidget);
|
||||
virtual void Visit(ProcessInfoWidget_C* pProcessInfoWidget);
|
||||
virtual void Visit(ProceduresWidget_C* pProceduresWidget);
|
||||
virtual void Visit(ProcessWidget_C* pProcessWidget);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,559 @@
|
|||
#include "ProcessWidget.h"
|
||||
|
||||
static const char WidgetName[] = "Processes";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QString ProcessWidget_C::GetColumName(Column_T Column)
|
||||
{
|
||||
switch(Column)
|
||||
{
|
||||
case Column_Name : return (QString("Name"));
|
||||
case Column_Pid : return (QString("Pid"));
|
||||
case Column_Path : return (QString("Path"));
|
||||
case Column_Description : return (QString("Description"));
|
||||
case Column_CmdLine : return (QString("CmdLine"));
|
||||
case Column_UserName : return (QString("User"));
|
||||
case Column_Desktop : return (QString("Desktop"));
|
||||
case Column_IsRpcServer : return (QString("RpcServer"));
|
||||
//case Column_IsListening : return (QString("Listening"));
|
||||
#ifdef _WIN64
|
||||
case Column_IsWow64 : return (QString("Image"));
|
||||
#endif
|
||||
case Column_MaxCalls : return (QString("MaxCalls"));
|
||||
default: return (QString("Unknown"));
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG ProcessWidget_C::GetProcesses()
|
||||
{
|
||||
return ( pProxyModel->rowCount() );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG ProcessWidget_C::GetTotalProcesses()
|
||||
{
|
||||
return ( pModel->rowCount() );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::resizeColumnsToContents()
|
||||
{
|
||||
int Index;
|
||||
|
||||
for( Index=0; Index < Column_Last; Index++)
|
||||
{
|
||||
pProcessTree->resizeColumnToContents(Index);
|
||||
pProcessView->resizeColumnToContents(Index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::SelectProcess(quint32 Pid)
|
||||
{
|
||||
QList<QTreeWidgetItem *> TreeItemList;
|
||||
QList<QStandardItem*> ViewItemList;
|
||||
|
||||
TreeItemList= pProcessTree->findItems( QString("%1").arg(Pid), Qt::MatchFixedString|Qt::MatchRecursive, Column_Pid);
|
||||
if (!TreeItemList.isEmpty())
|
||||
{
|
||||
pProcessTree->setCurrentItem( TreeItemList.first() );
|
||||
pProcessTree->scrollToItem( TreeItemList.first() );
|
||||
}
|
||||
ViewItemList = pModel->findItems( QString("%1").arg(Pid), Qt::MatchFixedString, Column_Pid);
|
||||
if (!ViewItemList.isEmpty())
|
||||
{
|
||||
QModelIndex ModelIndex = pProxyModel->mapFromSource( ViewItemList.first()->index() );
|
||||
pProcessView->selectionModel()->select( ModelIndex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||
pProcessView->scrollTo( ModelIndex );
|
||||
}
|
||||
pFilterWidget->Reset();
|
||||
this->ApplyUserFilter("");
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::SnapProcesses()
|
||||
{
|
||||
PrivateTreeItemList = pProcessTree->findItems(".*", Qt::MatchRegExp|Qt::MatchRecursive, Column_Pid);
|
||||
PrivateViewItemList = pModel->findItems(".*", Qt::MatchRegExp, Column_Pid);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::RemoveTerminatedProcesses()
|
||||
{
|
||||
QTreeWidgetItem* pParent;
|
||||
//
|
||||
// Remove processes from the TreeWidget
|
||||
// 1. Only child processes
|
||||
//
|
||||
for (auto Iter=PrivateTreeItemList.begin();Iter!=PrivateTreeItemList.end();Iter++)
|
||||
{
|
||||
if (*Iter!=NULL)
|
||||
{
|
||||
pParent = (*Iter)->parent();
|
||||
if (pParent != NULL) pParent->removeChild(*Iter);
|
||||
}
|
||||
}
|
||||
//
|
||||
// 2. Parent processes
|
||||
//
|
||||
for (auto Iter = PrivateTreeItemList.begin(); Iter != PrivateTreeItemList.end(); Iter++)
|
||||
{
|
||||
if (*Iter != NULL)
|
||||
{
|
||||
pParent = (*Iter)->parent();
|
||||
if (pParent == NULL) delete *Iter;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Remove processes from the TreeView
|
||||
//
|
||||
for (auto Iter=PrivateViewItemList.begin();Iter!=PrivateViewItemList.end();Iter++)
|
||||
{
|
||||
if (*Iter!=NULL) pModel->removeRow( (*Iter)->row());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool ProcessWidget_C::IsProcessPresent(quint32 Pid)
|
||||
{
|
||||
QList<QTreeWidgetItem *> TreeItemList;
|
||||
QList<QStandardItem*> ViewItemList;
|
||||
bool bProcessPresent = false;
|
||||
|
||||
TreeItemList = pProcessTree->findItems( QString("%1").arg(Pid), Qt::MatchFixedString|Qt::MatchRecursive, Column_Pid);
|
||||
if (TreeItemList.isEmpty()) goto End;
|
||||
|
||||
PrivateTreeItemList.removeOne(TreeItemList.first());
|
||||
|
||||
ViewItemList = pModel->findItems( QString("%1").arg(Pid), Qt::MatchFixedString, Column_Pid);
|
||||
if (ViewItemList.isEmpty()) goto End;
|
||||
|
||||
PrivateViewItemList.removeOne(ViewItemList.first());
|
||||
bProcessPresent = true;
|
||||
End:
|
||||
return (bProcessPresent);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::ProcessSelected(QTreeWidgetItem* pItem, int Column)
|
||||
{
|
||||
quint32 Pid;
|
||||
|
||||
Pid = pItem->data(Column_Pid,0).toInt();
|
||||
emit ProcessSelected(Pid);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::ProcessSelected(const QModelIndex& Index)
|
||||
{
|
||||
quint32 Pid;
|
||||
|
||||
Pid = pProxyModel->data( pProxyModel->index(Index.row(), Column_Pid) ).toUInt();
|
||||
emit ProcessSelected(Pid);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::SetRowColor(QTreeWidgetItem* pProcess,int Index,const QColor& Color)
|
||||
{
|
||||
for (int i=0;i<Column_Last;i++)
|
||||
{
|
||||
pProcess->setBackground(i, QBrush(Color) );
|
||||
pModel->setData(pModel->index(Index,i), QBrush(Color), Qt::BackgroundRole);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::UpdateProcess(RpcProcessInfo_T* pRpcProcessInfo)
|
||||
{
|
||||
QList<QTreeWidgetItem *> TreeItemList;
|
||||
QList<QStandardItem*> ViewItemList;
|
||||
QTreeWidgetItem* pProcess;
|
||||
int Index;
|
||||
|
||||
if (pRpcProcessInfo->bIsServer)
|
||||
{
|
||||
TreeItemList = pProcessTree->findItems( QString("%1").arg(pRpcProcessInfo->Pid), Qt::MatchFixedString|Qt::MatchRecursive, Column_Pid);
|
||||
if (TreeItemList.isEmpty()) return;
|
||||
|
||||
ViewItemList = pModel->findItems( QString("%1").arg(pRpcProcessInfo->Pid), Qt::MatchFixedString, Column_Pid);
|
||||
if (ViewItemList.isEmpty()) return;
|
||||
|
||||
pProcess= TreeItemList.first();
|
||||
if (pProcess==NULL) return;
|
||||
|
||||
Index = ViewItemList.first()->row();
|
||||
|
||||
if ( pRpcProcessInfo->MaxCalls == RPC_C_LISTEN_MAX_CALLS_DEFAULT)
|
||||
{
|
||||
AddProcessItem( pProcess, Index, Column_MaxCalls, Qt::DisplayRole, QString("Default") );
|
||||
}
|
||||
else
|
||||
{
|
||||
AddProcessItem( pProcess, Index, Column_MaxCalls, Qt::DisplayRole, (quint32)pRpcProcessInfo->MaxCalls );
|
||||
}
|
||||
//--
|
||||
AddProcessItem( pProcess, Index, Column_IsRpcServer, Qt::DisplayRole, true );
|
||||
|
||||
switch(pRpcProcessInfo->RpcProcessType)
|
||||
{
|
||||
case RpcProcessType_RPC:
|
||||
SetRowColor(pProcess,Index,QColor(200, 200, 255, 180));
|
||||
break;
|
||||
//--
|
||||
case RpcProcessType_DCOM:
|
||||
SetRowColor(pProcess,Index,QColor(255, 255, 200, 180));
|
||||
//SetRowColor(pProcess, Index, QColor(200, 200, 255, 180));
|
||||
break;
|
||||
//--
|
||||
case RpcProcessType_HYBRID:
|
||||
//SetRowColor(pProcess,Index,QColor(255, 200, 200, 180));
|
||||
SetRowColor(pProcess, Index, QColor(200, 200, 255, 180));
|
||||
break;
|
||||
//--
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::AddProcessItem(QTreeWidgetItem* pProcess,int Index, Column_T Column, Qt::ItemDataRole Role,const QVariant& Value)
|
||||
{
|
||||
pProcess->setData( Column, Role, Value );
|
||||
pModel->setData(pModel->index(Index, Column), Value, Role );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool ProcessWidget_C::AddProcess(RpcProcessInfo_T* pRpcProcessInfo)
|
||||
{
|
||||
QList<QTreeWidgetItem*> ParentList;
|
||||
QTreeWidgetItem* pParent = NULL;
|
||||
QTreeWidgetItem* pProcess;
|
||||
int Index;
|
||||
|
||||
Index = pModel->rowCount();
|
||||
pModel->setRowCount(Index+1);
|
||||
|
||||
pProcess = new QTreeWidgetItem;
|
||||
|
||||
if ( pRpcProcessInfo->hIcon!=NULL )
|
||||
{
|
||||
AddProcessItem(pProcess,Index,Column_Name, Qt::DecorationRole, QIcon( QPixmap::fromWinHICON( pRpcProcessInfo->hIcon ) ) );
|
||||
DestroyIcon( pRpcProcessInfo->hIcon );
|
||||
}
|
||||
|
||||
if (pRpcProcessInfo->Pid == 0)
|
||||
{
|
||||
AddProcessItem(pProcess,Index,Column_Name, Qt::DisplayRole, QString("[System Idle Process]") );
|
||||
AddProcessItem(pProcess,Index,Column_Pid, Qt::DisplayRole, (quint32) pRpcProcessInfo->Pid );
|
||||
pProcessTree->addTopLevelItem(pProcess);
|
||||
return true;
|
||||
}
|
||||
AddProcessItem(pProcess,Index,Column_Name, Qt::DisplayRole, QString::fromUtf16((const ushort*)pRpcProcessInfo->Name) );
|
||||
|
||||
AddProcessItem(
|
||||
pProcess,
|
||||
Index,
|
||||
Column_Name,
|
||||
Qt::ToolTipRole,
|
||||
QString("Path:\n").append(QString::fromUtf16((const ushort*)pRpcProcessInfo->Path)).append("\nCmdLine:\n").append(QString::fromUtf16((const ushort*)pRpcProcessInfo->CmdLine))
|
||||
);
|
||||
|
||||
AddProcessItem(pProcess,Index,Column_Pid, Qt::DisplayRole, (quint32) pRpcProcessInfo->Pid );
|
||||
AddProcessItem(pProcess,Index,Column_UserName, Qt::DisplayRole, QString::fromUtf16((const ushort*)pRpcProcessInfo->User) );
|
||||
AddProcessItem(pProcess,Index,Column_Path, Qt::DisplayRole, QString::fromUtf16((const ushort*)pRpcProcessInfo->Path) );
|
||||
AddProcessItem(pProcess,Index,Column_Description, Qt::DisplayRole, QString::fromUtf16((const ushort*)pRpcProcessInfo->Description) );
|
||||
AddProcessItem(pProcess,Index,Column_CmdLine, Qt::DisplayRole, QString::fromUtf16((const ushort*)pRpcProcessInfo->CmdLine) );
|
||||
AddProcessItem(pProcess,Index,Column_Desktop, Qt::DisplayRole, QString::fromUtf16((const ushort*)pRpcProcessInfo->Desktop) );
|
||||
#ifdef _WIN64
|
||||
if (pRpcProcessInfo->bIsWow64) AddProcessItem(pProcess,Index,Column_IsWow64, Qt::DisplayRole, QString("32-bit") );
|
||||
else AddProcessItem(pProcess,Index,Column_IsWow64, Qt::DisplayRole, QString("64-bit") );
|
||||
#endif
|
||||
|
||||
QList<QTreeWidgetItem *> ItemList;
|
||||
|
||||
ItemList = pProcessTree->findItems( QString("%1").arg(pRpcProcessInfo->ParentPid), Qt::MatchFixedString|Qt::MatchRecursive, Column_Pid);
|
||||
if (!ItemList.isEmpty())
|
||||
{
|
||||
pParent = ItemList.first();
|
||||
pParent->addChild(pProcess);
|
||||
pProcessTree->expandItem(pParent);
|
||||
}
|
||||
else
|
||||
{
|
||||
pProcessTree->addTopLevelItem(pProcess);
|
||||
}
|
||||
//
|
||||
// Add warning: when a non rpc server is selected -> view all endpoints and interfaces of the system
|
||||
//
|
||||
if (!pRpcProcessInfo->bIsServer)
|
||||
{
|
||||
for(int i=0;i<Column_Last;i++)
|
||||
{
|
||||
pProcess->setStatusTip(i,"WARNING: view all the system endpoints and interfaces.");
|
||||
}
|
||||
}
|
||||
UpdateProcess(pRpcProcessInfo);
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::AcceptVisitor(ViewVisitor_C* pVisitor)
|
||||
{
|
||||
pVisitor->Visit(this);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::Reset()
|
||||
{
|
||||
pProcessTree->clear();
|
||||
pProcessView->reset();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::SaveConfiguration(QSettings* pSettings)
|
||||
{
|
||||
pSettings->setValue("Processes/View/geometry",pProcessView->header()->saveState());
|
||||
pSettings->setValue("Processes/Tree/geometry",pProcessTree->header()->saveState());
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::LoadConfiguration(QSettings* pSettings)
|
||||
{
|
||||
pProcessView->header()->restoreState( pSettings->value("Processes/View/geometry").toByteArray() );
|
||||
pProcessTree->header()->restoreState( pSettings->value("Processes/Tree/geometry").toByteArray() );
|
||||
//
|
||||
// Force Tree sorting by PID
|
||||
//
|
||||
pProcessTree->sortByColumn(Column_Pid);
|
||||
pProcessTree->sortByColumn(-1);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::InitProcessTreeWidget(QWidget* pParent)
|
||||
{
|
||||
pProcessTree = new QTreeWidget(this);
|
||||
|
||||
QTreeWidgetItem* pHeaderItem = pProcessTree->headerItem();
|
||||
for (quint32 Idx = 0; Idx < Column_Last; Idx++)
|
||||
{
|
||||
pHeaderItem->setText( Idx, GetColumName((Column_T)Idx) );
|
||||
}
|
||||
pProcessTree->setColumnCount(Column_Last);
|
||||
pProcessTree->sortByColumn(Column_Pid);
|
||||
pProcessTree->sortByColumn(-1);
|
||||
pProcessTree->setAnimated(true);
|
||||
pProcessTree->setSortingEnabled(true);
|
||||
|
||||
pProcessTree->expandAll();
|
||||
pProcessTree->setRootIsDecorated(false);
|
||||
pProcessTree->setMouseTracking(true);
|
||||
|
||||
pProcessTree->hideColumn(Column_IsRpcServer);
|
||||
pProcessTree->hideColumn(Column_Desktop);
|
||||
|
||||
connect( pProcessTree, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(ProcessSelected(QTreeWidgetItem*, int)));
|
||||
connect( pProcessTree, SIGNAL(itemPressed(QTreeWidgetItem*, int)), this, SLOT(ProcessSelected(QTreeWidgetItem*, int)));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::InitProcessTreeView(QWidget* pParent)
|
||||
{
|
||||
pProxyModel = new QSortFilterProxyModel(this);
|
||||
pProxyModel->setDynamicSortFilter(true);
|
||||
pProxyModel->setFilterKeyColumn(Column_Pid);
|
||||
pProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
|
||||
pModel = new QStandardItemModel(0, Column_Last, this);
|
||||
|
||||
for(uint i=0;i<Column_Last;i++)
|
||||
{
|
||||
pModel->setHeaderData(i, Qt::Horizontal, GetColumName((Column_T)i) );
|
||||
}
|
||||
|
||||
pProcessView = new QTreeView(this);
|
||||
pProcessView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
pProcessView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
pProcessView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
pProcessView->setRootIsDecorated(false);
|
||||
pProcessView->setSortingEnabled(true);
|
||||
pProcessView->setAlternatingRowColors(true);
|
||||
pProcessView->setAnimated(true);
|
||||
pProcessView->setModel(pProxyModel);
|
||||
pProcessView->sortByColumn(Column_Pid, Qt::AscendingOrder);
|
||||
|
||||
pProcessView->hideColumn(Column_IsRpcServer);
|
||||
pProcessView->hideColumn(Column_Desktop);
|
||||
|
||||
pProxyModel->setSourceModel(pModel);
|
||||
connect( pProcessView, SIGNAL(pressed(const QModelIndex&)), this, SLOT(ProcessSelected(const QModelIndex&)));
|
||||
connect( pProcessView, SIGNAL(activated(const QModelIndex&)), this, SLOT(ProcessSelected(const QModelIndex&)));
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::UpdateUserFilter()
|
||||
{
|
||||
if (pFilterWidget->GetText()!="") ApplyUserFilter( pFilterWidget->GetText() );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::ApplyUserFilter(const QString & FilterText)
|
||||
{
|
||||
QRegExp FilterRegExp;
|
||||
|
||||
FilterRegExp.setPattern( FilterText );
|
||||
FilterRegExp.setCaseSensitivity( Qt::CaseInsensitive );
|
||||
|
||||
pProxyModel->setFilterKeyColumn(-1); //filter all columns: UGLY Qt
|
||||
pProxyModel->setFilterRegExp( FilterRegExp );
|
||||
|
||||
if ( pProxyModel->rowCount()==pModel->rowCount() )
|
||||
{
|
||||
//
|
||||
// In case of view switching, we have to update the selected process in the other view!
|
||||
//
|
||||
if ( (pStackedWidget->currentWidget()!=pProcessTree) &&
|
||||
(pProcessTree->header()->sortIndicatorSection()==-1) )
|
||||
{
|
||||
pStackedWidget->setCurrentWidget(pProcessTree);
|
||||
pProcessTree->header()->restoreState(pProcessView->header()->saveState());
|
||||
}
|
||||
else
|
||||
{
|
||||
pProxyModel->setFilterRegExp( QRegExp(".*") );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pStackedWidget->currentWidget()!=pProcessView)
|
||||
{
|
||||
pStackedWidget->setCurrentWidget(pProcessView);
|
||||
pProcessView->header()->restoreState(pProcessTree->header()->saveState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::CreateColumnsSelectionWidget()
|
||||
{
|
||||
pColumnsSelectionWidget = new QGroupBox(WidgetName,this);
|
||||
QVBoxLayout* pLayout = new QVBoxLayout(pColumnsSelectionWidget);
|
||||
|
||||
for (int i = 0; i < Column_Last; i++)
|
||||
{
|
||||
CheckBoxArray[i] = new QCheckBox(GetColumName((Column_T)i), pColumnsSelectionWidget);
|
||||
pLayout->addWidget(CheckBoxArray[i]);
|
||||
}
|
||||
pLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
|
||||
pColumnsSelectionWidget->setLayout(pLayout);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
QWidget* ProcessWidget_C::GetColumnsSelectionWidget()
|
||||
{
|
||||
for (int i = 0; i < Column_Last; i++)
|
||||
{
|
||||
CheckBoxArray[i]->setChecked(!pProcessTree->header()->isSectionHidden(i));
|
||||
}
|
||||
return pColumnsSelectionWidget;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ProcessWidget_C::UpdateColumnsVisibility()
|
||||
{
|
||||
for (int i = 0; i < Column_Last; i++)
|
||||
{
|
||||
pProcessTree->header()->setSectionHidden(i, !CheckBoxArray[i]->isChecked() );
|
||||
pProcessView->header()->setSectionHidden(i, !CheckBoxArray[i]->isChecked());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Switch to the view header
|
||||
void ProcessWidget_C::TreeHeaderClicked(int logicalIndex)
|
||||
{
|
||||
if (pStackedWidget->currentWidget()!=pProcessView)
|
||||
{
|
||||
pStackedWidget->setCurrentWidget(pProcessView);
|
||||
pProcessView->header()->restoreState(pProcessTree->header()->saveState());
|
||||
pProcessView->scrollTo(pProcessView->currentIndex());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Switch to the Tree after ascending and descending order
|
||||
void ProcessWidget_C::ViewHeaderClicked(int logicalIndex)
|
||||
{
|
||||
if (logicalIndex!=Column_Name) return;
|
||||
|
||||
if (pProcessView->header()->sortIndicatorOrder() == Qt::DescendingOrder) return;
|
||||
|
||||
if (pStackedWidget->currentWidget()!=pProcessTree)
|
||||
{
|
||||
pFilterWidget->Reset();
|
||||
ApplyUserFilter("");
|
||||
|
||||
pStackedWidget->setCurrentWidget(pProcessTree);
|
||||
pProcessTree->header()->restoreState(pProcessView->header()->saveState());
|
||||
pProcessTree->sortByColumn(Column_Pid);
|
||||
pProcessTree->sortByColumn(-1);
|
||||
pProcessTree->scrollToItem(pProcessTree->currentItem());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ProcessWidget_C::ProcessWidget_C(QWidget* pParent):QGroupBox(WidgetName)
|
||||
{
|
||||
QGridLayout* pGridLayout;
|
||||
|
||||
setObjectName(WidgetName);
|
||||
|
||||
pStackedWidget = new QStackedWidget(this);
|
||||
pGridLayout = new QGridLayout(this);
|
||||
|
||||
InitProcessTreeWidget(pParent);
|
||||
InitProcessTreeView(pParent);
|
||||
pProcessView->header()->installEventFilter(pParent);
|
||||
pProcessTree->header()->installEventFilter(pParent);
|
||||
|
||||
pStackedWidget->addWidget(pProcessTree);
|
||||
pStackedWidget->addWidget(pProcessView);
|
||||
//
|
||||
// Add user filtering (CTL+F) support
|
||||
//
|
||||
pFilterWidget = new FilterWidget_C(this);
|
||||
|
||||
pGridLayout->addWidget(pStackedWidget,0,0);
|
||||
pGridLayout->addWidget(pFilterWidget,1,0);
|
||||
setLayout(pGridLayout);
|
||||
connect( this, SIGNAL(ProcessSelected(quint32)), pParent, SLOT(ProcessSelected(quint32)) );
|
||||
connect( pProcessTree->header(),SIGNAL(sectionClicked(int)), this , SLOT(TreeHeaderClicked(int) ));
|
||||
connect( pProcessView->header(),SIGNAL(sectionClicked(int)), this , SLOT(ViewHeaderClicked(int) ));
|
||||
//
|
||||
// Create the Widget for column selection
|
||||
//
|
||||
CreateColumnsSelectionWidget();
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
#ifndef _PROCESS_WIDGET_H_
|
||||
#define _PROCESS_WIDGET_H_
|
||||
|
||||
#include "..\Qt\Qt.h"
|
||||
#include "..\RpcCommon\RpcView.h"
|
||||
#include "..\RpcCore\RpcCore.h"
|
||||
#include "View.h"
|
||||
#include "FilterWidget.h"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class ProcessWidget_C : public QGroupBox, public View_I
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
typedef enum {
|
||||
Column_Name,
|
||||
Column_Pid,
|
||||
Column_Path,
|
||||
Column_Description,
|
||||
#ifdef _WIN64
|
||||
Column_IsWow64,
|
||||
#endif
|
||||
Column_UserName,
|
||||
Column_CmdLine,
|
||||
Column_Desktop,
|
||||
Column_IsRpcServer,
|
||||
//Column_IsListening,
|
||||
Column_MaxCalls,
|
||||
Column_Last,
|
||||
}Column_T;
|
||||
|
||||
ProcessWidget_C(QWidget* pParent);
|
||||
virtual void AcceptVisitor(ViewVisitor_C* pVisitor);
|
||||
void resizeColumnsToContents();
|
||||
void SelectProcess(quint32 Pid);
|
||||
void SnapProcesses();
|
||||
void RemoveTerminatedProcesses();
|
||||
bool IsProcessPresent(quint32 Pid);
|
||||
bool AddProcess(RpcProcessInfo_T* pRpcProcessInfo);
|
||||
void UpdateProcess(RpcProcessInfo_T* pRpcProcessInfo);
|
||||
void Reset();
|
||||
ULONG GetProcesses();
|
||||
ULONG GetTotalProcesses();
|
||||
void UpdateUserFilter();
|
||||
void SaveConfiguration(QSettings*);
|
||||
void LoadConfiguration(QSettings*);
|
||||
QWidget* GetColumnsSelectionWidget();
|
||||
void UpdateColumnsVisibility();
|
||||
|
||||
private slots:
|
||||
void ProcessSelected(QTreeWidgetItem*, int);
|
||||
void ProcessSelected(const QModelIndex&);
|
||||
void ApplyUserFilter(const QString &);
|
||||
|
||||
signals:
|
||||
void ProcessSelected(quint32);
|
||||
|
||||
public slots:
|
||||
void TreeHeaderClicked(int logicalIndex);
|
||||
void ViewHeaderClicked(int logicalIndex);
|
||||
|
||||
private:
|
||||
QGridLayout* pGridLayout;
|
||||
QStackedWidget* pStackedWidget;
|
||||
QTreeWidget* pProcessTree;
|
||||
QTreeView* pProcessView;
|
||||
QSortFilterProxyModel* pProxyModel;
|
||||
QStandardItemModel* pModel;
|
||||
QList<QTreeWidgetItem*> PrivateTreeItemList;
|
||||
QList<QStandardItem*> PrivateViewItemList;
|
||||
FilterWidget_C* pFilterWidget;
|
||||
//--
|
||||
QGroupBox* pColumnsSelectionWidget;
|
||||
QCheckBox* CheckBoxArray[Column_Last];
|
||||
|
||||
void SetRowColor(QTreeWidgetItem* pProcess,int Index,const QColor& Color);
|
||||
void InitProcessTreeWidget(QWidget* pParent);
|
||||
void InitProcessTreeView(QWidget* pParent);
|
||||
void AddProcessItem(QTreeWidgetItem* pProcess,int Index, Column_T Column, Qt::ItemDataRole Role,const QVariant& Value);
|
||||
void CreateColumnsSelectionWidget();
|
||||
QString GetColumName(Column_T ProcessWigetColumn);
|
||||
};
|
||||
|
||||
#endif// _PROCESS_WIDGET_H_
|
|
@ -0,0 +1,250 @@
|
|||
#include "InterfaceSelectedVisitor.h"
|
||||
#include "EndpointsWidget.h"
|
||||
#include "InterfacesWidget.h"
|
||||
#include "InterfaceInfoWidget.h"
|
||||
#include "ProcessWidget.h"
|
||||
#include "ProcessInfoWidget.h"
|
||||
#include "ProceduresWidget.h"
|
||||
#include "RefreshVisitor.h"
|
||||
#include "../RpcCommon/Misc.h"
|
||||
#include "Pdb.h"
|
||||
#include <Dbghelp.h>
|
||||
|
||||
|
||||
typedef struct _EnumCtxt_T{
|
||||
RefreshVisitor_C* pRefreshVisitor;
|
||||
EndpointsWidget_C* pEndpointsWidget;
|
||||
InterfacesWidget_C* pInterfacesWidget;
|
||||
RpcCore_T* pRpcCore;
|
||||
VOID* pRpcCoreCtxt;
|
||||
}EnumCtxt_T;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static BOOL WINAPI EnumProc(DWORD Pid, DWORD Ppid, EnumCtxt_T* pEnumCtxt, BOOL* pbContinue)
|
||||
{
|
||||
ProcessEntry_C* pProcessEntry = new ProcessEntry_C(Ppid,Pid);
|
||||
|
||||
pEnumCtxt->pRefreshVisitor->ProcessVector.push_back(pProcessEntry);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
RefreshVisitor_C::RefreshVisitor_C(RpcCore_T* pRpcCore,void* pRpcCoreCtxt)
|
||||
{
|
||||
EnumCtxt_T EnumCtxt;
|
||||
|
||||
this->pRpcCore = pRpcCore;
|
||||
this->pRpcCoreCtxt = pRpcCoreCtxt;
|
||||
|
||||
this->NumberOfEndpoints = 0;
|
||||
this->NumberOfInterfaces = 0;
|
||||
|
||||
EnumCtxt.pRefreshVisitor = this;
|
||||
EnumProcess( (EnumProcessCallbackFn_T)&EnumProc, &EnumCtxt );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG RefreshVisitor_C::GetEndpoints()
|
||||
{
|
||||
return (this->NumberOfEndpoints);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG RefreshVisitor_C::GetInterfaces()
|
||||
{
|
||||
return (this->NumberOfInterfaces);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG RefreshVisitor_C::GetProcesses()
|
||||
{
|
||||
return (this->NumberOfProcesses);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG RefreshVisitor_C::GetTotalEndpoints()
|
||||
{
|
||||
return (this->TotalEndpoints);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG RefreshVisitor_C::GetTotalInterfaces()
|
||||
{
|
||||
return (this->TotalInterfaces);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ULONG RefreshVisitor_C::GetTotalProcesses()
|
||||
{
|
||||
return (this->TotalProcesses);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
RefreshVisitor_C::~RefreshVisitor_C()
|
||||
{
|
||||
for (UINT32 i = 0; i < ProcessVector.size(); i++)
|
||||
{
|
||||
delete ProcessVector[i];
|
||||
}
|
||||
ProcessVector.clear();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static BOOL __fastcall EnumEndpoints(DWORD Pid, RpcEndpointInfo_T* pRpcEndpointInfo, EnumCtxt_T* pEnumCtxt, BOOL* pbContinue)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(pbContinue);
|
||||
|
||||
if (!pEnumCtxt->pEndpointsWidget->IsEndpointsPresent(Pid,pRpcEndpointInfo->pName,pRpcEndpointInfo->pProtocole))
|
||||
{
|
||||
pEnumCtxt->pEndpointsWidget->AddEndpoint(Pid, pRpcEndpointInfo );
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RefreshVisitor_C::Visit(EndpointsWidget_C* pEndpointsWidget)
|
||||
{
|
||||
EnumCtxt_T EnumCtxt;
|
||||
std::vector<ProcessEntry_C*>::iterator Iter;
|
||||
|
||||
pEndpointsWidget->SnapEndpoint();
|
||||
|
||||
EnumCtxt.pRefreshVisitor = this;
|
||||
EnumCtxt.pEndpointsWidget = pEndpointsWidget;
|
||||
for (Iter=ProcessVector.begin();Iter!=ProcessVector.end();Iter++)
|
||||
{
|
||||
if (*Iter!=NULL)
|
||||
{
|
||||
pRpcCore->RpcCoreEnumProcessEndpointsFn(
|
||||
pRpcCoreCtxt,
|
||||
(*Iter)->Pid,
|
||||
(RpcCoreEnumProcessEndpointsCallbackFn_T) &EnumEndpoints,
|
||||
&EnumCtxt);
|
||||
}
|
||||
}
|
||||
pEndpointsWidget->RemoveUnregisteredEndpoints();
|
||||
pEndpointsWidget->UpdateUserFilter();
|
||||
this->NumberOfEndpoints = pEndpointsWidget->GetEndpoints();
|
||||
this->TotalEndpoints = pEndpointsWidget->GetTotalEndpoints();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static BOOL __fastcall EnumInterfaces(RpcInterfaceInfo_T* pRpcInterfaceInfo, EnumCtxt_T* pEnumCtxt, BOOL* pbContinue)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(pbContinue);
|
||||
RpcInterfaceInfo_T* pRpcInterfaceInfoFull = NULL;
|
||||
|
||||
if (!pEnumCtxt->pInterfacesWidget->IsInterfacePresent(pRpcInterfaceInfo->Pid,&pRpcInterfaceInfo->If))
|
||||
{
|
||||
pRpcInterfaceInfoFull = pEnumCtxt->pRpcCore->RpcCoreGetInterfaceInfoFn(pEnumCtxt->pRpcCoreCtxt,pRpcInterfaceInfo->Pid,&pRpcInterfaceInfo->If,RPC_INTERFACE_INFO_ALL);
|
||||
if (pRpcInterfaceInfoFull!=NULL)
|
||||
{
|
||||
pEnumCtxt->pInterfacesWidget->AddInterfaces(pRpcInterfaceInfoFull);
|
||||
pEnumCtxt->pRpcCore->RpcCoreFreeInterfaceInfoFn(pEnumCtxt->pRpcCoreCtxt,pRpcInterfaceInfoFull);
|
||||
}
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RefreshVisitor_C::Visit(InterfacesWidget_C* pInterfacesWidget)
|
||||
{
|
||||
EnumCtxt_T EnumCtxt;
|
||||
std::vector<ProcessEntry_C*>::iterator Iter;
|
||||
|
||||
pInterfacesWidget->SnapInterfaces();
|
||||
|
||||
EnumCtxt.pRefreshVisitor = this;
|
||||
EnumCtxt.pInterfacesWidget = pInterfacesWidget;
|
||||
EnumCtxt.pRpcCoreCtxt = this->pRpcCoreCtxt;
|
||||
EnumCtxt.pRpcCore = this->pRpcCore;
|
||||
for (Iter=ProcessVector.begin();Iter!=ProcessVector.end();Iter++)
|
||||
{
|
||||
if (*Iter!=NULL)
|
||||
{
|
||||
pRpcCore->RpcCoreEnumProcessInterfacesFn(
|
||||
pRpcCoreCtxt,
|
||||
(*Iter)->Pid,
|
||||
(RpcCoreEnumProcessInterfacesCallbackFn_T) &EnumInterfaces,
|
||||
&EnumCtxt,
|
||||
RPC_INTERFACE_INFO_DEFAULT);
|
||||
}
|
||||
}
|
||||
pInterfacesWidget->RemoveUnregisteredInterfaces();
|
||||
pInterfacesWidget->UpdateUserFilter();
|
||||
this->NumberOfInterfaces = pInterfacesWidget->GetInterfaces();
|
||||
this->TotalInterfaces = pInterfacesWidget->GetTotalInterfaces();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RefreshVisitor_C::Visit(InterfaceInfoWidget_C* pInterfaceInfoWidget)
|
||||
{
|
||||
//nothing to do here
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RefreshVisitor_C::Visit(ProcessInfoWidget_C* pProcessInfoWidget)
|
||||
{
|
||||
RpcProcessInfo_T* pRpcProcessInfo = NULL;
|
||||
|
||||
pRpcProcessInfo = pRpcCore->RpcCoreGetProcessInfoFn(pRpcCoreCtxt,pProcessInfoWidget->GetPid(),0,RPC_PROCESS_INFO_ALL);
|
||||
if (pRpcProcessInfo!=NULL)
|
||||
{
|
||||
pProcessInfoWidget->UpdateProcessInfo(pRpcProcessInfo);
|
||||
pRpcCore->RpcCoreFreeProcessInfoFn(pRpcCoreCtxt,pRpcProcessInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RefreshVisitor_C::Visit(ProceduresWidget_C* pProceduresWidget)
|
||||
{
|
||||
//nothing to do
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void RefreshVisitor_C::Visit(ProcessWidget_C* pProcessWidget)
|
||||
{
|
||||
std::vector<ProcessEntry_C*>::iterator Iter;
|
||||
RpcProcessInfo_T* pRpcProcessInfo = NULL;
|
||||
BOOL bWow64;
|
||||
bool bIsProcessPresent;
|
||||
ULONG ProcessInfoMask;
|
||||
|
||||
pProcessWidget->SnapProcesses();
|
||||
|
||||
for (Iter=ProcessVector.begin();Iter!=ProcessVector.end();Iter++)
|
||||
{
|
||||
if ( (*Iter!=NULL) )
|
||||
{
|
||||
bWow64 = IsProcessWow64((*Iter)->Pid);
|
||||
bIsProcessPresent = pProcessWidget->IsProcessPresent((*Iter)->Pid);
|
||||
if (bIsProcessPresent) ProcessInfoMask = 0;
|
||||
else ProcessInfoMask = RPC_PROCESS_INFO_ALL;
|
||||
|
||||
pRpcProcessInfo = pRpcCore->RpcCoreGetProcessInfoFn(pRpcCoreCtxt,(*Iter)->Pid,(*Iter)->Ppid,ProcessInfoMask);
|
||||
|
||||
if (pRpcProcessInfo!=NULL)
|
||||
{
|
||||
if (bIsProcessPresent) pProcessWidget->UpdateProcess(pRpcProcessInfo);
|
||||
else pProcessWidget->AddProcess(pRpcProcessInfo);
|
||||
|
||||
pRpcCore->RpcCoreFreeProcessInfoFn(pRpcCoreCtxt, pRpcProcessInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
pProcessWidget->RemoveTerminatedProcesses();
|
||||
this->NumberOfProcesses = pProcessWidget->GetProcesses();
|
||||
this->TotalProcesses = pProcessWidget->GetTotalProcesses();
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue