An ancient crutch on an old crutch

I'll start bluntly, once I got a revelation (well, not very powerful, to be honest) and the idea arose to print a program that transmits an image from a client to a server. Simple enough huh? Well, for an experienced programmer, it will be so. The conditions are simple - do not use third-party libraries. In principle, it's a little more complicated, but if you consider that you have to figure it out and look for examples, well, such an occupation. I decided that this task is within my reach. Plus, it is desirable that there is enough code so that it can be posted on the forum in case you need help. First of all, my eyes fell on FTP, by the way, the OS in which Windows is developed. The advantage of FTP is that you can transfer not only an image, but any file through it. After downloading Filezilla Server, sharing one read / write directory and creating a user with a password,tried to connect Filezilla Client everything worked. Created a simple example of C / C ++ code:

#include <iostream>
void main()
{
	FILE* fs;
	fopen_s(&fs, "1.txt", "w");
	if (fs)
	{
    fwrite("user\r\npassword\r\nsend D:\\share\\1.txt\r\nbye", 1, sizeof("user\r\npassword\r\nsend D:\\share\\1.txt\r\nbye"), fs);
    fwrite("\000", 1, sizeof("\000"), fs);
    fclose(fs);
	}
	system("ftp -s:1.txt 127.0.0.1");
}

, , send. ) ) , ftp . - . , .

, . char' . , , . , " - ", " - ". , - . - . ( ) . Thread', , *.tga .

:

#include <iostream>
#include <WinSock.h>
#pragma comment (lib,"WS2_32.lib")

#include <fstream>
#include <algorithm>
#include <string>
#include <iterator>
#include <vector>
void error(const char* msg)
{
    //perror(msg);
    std::cout<<'\n'<<WSAGetLastError();
    WSACleanup();
    std::cin.ignore();
    exit(1);
}
void bzero(char*buf, int l)
{
    for (int i = 0; i < l; i++)
        buf[i] = '\0';
}
struct arg_s
{
    unsigned char* buffer2;
    bool exit;
};
char** buffer;
struct arg_sa
{
    struct arg_s* lalk;
    int current;
};
#define type struct arg_sa
int sockfd, * newsockfd;//    
int buflen2 = 10292000;//      RGBA*Width*Height
struct sockaddr_in *cli_addr;
int* clilen;
int currentclient,cc;//-  (      )

typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;
#define N 8// 
#define F32 0xFFFFFFFF
uint32_t RK[N];// 
#define size64 sizeof(uint64_t)
#define ROR(x,n,xsize)((x>>n)|(x<<(xsize-n)))
#define ROL(x,n,xsize)((x<<n)|(x>>(xsize-n)))
#define RKEY(r)((ROR(K,r*3,size64*8))&F32)
const uint64_t K = 0x96EA704CFB1CF671;// 
struct hostent* server;
uint32_t F(uint32_t subblk, uint32_t key)
{
    return subblk + key;// 
}
void createRoundKeys()
{
    for (int i = 0; i < N; i++)
        RK[i] = (ROR(K, i * 8, size64 * 8)) & F32;
}
uint64_t decrypt(uint64_t c_block)//   
{
    //select subblocks
    uint32_t left = (c_block >> 32) & F32;
    uint32_t right = c_block & F32;
    uint32_t left_, right_;//subblock in the end of round
    for (int r = N - 1; r >= 0; r--)
    {
        uint32_t fk = F(left, RK[r]);
        left_ = left;
        right_ = right ^ fk;
        if (r > 0)//swap places to next round
        {
            left = right_;
            right = left_;
        }
        else //last round not swap
        {
            left = left_;
            right = right_;
        }
    }
    //collect subblock in block
    uint64_t block = left;
    block = (block << 32) | (right & F32);
    return block;
}
void session_(LPVOID args)//    
{
    int current = currentclient++;
    bzero((char*)&(cli_addr[current]), sizeof(&(cli_addr[current])));
    newsockfd[current] = accept(sockfd, (struct sockaddr*)&(cli_addr[current]), &(clilen[current]));
    if (newsockfd[current] < 0)
    {
        error("Error on accept\n");
    }
    char* s = new char[100];
    int n = recv(newsockfd[current], s, 100, 0);
    int buflen2 = atoi(s);//   
    FILE* f;
    std::string name = "Screen";
    cc++;
    _itoa_s(cc, s, 100, 10);
    name += s;
    name += ".tga";
    fopen_s(&f,name.c_str(), "wb");//      1 ,   
    if (f != NULL)
    {
        unsigned char tgaHeader[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        unsigned char header[6];
        n = recv(newsockfd[current], buffer[current], sizeof(tgaHeader), 0);
        fwrite((unsigned char*)buffer[current], 1, sizeof(tgaHeader), f);
        bzero(buffer[current], buflen2);
        n = recv(newsockfd[current], buffer[current],sizeof(header), 0);
        fwrite((unsigned char*)buffer[current], 1, sizeof(header), f);// 
        bzero(buffer[current], buflen2);
        n = recv(newsockfd[current], buffer[current], buflen2, 0);//   
        //
        // 
        createRoundKeys();
        unsigned long long id;
        std::vector<uint64_t>* plaintext = new std::vector<uint64_t>();
        int i = 0;
        while (i<buflen2)
        {
            memcpy(&id, (buffer[current]) + i, N);
            plaintext->push_back(decrypt(id));
            i += 8;
        }
        std::cout << "i=" << i << std::endl;
        i = 0;
        char str_[N + 1];
        memset(str_, 0, N);
        str_[N] = '\0';
        for (std::vector<uint64_t>::iterator it = plaintext->begin(); it != plaintext->end(); ++it)
        {
            memcpy(str_, &*it, N);
            fwrite((unsigned char*)str_, sizeof(unsigned char), N/*strlen(str_)*/, f);
            i += 8;
        }
        std::cout << "i=" << i << std::endl;
        //  
        //fwrite((unsigned char*)buffer[current], sizeof(char), buflen2, f);
        fclose(f);
    }
    system(name.c_str());//  *.tga  
}
int main()
{
    cc = 0;
    WSADATA ws = { 0 };
    if (WSAStartup(MAKEWORD(2, 2), &ws) == 0)
    {
        currentclient = 0;
        int maxclients = 2;//  
        cli_addr = new struct sockaddr_in[maxclients];
        clilen = new int[maxclients];
        buffer = new char* [maxclients];
        for (int i = 0; i < maxclients; i++)
        {
            clilen[i] = sizeof(cli_addr[i]);
        }
        sockfd = socket(AF_INET, SOCK_STREAM, 0);//tcp 
        if (sockfd < 0)
            error("ERROR opening socket");
        struct sockaddr_in serv_addr;
        bzero((char*)&serv_addr, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_addr.s_addr = INADDR_ANY;
        int port = 30000;//
        serv_addr.sin_port = htons(port);
        if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
            error("ERROR on binding");
        if (listen(sockfd, 10) < 0)
            error("ERROR listen");
        HANDLE* thread;//     
        struct arg_sa* args;
        while (true)
        {
            newsockfd = new int[maxclients];
            thread = (HANDLE*)malloc(sizeof(HANDLE) * maxclients);
            args = new struct arg_sa[maxclients];
            for (int i = 0; i < maxclients; i++)
            {
                args[i].lalk = new struct arg_s();
                buffer[i] = new char[buflen2];
            }
            int i = -1;
            while (++i < maxclients)
            {
                Sleep(1);
                args[i].current = i;
                args[i].lalk->exit = false;
                thread[i] = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)(session_), args, 0, 0);
            }
                for (int i = 0; i < maxclients; i++)
                    WaitForSingleObject(thread[i], INFINITE);//   
            i = -1;
            while (++i < maxclients)
            {
                shutdown(newsockfd[i], 0);
                TerminateThread(thread[i], 0);
            }
            //delete[] newsockfd;
            //free(thread);
            currentclient = 0;
            for (int i = 0; i < maxclients; i++)
            {
                //delete args[i].lalk;
                //delete[] args[i].lalk->buffer;
            }
            //delete[] args;
        }
        shutdown(sockfd, 0);
        WSACleanup();
        return 0;
    }
    std::cin.ignore();
}

