コード例 #1
0
ファイル: main.c プロジェクト: nextgens/limacharlie
static RBOOL
    updateCollectorConfigs
    (
        rList newConfigs
    )
{
    RBOOL isSuccess = FALSE;
    RU8 unused = 0;
    RU32 i = 0;
    rSequence tmpConf = NULL;
    RU32 confId = 0;

    if( rpal_memory_isValid( newConfigs ) )
    {
        rpal_debug_info( "updating collector configurations." );
        
        for( i = 0; i < ARRAY_N_ELEM( g_collectors ); i++ )
        {
            if( NULL != g_collectors[ i ].conf )
            {
                rpal_debug_info( "freeing collector %d config.", i );
                rSequence_free( g_collectors[ i ].conf );
                g_collectors[ i ].conf = NULL;
            }
        }

        while( rList_getSEQUENCE( newConfigs, RP_TAGS_HBS_CONFIGURATION, &tmpConf ) )
        {
            if( rSequence_getRU32( tmpConf, RP_TAGS_HBS_CONFIGURATION_ID, &confId ) &&
                confId < ARRAY_N_ELEM( g_collectors ) )
            {
                if( rSequence_getRU8( tmpConf, RP_TAGS_IS_DISABLED, &unused ) )
                {
                    g_collectors[ confId ].isEnabled = FALSE;
                }
                else
                {
                    g_collectors[ confId ].isEnabled = TRUE;
                    g_collectors[ confId ].conf = rSequence_duplicate( tmpConf );
                    rpal_debug_info( "set new collector %d config.", confId );
                }
            }
        }
                
        isSuccess = TRUE;
    }

    return isSuccess;
}
コード例 #2
0
ファイル: main.c プロジェクト: nextgens/limacharlie
static RVOID
    shutdownCollectors
    (

    )
{
    RU32 i = 0;

    if( !rEvent_wait( g_hbs_state.isTimeToStop, 0 ) )
    {
        rpal_debug_info( "signaling to collectors to stop." );
        rEvent_set( g_hbs_state.isTimeToStop );

        if( NULL != g_hbs_state.hThreadPool )
        {
            rpal_debug_info( "destroying collector thread pool." );
            rThreadPool_destroy( g_hbs_state.hThreadPool, TRUE );
            g_hbs_state.hThreadPool = NULL;

            for( i = 0; i < ARRAY_N_ELEM( g_collectors ); i++ )
            {
                if( g_collectors[ i ].isEnabled )
                {
                    rpal_debug_info( "cleaning up collector %d.", i );
                    g_collectors[ i ].cleanup( &g_hbs_state, g_collectors[ i ].conf );
                    rSequence_free( g_collectors[ i ].conf );
                    g_collectors[ i ].conf = NULL;
                }
            }
        }
    }
}
コード例 #3
0
static RVOID
    modKernelModeDiff
    (
        rEvent isTimeToStop
    )
{
    RU32 i = 0;
    RU32 nScratch = 0;
    RU32 prev_nScratch = 0;
    KernelAcqModule new_from_kernel[ 200 ] = { 0 };
    KernelAcqModule prev_from_kernel[ 200 ] = { 0 };

    while( !rEvent_wait( isTimeToStop, 1000 ) )
    {
        nScratch = ARRAY_N_ELEM( new_from_kernel );
        rpal_memory_zero( new_from_kernel, sizeof( new_from_kernel ) );
        if( !kAcq_getNewModules( new_from_kernel, &nScratch ) )
        {
            rpal_debug_warning( "kernel acquisition for new modules failed" );
            g_is_kernel_failure = TRUE;
            break;
        }

        for( i = 0; i < prev_nScratch; i++ )
        {
            notifyOfKernelModule( &(prev_from_kernel[ i ]) );
        }

        rpal_memory_memcpy( prev_from_kernel, new_from_kernel, sizeof( prev_from_kernel ) );
        prev_nScratch = nScratch;
    }
}
コード例 #4
0
RBOOL
    tr_and_match
    (
        StatefulMachine* machine,
        StatefulEvent* event,
        tr_and_match_params* parameters
    )
{
    RBOOL isMatch = FALSE;

    RU32 i = 0;

    if( NULL != machine &&
        NULL != event &&
        NULL != parameters )
    {
        isMatch = TRUE;

        for( i = 0; i < ARRAY_N_ELEM( parameters->params ); i++ )
        {
            if( !tr_match( machine, event, &(parameters->params[ i ]) ) )
            {
                isMatch = FALSE;
                break;
            }
        }
    }

    return isMatch;
}
コード例 #5
0
ファイル: main.c プロジェクト: refractionPOINT/limacharlie
static RVOID
    relaunchInPermanentLocation
    (

    )
{
    RPWCHAR bootstrapLocations[] = { _WCH( "%SYSTEMDRIVE%\\$Recycle.Bin\\MALWARE_DEMO_WINDOWS_1.exe" ),
                                     _WCH( "%SYSTEMDRIVE%\\RECYCLER\\MALWARE_DEMO_WINDOWS_1.exe" ),
                                     _WCH( "%windir%\\system32\\tasks\\MALWARE_DEMO_WINDOWS_1.exe" ),
                                     _WCH( "%USERPROFILE%\\MALWARE_DEMO_WINDOWS_1.exe" ) };
    RU32 i = 0;

    STARTUPINFOW startupInfo = {0};
    PROCESS_INFORMATION procInfo = {0};
    RPWCHAR expandedPath = NULL;

    for( i = 0; i < ARRAY_N_ELEM( bootstrapLocations ); i++ )
    {
        rpal_debug_info( "trying to move to bootstrap location %d...", i );
        rpal_file_delete( bootstrapLocations[ i ], FALSE );
        if( rpal_file_move( g_self_path, bootstrapLocations[ i ] ) )
        {
            rpal_debug_info( "successfully moved to bootstrap location!" );

            rpal_debug_info( "launching in new location (%ls)...", bootstrapLocations[ i ] );
            if( rpal_string_expand( bootstrapLocations[ i ], &expandedPath ) &&
                0 != CreateProcessW( expandedPath, 
                                     NULL, 
                                     NULL, 
                                     NULL, 
                                     FALSE, 
                                     CREATE_NO_WINDOW, 
                                     NULL, 
                                     NULL, 
                                     &startupInfo, 
                                     &procInfo ) )
            {
                rpal_debug_info( "successfully launched from new location." );
            }
            else
            {
                rpal_debug_error( "error launching from permanent location: %d.", GetLastError() );
            }

            if( NULL != expandedPath )
            {
                rpal_memory_free( expandedPath );
            }

            break;
        }
        else
        {
            rpal_debug_warning( "could not move to new bootstrap location, may not have permission..." );
        }
    }
}
コード例 #6
0
ファイル: main.c プロジェクト: nextgens/limacharlie
static RBOOL
    startCollectors
    (

    )
{
    RBOOL isSuccess = FALSE;
    RU32 i = 0;

    rEvent_unset( g_hbs_state.isTimeToStop );
    if( NULL != ( g_hbs_state.hThreadPool = rThreadPool_create( 1, 
                                                                15,
                                                                MSEC_FROM_SEC( 10 ) ) ) )
    {
        isSuccess = TRUE;

        for( i = 0; i < ARRAY_N_ELEM( g_collectors ); i++ )
        {
            if( g_collectors[ i ].isEnabled )
            {
                if( !g_collectors[ i ].init( &g_hbs_state, g_collectors[ i ].conf ) )
                {
                    isSuccess = FALSE;
                    rpal_debug_warning( "collector %d failed to init.", i );
                }
                else
                {
                    rpal_debug_info( "collector %d started.", i );
                }
            }
            else
            {
                rpal_debug_info( "collector %d disabled.", i );
            }
        }
    }

    return isSuccess;
}
コード例 #7
0
    TRANSITION( isFinal, TRUE, FALSE, RP_TAGS_NOTIFICATION_NEW_PROCESS, toState, recon_tools[ 4 ], tr_match ), \
    TRANSITION( isFinal, TRUE, FALSE, RP_TAGS_NOTIFICATION_NEW_PROCESS, toState, recon_tools[ 5 ], tr_match ), \
    TRANSITION( isFinal, TRUE, FALSE, RP_TAGS_NOTIFICATION_NEW_PROCESS, toState, recon_tools[ 6 ], tr_match ), \
    TRANSITION( isFinal, TRUE, FALSE, RP_TAGS_NOTIFICATION_NEW_PROCESS, toState, recon_tools[ 7 ], tr_match ), \
    TRANSITION( isFinal, TRUE, FALSE, RP_TAGS_NOTIFICATION_NEW_PROCESS, toState, recon_tools[ 8 ], tr_match ), \
    TRANSITION( isFinal, TRUE, FALSE, RP_TAGS_NOTIFICATION_NEW_PROCESS, toState, recon_tools[ 9 ], tr_match ), \
    TRANSITION( isFinal, TRUE, FALSE, RP_TAGS_NOTIFICATION_NEW_PROCESS, toState, recon_tools[ 10 ], tr_match ), \
    TRANSITION( isFinal, TRUE, FALSE, RP_TAGS_NOTIFICATION_NEW_PROCESS, toState, recon_tools[ 11 ], tr_match ), \
    TRANSITION( FALSE, FALSE, FALSE, 0, 0, expired, tr_match )
