DLL注入器源码

Code:

namespace THInjector
{
    DWORD WINAPI LoadDll(PVOID param)
    {
        PMANUAL_INJECT ManualInject = (PMANUAL_INJECT)param;

        HMODULE hModule;
        DWORD i, count;
        DWORD_PTR delta, Function;

        PDWORD_PTR ptr;
        PWORD list;

        PIMAGE_BASE_RELOCATION pIBR;
        PIMAGE_IMPORT_DESCRIPTOR pIID;
        PIMAGE_IMPORT_BY_NAME pIBN;
        PIMAGE_THUNK_DATA FirstThunk, OrigFirstThunk;

        PDLL_MAIN EntryPoint;

        pIBR = ManualInject->BaseRelocation;
        delta = (DWORD_PTR)((LPBYTE)ManualInject->ImageBase - ManualInject->NtHeaders->OptionalHeader.ImageBase); // Calculate the delta

                                                                                                                  // Relocate the image

        while (pIBR->VirtualAddress)
        {
            if (pIBR->SizeOfBlock >= sizeof(IMAGE_BASE_RELOCATION))
            {
                count = (pIBR->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
                list = (PWORD)(pIBR + 1);

                for (i = 0; i<count; i++)
                {
                    if (list[i])
                    {
                        ptr = (PDWORD_PTR)((LPBYTE)ManualInject->ImageBase + (pIBR->VirtualAddress + (list[i] & 0xFFF)));
                        *ptr += delta;
                    }
                }
            }

            pIBR = (PIMAGE_BASE_RELOCATION)((LPBYTE)pIBR + pIBR->SizeOfBlock);
        }

        pIID = ManualInject->ImportDirectory;

        // Resolve DLL imports

        while (pIID->Characteristics)
        {
            OrigFirstThunk = (PIMAGE_THUNK_DATA)((LPBYTE)ManualInject->ImageBase + pIID->OriginalFirstThunk);
            FirstThunk = (PIMAGE_THUNK_DATA)((LPBYTE)ManualInject->ImageBase + pIID->FirstThunk);

            hModule = ManualInject->fnLoadLibraryA((LPCSTR)ManualInject->ImageBase + pIID->Name);

            if (!hModule)
            {
                return FALSE;
            }

            while (OrigFirstThunk->u1.AddressOfData)
            {
                if (OrigFirstThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG)
                {
                    // Import by ordinal

                    Function = (DWORD_PTR)ManualInject->fnGetProcAddress(hModule, (LPCSTR)(OrigFirstThunk->u1.Ordinal & 0xFFFF));

                    if (!Function)
                    {
                        return FALSE;
                    }

                    FirstThunk->u1.Function = Function;
                }

                else
                {
                    // Import by name

                    pIBN = (PIMAGE_IMPORT_BY_NAME)((LPBYTE)ManualInject->ImageBase + OrigFirstThunk->u1.AddressOfData);
                    Function = (DWORD_PTR)ManualInject->fnGetProcAddress(hModule, (LPCSTR)pIBN->Name);

                    if (!Function)
                    {
                        return FALSE;
                    }

                    FirstThunk->u1.Function = Function;
                }

                OrigFirstThunk++;
                FirstThunk++;
            }

            pIID++;
        }
            
        if (ManualInject->NtHeaders->OptionalHeader.AddressOfEntryPoint)
        {
            EntryPoint = (PDLL_MAIN)((LPBYTE)ManualInject->ImageBase + ManualInject->NtHeaders->OptionalHeader.AddressOfEntryPoint);
            return EntryPoint((HMODULE)ManualInject->ImageBase, DLL_PROCESS_ATTACH, NULL); // Call the entry point
        }

        return TRUE;
    }

    int InjectDLL(PVOID buffer, DWORD size, LPCWSTR process)
    {
        PIMAGE_DOS_HEADER pIDH;
        PIMAGE_NT_HEADERS pINH;
        PIMAGE_SECTION_HEADER pISH;

        HANDLE hProcess, hThread, hToken, hSnap;
        PVOID image, mem, mem2, mem3;
        DWORD i, ProcessId, threadId = -1;

        TOKEN_PRIVILEGES tp;
        MANUAL_INJECT ManualInject; 
        
        THREADENTRY32 te32;
        CONTEXT ctx;

        if (OpenProcessToken((HANDLE)-1, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
        {
            tp.PrivilegeCount = 1;
            tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

            tp.Privileges[0].Luid.LowPart = 20;
            tp.Privileges[0].Luid.HighPart = 0;

            AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL);
            CloseHandle(hToken);
        }

        pIDH = (PIMAGE_DOS_HEADER)buffer;

        if (pIDH->e_magic != IMAGE_DOS_SIGNATURE)
        {
            return 0;
        }

        pINH = (PIMAGE_NT_HEADERS)((LPBYTE)buffer + pIDH->e_lfanew);

        if (pINH->Signature != IMAGE_NT_SIGNATURE)
        {
            return 0;
        }

        if (!(pINH->FileHeader.Characteristics & IMAGE_FILE_DLL))
        {
            return 0;
        }

        hProcess = Process::GetProcessHandle(process);
        ProcessId = Process::GetProcessW(process).th32ProcessID;

        image = VirtualAllocEx(hProcess, NULL, pINH->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); // Allocate memory for the DLL

        if (!image)
        {
            CloseHandle(hProcess);
            return 0;
        }

        // Copy the header to target process

        if (!WriteProcessMemory(hProcess, image, buffer, pINH->OptionalHeader.SizeOfHeaders, NULL))
        {
            VirtualFreeEx(hProcess, image, 0, MEM_RELEASE);
            CloseHandle(hProcess);
            return 0;
        }

        pISH = (PIMAGE_SECTION_HEADER)(pINH + 1);

        // Copy the DLL to target process

        for (i = 0; i<pINH->FileHeader.NumberOfSections; i++)
        {
            WriteProcessMemory(hProcess, (PVOID)((LPBYTE)image + pISH[i].VirtualAddress), (PVOID)((LPBYTE)buffer + pISH[i].PointerToRawData), pISH[i].SizeOfRawData, NULL);
        }

        mem = VirtualAllocEx(hProcess, NULL, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); // Allocate memory for the loader code


        if (!mem)
        {
            VirtualFreeEx(hProcess, image, 0, MEM_RELEASE);
            CloseHandle(hProcess);
            return 0;
        }

        mem2 = VirtualAllocEx(hProcess, NULL, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); // Allocate memory for the shellcode

        if (!mem2)
        {
            VirtualFreeEx(hProcess, image, 0, MEM_RELEASE);
            VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE);
            CloseHandle(hProcess);
            return 0;
        }

        mem3 = VirtualAllocEx(hProcess, NULL, sizeof(int), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); // Allocate memory for the shellcode

        if (!mem3)
        {
            VirtualFreeEx(hProcess, image, 0, MEM_RELEASE);
            VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE);
            VirtualFreeEx(hProcess, mem2, 0, MEM_RELEASE);
            CloseHandle(hProcess);
            return 0;
        }
        int value = 0;
        WriteProcessMemory(hProcess, mem3, &value, sizeof(int), NULL);

        memset(&ManualInject, 0, sizeof(MANUAL_INJECT));

        ManualInject.ImageBase = image;
        ManualInject.NtHeaders = (PIMAGE_NT_HEADERS)((LPBYTE)image + pIDH->e_lfanew);
        ManualInject.BaseRelocation = (PIMAGE_BASE_RELOCATION)((LPBYTE)image + pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
        ManualInject.ImportDirectory = (PIMAGE_IMPORT_DESCRIPTOR)((LPBYTE)image + pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
        ManualInject.fnLoadLibraryA = LoadLibraryA;
        ManualInject.fnGetProcAddress = GetProcAddress;

        SIZE_T number = 0;

        WriteProcessMemory(hProcess, mem, &ManualInject, sizeof(MANUAL_INJECT), NULL); // Write the loader information to target process
        WriteProcessMemory(hProcess, (PMANUAL_INJECT)mem + 1, LoadDll, 0x1000, &number); // Write the loader code to target process

        // WRITING SHELLCODE

        unsigned char shellcode[]{ 0x9C, 0x50, 0x53, 0x51, 0x52, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, 0x53, // push     REGISTERS
                                   0x48, 0x83, 0xEC, 0x30,                                                       // sub rsp, 0x30
                                   0x48, 0xB9,       0x00, 0x00, 0x00, 0x00 ,0x00 ,0x00 ,0x00 ,0x00,             // movabs rcx, 0x0000000000000000
                                   0x36, 0x80, 0x39, 0x00,                                                       // cmp byte ptr ss : [rcx], 0
                                   0x74, 0x02,                                                                   // je 0x02
                                   0xEB, 0x1A,                                                                   // jmp short 0x1A
                                   0x36, 0xC6, 0x01, 0x01,                                                       // mov byte ptr ss:[rcx], 1
                                   0x48, 0xB9,       0x00, 0x00, 0x00, 0x00 ,0x00 ,0x00 ,0x00 ,0x00,             // movabs rcx, 0x0000000000000000
                                   0x48, 0xB8,       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,             // mobabs rax, 0x0000000000000000
                                   0xFF, 0xD0,                                                                   // call rax
                                   0x48, 0x83, 0xC4, 0x30,                                                       // add      RSP, 0x30
                                   0x41, 0x5B, 0x41, 0x5A, 0x41, 0x59, 0x41, 0x58, 0x5A, 0x59, 0x5B, 0x58, 0x9D, // pop      REGISTER
                                   0xC3                                                                          // ret
                                  };

        // Replacing param
        *(DWORD_PTR*)(shellcode + 19) = (DWORD_PTR)mem3;
        *(DWORD_PTR*)(shellcode + 41) = (DWORD_PTR)mem;
        *(DWORD_PTR*)(shellcode + 51) = (DWORD_PTR)((PMANUAL_INJECT)mem + 1);

        WriteProcessMemory(hProcess, mem2, shellcode, sizeof(shellcode), &number);

        // END WRITING SHELLCODE

        // Find a thread to hijhack
        HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
        if (h != INVALID_HANDLE_VALUE) {
            THREADENTRY32 te;
            te.dwSize = sizeof(te);
            if (Thread32First(h, &te)) {
                do {
                    if (te.th32OwnerProcessID == ProcessId) {
                        threadId = te.th32ThreadID;
                        break;
                    }
                    te.dwSize = sizeof(te);
                } while (Thread32Next(h, &te));
            }
        }
        CloseHandle(h);

        if (threadId == -1)
        {
            VirtualFreeEx(hProcess, image, 0, MEM_RELEASE);
            VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE);
            CloseHandle(hProcess);
            return 0;
        }

        HMODULE mod = GetModuleHandleA("ntdll.dll");
        HHOOK injectHook = SetWindowsHookExA(WH_GETMESSAGE, (HOOKPROC)mem2, mod, threadId);

        while (1)
        {
            int var = -1;
            ReadProcessMemory(hProcess, mem3, &var, sizeof(int), NULL);

            if (var == 1)
            {
                UnhookWindowsHookEx(injectHook);
                break;
            }

            Sleep(1);
        }

        Sleep(1000);

        VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE);
        VirtualFreeEx(hProcess, mem2, 0, MEM_RELEASE);
        VirtualFreeEx(hProcess, mem3, 0, MEM_RELEASE);
        CloseHandle(hProcess);

        return 1;
    }
}

