简单注入

Usage: ManualInject [DLL name] [PID]

How it works

1 ) Open the DLL file (CreateFile)

2 ) Read the DLL into memory (ReadFile)

3 ) Validate the DLL image.

4 ) Open the target process (OpenProcess)

5 ) Allocate memory for the DLL and loader code in the target process (VirtualAllocEx)

6 ) Copy the DLL image into target process's address space (WriteProcessMemory)

7 ) Copy the loader code into target process's address space (WriteProcessMemory)

8 ) Create a remote thread to execute the loader code in target process's address space (CreateRemoteThread)

9 ) Wait for the loader code to complete (WaitForSingleObject). The loader code perform relocations and resolve DLL imports for the image, and then call the entry point if found.

10 ) Free the loader code (VirtualFreeEx)

#include <stdio.h>
#include <Windows.h>

typedef HMODULE (WINAPI *pLoadLibraryA)(LPCSTR);
typedef FARPROC (WINAPI *pGetProcAddress)(HMODULE,LPCSTR);

typedef BOOL (WINAPI *PDLL_MAIN)(HMODULE,DWORD,PVOID);

typedef struct _MANUAL_INJECT
{
    PVOID ImageBase;
    PIMAGE_NT_HEADERS NtHeaders;
    PIMAGE_BASE_RELOCATION BaseRelocation;
    PIMAGE_IMPORT_DESCRIPTOR ImportDirectory;
    pLoadLibraryA fnLoadLibraryA;
    pGetProcAddress fnGetProcAddress;
}MANUAL_INJECT,*PMANUAL_INJECT;