#else
#define RECON_TRANSITIONS(isFinal,toState) \
    TRANSITION( isFinal, TRUE, FALSE, RP_TAGS_NOTIFICATION_NEW_PROCESS, toState, recon_tools[ 0 ], tr_match ), \
    TRANSITION( isFinal, TRUE, FALSE, RP_TAGS_NOTIFICATION_NEW_PROCESS, toState, recon_tools[ 1 ], tr_match ), \
    TRANSITION( isFinal, TRUE, FALSE, RP_TAGS_NOTIFICATION_NEW_PROCESS, toState, recon_tools[ 2 ], tr_match ), \
    TRANSITION( isFinal, TRUE, FALSE, RP_TAGS_NOTIFICATION_NEW_PROCESS, toState, recon_tools[ 3 ], tr_match ), \
    TRANSITION( isFinal, TRUE, FALSE, RP_TAGS_NOTIFICATION_NEW_PROCESS, toState, recon_tools[ 4 ], tr_match ), \
    TRANSITION( isFinal, TRUE, FALSE, RP_TAGS_NOTIFICATION_NEW_PROCESS, toState, recon_tools[ 5 ], tr_match ), \
    TRANSITION( FALSE, FALSE, FALSE, 0, 0, expired, tr_match )
#endif



STATE( 0, ARRAY_N_ELEM( recon_tools ) + 1, RECON_TRANSITIONS( FALSE, 1 ) );
STATE( 1, ARRAY_N_ELEM( recon_tools ) + 1, RECON_TRANSITIONS( FALSE, 2 ) );
STATE( 2, ARRAY_N_ELEM( recon_tools ) + 1, RECON_TRANSITIONS( FALSE, 3 ) );
STATE( 3, ARRAY_N_ELEM( recon_tools ) + 1, RECON_TRANSITIONS( TRUE, 0 ) );

