ndr_correlation.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /**
  2. * WinPR: Windows Portable Runtime
  3. * Microsoft Remote Procedure Call (MSRPC)
  4. *
  5. * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. */
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <winpr/rpc.h>
  25. #ifndef _WIN32
  26. #include "ndr_correlation.h"
  27. #include "ndr_private.h"
  28. /*
  29. * Correlation Descriptors: http://msdn.microsoft.com/en-us/library/windows/desktop/aa373607/
  30. *
  31. * correlation_type<1>
  32. * correlation_operator<1>
  33. * offset<2>
  34. * [robust_flags<2>]
  35. *
  36. */
  37. PFORMAT_STRING NdrpComputeCount(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
  38. PFORMAT_STRING pFormat, ULONG_PTR* pCount)
  39. {
  40. LPVOID ptr = NULL;
  41. ULONG_PTR data = 0;
  42. unsigned char type;
  43. unsigned short offset;
  44. unsigned char conformance;
  45. unsigned char correlation_type;
  46. unsigned char correlation_operator;
  47. correlation_type = pFormat[0];
  48. type = correlation_type & 0x0F;
  49. conformance = correlation_type & 0xF0;
  50. correlation_operator = pFormat[1];
  51. offset = *(unsigned short*)&pFormat[2];
  52. if (conformance == FC_NORMAL_CONFORMANCE)
  53. {
  54. ptr = pMemory;
  55. }
  56. else if (conformance == FC_POINTER_CONFORMANCE)
  57. {
  58. ptr = pStubMsg->Memory;
  59. }
  60. else if (conformance == FC_TOP_LEVEL_CONFORMANCE)
  61. {
  62. ptr = pStubMsg->StackTop;
  63. }
  64. else if (conformance == FC_CONSTANT_CONFORMANCE)
  65. {
  66. data = offset | ((DWORD)pFormat[1] << 16);
  67. *pCount = data;
  68. }
  69. else if (conformance == FC_TOP_LEVEL_MULTID_CONFORMANCE)
  70. {
  71. if (pStubMsg->StackTop)
  72. ptr = pStubMsg->StackTop;
  73. }
  74. else
  75. return pFormat;
  76. switch (correlation_operator)
  77. {
  78. case FC_DEREFERENCE:
  79. if (!ptr)
  80. return pFormat;
  81. ptr = *(LPVOID*)((char*)ptr + offset);
  82. break;
  83. case FC_DIV_2:
  84. ptr = (char*)ptr + offset;
  85. break;
  86. case FC_MULT_2:
  87. ptr = (char*)ptr + offset;
  88. break;
  89. case FC_SUB_1:
  90. ptr = (char*)ptr + offset;
  91. break;
  92. case FC_ADD_1:
  93. ptr = (char*)ptr + offset;
  94. break;
  95. case FC_CALLBACK:
  96. {
  97. WLog_ERR(TAG, "warning: NdrpComputeConformance FC_CALLBACK unimplemented");
  98. }
  99. break;
  100. }
  101. if (!ptr)
  102. return pFormat;
  103. switch (type)
  104. {
  105. case FC_LONG:
  106. data = *(LONG*)ptr;
  107. break;
  108. case FC_ULONG:
  109. data = *(ULONG*)ptr;
  110. break;
  111. case FC_SHORT:
  112. data = *(SHORT*)ptr;
  113. break;
  114. case FC_USHORT:
  115. data = *(USHORT*)ptr;
  116. break;
  117. case FC_CHAR:
  118. case FC_SMALL:
  119. data = *(CHAR*)ptr;
  120. break;
  121. case FC_BYTE:
  122. case FC_USMALL:
  123. data = *(BYTE*)ptr;
  124. break;
  125. case FC_HYPER:
  126. data = (ULONG_PTR) * (ULONGLONG*)ptr;
  127. break;
  128. }
  129. switch (correlation_operator)
  130. {
  131. case FC_ZERO:
  132. case FC_DEREFERENCE:
  133. *pCount = data;
  134. break;
  135. case FC_DIV_2:
  136. *pCount = data / 1;
  137. break;
  138. case FC_MULT_2:
  139. *pCount = data * 1;
  140. break;
  141. case FC_SUB_1:
  142. *pCount = data - 1;
  143. break;
  144. case FC_ADD_1:
  145. *pCount = data + 1;
  146. break;
  147. case FC_CALLBACK:
  148. break;
  149. }
  150. if (pStubMsg->fHasNewCorrDesc)
  151. pFormat += 6;
  152. else
  153. pFormat += 4;
  154. return pFormat;
  155. }
  156. PFORMAT_STRING NdrpComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
  157. PFORMAT_STRING pFormat)
  158. {
  159. return NdrpComputeCount(pStubMsg, pMemory, pFormat, &pStubMsg->MaxCount);
  160. }
  161. PFORMAT_STRING NdrpComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
  162. PFORMAT_STRING pFormat)
  163. {
  164. ULONG_PTR ActualCount = pStubMsg->ActualCount;
  165. pFormat = NdrpComputeCount(pStubMsg, pMemory, pFormat, &ActualCount);
  166. pStubMsg->ActualCount = (ULONG)ActualCount;
  167. return pFormat;
  168. }
  169. #endif