DWORD WINAPI LoadDll(PVOID p)
{
    PMANUAL_INJECT ManualInject;

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

    PDWORD ptr;
    PWORD list;

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

    PDLL_MAIN EntryPoint;

    ManualInject=(PMANUAL_INJECT)p;

    pIBR=ManualInject->BaseRelocation;
    delta=(DWORD)((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)((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)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)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;
}

DWORD WINAPI LoadDllEnd()
{
    return 0;
}

int wmain(int argc,wchar_t* argv[])
{
    PIMAGE_DOS_HEADER pIDH;
    PIMAGE_NT_HEADERS pINH;
    PIMAGE_SECTION_HEADER pISH;
    
    HANDLE hProcess,hThread,hFile,hToken;
    PVOID buffer,image,mem;
    DWORD i,FileSize,ProcessId,ExitCode,read;

    TOKEN_PRIVILEGES tp;
    MANUAL_INJECT ManualInject;

    if(argc<3)
    {
        printf("\nUsage: ManualInject [DLL name] [PID]\n");
        return -1;
    }

    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);
    }

    printf("\nOpening the DLL.\n");
    hFile=CreateFile(argv[1],GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL); // Open the DLL

    if(hFile==INVALID_HANDLE_VALUE)
    {
        printf("\nError: Unable to open the DLL (%d)\n",GetLastError());
        return -1;
    }

    FileSize=GetFileSize(hFile,NULL);
    buffer=VirtualAlloc(NULL,FileSize,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);

    if(!buffer)
    {
        printf("\nError: Unable to allocate memory for DLL data (%d)\n",GetLastError());
        
        CloseHandle(hFile);
        return -1;
    }

    // Read the DLL

    if(!ReadFile(hFile,buffer,FileSize,&read,NULL))
    {
        printf("\nError: Unable to read the DLL (%d)\n",GetLastError());

        VirtualFree(buffer,0,MEM_RELEASE);
        CloseHandle(hFile);

        return -1;
    }

    CloseHandle(hFile);

    pIDH=(PIMAGE_DOS_HEADER)buffer;

    if(pIDH->e_magic!=IMAGE_DOS_SIGNATURE)
    {
        printf("\nError: Invalid executable image.\n");
        
        VirtualFree(buffer,0,MEM_RELEASE);
        return -1;
    }

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

    if(pINH->Signature!=IMAGE_NT_SIGNATURE)
    {
        printf("\nError: Invalid PE header.\n");
        
        VirtualFree(buffer,0,MEM_RELEASE);
        return -1;
    }

    if(!(pINH->FileHeader.Characteristics & IMAGE_FILE_DLL))
    {
        printf("\nError: The image is not DLL.\n");
        
        VirtualFree(buffer,0,MEM_RELEASE);
        return -1;
    }

    ProcessId=wcstoul(argv[2],NULL,0);

    printf("\nOpening target process.\n");
    hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,ProcessId);

    if(!hProcess)
    {
        printf("\nError: Unable to open target process (%d)\n",GetLastError());
        
        VirtualFree(buffer,0,MEM_RELEASE);
        CloseHandle(hProcess);

        return -1;
    }

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

    if(!image)
    {
        printf("\nError: Unable to allocate memory for the DLL (%d)\n",GetLastError());
        
        VirtualFree(buffer,0,MEM_RELEASE);
        CloseHandle(hProcess);

        return -1;
    }

    // Copy the header to target process

    printf("\nCopying headers into target process.\n");

    if(!WriteProcessMemory(hProcess,image,buffer,pINH->OptionalHeader.SizeOfHeaders,NULL))
    {
        printf("\nError: Unable to copy headers to target process (%d)\n",GetLastError());
        
        VirtualFreeEx(hProcess,image,0,MEM_RELEASE);
        CloseHandle(hProcess);

        VirtualFree(buffer,0,MEM_RELEASE);
        return -1;
    }

    pISH=(PIMAGE_SECTION_HEADER)(pINH+1);

    // Copy the DLL to target process

    printf("\nCopying sections to target process.\n");

    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);
    }

    printf("\nAllocating memory for the loader code.\n");
    mem=VirtualAllocEx(hProcess,NULL,4096,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); // Allocate memory for the loader code

    if(!mem)
    {
        printf("\nError: Unable to allocate memory for the loader code (%d)\n",GetLastError());

        VirtualFreeEx(hProcess,image,0,MEM_RELEASE);
        CloseHandle(hProcess);

        VirtualFree(buffer,0,MEM_RELEASE);
        return -1;
    }

    printf("\nLoader code allocated at %#x\n",mem);
    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;

    printf("\nWriting loader code to target process.\n");

    WriteProcessMemory(hProcess,mem,&ManualInject,sizeof(MANUAL_INJECT),NULL); // Write the loader information to target process
    WriteProcessMemory(hProcess,(PVOID)((PMANUAL_INJECT)mem+1),LoadDll,(DWORD)LoadDllEnd-(DWORD)LoadDll,NULL); // Write the loader code to target process

    printf("\nExecuting loader code.\n");
    hThread=CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)((PMANUAL_INJECT)mem+1),mem,0,NULL); // Create a remote thread to execute the loader code

    if(!hThread)
    {
        printf("\nError: Unable to execute loader code (%d)\n",GetLastError());

        VirtualFreeEx(hProcess,mem,0,MEM_RELEASE);
        VirtualFreeEx(hProcess,image,0,MEM_RELEASE);

        CloseHandle(hProcess);

        VirtualFree(buffer,0,MEM_RELEASE);
        return -1;
    }

    WaitForSingleObject(hThread,INFINITE);
    GetExitCodeThread(hThread,&ExitCode);

    if(!ExitCode)
    {
        VirtualFreeEx(hProcess,mem,0,MEM_RELEASE);
        VirtualFreeEx(hProcess,image,0,MEM_RELEASE);

        CloseHandle(hThread);
        CloseHandle(hProcess);

        VirtualFree(buffer,0,MEM_RELEASE);
        return -1;
    }

    CloseHandle(hThread);
    VirtualFreeEx(hProcess,mem,0,MEM_RELEASE);

    CloseHandle(hProcess);

    printf("\nDLL injected at %#x\n",image);
    
    if(pINH->OptionalHeader.AddressOfEntryPoint)
    {
        printf("\nDLL entry point: %#x\n",(PVOID)((LPBYTE)image+pINH->OptionalHeader.AddressOfEntryPoint));
    }

    VirtualFree(buffer,0,MEM_RELEASE);
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容