• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

E:/PROJECTS/cvsed/mixed/VIRTUA~1/kdvm/vmwrpc.h

Go to the documentation of this file.
00001 
00008 #pragma once
00009 
00010 //#ifdef _DEBUG
00011 #define VMWRPC_PARAMETER_CHECKING
00012 //#endif
00013 
00014 #pragma pack(push, 4)
00016 class VMWareRpcData
00017 {
00018 public:
00019         unsigned m_Cookie1;
00020         unsigned m_Cookie2;
00021         unsigned m_ChannelNumber;
00022         
00023         unsigned m_ReplyId;
00024         unsigned m_CachedReplySize;
00025 };
00026 #pragma pack(pop)
00027 
00028 #ifdef _AMD64_
00029 extern "C"
00030 {
00031         //Channel manipulation functions are defined in vmwrpc64.asm
00032         int VMWareOpenChannel(VMWareRpcData *pChannel);
00033         bool VMWareCloseChannel(VMWareRpcData *pChannel);
00034         bool VMWareSendRequestLength(VMWareRpcData *pChannel, size_t sizeNotCountingNULL);
00035         bool VMWareSendPartialData(VMWareRpcData *pChannel, size_t sizeNotCountingNULL, const void *pData);
00036         bool VMWareSendData(VMWareRpcData *pChannel, size_t sizeNotCountingNULL, const void *pData);
00037         unsigned  VMWareGetReplySize(VMWareRpcData *pChannel);
00038         bool  VMWareRecvData(VMWareRpcData *pChannel, size_t sizeNotCountingNULL, void *pData);
00039         bool  VMWareEndReceive(VMWareRpcData *pChannel);
00040 }
00041 #endif
00042 
00044 /*
00045         \remarks See details on VMWare backdoor commands here: http://chitchat.at.infoseek.co.jp/vmware/backdoor.html
00046 */
00047 namespace VMWareRPC
00048 {
00049 #ifndef _AMD64_
00051         static unsigned __declspec(naked) __fastcall OpenChannel(VMWareRpcData *pChannel)
00052         {
00053                 __asm
00054                 {
00055                         pushad
00056                         mov eax, 0x564D5868
00057                         mov ebx, 0xC9435052
00058                         xchg ecx,ebp
00059                         mov ecx, 0x0000001E
00060                         mov edx, 0x5658
00061                         out dx, eax
00062                         test ecx, 0x00010000
00063                         jz vmware_rpc_open_channel_error
00064                         mov [ebp].m_Cookie1, esi
00065                         mov [ebp].m_Cookie2, edi
00066                         mov [ebp].m_ChannelNumber, edx
00067                         popad
00068                         xor eax, eax
00069                         inc eax
00070                         ret
00071 vmware_rpc_open_channel_error:
00072                         mov edx, 0x5658
00073                         in eax, dx
00074                         cmp eax, 'XOBV' //'VBOX' signature is returned, if this call was made under VirtualBox
00075                         jz vmware_rpc_open_channel_vbox
00076                         popad 
00077                         xor eax, eax
00078                         ret
00079 vmware_rpc_open_channel_vbox:
00080                         popad
00081                         xor eax, eax
00082                         add eax, 2
00083                         ret
00084                 }
00085         }
00086 
00088         static bool __declspec(naked) __fastcall CloseChannel(VMWareRpcData *pChannel)
00089         {
00090                 __asm
00091                 {
00092                         pushad
00093                         mov eax, 0x564D5868
00094                         mov edx, [ecx].m_ChannelNumber
00095                         or edx, 0x5658
00096                         mov esi, [ecx].m_Cookie1
00097                         mov edi, [ecx].m_Cookie2
00098                         mov ecx, 0x0006001E
00099                         out dx, eax
00100                         cmp ecx, 0x00010000
00101                         popad
00102                         setz al
00103                         and eax,1
00104                         ret
00105                 }
00106         }
00107 
00109         static bool __declspec(naked) __fastcall SendRequestLength(VMWareRpcData *pChannel, size_t sizeNotCountingNULL)
00110         {
00111                 __asm
00112                 {
00113                         pushad
00114                         mov eax, 0x564D5868
00115                         mov ebx, edx
00116                         mov edx, [ecx].m_ChannelNumber
00117                         or edx, 0x5658
00118                         mov esi, [ecx].m_Cookie1
00119                         mov edi, [ecx].m_Cookie2
00120                         mov ecx, 0x0001001E
00121                         out dx, eax
00122                         cmp ecx, 0x00810000
00123                         jnz vmware_rpc_send_size_error
00124 
00125                         popad
00126                         xor eax,eax
00127                         inc eax
00128                         ret
00129 
00130 vmware_rpc_send_size_error:
00131                         popad
00132                         xor eax,eax
00133                         ret
00134                 }
00135         }
00136 
00138         static bool __declspec(naked) __fastcall SendPartialData(VMWareRpcData *pChannel, size_t sizeNotCountingNULL, const void *pData)
00139         {
00140                 __asm
00141                 {
00142                         pushad
00143                         mov eax, 0x564D5868
00144                         //ecx <- byte count to send (minus null)
00145                         xchg ecx, edx
00146                         mov ebx, 0x00010000
00147                         mov esi, [esp+0x24]     //pData
00148                         mov edi, [edx].m_Cookie2
00149                         mov ebp, [edx].m_Cookie1
00150                         mov edx, [edx].m_ChannelNumber
00151                         or edx, 0x5659
00152                         rep outsb
00153 
00154                         cmp ebx, 0x00010000
00155                         jnz vmware_rpc_send_partial_error
00156 
00157                         popad
00158                         xor eax,eax
00159                         inc eax
00160                         ret 4
00161 
00162 vmware_rpc_send_partial_error:
00163                         popad
00164                         xor eax,eax
00165                         ret 4
00166                 }
00167         }
00168 
00170         static bool __declspec(naked) __fastcall SendData(VMWareRpcData *pChannel, size_t sizeNotCountingNULL, const void *pData)
00171         {
00172                 __asm
00173                 {
00174                         pushad
00175                         mov eax, 0x564D5868
00176                         mov ebx, edx
00177                         mov edx, [ecx].m_ChannelNumber
00178                         or edx, 0x5658
00179                         mov esi, [ecx].m_Cookie1
00180                         mov edi, [ecx].m_Cookie2
00181                         // ebp <- class pointer
00182                         xchg ebp, ecx
00183                         mov ecx, 0x0001001E
00184                         out dx, eax
00185                         cmp ecx, 0x00810000
00186                         jnz vmware_rpc_send_data_error
00187 
00188                         //ecx <- byte count to send (minus null)
00189                         xchg ecx, ebx
00190                         mov ebx, 0x00010000
00191                         mov esi, [esp+0x24]     //pData
00192                         mov edx, [ebp].m_ChannelNumber
00193                         or edx, 0x5659
00194                         mov edi, [ebp].m_Cookie2
00195                         mov ebp, [ebp].m_Cookie1
00196                         rep outsb
00197 
00198                         cmp ebx, 0x00010000
00199                         jnz vmware_rpc_send_data_error
00200 
00201                         popad
00202                         xor eax,eax
00203                         inc eax
00204                         ret 4
00205 
00206 vmware_rpc_send_data_error:
00207                         popad
00208                         xor eax,eax
00209                         ret
00210                 }
00211         }
00212 
00214         static unsigned __declspec(naked) __fastcall GetReplySize(VMWareRpcData *pChannel)
00215         {
00216                 __asm
00217                 {
00218                         push ebx
00219                         push esi
00220                         push edi
00221                         push ebp
00222                         mov eax, 0x564D5868
00223                         mov edx, [ecx].m_ChannelNumber
00224                         or edx, 0x5658
00225                         mov esi, [ecx].m_Cookie1
00226                         mov edi, [ecx].m_Cookie2
00227                         xchg ebp, ecx
00228                         mov ecx, 0x0003001E
00229                         out dx, eax
00230                         mov [ebp].m_ReplyId, edx
00231                         cmp ecx, 0x00830000
00232                         jz return_from_get_reply_size
00233                         or ebx, -1
00234 return_from_get_reply_size:                     
00235                         xchg eax,ebx
00236                         pop ebp
00237                         pop edi
00238                         pop esi
00239                         pop ebx
00240                         ret
00241                 }
00242         }
00243 
00245         static bool __declspec(naked) __fastcall RecvData(VMWareRpcData *pChannel, size_t sizeNotCountingNULL, void *pData)
00246         {
00247                 __asm
00248                 {
00249                         pushad
00250                         mov eax, 0x564D5868
00251                         mov ebx, 0x00010000
00252                         xchg ecx, edx
00253                         mov edi, [esp+0x24]     //pData
00254                         mov esi, [edx].m_Cookie1
00255                         mov ebp, [edx].m_Cookie2
00256                         mov edx, [edx].m_ChannelNumber
00257                         or edx, 0x5659
00258                         rep insb
00259 
00260                         cmp ebx, 0x00010000
00261                         jnz vmware_rpc_recv_data_error
00262 
00263                         popad
00264                         xor eax,eax
00265                         inc eax
00266                         ret 4
00267 
00268 vmware_rpc_recv_data_error:
00269                         popad
00270                         xor eax,eax
00271                         ret 4
00272                 }
00273         }
00274 
00276         static bool __declspec(naked) __fastcall EndReceive(VMWareRpcData *pChannel)
00277         {
00278                 __asm
00279                 {
00280                         pushad
00281                         mov eax, 0x564D5868
00282                         mov ebx, [ecx].m_ReplyId
00283                         mov edx, [ecx].m_ChannelNumber
00284                         or edx, 0x5658
00285                         mov esi, [ecx].m_Cookie1
00286                         mov edi, [ecx].m_Cookie2
00287                         mov ecx, 0x0005001E
00288                         out dx, eax
00289                         cmp ecx, 0x00010000
00290                         popad
00291                         setz al
00292                         and eax,1
00293                         ret
00294                 }
00295         }
00296 #else
00297         
00298         static inline int OpenChannel(VMWareRpcData *pChannel)
00299         {
00300                 return VMWareOpenChannel(pChannel);
00301         }
00302 
00303         static inline bool CloseChannel(VMWareRpcData *pChannel)
00304         {
00305                 return VMWareCloseChannel(pChannel);
00306         }
00307 
00308         static inline bool SendRequestLength(VMWareRpcData *pChannel, size_t sizeNotCountingNULL)
00309         {
00310                 return VMWareSendRequestLength(pChannel, sizeNotCountingNULL);
00311         }
00312 
00313         static inline bool  SendPartialData(VMWareRpcData *pChannel, size_t sizeNotCountingNULL, const void *pData)
00314         {
00315                 return VMWareSendPartialData(pChannel, sizeNotCountingNULL, pData);
00316         }
00317 
00318         static inline bool  SendData(VMWareRpcData *pChannel, size_t sizeNotCountingNULL, const void *pData)
00319         {
00320                 return VMWareSendData(pChannel, sizeNotCountingNULL, pData);
00321         }
00322 
00323         static inline unsigned  GetReplySize(VMWareRpcData *pChannel)
00324         {
00325                 return VMWareGetReplySize(pChannel);
00326         }
00327 
00328         static inline bool  RecvData(VMWareRpcData *pChannel, size_t sizeNotCountingNULL, void *pData)
00329         {
00330                 return VMWareRecvData(pChannel, sizeNotCountingNULL, pData);
00331         }
00332 
00333         static inline bool  EndReceive(VMWareRpcData *pChannel)
00334         {
00335                 return VMWareEndReceive(pChannel);
00336         }
00337 #endif
00338 }
00339 
00341 
00350 class VMWareRPCChannel : protected VMWareRpcData
00351 {
00352 private:
00353         bool m_bVBoxDetected;
00354 
00355 protected:
00356         bool Send(const char *pData, unsigned Size = 0)
00357         {
00358                 if (!Size)
00359                         Size = strlen(pData);
00360                 m_CachedReplySize = -1;
00361                 return VMWareRPC::SendData(this, Size, pData);
00362         }
00363 
00364         bool Receive(void *pData, unsigned Size)
00365         {
00366                 if (m_CachedReplySize == -1)
00367                         return false;
00368                 if (Size > m_CachedReplySize)
00369                         Size = m_CachedReplySize;
00370                 if (!Size)
00371                         return true;
00372                 if (!VMWareRPC::RecvData(this, Size, pData))
00373                 {
00374                         m_CachedReplySize = m_ChannelNumber = -1;
00375                         return false;
00376                 }
00377                 m_CachedReplySize -= Size;
00378                 return true;
00379         }
00380 
00381         bool EndReceive()
00382         {
00383                 if (!VMWareRPC::EndReceive(this))
00384                         return false;
00385                 m_CachedReplySize = -1;
00386                 return true;
00387         }
00388 
00389         unsigned GetReplySize()
00390         {
00391                 if (m_CachedReplySize != -1)
00392                         return m_CachedReplySize;
00393                 m_CachedReplySize = VMWareRPC::GetReplySize(this);
00394                 return m_CachedReplySize;
00395         }
00396 
00397 public:
00398 
00399         VMWareRPCChannel()
00400                 : m_bVBoxDetected(false)
00401         {
00402                 switch (VMWareRPC::OpenChannel(this))
00403                 {
00404                 case 1:
00405                         break;
00406                 case 2:
00407                         m_bVBoxDetected = true;
00408                         // no break here;
00409                 default:
00410                         m_ChannelNumber = -1;
00411 
00412                 }
00413                 m_CachedReplySize = -1;
00414         }
00415         
00416         ~VMWareRPCChannel()
00417         {
00418                 VMWareRPC::CloseChannel(this);
00419         }
00420 
00422         unsigned ExecuteCommand(const char *pszRequest, char *pszBuffer, unsigned MaxBufferSize)
00423         {
00424                 ASSERT(pszRequest && pszBuffer && (MaxBufferSize > 1));
00425                 if (!Send(pszRequest))
00426                         return -1;
00427                 unsigned size = GetReplySize();
00428                 if ((size == -1) || (size >= MaxBufferSize))
00429                         return -1;
00430                 if (!Receive(pszBuffer, size))
00431                         return -1;
00432                 pszBuffer[size] = 0;
00433                 if (!EndReceive())
00434                         return -1;
00435                 return size;
00436         }
00437         
00438         bool Valid()
00439         {
00440                 return m_ChannelNumber != -1;
00441         }
00442 
00443         bool IsVBoxDetected()
00444         {
00445                 return m_bVBoxDetected;
00446         }
00447 };
00448 
00449 /*class AdvancedRPCChannel : private VMWareRPCChannel
00450 {
00451 public:
00452         bool PrepareSend(unsigned SendSize)
00453         {
00454                 return VMWareRPC::SendRequestLength(this, SendSize);
00455         }
00456 
00457         bool SendPartial(const void *pData, unsigned Size)
00458         {
00459                 return VMWareRPC::SendPartialData(this, Size, pData);
00460         }
00461 
00462         unsigned GetReplySize()
00463         {
00464                 return __super::GetReplySize();
00465         }
00466 
00467         bool Receive(void *pData, unsigned Size)
00468         {
00469                 return __super::Receive(pData, Size);
00470         }
00471 
00472         bool Valid()
00473         {
00474                 return __super::Valid();
00475         }
00476 
00477         bool EndReceive()
00478         {
00479                 return __super::EndReceive();
00480         }
00481 };*/
00482 
00484 template <char *t_pBuffer, unsigned t_BufferSize> class BufferedRPCChannel : private VMWareRPCChannel
00485 {
00486 private:
00487         unsigned m_BufferPos;
00488         unsigned m_TotalTransferSize;
00489 
00490         enum
00491         {
00492                 Idle,
00493                 Sending,
00494                 Sent,
00495                 Receiving,
00496                 Received,
00497         } m_Phase;
00498 
00499 private:
00500         bool SendBufferedData()
00501         {
00502 #ifdef VMWRPC_PARAMETER_CHECKING
00503                 if (m_Phase != Sending)
00504                         return false;
00505                 if (m_BufferPos != m_TotalTransferSize)
00506                         return false;
00507 #endif
00508                 if (!__super::Send(t_pBuffer, m_TotalTransferSize))
00509                         return false;
00510                 m_Phase = Sent;
00511                 return true;
00512         }
00513 
00514 public:
00515         BufferedRPCChannel()
00516                 : m_BufferPos(0)
00517                 , m_TotalTransferSize(0)
00518                 , m_Phase(Idle)
00519         {
00520         }
00521 
00522         ~BufferedRPCChannel()
00523         {
00524         }
00525 
00526         bool PrepareSend(unsigned SendSize)
00527         {
00528                 if ((m_Phase != Idle) || (SendSize > t_BufferSize))
00529                         return false;
00530                 m_TotalTransferSize = SendSize;
00531                 m_Phase = Sending;
00532                 m_BufferPos = 0;
00533                 return true;
00534         }
00535 
00536         bool SendPartial(const void *pData, unsigned Size)
00537         {
00538                 if (!Size)
00539                         return true;
00540 #ifdef VMWRPC_PARAMETER_CHECKING
00541                 if (m_Phase != Sending)
00542                         return false;
00543                 if (Size > (m_TotalTransferSize - m_BufferPos))
00544                         return false;
00545 #endif
00546                 memcpy(t_pBuffer + m_BufferPos, pData, Size);
00547                 m_BufferPos += Size;
00548                 return true;
00549         }
00550 
00551         unsigned GetReplySize()
00552         {
00553                 if (m_Phase == Receiving)
00554                         return m_TotalTransferSize;
00555                 if (!SendBufferedData())
00556                         return -1;
00557                 if (m_Phase != Sent)
00558                         return -1;
00559                 m_TotalTransferSize = __super::GetReplySize();
00560                 if (m_TotalTransferSize && (m_TotalTransferSize != -1) && (m_TotalTransferSize <= t_BufferSize))
00561                 {
00562                         if (!__super::Receive(t_pBuffer, t_BufferSize))
00563                                 return -1;
00564                         m_Phase = Receiving;
00565                         m_BufferPos = 0;
00566                         return m_TotalTransferSize;
00567                 }
00568                 else
00569                         return -1;
00570         }
00571 
00572         bool Receive(void *pData, unsigned Size)
00573         {
00574                 if (!Size)
00575                         return true;
00576 #ifdef VMWRPC_PARAMETER_CHECKING
00577                 if (m_Phase != Receiving)
00578                         return false;
00579                 if (Size > (m_TotalTransferSize - m_BufferPos))
00580                         return false;
00581 #endif
00582                 memcpy(pData, t_pBuffer + m_BufferPos, Size);
00583                 m_BufferPos += Size;
00584                 if (m_BufferPos == m_TotalTransferSize)
00585                         m_Phase = Received;
00586                 return true;
00587         }
00588 
00589         bool Valid()
00590         {
00591                 return __super::Valid();
00592         }
00593 
00594         bool EndReceive()
00595         {
00596                 if (m_Phase != Received)
00597                         return false;
00598                 if (!__super::EndReceive())
00599                         return false;
00600                 m_Phase = Idle;
00601                 return true;
00602         }
00603 
00604         bool NeedRestartInVBoxMode()
00605         {
00606                 return __super::IsVBoxDetected();
00607         }
00608 
00609 };