327 lines
10 KiB
C++
327 lines
10 KiB
C++
// 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 <com/com.hpp>
|
|
|
|
#include <remoteps/procaddr.hpp>
|
|
#include <common/process.hpp>
|
|
#include <common/library.hpp>
|
|
#include <socket/wsadata.hpp>
|
|
|
|
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<InterceptGetHostByName> 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<InterceptGetHostByName>::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<InterceptGetComputerName> 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<InterceptGetComputerName>::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;
|
|
}
|
|
|