BOOL CRemoteLoader::CallEntryPoint( PVOID BaseAddress, FARPROC Entrypoint )
{
	PushInt( ( INT ) BaseAddress );
	PushInt( DLL_PROCESS_ATTACH );
	PushInt( 0 );
	PushCall( CCONV_STDCALL, Entrypoint );

	return ExecuteRemoteThreadBuffer( AssembleRemoteThreadBuffer() );
}
FARPROC CRemoteLoader::GetRemoteProcAddress( PCHAR Module, SHORT Function )
{
	HMODULE hKernel32 = LoadLibraryA( "Kernel32.dll" );

	if( hKernel32 == NULL ) return NULL;

	DWORD GetProcAddressOffset = ( DWORD ) GetProcAddress - ( DWORD ) hKernel32;

	HMODULE hRemoteKernel32 = GetRemoteModuleHandleA( "Kernel32.dll" );

	if( hRemoteKernel32 == NULL ) return NULL;
	
	HMODULE hRemoteModule = GetRemoteModuleHandleA( Module );

	if( hRemoteModule == NULL ) return NULL;
	
	PVOID ReturnPointerValue = RemoteAllocateMemory( sizeof( DWORD ) );

	PushInt( ( INT ) hRemoteModule ); // HACKHACK: Why is this an int?
	PushInt( ( INT ) Function );
	PushCall( CCONV_STDCALL, ( FARPROC )( ( DWORD_PTR ) hRemoteKernel32 + ( DWORD_PTR ) GetProcAddressOffset ) );

	//mov ptr, eax
	AddByteToBuffer( 0xA3 );
	AddLongToBuffer( ( DWORD ) ReturnPointerValue );

	//xor eax, eax
	AddByteToBuffer( 0x33 );
	AddByteToBuffer( 0xC0 );

	//retn 4
	AddByteToBuffer( 0xC2 );
	AddByteToBuffer( 0x04 );
	AddByteToBuffer( 0x00 );

	if( ExecuteRemoteThreadBuffer( m_CurrentRemoteThreadBuffer, true ) == false )
	{
		RemoteFreeMemory( ReturnPointerValue, sizeof( DWORD ) );

		return NULL;
	}

	DWORD ProcAddressRemote = 0;

	if( ReadProcessMemory( GetProcess(), ReturnPointerValue, &ProcAddressRemote, sizeof( DWORD ), NULL ) == TRUE )
	{
		RemoteFreeMemory( ReturnPointerValue, sizeof( DWORD ) );

		return ( FARPROC ) ProcAddressRemote;
	}
	
	RemoteFreeMemory( ReturnPointerValue, sizeof( DWORD ) );

	return NULL;
}
Example #3
0
void LoadCode(int fd, struct Module_st* CMData)
{
  Word i,j;
  Word offset=CMData->CodeOffset;
  Word size=CMData->CodeSize;
  Byte* code;
  Byte opcode;
  ConstInd tmpIndex;
  INSTR_InstrCategory instrCat;
  INSTR_OperandType* opType;
  int argid=0;

  if(size<=0){
    debug("No code for current module.\n");
    return;
  }
  debug("Loading 0x%lx bytes of code at %lx to offset 0x%lx.\n",size,lseek(fd,0,SEEK_CUR),offset);
  code=(Byte*)LK_VECTOR_GetPtr(&Code,offset);
  debug("After get\n");
  
  opcode=-1;
  instrCat=INSTR_CAT_X;
  opType=NULL;
  
  for(i=0;i<size;)
  {
    j=i;
    opcode=code[j++]=LK_FILE_GET1(fd);
    debug("\t%lx:%lx:[%x]%s\t",lseek(fd,0,SEEK_CUR)-1,i,opcode,INSTR_instrName(opcode));
    if(opcode==call_link_only)
    {
      code[j]=LK_FILE_GET1(fd);
      tmpIndex=GetConstInd(fd,CMData);
      PushCall(CMData->Pit,tmpIndex,offset+i,code[j]);
      i += INSTR_instrSize(opcode);
      
      continue;
    }
    else if(opcode==execute_link_only)
    {
      tmpIndex=GetConstInd(fd,CMData);
      PushCall(CMData->Pit,tmpIndex,offset+i,-1);
      i += INSTR_instrSize(opcode);
      continue;
    }
    
    instrCat=INSTR_instrType(opcode);
    opType=INSTR_operandTypes(instrCat);
    argid=0;
    do{
      switch(opType[argid])
      {
        case INSTR_P:
          j++;
          break;
          
        case INSTR_WP:
          j+=sizeof(Word);
          break;
          
        case INSTR_SEG:
          LK_FILE_GET1(fd);//Consume dummy argument
          *(Byte*)(code+j)=CMData->SegmentID;
          debug("ID:%d\t",CMData->SegmentID);
          j+=sizeof(Byte);
          break;
        
        case INSTR_R:
        case INSTR_E:
        case INSTR_N:
        case INSTR_I1:
        case INSTR_CE:
          *(Byte*)(code+j)=LK_FILE_GET1(fd);
          debug("%d\t",*(Byte*)(code+j));
          j+=sizeof(Byte);
          break;

//         case INSTR_I2:
//           *(TwoBytes*)(code+j)=GET2();
//           j+=sizeof(TwoBytes);
//           break;
          
        case INSTR_C:
          *(TwoBytes*)(code+j)=PackConstInd(GetConstInd(fd,CMData));
          debug("C:%d\t",*(TwoBytes*)(code+j));
          j+=sizeof(TwoBytes);
          break;
          
        case INSTR_K:
          *(TwoBytes*)(code+j)=PackKindInd(GetKindInd(fd,CMData));
          debug("K:%d\t",*(TwoBytes*)(code+j));
          j+=sizeof(TwoBytes);
          break;
          
        case INSTR_MT:
          *(ImportTabInd*)(code+j)=GetImportTabInd(fd,CMData);
          debug("IT:%d\t",*(ImportTabInd*)(code+j));
          j+=sizeof(ImportTabInd);
          break;
          
        case INSTR_IT:
          *(ImplGoalInd*)(code+j)=GetImplGoalInd(fd,CMData);
          debug("IG:%d\t",*(ImplGoalInd*)(code+j));
          j+=sizeof(ImplGoalInd);
          break;
          
        case INSTR_HT:
          *(HashTabInd*)(code+j)=GetHashTabInd(fd,CMData);
          debug("HT:%d\t",*(HashTabInd*)(code+j));
          j+=sizeof(HashTabInd);
          break;
          
        case INSTR_BVT:
          *(BvrTabInd*)(code+j)=GetBvrTabInd(fd,CMData);
          debug("BT:%d\t",*(BvrTabInd*)(code+j));
          j+=sizeof(BvrTabInd);
          break;
          
        case INSTR_S:
          *(StringInd*)(code+j)=GetStringInd(fd,CMData);
          debug("S:%d\t",*(StringInd*)(code+j));
          j+=sizeof(StringInd);
          break;
        
        case INSTR_L:
          *(CodeInd*)(code+j)=GetCodeInd(fd,CMData);
          debug("L:%d\t",*(CodeInd*)(code+j));
          j+=sizeof(CodeInd);
          break;
          
        case INSTR_I:
          *(INT4*)(code+j)=LK_FILE_GET4(fd);
          debug("I:%d\t",*(INT4*)(code+j));
          j+=sizeof(INT4);
          break;

        case INSTR_F:
          *(INT4*)(code+j)=GetFloat(fd);
          debug("F:%d\t",*(INT4*)(code+j));
          j+=sizeof(INT4);
          break;
          
        case INSTR_X:
          break;
        default:
          bad("Unknown Operand Type %d\n",opType[argid]);
          EM_THROW(LK_LinkError);
          break;
      }
      argid++;
    }
    while(opType[argid]!=INSTR_X);
    debug("\n");
    i += INSTR_instrSize(opcode);
  }
  debug("NOWD -> %d[%d,%d]\n",166,(*(ConstInd*)(code+166)).gl_flag,(*(ConstInd*)(code+166)).index);
          
}
void CRemoteCode::PushCall( calling_convention_t cconv, FARPROC CallAddress )
{
	DebugShout( "PushCall [0x%X][0x%X]", cconv, CallAddress );

	int iFunctionBegin	= (int)m_CurrentInvokeInfo.params.size();

	m_CurrentInvokeInfo.calladdress = reinterpret_cast<unsigned long>( CallAddress );
	m_CurrentInvokeInfo.cconv		= cconv;

	switch( cconv )
	{
	case CCONV_CDECL:
		{
			DebugShout( "Entering __cdecl" );

			int iCalculateAddEsp = (iFunctionBegin * 4);

			PushAllParameters( true );

			AddByteToBuffer( MOV_EAX_VALUE );
			AddLongToBuffer( m_CurrentInvokeInfo.calladdress );
			AddByteToBuffer( CALL_EXTERNAL );
			AddByteToBuffer( 0xD0 );			//eax

			if( iCalculateAddEsp != 0 )
			{
				bool bUseByte = (iCalculateAddEsp <= 0xFF);

				if( bUseByte )
				{
					//add esp, [BYTE]
					AddByteToBuffer( 0x83 );
					AddByteToBuffer( 0xC4 );
					AddByteToBuffer((unsigned char)iCalculateAddEsp);
				}
				else
				{
					
					//add esp, [LONG]
					AddByteToBuffer( 0x81 );
					AddByteToBuffer( 0xC4 );
					AddLongToBuffer( iCalculateAddEsp );
				}
			}

			break;
		}
	case CCONV_STDCALL:
		{
			DebugShout( "Entering __stdcall" );

			PushAllParameters( true );

			AddByteToBuffer( MOV_EAX_VALUE );
			AddLongToBuffer( m_CurrentInvokeInfo.calladdress );
			AddByteToBuffer( CALL_EXTERNAL );
			AddByteToBuffer( 0xD0 );			//eax

			break;
		}
	case CCONV_THISCALL:
		{
			DebugShout( "Entering __thiscall" );

			if( iFunctionBegin == 0 ) //no params...
			{
				DebugShout( "No parameters passed for __thiscall, requires at least one parameter (ECX)" );

				break;
			}

			//first parameter of __thiscall is ALWAYS ECX. ALWAYS.
			//the parameter type should also be PARAMETER_TYPE_POINTER
			if( m_CurrentInvokeInfo.params[0].ptype != PARAMETER_TYPE_POINTER )
			{
				DebugShout( "\"THIS\" parameter type invalid [%i]", m_CurrentInvokeInfo.params[0].ptype );
			}

			void *pThis = m_CurrentInvokeInfo.params[0].pparam;

			if( pThis == NULL )
			{
				DebugShout( "\"THIS\" parameter NULL for __thiscall function (ECX)" );
			}

			AddByteToBuffer( 0x8B );
			AddByteToBuffer( 0x0D );
			AddLongToBuffer((unsigned long)pThis);

			//now we need to remove the first parameter from the vector, so when we execute the
			//parameter iteration function it is not included.....

			m_CurrentInvokeInfo.params.erase( m_CurrentInvokeInfo.params.begin() );

			PushAllParameters( true );

			AddByteToBuffer( MOV_EAX_VALUE );
			AddLongToBuffer( m_CurrentInvokeInfo.calladdress );
			AddByteToBuffer( CALL_EXTERNAL );
			AddByteToBuffer( 0xD0 );			//eax

			break;
		}
	case CCONV_FASTCALL:
		{
			DebugShout( "Entering __fastcall" );
			
			if( iFunctionBegin == 0 )
			{
				PushCall( CCONV_STDCALL, CallAddress );

				return;
			}
			else if( iFunctionBegin == 1 )
			{
				unsigned long ulEdxParam = *(unsigned long *)m_CurrentInvokeInfo.params[0].pparam;

				AddByteToBuffer( 0xBA );
				AddLongToBuffer( ulEdxParam );

				m_CurrentInvokeInfo.params.erase( m_CurrentInvokeInfo.params.begin() );

				PushCall( CCONV_STDCALL, CallAddress );

				return;
			}
			else
			{
				unsigned long ulEdxParam = *(unsigned long *)m_CurrentInvokeInfo.params[0].pparam;
				unsigned long ulEaxParam = *(unsigned long *)m_CurrentInvokeInfo.params[1].pparam;
				
				AddByteToBuffer( 0xBA );
				AddLongToBuffer( ulEdxParam );
				AddByteToBuffer( MOV_EAX_VALUE );
				AddLongToBuffer( ulEaxParam );

				m_CurrentInvokeInfo.params.erase( m_CurrentInvokeInfo.params.begin() );
				m_CurrentInvokeInfo.params.erase( m_CurrentInvokeInfo.params.begin() );

				PushAllParameters( true );

				AddByteToBuffer( 0xBB );
				AddLongToBuffer( m_CurrentInvokeInfo.calladdress );
				AddByteToBuffer( CALL_EXTERNAL );
				AddByteToBuffer( 0xD3 );		//ebx
			}

			break;
		}
	}

	//clear data
	m_CurrentInvokeInfo.params.clear();
	m_CurrentInvokeInfo.calladdress = NULL;
}
HMODULE CRemoteLoader::LoadLibraryByPathW( PWCHAR Path )
{
	if( Path == NULL )
	{
		DebugShout( "[LoadLibraryByPathW] szString is NULL" );

		return NULL;
	}

	FARPROC RemoteLoadLibraryW = GetRemoteProcAddress( "kernel32.dll", "LoadLibraryW" );

	if( RemoteLoadLibraryW == NULL )
	{
		DebugShout( "[LoadLibraryByPathW] LoadLibraryW Resolve Failure" );

		return NULL;
	}

	DebugShout( "[LoadLibraryByPathW] LoadLibraryW = 0x%X", RemoteLoadLibraryW );

	PVOID ReturnPointerValue = RemoteAllocateMemory( sizeof( DWORD ) );

	PushUNICODEString( Path );

	PushCall( CCONV_STDCALL, RemoteLoadLibraryW );

	//mov ptr, eax
	AddByteToBuffer( 0xA3 );
	AddLongToBuffer( ( DWORD ) ReturnPointerValue );

	//xor eax, eax
	AddByteToBuffer( 0x33 );
	AddByteToBuffer( 0xC0 );

	//retn 4
	AddByteToBuffer( 0xC2 );
	AddByteToBuffer( 0x04 );
	AddByteToBuffer( 0x00 );

	if( ExecuteRemoteThreadBuffer( m_CurrentRemoteThreadBuffer, true ) == false )
	{
		DebugShout( "[LoadLibraryByPathW] ExecuteRemoteThreadBuffer failed" );

		RemoteFreeMemory( ReturnPointerValue, sizeof( DWORD ) );

		return NULL;
	}

	DebugShout( "[LoadModuleByNameW] ExecuteRemoteThreadBuffer succeeded" );

	DWORD RemoteModuleHandle = 0;

	if( ReadProcessMemory( GetProcess(), ReturnPointerValue, &RemoteModuleHandle, sizeof( DWORD ), NULL ) == TRUE )
	{
		RemoteFreeMemory( ReturnPointerValue, sizeof( DWORD ) );
	}
	else
	{
		RemoteFreeMemory( ReturnPointerValue, sizeof( DWORD ) );

		if( RemoteModuleHandle == 0 )
		{
			RemoteModuleHandle = ( DWORD ) GetRemoteModuleHandleW( Path );
		}
	}

	return ( HMODULE ) RemoteModuleHandle;
}