Files
Work/remoteps/remoteps.cpp
2024-08-07 09:16:27 -04:00

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;
}