diff --git a/README.md b/README.md index d7ee640..10d4117 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -RpcView -======= +# RpcView RpcView is an open-source tool to explore and decompile all RPC functionalities present on a Microsoft system. @@ -7,10 +6,9 @@ You can download the last [automatically built release](https://ci.appveyor.com/ [![Build status](https://ci.appveyor.com/api/projects/status/o5wy6mdk16tuht70?svg=true)](https://ci.appveyor.com/project/silverf0x/rpcview) -**Warning**: you have to install "Microsoft Visual C++ 2015 Redistributable" to use RpcView. +> **Warning**: you have to install "Microsoft Visual C++ 2015 Redistributable" to use RpcView. -How to add a new RPC runtime ----------------------------------- +## How to add a new RPC runtime Basically you have two possibilities to support a new RPC runtime (rpcrt4.dll) version: @@ -24,8 +22,7 @@ Currently, the supported versions are organized as follows: - RpcCore3 for Windows 8 - RpcCore4 for Windows 8.1 and 10 -Compilation --------------- +## Compilation Required elements to compiled the project: @@ -33,11 +30,14 @@ Required elements to compiled the project: * CMake (at least 3.0.2) * Qt5 (currently 5.9.1) -Before running CMake you have to set the CMAKE_PREFIX_PATH environment variable with the current Qt path, for instance (x64): +Before running CMake you have to set the CMAKE_PREFIX_PATH environment variable with the Qt **full path**, for instance (x64): ``` set CMAKE_PREFIX_PATH=C:\Qt\Qt5.9.1\5.9.1\msvc2015_64 ``` -Then you can run CMake to produce the project solution. +Before running CMake to produce the project solution you have to create the buikd directories: +- ```RpcView/Build/x64``` for 64-bit targets +- ```RpcView/Build/x86``` for 32-bit targets. + Here is an example to generate the x64 solution with Visual Studio 2015 from the ```RpcView/Build/x64``` directory: ```cmake @@ -105,8 +105,8 @@ 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 ----------------------- +## Acknowledgements + * Jeremy * Julien * Yoanne diff --git a/RpcCommon/Misc.c b/RpcCommon/Misc.c index 77b85eb..f163bc3 100644 --- a/RpcCommon/Misc.c +++ b/RpcCommon/Misc.c @@ -50,7 +50,7 @@ BOOL WINAPI EnumProcess(EnumProcessCallbackFn_T EnumProcessCallbackFn,void* pCal BOOL bContinue=TRUE; hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); - if (hSnapshot==NULL) goto End; + if (hSnapshot == INVALID_HANDLE_VALUE) goto End; ProcessEntry.dwSize=sizeof(ProcessEntry); if (!Process32FirstW(hSnapshot,&ProcessEntry)) goto End; do @@ -61,7 +61,7 @@ BOOL WINAPI EnumProcess(EnumProcessCallbackFn_T EnumProcessCallbackFn,void* pCal }while(Process32NextW(hSnapshot,&ProcessEntry)); End: - if (hSnapshot!=NULL) CloseHandle(hSnapshot); + if (hSnapshot != INVALID_HANDLE_VALUE) CloseHandle(hSnapshot); return (bResult); } @@ -162,74 +162,6 @@ 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) { @@ -375,7 +307,7 @@ BOOL WINAPI GetUserAndDomainName(DWORD Pid, WCHAR* Buffer, ULONG BufferLengthInB pTokenUser=(TOKEN_USER*)OS_ALLOC(Bytes); if (pTokenUser==NULL) goto End; if (!GetTokenInformation(hToken,TokenUser,pTokenUser,Bytes,&Bytes)) goto End; - dwSize=sizeof(UserName); + dwSize=_countof(UserName); if (!LookupAccountSidW(NULL,pTokenUser->User.Sid,UserName,&dwSize,DomainName,&dwSize,&SidType)) goto End; StringCbPrintfW(Buffer,BufferLengthInBytes,L"%s\\%s",DomainName,UserName); bResult=TRUE; diff --git a/RpcCommon/Misc.h b/RpcCommon/Misc.h index 3d95a9c..1d955b9 100644 --- a/RpcCommon/Misc.h +++ b/RpcCommon/Misc.h @@ -36,15 +36,12 @@ 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); diff --git a/RpcCore/RpcCore.c b/RpcCore/RpcCore.c index 76825f7..159b05f 100644 --- a/RpcCore/RpcCore.c +++ b/RpcCore/RpcCore.c @@ -226,6 +226,7 @@ BOOL WINAPI GetRpcServerAddressInProcess(DWORD Pid,RpcCoreInternalCtxt_T* pRpcCo EnumProcessModulesEx(hProcess, NULL, 0, &cbSize, LIST_MODULES_ALL); if (cbSize == 0) goto End; pHmodule = (HMODULE*)malloc(cbSize); + if (pHmodule == NULL) goto End; EnumProcessModulesEx(hProcess, pHmodule, cbSize, &cbSize, LIST_MODULES_ALL); for(ULONG i=0;i& listProcType, std::ostringstream& ossProc); BOOL __fastcall RpcDecompilerDecodeOneProcedureInlined(VOID* pContext, UINT ProcIndex, IdlFunctionDesc& IdlFunctionDesc, std::list& listProcType); BOOL __fastcall RpcDecompilerPrintOneProcedureInlined(VOID* pContext, UINT ProcOffset, IdlFunctionDesc& IdlFunctionDesc, std::list& listProcType, std::ostringstream& ossProc); - BOOL __fastcall RpcDecompilerPrintHiddenFUProcedure(VOID* pRpcDecompilerCtxt, UINT * procOffset, std::list& listProcType, std::ostringstream& ossProc); BOOL __fastcall RpcDecompilerPrintAllProceduresNew(VOID* pRpcDecompilerCtxt); @@ -445,128 +444,6 @@ End: return (bResult); } - - BOOL __fastcall RpcDecompilerPrintHiddenFUProcedure(VOID* pContext, UINT * procOffset, std::list& 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 << " */"<