fork download
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. typedef unsigned char u_char;
  5. typedef char CCHAR;
  6. typedef int16_t WCHAR;
  7. typedef uint32_t ULONG;
  8. typedef uint32_t DWORD;
  9. typedef uint64_t LARGE_INTEGER;
  10.  
  11. #pragma pack(1)
  12.  
  13. typedef struct smb2_FileBothDirectoryInformation {
  14. ULONG NextEntryOffset;
  15. ULONG FileIndex;
  16. LARGE_INTEGER CreationTime;
  17. LARGE_INTEGER LastAccessTime;
  18. LARGE_INTEGER LastWriteTime;
  19. LARGE_INTEGER ChangeTime;
  20. LARGE_INTEGER EndOfFile;
  21. LARGE_INTEGER AllocationSize;
  22. ULONG FileAttributes;
  23. ULONG FileNameLength;
  24. ULONG EaSize;
  25. CCHAR ShortNameLength;
  26. CCHAR Reserved;
  27. WCHAR ShortName[12];
  28. LARGE_INTEGER FileId; // Missing in [MS-FSCC]: File System Control Codes - 2.4.8 FileBothDirectoryInformation
  29. u_char Reserved2[2]; // Missing in [MS-FSCC]: File System Control Codes - 2.4.8 FileBothDirectoryInformation
  30. WCHAR FileName[1];
  31. } smb2_FileBothDirectoryInformation_t;
  32.  
  33. typedef struct {
  34. uint16_t StructureSize;
  35. uint16_t OutputBufferOffset;
  36. uint32_t OutputBufferLength;
  37. u_char Buffer[1];
  38. } smb2_query_directory_response_t;
  39. #pragma pack()
  40.  
  41. //https://stackoverflow.com/questions/15934111/portable-and-safe-way-to-add-byte-offset-to-any-pointer
  42. template <typename T> inline void addOffset(std::ptrdiff_t offset, T *&ptr) {
  43. if (!ptr) return;
  44. ptr = (T*)((const unsigned char*)ptr + offset);
  45. }
  46. template <typename T> inline T* offset(std::ptrdiff_t offset, T *ptr) {
  47. return (T*)((const unsigned char*)ptr + offset);
  48. }
  49. //SomeType* ptr; int offset = 12345; offset_ptr(offset, ptr);
  50. template <typename T> inline void offset_ptr(std::ptrdiff_t byte_offset, const T* &ref_ptr) {
  51. ref_ptr = (T*)((const unsigned char*)ref_ptr + byte_offset);
  52. }
  53.  
  54. //If you use this marco like `typedef struct {} SomeType; SomeType* ptr; OFFSET_PTR(16, ptr);`
  55. //IDE error: expression must be a modifiable value. Compile: error C2106: '=': left operand must be l-value.
  56. #define OFFSET_PTR(byte_offset, ref_ptr) ((const unsigned char*)ref_ptr = (const unsigned char*)ref_ptr + byte_offset)
  57.  
  58. char packet_bytes[9] = {0};
  59.  
  60. int main() {
  61. printf("(int)sizeof(smb2_query_directory_response_t) = %d\n", (int)sizeof(smb2_query_directory_response_t));
  62. printf("(int)sizeof(smb2_FileBothDirectoryInformation_t) = %d\n", (int)sizeof(smb2_FileBothDirectoryInformation_t));
  63.  
  64. const smb2_query_directory_response_t* pQueryDirInfoRsp = (smb2_query_directory_response_t*)packet_bytes;
  65. const smb2_FileBothDirectoryInformation_t *pFileBothDirInfo = pQueryDirInfoRsp->OutputBufferLength ? reinterpret_cast<const smb2_FileBothDirectoryInformation_t*>(pQueryDirInfoRsp->Buffer) : NULL;
  66. while (pFileBothDirInfo)
  67. {
  68. // ideone runs on linux with a compiler who consider wchar_t 4 bytes?
  69. // https://stackoverflow.com/questions/16944750/c-unicode-characters-printing
  70. //wprintf(L"%.*s|%.*s\n", pFileBothDirInfo->FileNameLength/2, pFileBothDirInfo->FileName, pFileBothDirInfo->ShortNameLength/2, pFileBothDirInfo->ShortName);
  71. if (pFileBothDirInfo->NextEntryOffset)
  72. {
  73. offset_ptr(pFileBothDirInfo->NextEntryOffset, pFileBothDirInfo);
  74.  
  75. const unsigned char *ptrTemp;
  76. ptrTemp = ((const unsigned char*)pFileBothDirInfo + 10);
  77. //be equivalent to
  78. //((const unsigned char*)pFileBothDirInfo) = ( (const unsigned char*)pFileBothDirInfo + 10 );
  79. OFFSET_PTR(pFileBothDirInfo->NextEntryOffset, pFileBothDirInfo);
  80. printf("ptrTemp = %p", ptrTemp);
  81. }
  82. else
  83. {
  84. break;
  85. }
  86. }
  87. return 0;
  88. }
Compilation error #stdin compilation error #stdout 0s 15232KB
stdin
Standard input is empty
compilation info
prog.cpp: In function ‘int main()’:
prog.cpp:79:33: error: lvalue required as left operand of assignment
    OFFSET_PTR(pFileBothDirInfo->NextEntryOffset, pFileBothDirInfo);
                                 ^
prog.cpp:56:107: note: in definition of macro ‘OFFSET_PTR’
 #define OFFSET_PTR(byte_offset, ref_ptr) ((const unsigned char*)ref_ptr = (const unsigned char*)ref_ptr + byte_offset)
                                                                                                           ^~~~~~~~~~~
stdout
Standard output is empty