// Note: Proxy/Stub Information // To build a separate proxy/stub DLL, // run nmake -f remotepsps.mk in the project directory. #include "stdafx.h" #include "resource.h" #include "initguid.h" #include "remoteps.h" #include "remoteps_i.c" #include "RemoteProcess.hpp" #include #include #include #include #include class InterceptGetHostByName { public: InterceptGetHostByName(const String &masquerade); ~InterceptGetHostByName(); private: enum {CodeSize=32}; typedef hostent *(__stdcall *LPFNGETHOSTBYNAME)(const char *name); bool intercept(void); void createForwarderThunk(void); bool setForwarderThunk(void); DWORD getAddress(void); hostent *__stdcall gethostbyname(const char *strHostName); BYTE mForwarderThunk[CodeSize]; Process mThisProcess; DWORD mBaseAddress; hostent *mpHostEnt; WSASystem mWSASystem; bool mIsOkay; }; InterceptGetHostByName::InterceptGetHostByName(const String &strMasquerade) : mIsOkay(false), mBaseAddress(0) { mpHostEnt=::gethostbyname(strMasquerade); if(!mpHostEnt)return; mThisProcess.openProcess(::GetCurrentProcessId(),Process::AllAccess); if(!mThisProcess.isOkay())return; createForwarderThunk(); if(!intercept())return; mIsOkay=true; } InterceptGetHostByName::~InterceptGetHostByName() { } bool InterceptGetHostByName::intercept(void) { DWORD countBytes; if(0==(mBaseAddress=getAddress()))return false; if(!setForwarderThunk())return false; return true; } void InterceptGetHostByName::createForwarderThunk(void) { ProcAddress procAddress; mForwarderThunk[0]=0x51; // push ecx mForwarderThunk[1]=0xB9; // mov ecx,this *((unsigned*)(mForwarderThunk+2))=(unsigned)this; // "" "" mForwarderThunk[6]=0x8B; // mov eax,[esp+12] mForwarderThunk[7]=0x44; // "" mForwarderThunk[8]=0x24; // "" mForwarderThunk[9]=0x0C; // "" mForwarderThunk[10]=0x50; // push eax mForwarderThunk[11]=0x50; // push eax mForwarderThunk[12]=0xB8; // mov eax,function address *((unsigned*)(mForwarderThunk+13))=(unsigned)procAddress.getProcAddress((ProcAddress::LPFNMETHODVOID)&InterceptGetHostByName::gethostbyname); mForwarderThunk[17]=0xFF; // call eax mForwarderThunk[18]=0xD0; // "" "" mForwarderThunk[19]=0x59; // pop ecx mForwarderThunk[20]=0xC2; // retn 4 *((short*)(mForwarderThunk+21))=4; // "" "" } DWORD InterceptGetHostByName::getAddress(void) { Library sockLib("wsock32.dll"); if(!sockLib.isOkay())return false; return (DWORD)sockLib.procAddress("gethostbyname"); } bool InterceptGetHostByName::setForwarderThunk(void) { DWORD countBytes; mThisProcess.writeProcessMemory((void*)mBaseAddress,mForwarderThunk,sizeof(mForwarderThunk),&countBytes); return countBytes==sizeof(mForwarderThunk); } hostent *InterceptGetHostByName::gethostbyname(const char *hostname) { InterceptGetHostByName *pInterceptGetHostByName; _asm mov pInterceptGetHostByName,ecx; return pInterceptGetHostByName->mpHostEnt; } // ********************************************************************************** class InterceptGetComputerName { public: InterceptGetComputerName(const String &masquerade); ~InterceptGetComputerName(); private: enum {CodeSize=32}; typedef int (__stdcall *LPFNGETCOMPUTERNAME)(LPSTR lpComputerName,LPDWORD cbBytes); bool intercept(void); void createForwarderThunk(void); bool setForwarderThunk(void); DWORD getAddress(void); int __stdcall getcomputername(LPSTR lpComputerName,LPDWORD cbBytes); BYTE mForwarderThunk[CodeSize]; Process mThisProcess; DWORD mBaseAddress; WSASystem mWSASystem; String mComputerName; bool mIsOkay; }; InterceptGetComputerName::InterceptGetComputerName(const String &strMasquerade) : mIsOkay(false), mBaseAddress(0) { if(strMasquerade.isNull())return; mComputerName=strMasquerade; mThisProcess.openProcess(::GetCurrentProcessId(),Process::AllAccess); if(!mThisProcess.isOkay())return; createForwarderThunk(); if(!intercept())return; mIsOkay=true; } InterceptGetComputerName::~InterceptGetComputerName() { } bool InterceptGetComputerName::intercept(void) { DWORD countBytes; if(0==(mBaseAddress=getAddress()))return false; if(!setForwarderThunk())return false; return true; } void InterceptGetComputerName::createForwarderThunk(void) { ProcAddress procAddress; mForwarderThunk[0]=0x51; // push ecx mForwarderThunk[1]=0xB9; // mov ecx,this *((unsigned*)(mForwarderThunk+2))=(unsigned)this; // "" "" mForwarderThunk[6]=0x8B; // mov eax,[esp+8] mForwarderThunk[7]=0x44; // "" mForwarderThunk[8]=0x24; // "" mForwarderThunk[9]=0x0C; // "" mForwarderThunk[10]=0x50; // push eax mForwarderThunk[11]=0x8B; // mov eax,[esp+16] mForwarderThunk[12]=0x44; // "" mForwarderThunk[13]=0x24; // "" mForwarderThunk[14]=0x14; // "" mForwarderThunk[15]=0x50; // push eax mForwarderThunk[15]=0x50; // push eax // mForwarderThunk[11]=0x50; // push eax mForwarderThunk[16]=0xB8; // mov eax,function address *((unsigned*)(mForwarderThunk+17))=(unsigned)procAddress.getProcAddress((ProcAddress::LPFNMETHODVOID)&InterceptGetComputerName::getcomputername); mForwarderThunk[21]=0xFF; // call eax mForwarderThunk[22]=0xD0; // "" "" mForwarderThunk[23]=0x59; // pop ecx mForwarderThunk[24]=0xC2; // retn 8 *((short*)(mForwarderThunk+25))=8; // "" "" } DWORD InterceptGetComputerName::getAddress(void) { Library k32("kernel32.dll"); if(!k32.isOkay())return false; return (DWORD)k32.procAddress("GetComputerNameW"); } bool InterceptGetComputerName::setForwarderThunk(void) { DWORD countBytes; mThisProcess.writeProcessMemory((void*)mBaseAddress,mForwarderThunk,sizeof(mForwarderThunk),&countBytes); return countBytes==sizeof(mForwarderThunk); } int InterceptGetComputerName::getcomputername(LPSTR lpComputerName,LPDWORD cbBytes) { InterceptGetComputerName *pInterceptGetComputerName; _asm mov pInterceptGetComputerName,ecx; ::strcpy(lpComputerName,"ganymede"); *cbBytes=::strlen("ganymede"); // return pInterceptGetHostByName->mpHostEnt; return 1; } // ****************************************************************** LONG CExeModule::Unlock() { LONG l = CComModule::Unlock(); if (l == 0) { #if _WIN32_WINNT >= 0x0400 if (CoSuspendClassObjects() == S_OK) PostThreadMessage(dwThreadID, WM_QUIT, 0, 0); #else PostThreadMessage(dwThreadID, WM_QUIT, 0, 0); #endif } return l; } CExeModule _Module; BEGIN_OBJECT_MAP(ObjectMap) OBJECT_ENTRY(CLSID_CoRemoteProcess, RemoteProcess) END_OBJECT_MAP() LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2) { while (*p1 != NULL) { LPCTSTR p = p2; while (*p != NULL) { if (*p1 == *p++) return p1+1; } p1++; } return NULL; } ///////////////////////////////////////////////////////////////////////////// extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/) { HRESULT hRes; ComObj comObj; // InterceptGetHostByName interceptGetHostByName("scas1user120.li.net"); // InterceptGetComputerName interceptGetComputerName("ganymede"); lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT // HRESULT hRes = CoInitialize(NULL); hRes = CoInitialize(NULL); // If you are running on NT 4.0 or higher you can use the following call // instead to make the EXE free threaded. // This means that calls come in on a random RPC thread // hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED); // _ASSERTE(SUCCEEDED(hRes)); _Module.Init(ObjectMap, hInstance); _Module.dwThreadID = GetCurrentThreadId(); TCHAR szTokens[] = _T("-/"); int nRet = 0; BOOL bRun = TRUE; LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens); while (lpszToken != NULL) { if (lstrcmpi(lpszToken, _T("UnregServer"))==0) { _Module.UpdateRegistryFromResource(IDR_Remoteps, FALSE); nRet = _Module.UnregisterServer(); bRun = FALSE; break; } if (lstrcmpi(lpszToken, _T("RegServer"))==0) { _Module.UpdateRegistryFromResource(IDR_Remoteps, TRUE); nRet = _Module.RegisterServer(TRUE); bRun = FALSE; break; } lpszToken = FindOneOf(lpszToken, szTokens); } if (bRun) { hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,REGCLS_MULTIPLEUSE); _ASSERTE(SUCCEEDED(hRes)); MSG msg; while (GetMessage(&msg, 0, 0, 0)) DispatchMessage(&msg); _Module.RevokeClassObjects(); } CoUninitialize(); return nRet; }