zoukankan      html  css  js  c++  java
  • win32-ReadProcessMemory在x86和x64下运行

    #include <iostream>
    #include <Windows.h>
    #include <winternl.h>
    #include <tchar.h>
    #pragma comment(lib, "ntdll")
    
    int main()
    {
        // create destination process - this is the process to be hollowed out
        LPSTARTUPINFOA si = new STARTUPINFOA();
        LPPROCESS_INFORMATION pi = new PROCESS_INFORMATION();
        PROCESS_BASIC_INFORMATION* pbi = new PROCESS_BASIC_INFORMATION();
        ULONG returnLenght = 0;
        CreateProcessA(NULL, (LPSTR)"c:\windows\system32\calc.exe", NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, si, pi);
        HANDLE destProcess = pi->hProcess;
    
        // get destination imageBase offset address from the PEB
        NtQueryInformationProcess(destProcess, ProcessBasicInformation, pbi, sizeof(PROCESS_BASIC_INFORMATION), &returnLenght);
        ULONG_PTR  pebImageBaseOffset = (ULONG_PTR)pbi->PebBaseAddress + 8; //如果是在x64,则改成16
    
        // get destination imageBaseAddress
        LPVOID destImageBase = 0;
        SIZE_T bytesRead = NULL;
        ReadProcessMemory(destProcess, (LPCVOID)pebImageBaseOffset, &destImageBase, sizeof(ULONG_PTR), &bytesRead); 
    std::cout
    << "pebImageBaseOffset is: " << destImageBase << std::endl; std::cin.get();
    }

    因为PebBaseAddress在x86下是指向PEB+8,在x64下是指向PEB+16

    具体的结构体:

    typedef struct _PEB {
        BYTE Reserved1[2]; //2个字节
        BYTE BeingDebugged; //1个字节
        BYTE Reserved2[1]; //1个字节
        PVOID Reserved3[2]; 
        PPEB_LDR_DATA Ldr;
        PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
        PVOID Reserved4[3];
        PVOID AtlThunkSListPtr;
        PVOID Reserved5;
        ULONG Reserved6;
        PVOID Reserved7;
        ULONG Reserved8;
        ULONG AtlThunkSListPtr32;
        PVOID Reserved9[45];
        BYTE Reserved10[96];
        PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
        BYTE Reserved11[128];
        PVOID Reserved12[1];
        ULONG SessionId;
    } PEB, *PPEB;

    如果在x86下,则是以4字节对齐,那么偏移8才能指向Reserved3[1]

    在x64下,则是以8字节对齐,那么只有偏移16才能指向Reserved3[1]

    可以看这个链接:https://blog.csdn.net/v2x222/article/details/71082150 (ImageBaseAddress : Ptr32 Void  and +0x010 ImageBaseAddress : Ptr64 Void)

    第二个sample:

    #include <iostream>
    #include <Windows.h>
    #include <winternl.h>
    #pragma comment(lib, "ntdll")
    
    using NtUnmapViewOfSection = NTSTATUS(WINAPI*)(HANDLE, PVOID);
    
    typedef struct BASE_RELOCATION_BLOCK {
        DWORD PageAddress;
        DWORD BlockSize;
    } BASE_RELOCATION_BLOCK, * PBASE_RELOCATION_BLOCK;
    
    typedef struct BASE_RELOCATION_ENTRY {
        USHORT Offset : 12;
        USHORT Type : 4;
    } BASE_RELOCATION_ENTRY, * PBASE_RELOCATION_ENTRY;
    
    
    int main()
    {
        // create destination process - this is the process to be hollowed out
        LPSTARTUPINFOA si = new STARTUPINFOA();
        LPPROCESS_INFORMATION pi = new PROCESS_INFORMATION();
        PROCESS_BASIC_INFORMATION* pbi = new PROCESS_BASIC_INFORMATION();
        ULONG returnLenght = 0;
        CreateProcessA(NULL, (LPSTR)"c:\windows\syswow64\notepad.exe", NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, si, pi);
        HANDLE destProcess = pi->hProcess;
        
        // get destination imageBase offset address from the PEB
        NtQueryInformationProcess(destProcess, ProcessBasicInformation, pbi, sizeof(PROCESS_BASIC_INFORMATION), &returnLenght);
        ULONG_PTR pebImageBaseOffset = (ULONG_PTR)pbi->PebBaseAddress + 16;
      
        // get destination imageBaseAddress
        LPVOID destImageBase = 0;
        SIZE_T bytesRead = NULL;
        ReadProcessMemory(destProcess, (LPCVOID)pebImageBaseOffset, &destImageBase, sizeof(ULONG_PTR), &bytesRead);
    
        // read source file - this is the file that will be executed inside the hollowed process
        HANDLE sourceFile = CreateFileA("c:\windows\system32\calc.exe", GENERIC_READ, NULL, NULL, OPEN_ALWAYS, NULL, NULL);
        ULONG_PTR sourceFileSize = GetFileSize(sourceFile, NULL);
        SIZE_T fileBytesRead = 0;
        LPVOID sourceFileBytesBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sourceFileSize);
        ReadFile(sourceFile, sourceFileBytesBuffer, sourceFileSize, NULL, NULL);
    
        // get source image size
        PIMAGE_DOS_HEADER sourceImageDosHeaders = (PIMAGE_DOS_HEADER)sourceFileBytesBuffer;
        PIMAGE_NT_HEADERS sourceImageNTHeaders = (PIMAGE_NT_HEADERS)((ULONG_PTR)sourceFileBytesBuffer + sourceImageDosHeaders->e_lfanew);
        SIZE_T sourceImageSize = sourceImageNTHeaders->OptionalHeader.SizeOfImage;
    
        // carve out the destination image
        NtUnmapViewOfSection myNtUnmapViewOfSection = (NtUnmapViewOfSection)(GetProcAddress(GetModuleHandleA("ntdll"), "NtUnmapViewOfSection"));
        myNtUnmapViewOfSection(destProcess, destImageBase);
    
        // allocate new memory in destination image for the source image
        LPVOID newDestImageBase = VirtualAllocEx(destProcess, destImageBase, sourceImageSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        destImageBase = newDestImageBase;
    
        // get delta between sourceImageBaseAddress and destinationImageBaseAddress
        ULONG_PTR deltaImageBase = (ULONG_PTR)destImageBase - sourceImageNTHeaders->OptionalHeader.ImageBase;
    
        // set sourceImageBase to destImageBase and copy the source Image headers to the destination image
        sourceImageNTHeaders->OptionalHeader.ImageBase = (ULONG_PTR)destImageBase;
        WriteProcessMemory(destProcess, newDestImageBase, sourceFileBytesBuffer, sourceImageNTHeaders->OptionalHeader.SizeOfHeaders, NULL);
        // get pointer to first source image section
        PIMAGE_SECTION_HEADER sourceImageSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)sourceFileBytesBuffer + sourceImageDosHeaders->e_lfanew + sizeof(_IMAGE_NT_HEADERS64)); //IMAGE_NT_HEADERS32
        PIMAGE_SECTION_HEADER sourceImageSectionOld = sourceImageSection;
    
        // copy source image sections to destination
        for (int i = 0; i < sourceImageNTHeaders->FileHeader.NumberOfSections; i++)
        {
            PVOID destinationSectionLocation = (PVOID)((ULONG_PTR)destImageBase + sourceImageSection->VirtualAddress);
            PVOID sourceSectionLocation = (PVOID)((ULONG_PTR)sourceFileBytesBuffer + sourceImageSection->PointerToRawData);
            WriteProcessMemory(destProcess, destinationSectionLocation, sourceSectionLocation, sourceImageSection->SizeOfRawData, NULL);
            sourceImageSection++;
        }
    
        // get address of the relocation table
        IMAGE_DATA_DIRECTORY relocationTable = sourceImageNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
    
        // patch the binary with relocations
        sourceImageSection = sourceImageSectionOld;
        for (int i = 0; i < sourceImageNTHeaders->FileHeader.NumberOfSections; i++)
        {
            BYTE* relocSectionName = (BYTE*)".reloc";
            if (memcmp(sourceImageSection->Name, relocSectionName, 5) != 0)
            {
                sourceImageSection++;
                continue;
            }
    
            ULONG_PTR sourceRelocationTableRaw = sourceImageSection->PointerToRawData;
            ULONG_PTR relocationOffset = 0;
    
            while (relocationOffset < relocationTable.Size) {
                PBASE_RELOCATION_BLOCK relocationBlock = (PBASE_RELOCATION_BLOCK)((ULONG_PTR)sourceFileBytesBuffer + sourceRelocationTableRaw + relocationOffset);
                relocationOffset += sizeof(BASE_RELOCATION_BLOCK);
                ULONG_PTR relocationEntryCount = (relocationBlock->BlockSize - sizeof(BASE_RELOCATION_BLOCK)) / sizeof(BASE_RELOCATION_ENTRY);
                PBASE_RELOCATION_ENTRY relocationEntries = (PBASE_RELOCATION_ENTRY)((ULONG_PTR)sourceFileBytesBuffer + sourceRelocationTableRaw + relocationOffset);
    
                for (ULONG_PTR y = 0; y < relocationEntryCount; y++)
                {
                    relocationOffset += sizeof(BASE_RELOCATION_ENTRY);
    
                    if (relocationEntries[y].Type == 0)
                    {
                        continue;
                    }
    
                    ULONG_PTR patchAddress = relocationBlock->PageAddress + relocationEntries[y].Offset;
                    ULONG_PTR patchedBuffer = 0;
                    ReadProcessMemory(destProcess, (LPCVOID)((ULONG_PTR)destImageBase + patchAddress), &patchedBuffer, sizeof(ULONG_PTR), &bytesRead);
                    patchedBuffer += deltaImageBase;
    
                    WriteProcessMemory(destProcess, (PVOID)((ULONG_PTR)destImageBase + patchAddress), &patchedBuffer, sizeof(ULONG_PTR), &fileBytesRead);
                }
            }
        }
        
    
        return 0;
    }
  • 相关阅读:
    程序书写规范
    点灯主要顺序
    复用功能重映射
    STM32 (战舰)
    html5 javascript 新增加的高级选择器更精准更实用
    html5 javascript 事件练习3键盘控制练习
    html5 javascript 事件练习3随机键盘
    html5 javascript 事件练习2
    html5 javascript 事件练习1
    html5dom2
  • 原文地址:https://www.cnblogs.com/strive-sun/p/13226283.html
Copyright © 2011-2022 走看看