accept . WaitForSingleObject . . M+1 , M . , .

:

#include <iostream>
#include <WinSock.h>
#include <vector>
#pragma comment (lib,"WS2_32.lib")
void error(const char* msg)
{
    //perror(msg);
    std::cout << '\n' << WSAGetLastError();
    WSACleanup();
    std::cin.ignore();
    exit(1);
}
void bzero(char* buf, int l)
{
    for (int i = 0; i < l; i++)
        buf[i] = '\0';
}
typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;
#define N 8
#define F32 0xFFFFFFFF
uint32_t RK[N];// 
#define size64 sizeof(uint64_t)
#define ROR(x,n,xsize)((x>>n)|(x<<(xsize-n)))
#define ROL(x,n,xsize)((x<<n)|(x>>(xsize-n)))
#define RKEY(r)((ROR(K,r*3,size64*8))&F32)
const uint64_t K = 0x96EA704CFB1CF671;// 
void createRoundKeys()
{
    for (int i = 0; i < N; i++)
        RK[i] = (ROR(K, i * 8, size64 * 8)) & F32;
}
uint32_t F(uint32_t subblk, uint32_t key)
{
    return subblk + key;// 
}
uint64_t encrypt(uint64_t block)//   
{
    //select subblocks
    uint32_t left = (block >> 32) & F32;
    uint32_t right = block & F32;
    uint32_t left_, right_;//subblock in the end of round
    for (int r = 0; r < N; r++)
    {
        uint32_t fk = F(left, RK[r]);
        left_ = left;
        right_ = right ^ fk;
        if (r < N - 1)//swap places to next round
        {
            left = right_;
            right = left_;
        }
        else//last round not swap
        {
            left = left_;
            right = right_;
        }
    }
    //collect subblock in block
    uint64_t c_block = left;
    c_block = (c_block << 32) | (right & F32);
    return c_block;
}
int main()
{
    keybd_event(VK_LWIN, 0, 0, 0);
    keybd_event('M', 0, 0, 0);
    keybd_event('M', 0, KEYEVENTF_KEYUP, 0);
    keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0);//    
    Sleep(1000);//    
    WSADATA ws = { 0 };
    if (WSAStartup(MAKEWORD(2, 2), &ws) == 0)
    {
        int sockfd;
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        struct sockaddr_in serv_addr, cli_addr;
        bzero((char*)&serv_addr, sizeof(serv_addr));
        bzero((char*)&cli_addr, sizeof(cli_addr));
        serv_addr.sin_family = AF_INET;

        const char* add = "127.0.0.1";// 
        serv_addr.sin_addr.s_addr = inet_addr(add);
        int port = 30000;//
        serv_addr.sin_port = htons(port);
        int servlen = sizeof(serv_addr);
        int n = connect(sockfd, (struct sockaddr*)&serv_addr, servlen);
        
        //   
        HDC ScreenDC = GetDC(0);
        HDC MemoryDC = CreateCompatibleDC(ScreenDC);
        int ScreenHeight = GetSystemMetrics(SM_CYSCREEN);
        int ScreenWidth = GetSystemMetrics(SM_CXSCREEN);
        ScreenWidth = ((ScreenWidth - 1) / 4 + 1) * 4;
        BITMAPINFO BMI;
        BMI.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        BMI.bmiHeader.biWidth = ScreenWidth;
        BMI.bmiHeader.biHeight = ScreenHeight;
        BMI.bmiHeader.biSizeImage = ScreenWidth * ScreenHeight * 3;
        BMI.bmiHeader.biCompression = BI_RGB;
        BMI.bmiHeader.biBitCount = 24;
        BMI.bmiHeader.biPlanes = 1;
        DWORD ScreenshotSize;
        ScreenshotSize = BMI.bmiHeader.biSizeImage;
        unsigned char* ImageBuffer;
        HBITMAP hBitmap = CreateDIBSection(ScreenDC, &BMI, DIB_RGB_COLORS, (void**)&ImageBuffer, 0, 0);
        SelectObject(MemoryDC, hBitmap);
        BitBlt(MemoryDC, 0, 0, ScreenWidth, ScreenHeight, ScreenDC, 0, 0, SRCCOPY);
        DeleteDC(MemoryDC);
        ReleaseDC(NULL, ScreenDC);
        FILE* sFile = 0;
        unsigned char tgaHeader[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        unsigned char header[6];
        unsigned char tempColors = 0;
        fopen_s(&sFile, "S.tga", "wb");
        if (!sFile) {
            exit(1);
        }
        header[0] = ScreenWidth % 256;
        header[1] = ScreenWidth / 256;
        header[2] = ScreenHeight % 256;
        header[3] = ScreenHeight / 256;
        header[4] = BMI.bmiHeader.biBitCount;
        header[5] = 0;
        fwrite(tgaHeader, 1, sizeof(tgaHeader), sFile);
        fwrite(header, sizeof(header), 1, sFile);
        //    
        
        //      
        createRoundKeys();
        std::vector<uint64_t>* msg = new std::vector<uint64_t>(),*crpt = new std::vector<uint64_t>();
        unsigned long long id;
        int i = 0;
        while (i < BMI.bmiHeader.biSizeImage)
        {
            memcpy(&id, (ImageBuffer + i), N);
            msg->push_back(id);
            i += 8;
        }
        std::cout << "i=" << i << std::endl; 
        uint64_t cipher;
        i = 0;
        char str_[N + 1];
        memset(str_, 0, N);
        str_[N] = '\0';
        for (std::vector<uint64_t>::iterator it = msg->begin(); it != msg->end(); ++it)
        {
            cipher = encrypt(*it);
            memcpy(str_, &cipher, N);
            fwrite((unsigned char*)str_, sizeof(unsigned char), N, sFile);
            i += 8;
        }
        std::cout << "i=" << i << std::endl;
        //
        //fwrite(ImageBuffer, BMI.bmiHeader.biSizeImage, 1, sFile);
        std::cout << BMI.bmiHeader.biSizeImage << std::endl;
        fclose(sFile);
        DeleteObject(hBitmap);
        FILE* f;
        fopen_s(&f, "S.tga", "rb");
        int count = 0;
        if (f != NULL)
        {
            while (getc(f) != EOF)
                count++;//       
            fclose(f);
        }
        count -= 18;
        std::cout << count<< std::endl;
        char* s = new char[100];
        _itoa_s(count, s, 100, 10);
        n = send(sockfd, s, 100, 0);// 
        char* buffer = new char[count];
        fopen_s(&f, "S.tga", "rb");
        size_t bytes;
        if (f != NULL)
        {
            memcpy(buffer, tgaHeader, sizeof(tgaHeader));
            n = send(sockfd, buffer, sizeof(tgaHeader), 0);
            bzero(buffer, count);
            memcpy(buffer, header, sizeof(header));
            n = send(sockfd, buffer, sizeof(header), 0);
            bzero(buffer, count);// 
            for(int i=0;i<18;i++)
                fgetc(f);
            bzero(buffer, count);
            bytes = fread(buffer, sizeof(unsigned char), count, f);
            n = send(sockfd,buffer, count, 0);//   
            fclose(f);
        }
        Sleep(1000);
        shutdown(sockfd, 0);
        WSACleanup();
        //system("del S.tga");
        delete[] buffer,s;
        return 0;
    }
    //std::cin.ignore();
}

S.tga,

,

Screen.tga

, CBC CFB , , .

!




All Articles