Add whole project

This commit is contained in:
silverf0x 2017-03-14 21:47:33 +01:00
parent c3a8ee9d1c
commit f557104055
110 changed files with 20426 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/Build

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

34
CMakeLists.txt Normal file
View File

@ -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)

47
Qt/Qt.h Normal file
View File

@ -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

BIN
Qt/lib/x64/QtCore.lib Normal file

Binary file not shown.

BIN
Qt/lib/x64/QtGui.lib Normal file

Binary file not shown.

BIN
Qt/lib/x86/QtCore.lib Normal file

Binary file not shown.

BIN
Qt/lib/x86/QtGui.lib Normal file

Binary file not shown.

105
README.md Normal file
View File

@ -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

402
RpcCommon/Misc.c Normal file
View File

@ -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);
}

56
RpcCommon/Misc.h Normal file
View File

@ -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_

46
RpcCommon/RpcCommon.h Normal file
View File

@ -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_

33
RpcCommon/RpcView.h Normal file
View File

@ -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_

25
RpcCommon/ntdll.c Normal file
View File

@ -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);
}

351
RpcCommon/ntdll.h Normal file
View File

@ -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_

34
RpcCore/CMakeLists.txt Normal file
View File

@ -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)

1072
RpcCore/RpcCore.c Normal file

File diff suppressed because it is too large Load Diff

2
RpcCore/RpcCore.def Normal file
View File

@ -0,0 +1,2 @@
EXPORTS
RpcCoreHelper

211
RpcCore/RpcCore.h Normal file
View File

@ -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_

View File

@ -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_

View File

@ -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_

View File

@ -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_

View File

@ -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_

View File

@ -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_

View File

@ -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_

View File

@ -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_

View File

@ -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

View File

@ -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_

View File

@ -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)

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

168
RpcDecompiler/IdlType.cpp Normal file
View File

@ -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);
}

47
RpcDecompiler/IdlType.h Normal file
View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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++;
//....
}

View File

@ -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 << "*/";
}

View File

@ -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, &param, 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 */ &paramOffset,
/* 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 */ &paramSizeInBytes,
/* 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 */ &paramOffset,
/* 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 */ &paramSizeInBytes,
/* 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

View File

@ -0,0 +1,2 @@
EXPORTS
RpcDecompilerHelper

View File

@ -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_

View File

@ -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

View File

@ -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_

View File

@ -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;
}

View File

@ -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_

View File

@ -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;
}

View File

@ -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

View File

@ -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_

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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;
}

View File

@ -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_

54
RpcView/CMakeLists.txt Normal file
View File

@ -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")

View File

@ -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;
}
}

View File

@ -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_

View File

@ -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);
}

View File

@ -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_

View File

@ -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);
}

View File

@ -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

265
RpcView/EndpointsWidget.cpp Normal file
View File

@ -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();
}

63
RpcView/EndpointsWidget.h Normal file
View File

@ -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_

21
RpcView/EulaDialog.h Normal file
View File

@ -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_

63
RpcView/FilterWidget.cpp Normal file
View File

@ -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 &)) );
}

26
RpcView/FilterWidget.h Normal file
View File

@ -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_

View File

@ -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);
}
}

35
RpcView/IdlHighlighter.h Normal file
View File

@ -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_

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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_

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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_

BIN
RpcView/Main.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

803
RpcView/MainWindow.cpp Normal file
View File

@ -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();
}

119
RpcView/MainWindow.h Normal file
View File

@ -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_

194
RpcView/Pdb.c Normal file
View File

@ -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;
}

10
RpcView/Pdb.h Normal file
View File

@ -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_

View File

@ -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();
}

View File

@ -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_

19
RpcView/ProcessEntry.h Normal file
View File

@ -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_

View File

@ -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);
}

View File

@ -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_

View File

@ -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);
}

View File

@ -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

559
RpcView/ProcessWidget.cpp Normal file
View File

@ -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();
}

87
RpcView/ProcessWidget.h Normal file
View File

@ -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_

250
RpcView/RefreshVisitor.cpp Normal file
View File

@ -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