内存写入注入

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表

 

posted @ 2020-12-12 22:41  Harmonica11  阅读(574)  评论(0编辑  收藏  举报