• 内存写入注入


    1,拉伸文件
    2,打开进程
    3,分配空间
    4,修复重定位表
    5,修复IAT表
    6,写入模块
    7,创建远程线程
    //内存写入注入
    CHAR* SrcBuffer;            //
    CHAR* ImageBuffer;            //拉伸后的源文件
    DWORD SizeOfImage;
    DWORD ImageBase;
    DWORD OEP;
    LPVOID lp;                    //VirtualAllocEx返回的地址
    BOOL HasReloc = FALSE;
    
    
    BOOL ExtendSrc() {
        WORD peCheck = *(WORD*)(SrcBuffer);
        if (peCheck != 0x5A4D) {
            return FALSE;
        }
        DWORD e_lfanew = *(DWORD*)(SrcBuffer + 0x3c);
        CHAR* peHeader = SrcBuffer + e_lfanew + 0x4;
        CHAR* opHeader = peHeader + 0x14;
        DWORD SectionAlignment = *(DWORD*)(opHeader + 0x20);
        SizeOfImage = *(DWORD*)(opHeader + 0x38);
        ImageBase = *(DWORD*)(opHeader + 0x1c);
        OEP = *(DWORD*)(opHeader + 0x10);
        if (*(DWORD*)(opHeader + 0x60 + 0x28) != NULL) {
            HasReloc = TRUE;
        }
        DWORD SizeoOfHeaders = *(DWORD*)(opHeader + 0x3c);
        WORD NumberOfSections = *(WORD*)(peHeader + 0x2);
        WORD SizeOfOptionalHeader = *(WORD*)(peHeader + 0x10);
        CHAR* Sections_addr = opHeader + SizeOfOptionalHeader;
    
        ImageBuffer = (CHAR*)malloc(SizeOfImage + 1);
        if (ImageBuffer == NULL) {
            return FALSE;
        }
        else {
            memset(ImageBuffer, 'x00', SizeOfImage + 1);
        }
        memcpy(ImageBuffer, SrcBuffer, SizeoOfHeaders);
    
        DWORD Misc;
        DWORD VirtualAddress;
        DWORD SizeOfRawData;
        DWORD PointerToRawData;
        for (DWORD j = 0; j < NumberOfSections; j++) {
            Misc = *(DWORD*)(Sections_addr + 0x8);
            VirtualAddress = *(DWORD*)(Sections_addr + 0xc);
            SizeOfRawData = *(DWORD*)(Sections_addr + 0x10);
            PointerToRawData = *(DWORD*)(Sections_addr + 0x14);
            if (SizeOfRawData == NULL) {
                Sections_addr = Sections_addr + 0x28;
                continue;
            }
            if (Misc > SizeOfRawData) {
                memcpy(ImageBuffer + VirtualAddress, SrcBuffer + PointerToRawData, Misc);
            }
            else {
                memcpy(ImageBuffer + VirtualAddress, SrcBuffer + PointerToRawData, SizeOfRawData);
            }
            Sections_addr = Sections_addr + 0x28;
        }
        free(SrcBuffer);
        SrcBuffer = NULL;
        return TRUE;
    }
    
    VOID repairReloc(DWORD newAddr) {
        DWORD e_lfanew = *(DWORD*)(ImageBuffer + 0x3c);
        CHAR* peHeader = ImageBuffer + e_lfanew + 0x4;
        CHAR* opHeader = peHeader + 0x14;
        DWORD relocRVA = *(DWORD*)(opHeader + 0x60 + 0x28);
    
        CHAR* addr = ImageBuffer + relocRVA;
        CHAR* size = addr + 4;
        CHAR* data = size + 4;
        while (*(DWORD*)addr != 0 && *(DWORD*)size != 0) {
            DWORD num = (*(DWORD*)size - 8) / 2;
            for (DWORD i = 0; i < num; i++) {
                WORD Characteristics = (*(WORD*)data & 0xf000) >> 12;
                WORD offset = *(WORD*)data & 0x0fff;
                if (Characteristics == 0x3) {
                    DWORD NewData = *(DWORD*)(ImageBuffer + *(DWORD*)addr + offset) - ImageBase + newAddr;
                    *(DWORD*)(ImageBuffer + *(DWORD*)addr + offset) = NewData;
                }
                data += 2;
            }
            addr += *(DWORD*)size;
            size = addr + 4;
            data = size + 4;
        }
    }
    
    VOID repairIAT() {
        ULONG uSize;
        PIMAGE_IMPORT_DESCRIPTOR PImport;
        CHAR* PThunk;
        CHAR* POriginalFirstThunk;
        CHAR* szModule;
        CHAR* szFunc;
        PImport = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToDataEx(ImageBuffer, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &uSize, NULL);
        while (TRUE) {
            szModule = (CHAR*)ImageBuffer + PImport->Name;
            if (strcmp(szModule, "KERNEL32.dll") == 0) {
                break;
            }
            PImport++;
        }
        HMODULE hKernel = GetModuleHandleA("KERNEL32.dll");
        POriginalFirstThunk = (CHAR*)ImageBuffer + PImport->OriginalFirstThunk;
        PThunk = (CHAR*)ImageBuffer + PImport->FirstThunk;
        while (*(DWORD*)POriginalFirstThunk != 0) {
            if ((*(DWORD*)POriginalFirstThunk & 0x80000000) == 0) {
                szFunc = (CHAR*)ImageBuffer + *(DWORD*)POriginalFirstThunk + 0x2;
                DWORD ret = (DWORD)GetProcAddress(hKernel, szFunc);
                *(DWORD*)PThunk = ret;
            }
            else {
                DWORD ret = (DWORD)GetProcAddress(hKernel, (LPCSTR)(*(DWORD*)POriginalFirstThunk & 0x7ffffff));
                *(DWORD*)PThunk = ret;
            }
            POriginalFirstThunk += 4;
            PThunk += 4;
        }
    }
    BOOL MyAlloc(HANDLE p) {
            if (HasReloc) {
                lp = VirtualAllocEx(p, NULL, SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
                if (lp == NULL) {
                    return FALSE;
                }
                repairReloc((DWORD)lp);
                repairIAT();
            }
            else
            {
                return FALSE;
            }
        return TRUE;
    }
    
    
    BOOL inject(DWORD PID) {
        FILE* fp;
        WCHAR fileName[] = L"testDll.dll";
        _wfopen_s(&fp, fileName, L"rb");
        if (fp == NULL) {
            MessageBox(0, L"can't open file", 0, MB_OK);
            return FALSE;
        }
        fseek(fp, 0, SEEK_END);
        DWORD len = ftell(fp);
        fseek(fp, 0, SEEK_SET);
        SrcBuffer = (CHAR*)malloc(len + 1);
        if (SrcBuffer != NULL) {
            fread(SrcBuffer, len + 1, 1, fp);
        }
        fclose(fp);
        //拉伸文件
        BOOL isExtend = ExtendSrc();
        if (isExtend == FALSE) {
            free(SrcBuffer);
            SrcBuffer = NULL;
                return FALSE;
        }
        //打开进程
        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
        if (hProcess == NULL) {
            MessageBox(0, L"无法打开进程", 0, 0);
            return FALSE;
        }
        //分配空间,修复重定位表
        BOOL allocCheck = MyAlloc(hProcess);
        if (allocCheck == FALSE) {
            free(ImageBuffer);
            ImageBuffer = NULL;
            return FALSE;
        }
        //内存写入
        BOOL writeCheck = WriteProcessMemory(hProcess, lp, ImageBuffer, SizeOfImage, NULL);
        if (writeCheck == FALSE) {
            free(ImageBuffer);
            ImageBuffer = NULL;
            return FALSE;
        }
        HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, NULL,
            (LPTHREAD_START_ROUTINE)((CHAR*)lp+0x117e0),
            NULL, NULL, NULL);
    
        return TRUE;
    }

    线程函数

    DWORD WINAPI ThreadProc(_In_ LPVOID lpParameter) {
        typedef int(__stdcall* pfMessageBoxA)(HWND, LPCSTR, LPCSTR, UINT);
        pfMessageBoxA MessageBoxA = NULL;
        BOOL res = FALSE;
        HMODULE m = LoadLibraryA("User32.dll");
        if (m) {
            MessageBoxA = (pfMessageBoxA)GetProcAddress(m, "MessageBoxA");
            MessageBoxA(0, 0, 0, 0);
            FreeLibrary(m);
        }
        return 0;
    }

    因为只修复了KERNEL32.dll,使用API要显式调用,也可以在线程函数中进一步修复IAT表

  • 相关阅读:
    CodeBlocks "no such file or directory" 错误解决方案(创建类找不到头文件)
    WCF配置文件与文件下载之坎坷路
    使用Visual Studio 2010打造C语言编译器
    一个小程序引发的思考
    在C#使用文件监控对象FileSystemWatcher 实现数据同步
    C 语言 static、extern与指针函数介绍
    检测端口是否被占用
    C# ini文件读写类
    C学习笔记(2)--指针
    plsql auto 常用语法
  • 原文地址:https://www.cnblogs.com/harmonica11/p/14127183.html
Copyright © 2020-2023  润新知