STATEFUL_MACHINE( 0, STATEFUL_MACHINE_0_EVENT, RECON_N_PER_BURST, STATE_PTR( 0 ),
                                                                  STATE_PTR( 1 ),
                                                                  STATE_PTR( 2 ),
                                                                  STATE_PTR( 3 ) );
コード例 #8
0
ファイル: main.c プロジェクト: sun123qiang123/limacharlie
static
VOID WINAPI 
    ServiceMain
    (
        DWORD  dwArgc,
        RPCHAR lpszArgv
    )
{
    RU32 memUsed = 0;
    RWCHAR svcName[] = { _SERVICE_NAME };
    RU32 i = 0;

    UNREFERENCED_PARAMETER( dwArgc );
    UNREFERENCED_PARAMETER( lpszArgv );


    if( NULL == ( g_svc_status_handle = RegisterServiceCtrlHandlerW( svcName, SvcCtrlHandler ) ) )
    {
        return;
    }

    rpal_memory_zero( &g_svc_status, sizeof( g_svc_status ) );
    g_svc_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    g_svc_status.dwControlsAccepted = 0;
    g_svc_status.dwCurrentState = SERVICE_START_PENDING;
    g_svc_status.dwWin32ExitCode = 0;
    g_svc_status.dwServiceSpecificExitCode = 0;
    g_svc_status.dwCheckPoint = 0;
    SetServiceStatus( g_svc_status_handle, &g_svc_status );

    if( NULL == ( g_timeToQuit = rEvent_create( TRUE ) ) )
    {
        g_svc_status.dwControlsAccepted = 0;
        g_svc_status.dwCurrentState = SERVICE_STOPPED;
        g_svc_status.dwWin32ExitCode = GetLastError();
        g_svc_status.dwCheckPoint = 1;
        SetServiceStatus( g_svc_status_handle, &g_svc_status );
        return;
    }

    rpal_debug_info( "initialising rpHCP." );
    if( !rpHostCommonPlatformLib_launch( g_svc_primary, g_svc_secondary ) )
    {
        rpal_debug_warning( "error launching hcp." );
    }

    for( i = 0; i < ARRAY_N_ELEM( g_manual_loads ); i++ )
    {
        if( NULL != g_manual_loads[ i ].modPath )
        {
            if( 0 != g_manual_loads[ i ].nMod )
            {
#ifdef HCP_EXE_ENABLE_MANUAL_LOAD
                rpHostCommonPlatformLib_load( g_manual_loads[ i ].modPath, g_manual_loads[ i ].nMod );
#endif
            }
            else
            {
                rpal_debug_error( "Mismatched number of -m modulePath and -n moduleId statements provided!" );
            }

            rpal_memory_free( g_manual_loads[ i ].modPath );
            g_manual_loads[ i ].modPath = NULL;
        }
        else
        {
            break;
        }
    }

    g_svc_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    g_svc_status.dwCurrentState = SERVICE_RUNNING;
    g_svc_status.dwWin32ExitCode = 0;
    g_svc_status.dwCheckPoint = 1;
    SetServiceStatus( g_svc_status_handle, &g_svc_status );

    rpal_debug_info( "...running, waiting to exit..." );
    rEvent_wait( g_timeToQuit, RINFINITE );
    rEvent_free( g_timeToQuit );

    rpal_debug_info( "...exiting..." );
    rpal_Context_cleanup();

    memUsed = rpal_memory_totalUsed();
    if( 0 != memUsed )
    {
        rpal_debug_critical( "Memory leak: %d bytes.\n", memUsed );
        //rpal_memory_findMemory();
#ifdef RPAL_FEATURE_MEMORY_ACCOUNTING
        rpal_memory_printDetailedUsage();
#endif
    }

    g_svc_status.dwControlsAccepted = 0;
    g_svc_status.dwCurrentState = SERVICE_STOPPED;
    g_svc_status.dwWin32ExitCode = 0;
    g_svc_status.dwCheckPoint = 3;
    SetServiceStatus( g_svc_status_handle, &g_svc_status );
}
コード例 #9
0
ファイル: main.c プロジェクト: sun123qiang123/limacharlie
static
RU32
    installService
    (

    )
{
    HMODULE hModule = NULL;
    RWCHAR curPath[ RPAL_MAX_PATH ] = { 0 };
    RWCHAR destPath[] = _WCH( "%SYSTEMROOT%\\system32\\rphcp.exe" );
    RWCHAR svcPath[] = _WCH( "\"%SYSTEMROOT%\\system32\\rphcp.exe\" -w" );
    SC_HANDLE hScm = NULL;
    SC_HANDLE hSvc = NULL;
    RWCHAR svcName[] = { _SERVICE_NAMEW };
    RWCHAR svcDisplay[] = { _WCH( "rp_HCP_Svc" ) };

    rpal_debug_info( "installing service" );

    hModule = GetModuleHandleW( NULL );
    if( NULL != hModule )
    {
        if( ARRAY_N_ELEM( curPath ) > GetModuleFileNameW( hModule, curPath, ARRAY_N_ELEM( curPath ) ) )
        {
            if( rpal_file_copy( curPath, destPath ) )
            {
                if( NULL != ( hScm = OpenSCManagerA( NULL, NULL, SC_MANAGER_CREATE_SERVICE ) ) )
                {
                    if( NULL != ( hSvc = CreateServiceW( hScm,
                                                         svcName,
                                                         svcDisplay,
                                                         SERVICE_ALL_ACCESS,
                                                         SERVICE_WIN32_OWN_PROCESS,
                                                         SERVICE_AUTO_START,
                                                         SERVICE_ERROR_NORMAL,
                                                         svcPath,
                                                         NULL,
                                                         NULL,
                                                         NULL,
                                                         NULL,
                                                         _WCH( "" ) ) ) )
                    {
                        if( StartService( hSvc, 0, NULL ) )
                        {
                            // Emitting as error level to make sure it's displayed in release.
                            rpal_debug_error( "service installer!" );
                            return 0;
                        }
                        else
                        {
                            rpal_debug_error( "could not start service: %d", GetLastError() );
                        }

                        CloseServiceHandle( hSvc );
                    }
                    else
                    {
                        rpal_debug_error( "could not create service in SCM: %d", GetLastError() );
                    }

                    CloseServiceHandle( hScm );
                }
                else
                {
                    rpal_debug_error( "could not open SCM: %d", GetLastError() );
                }
            }
            else
            {
                rpal_debug_error( "could not move executable to service location: %d", GetLastError() );
            }
        }
        else
        {
            rpal_debug_error( "could not get current executable path: %d", GetLastError() );
        }

        CloseHandle( hModule );
    }
    else
    {
        rpal_debug_error( "could not get current executable handle: %d", GetLastError() );
    }
    
    return GetLastError();
}
コード例 #10
0
static RBOOL
    getSnapshot
    (
        processEntry* toSnapshot
    )
{
    RBOOL isSuccess = FALSE;
    RU32 i = 0;

    if( NULL != toSnapshot )
    {
        rpal_memory_zero( toSnapshot, sizeof( g_snapshot_1 ) );
    }

    if( NULL != toSnapshot )
    {
#ifdef RPAL_PLATFORM_WINDOWS
        HANDLE hSnapshot = NULL;
        PROCESSENTRY32W procEntry = { 0 };
        procEntry.dwSize = sizeof( procEntry );

        if( INVALID_HANDLE_VALUE != ( hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ) ) )
        {
            if( Process32FirstW( hSnapshot, &procEntry ) )
            {
                isSuccess = TRUE;

                do
                {
                    if( 0 == procEntry.th32ProcessID )
                    {
                        continue;
                    }

                    toSnapshot[ i ].pid = procEntry.th32ProcessID;
                    toSnapshot[ i ].ppid = procEntry.th32ParentProcessID;
                    i++;
                } while( Process32NextW( hSnapshot, &procEntry ) &&
                         MAX_SNAPSHOT_SIZE > i );
            }

            CloseHandle( hSnapshot );
        }
#elif defined( RPAL_PLATFORM_LINUX )
        RWCHAR procDir[] = _WCH( "/proc/" );
        rDir hProcDir = NULL;
        rFileInfo finfo = {0};

        if( rDir_open( (RPWCHAR)&procDir, &hProcDir ) )
        {
            isSuccess = TRUE;

            while( rDir_next( hProcDir, &finfo ) &&
                   MAX_SNAPSHOT_SIZE > i )
            {
                if( rpal_string_wtoi( (RPWCHAR)finfo.fileName, &( toSnapshot[ i ].pid ) )
                    && 0 != toSnapshot[ i ].pid )
                {
                    i++;
                }
            }

            rDir_close( hProcDir );
        }
#elif defined( RPAL_PLATFORM_MACOSX )
        int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
        struct kinfo_proc* infos = NULL;
        size_t size = 0;
        int ret = 0;
        int j = 0;

        if( 0 == ( ret = sysctl( mib, ARRAY_N_ELEM( mib ), infos, &size, NULL, 0 ) ) )
        {
            if( NULL != ( infos = rpal_memory_alloc( size ) ) )
            {
                while( 0 != ( ret = sysctl( mib, ARRAY_N_ELEM( mib ), infos, &size, NULL, 0 ) ) && ENOMEM == errno )
                {
                    if( NULL == ( infos = rpal_memory_realloc( infos, size ) ) )
                    {
                        break;
                    }
                }
            }
        }

        if( 0 == ret && NULL != infos )
        {
            isSuccess = TRUE;
            size = size / sizeof( struct kinfo_proc );
            for( j = 0; j < size; j++ )
            {
                toSnapshot[ i ].pid = infos[ j ].kp_proc.p_pid;
                toSnapshot[ i ].ppid = infos[ j ].kp_eproc.e_ppid;
                i++;
            }

            if( NULL != infos )
            {
                rpal_memory_free( infos );
                infos = NULL;
            }
        }
#endif
    }

    return isSuccess;
}
コード例 #11
0
static RVOID
    kernelModeDiff
    (
        rEvent isTimeToStop
    )
{
    RU32 i = 0;
    RU32 nScratch = 0;
    RU32 nProcessEntries = 0;
    KernelAcqProcess new_from_kernel[ 200 ] = { 0 };
    processEntry tracking_user[ MAX_SNAPSHOT_SIZE ] = { 0 };
    
    while( !rEvent_wait( isTimeToStop, 1000 ) )
    {
        nScratch = ARRAY_N_ELEM( new_from_kernel );
        rpal_memory_zero( new_from_kernel, sizeof( new_from_kernel ) );
        if( !kAcq_getNewProcesses( new_from_kernel, &nScratch ) )
        {
            rpal_debug_warning( "kernel acquisition for new processes failed" );
            g_is_kernel_failure = TRUE;
            break;
        }

        for( i = 0; i < nScratch; i++ )
        {
            notifyOfProcess( new_from_kernel[ i ].pid,
                             new_from_kernel[ i ].ppid,
                             TRUE,
                             new_from_kernel[ i ].path,
                             new_from_kernel[ i ].cmdline,
                             new_from_kernel[ i ].uid,
                             new_from_kernel[ i ].ts );

            if( nProcessEntries >= ARRAY_N_ELEM( tracking_user ) - 1 )
            {
                continue;
            }

            tracking_user[ nProcessEntries ].pid = new_from_kernel[ i ].pid;
            tracking_user[ nProcessEntries ].ppid = new_from_kernel[ i ].ppid;
            nProcessEntries++;
        }

        for( i = 0; i < nProcessEntries; i++ )
        {
            if( !processLib_isPidInUse( tracking_user[ i ].pid ) )
            {
                notifyOfProcess( tracking_user[ i ].pid, 
                                 tracking_user[ i ].ppid, 
                                 FALSE, 
                                 NULL, 
                                 NULL,
                                 KERNEL_ACQ_NO_USER_ID,
                                 0 );
                if( nProcessEntries != i + 1 )
                {
                    rpal_memory_memmove( &(tracking_user[ i ]), &(tracking_user[ i + 1 ]), nProcessEntries - i + 1 );
                }
                nProcessEntries--;
            }
        }
    }
}
コード例 #12
0
ファイル: beacon.c プロジェクト: nextgens/limacharlie
static
RBOOL
    postHttp
    (
        RPCHAR location,
        RPCHAR params,
        RBOOL isEnforceCert,
        RPVOID* receivedData,
        RU32* receivedSize
    )
{
    RBOOL isSuccess = FALSE;

    DWORD timeout = ( 1000 * 10 );

    DWORD bytesToRead = 0;
    DWORD bytesReceived = 0;
    DWORD bytesRead = 0;
    RPU8 pReceivedBuffer = NULL;

    URL_COMPONENTSA components = {0};

    RBOOL isSecure = FALSE;
    RCHAR pUser[ 1024 ] = {0};
    RCHAR pPass[ 1024 ] = {0};
    RCHAR pUrl[ 1024 ] = {0};
    RCHAR pPage[ 1024 ] = {0};
    INTERNET_PORT port = 0;

    InternetCrackUrl_f pInternetCrackUrl = NULL;
    InternetOpen_f pInternetOpen = NULL;
    InternetConnect_f pInternetConnect = NULL;
    InternetCloseHandle_f pInternetCloseHandle = NULL;
    HttpOpenRequest_f pHttpOpenRequest = NULL;
    HttpSendRequest_f pHttpSendRequest = NULL;
    InternetQueryDataAvailable_f pInternetQueryDataAvailable = NULL;
    InternetReadFile_f pInternetReadFile = NULL;
    InternetSetOption_f pInternetSetOption = NULL;

    HMODULE hWininet = NULL;
    HINTERNET hInternet = NULL;
    HINTERNET hConnect = NULL;
    HINTERNET hHttp = NULL;
    DWORD flags = INTERNET_FLAG_DONT_CACHE | 
                  INTERNET_FLAG_NO_UI | 
                  INTERNET_FLAG_NO_CACHE_WRITE;

    RCHAR contentType[] = "Content-Type: application/x-www-form-urlencoded";
    RCHAR userAgent[] = "rpHCP";
    RCHAR method[] = "POST";
    RCHAR importDll[] = "wininet.dll";
    RCHAR import1[] = "InternetCrackUrlA";
    RCHAR import2[] = "InternetOpenA";
    RCHAR import3[] = "InternetConnectA";
    RCHAR import4[] = "InternetCloseHandle";
    RCHAR import5[] = "HttpOpenRequestA";
    RCHAR import6[] = "HttpSendRequestA";
    RCHAR import7[] = "InternetQueryDataAvailable";
    RCHAR import8[] = "InternetReadFile";
    RCHAR import9[] = "InternetSetOptionA";

    if( NULL != location )
    {
        rpal_debug_info( "posting to %s", location );
        
        if( NULL != ( hWininet = GetModuleHandleA( (RPCHAR)&importDll ) ) ||
            NULL != ( hWininet = LoadLibraryA( (RPCHAR)&importDll ) ) )
        {
            pInternetCrackUrl = (InternetCrackUrl_f)GetProcAddress( hWininet, (RPCHAR)&import1 );
            pInternetOpen = (InternetOpen_f)GetProcAddress( hWininet, (RPCHAR)&import2 );
            pInternetConnect = (InternetConnect_f)GetProcAddress( hWininet, (RPCHAR)&import3 );
            pInternetCloseHandle = (InternetCloseHandle_f)GetProcAddress( hWininet, (RPCHAR)&import4 );
            pHttpOpenRequest = (HttpOpenRequest_f)GetProcAddress( hWininet, (RPCHAR)&import5 );
            pHttpSendRequest = (HttpSendRequest_f)GetProcAddress( hWininet, (RPCHAR)&import6 );
            pInternetQueryDataAvailable = (InternetQueryDataAvailable_f)GetProcAddress( hWininet, (RPCHAR)&import7 );
            pInternetReadFile = (InternetReadFile_f)GetProcAddress( hWininet, (RPCHAR)&import8 );
            pInternetSetOption = (InternetSetOption_f)GetProcAddress( hWininet, (RPCHAR)&import9 );


            if( NULL != pInternetCrackUrl &&
                NULL != pInternetOpen &&
                NULL != pInternetConnect &&
                NULL != pInternetCloseHandle &&
                NULL != pHttpOpenRequest &&
                NULL != pHttpSendRequest &&
                NULL != pInternetQueryDataAvailable &&
                NULL != pInternetReadFile &&
                NULL != pInternetSetOption )
            {
                components.lpszHostName = pUrl;
                components.dwHostNameLength = sizeof( pUrl );
                components.lpszUrlPath = pPage;
                components.dwUrlPathLength = sizeof( pPage );
                components.lpszUserName = pUser;
                components.dwUserNameLength = sizeof( pUser );
                components.lpszPassword = pPass;
                components.dwPasswordLength = sizeof( pPass );
                components.dwStructSize = sizeof( components );

                if( !pInternetCrackUrl( location, 0, 0, &components ) )
                {
                    if( rpal_string_strlen( location ) < ARRAY_N_ELEM( pUrl ) )
                    {
                        rpal_string_strcpya( pUrl, location );
                    }
                    components.nPort = 80;
                    components.nScheme = INTERNET_SCHEME_HTTP;
                }

                port = components.nPort;

                if( INTERNET_SCHEME_HTTPS == components.nScheme )
                {
                    isSecure = TRUE;
                }

                if( !isEnforceCert && isSecure )
                {
                    flags |= INTERNET_FLAG_IGNORE_CERT_CN_INVALID | 
                                INTERNET_FLAG_IGNORE_CERT_DATE_INVALID;
                }

                if( isSecure )
                {
                    flags |= INTERNET_FLAG_SECURE;
                }

                hInternet = pInternetOpen( (RPCHAR)&userAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );

                if( NULL != hInternet )
                {
                    pInternetSetOption( hInternet, INTERNET_OPTION_CONNECT_TIMEOUT, &timeout, sizeof( timeout ) );

                    hConnect = pInternetConnect( hInternet, 
                                                    pUrl, 
                                                    port,
                                                    pUser, pPass,
                                                    INTERNET_SERVICE_HTTP,
                                                    flags, (DWORD_PTR)NULL );

                    if( NULL != hConnect )
                    {
                        hHttp = pHttpOpenRequest( hConnect, 
                                                    (RPCHAR)&method, 
                                                    pPage ? pPage : "", 
                                                    NULL,
                                                    NULL,
                                                    NULL,
                                                    flags,
                                                    (DWORD_PTR)NULL );

                        if( hHttp )
                        {
                            if( pHttpSendRequest( hHttp, 
                                                    (RPCHAR)&contentType,
                                                    (DWORD)(-1),
                                                    params,
                                                    (DWORD)rpal_string_strlen( params ) ) )
                            {
                                isSuccess = TRUE;

                                if( NULL != receivedData &&
                                    NULL != receivedSize )
                                {
                                    while( pInternetQueryDataAvailable( hHttp, &bytesToRead, 0, 0 ) &&
                                            0 != bytesToRead )
                                    {
                                        pReceivedBuffer = rpal_memory_realloc( pReceivedBuffer, bytesReceived + bytesToRead );

                                        if( rpal_memory_isValid( pReceivedBuffer ) )
                                        {
                                            if( pInternetReadFile( hHttp, pReceivedBuffer + bytesReceived, bytesToRead, &bytesRead ) )
                                            {
                                                bytesReceived += bytesRead;
                                                bytesToRead = 0;
                                                bytesRead = 0;
                                            }
                                            else
                                            {
                                                rpal_memory_free( pReceivedBuffer );
                                                pReceivedBuffer = NULL;
                                                bytesReceived = 0;
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            pReceivedBuffer = NULL;
                                            bytesReceived = 0;
                                            isSuccess = FALSE;
                                            break;
                                        }
                                    }

                                    if( isSuccess &&
                                        rpal_memory_isValid( pReceivedBuffer ) &&
                                        0 != bytesReceived )
                                    {
                                        *receivedData = pReceivedBuffer;
                                        *receivedSize = bytesReceived;
                                    }
                                }
                            }

                                
                            pInternetCloseHandle( hHttp );
                        }
                            
                        pInternetCloseHandle( hConnect );
                    }
                        
                    pInternetCloseHandle( hInternet );
                }
            }
        }
    }

    return isSuccess;
}