转载于:https://www.cnblogs.com/L1079991001/p/10473012.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
易语言是一种基于Windows平台开发的编程语言,它的特点是简单易学、上手快。在易语言中,dll注入是一种常见的程序,它用于向目标进程注入外部dll文件,并在目标进程的执行环境中执行特定的功能。 易语言编写的dll注入源码主要包括以下几个主要步骤: 1. 获取目标进程的句柄:通过调用Windows API函数OpenProcess,获取目标进程的句柄,以便后续操作。 2. 分配内存空间:使用VirtualAllocEx函数,在目标进程中分配一块内存空间,用于存放将要注入dll文件路径。 3. 写入dll文件路径:通过WriteProcessMemory函数,将dll文件路径写入到目标进程的内存空间中。 4. 获取LoadLibraryA函数地址:使用GetProcAddress函数,获取Kernel32.dll中的LoadLibraryA函数的地址,以便后续调用。 5. 在目标进程中执行LoadLibraryA函数:通过CreateRemoteThread函数,在目标进程中创建一个远程线程,并在远程线程中执行LoadLibraryA函数,将之前写入的dll文件路径作为参数传递给LoadLibraryA函数。 6. 等待注入完成:使用WaitForSingleObject函数,等待远程线程执行完毕。 7. 清理资源:释放句柄、释放内存空间等,确保程序的运行环境干净。 通过以上步骤,我们可以实现一个简单的易语言dll注入。当然,根据不同的需求,还可以对源码进行优化和功能拓展,例如添加注入成功与否的判断、错误处理等,以提升注入的可靠性和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值