zoukankan      html  css  js  c++  java
  • win32

    #include <iostream>
    #include <Windows.h>
    #include <ShlObj.h>
    #include <Shlwapi.h>
    
    #pragma comment(lib, "Shell32.lib")
    #pragma comment(lib, "Shlwapi.lib")
    
    DWORD align(DWORD size, DWORD align, DWORD addr) {
        if (!(size % align))
            return addr + size;
        return addr + (size / align + 1) * align;
    }
    
    int main(int argc, char* argv[])
    {
        /*if (argc < 3)
        {
            std::cout << "Argomenti insufficienti.
    ";
            return 0;
        }*/
    
        HANDLE FirstFile = CreateFileA("Test_Hello World.exe", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);            // File to read data from
        if (FirstFile == INVALID_HANDLE_VALUE)
        {
            std::cout << "Impossibile aprire il file passato come primo argomento.
    ";
            return 0;
        }
    
        HANDLE SecFile = CreateFileA("Test_Hello World.exe", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);               // File to write the read data in
        if (SecFile == INVALID_HANDLE_VALUE)
        {
            std::cout << "Impossibile aprire il file passato come secondo argomento.
    ";
            return 0;
        }
    
        DWORD FirstFS = GetFileSize(FirstFile, 0);              // First file dimension
        DWORD SecondFS = GetFileSize(SecFile, 0);               // Second file dimension
    
        BYTE* FirstFB = (BYTE*)VirtualAlloc(NULL, FirstFS, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);           // Allocates memory for the first file
        BYTE* SecondFB = (BYTE*)VirtualAlloc(NULL, SecondFS, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);         // Allocates memory for the second file
    
        DWORD BytesRead = 0;
        DWORD BytesWritten = 0;
    
        if (bool Read = ReadFile(FirstFile, FirstFB, FirstFS, &BytesRead, NULL) == FALSE)                   // Reads the first file
        {
            std::cout << "Impossibile leggere primo file.
    ";
            return 0;
        }
        else
        {
            std::cout << "Letti " << BytesRead << " dal primo file.
    ";
            BytesRead = 0;
        }
    
        if (bool Read = ReadFile(SecFile, SecondFB, SecondFS, &BytesRead, NULL) == FALSE)                       // Reads the second file
        {
            std::cout << "Impossibile leggere secondo file.
    ";
            return 0;
        }
        else
        {
            std::cout << "Letti " << BytesRead << " bytes dal secondo file.
    ";
            BytesRead = 0;
        }
    
        /*
        *
        * The code is problematic beyond this point!
        *
        * SecondFB = Pointer to the second file's data buffer that needs to be modified by adding the new section.
        * FirstFB = Pointer to the first file's data buffer that will be written inside the ".sdata" section.
        * Both of them have been loaded in memory using VirtualAlloc.
        *
        * Ask me anything for further info and many, many thanks :D
    
        */
    
        // Here I add a new section to the second file.
    
        PIMAGE_DOS_HEADER sIDH = (IMAGE_DOS_HEADER*)SecondFB;
        PIMAGE_NT_HEADERS sINH = (IMAGE_NT_HEADERS*)(SecondFB + sIDH->e_lfanew);
        PIMAGE_FILE_HEADER sIFH = (PIMAGE_FILE_HEADER)(SecondFB + sIDH->e_lfanew + sizeof(DWORD));
        PIMAGE_OPTIONAL_HEADER sIOH = (PIMAGE_OPTIONAL_HEADER)(SecondFB + sIDH->e_lfanew + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER));
        PIMAGE_SECTION_HEADER sISH = (PIMAGE_SECTION_HEADER)(SecondFB + sIDH->e_lfanew + sizeof(IMAGE_NT_HEADERS));
    
        // Here I name the new section inside the file
        ZeroMemory(&sISH[sIFH->NumberOfSections], sizeof(IMAGE_SECTION_HEADER));
        CopyMemory(sISH[sIFH->NumberOfSections].Name, ".scode", 8);
    
        /*
            0xE00000E0 = IMAGE_SCN_MEM_WRITE |
                         IMAGE_SCN_CNT_CODE  |
                         IMAGE_SCN_CNT_UNINITIALIZED_DATA  |
                         IMAGE_SCN_MEM_EXECUTE |
                         IMAGE_SCN_CNT_INITIALIZED_DATA |
                         IMAGE_SCN_MEM_READ
    
    
        */
    
        // Here all the required information gets filled in
        sISH[sIFH->NumberOfSections].VirtualAddress = align(sISH[sIFH->NumberOfSections - 1].Misc.VirtualSize, sIOH->SectionAlignment, sISH[sIFH->NumberOfSections - 1].VirtualAddress);
        sISH[sIFH->NumberOfSections].SizeOfRawData = align(FirstFS, sIOH->SectionAlignment, 0);
        sISH[sIFH->NumberOfSections].Misc.VirtualSize = align(FirstFS, sIOH->SectionAlignment, 0);
        sISH[sIFH->NumberOfSections].PointerToRawData = align(sISH[sIFH->NumberOfSections - 1].SizeOfRawData, sIOH->FileAlignment, sISH[sIFH->NumberOfSections - 1].PointerToRawData);
        sISH[sIFH->NumberOfSections].Characteristics = 0xE00000E0;
    
        // Here the changes are written to the second file
        SetFilePointer(SecFile, sISH[sIFH->NumberOfSections].PointerToRawData + sISH[sIFH->NumberOfSections].SizeOfRawData, NULL, FILE_BEGIN);
        SetEndOfFile(SecFile);
    
        sIOH->SizeOfImage = sISH[sIFH->NumberOfSections].VirtualAddress + sISH[sIFH->NumberOfSections].Misc.VirtualSize;
        sIFH->NumberOfSections += 1;
        SetFilePointer(SecFile, 0, NULL, FILE_BEGIN);
    
        BytesWritten = 0;
    
        bool W = WriteFile(SecFile, SecondFB, SecondFS, &BytesWritten, NULL);
    
        if (W == FALSE)
        {
            std::cout << "Impossibile aggiungere sezione alla stub.
    ";
            return 0;
        }
        else
        {
            std::cout << "Scritti " << BytesWritten << " bytes nella stub. (Aggiunta nuova sezione.)
    ";
            BytesWritten = 0;
        }
    
        // Here I write the data inside the new section
        SetFilePointer(SecFile, sISH[sIFH->NumberOfSections - 1].PointerToRawData, 0, FILE_BEGIN);
        if (bool Write = WriteFile(SecFile, FirstFB, FirstFS, &BytesWritten, NULL) == FALSE)
        {
            std::cout << "Impossibile aggiungere sezione alla stub.
    ";
        }
        else
        {
            std::cout << "Scritti " << BytesWritten << " bytes nella stub.
    ";
            BytesWritten = 0;
        }
    
        // Here I close all the handles
    
        VirtualFree(FirstFB, FirstFS, MEM_RELEASE);
        CloseHandle(FirstFile);
    
        VirtualFree(SecondFB, SecondFS, MEM_RELEASE);
        CloseHandle(SecFile);
    
        std::cout << "Binding completato.
    ";
    
        return 0;
    }
  • 相关阅读:
    带字数限制提示的输入框效果
    js快速获取数组中的最大值最小值
    js实现连线题
    js自定义图片提示效果
    为了遇见你
    为了明天(励志篇)
    你为什么总是不理我
    爱情,是我一生中最虔诚的信仰
    你是我心中永远抹不掉的痛
    爱你一万次够不够
  • 原文地址:https://www.cnblogs.com/strive-sun/p/13825731.html
Copyright © 2011-2022 走看看