zoukankan      html  css  js  c++  java
  • 矛与盾注入到目标进程

    假设我们有如下代码:

    image而且我们知道函数add 的地址是  0x00401630. 这篇文章的目的就是写一个程序,注入到目标进程,然后调用这个进程的add()函数。

    要注入到目标进程有很多种方法, 这里我选择用CreateRemoreThread 来示例。

    HANDLE CreateRemoteThread(
         HANDLE hProcess,    //目标进程的句柄
         LPSECURITY_ATTRIBUTES lpThreadAttributes,//指向线程的安全描述结构体的指针,一般设置为NULL,表示使用默认的安全级别
         SIZE_T dwStackSize,//线程堆栈大小,一般设置为0,表示使用默认的大小,一般为1M
         LPTHREAD_START_ROUTINE lpStartAddress,//线程函数的地址
         LPVOID lpParameter,//线程参数
         DWORD dwCreationFlags,//线程的创建方式
         LPDWORD lpThreadId//输出参数,记录创建的远程线程的ID
    );

    使用CreateRemoteThread 来完成代码注入非常简单, 只需要进行如下 步骤:

    1. 打开目标进程
    2. 分配空间, 把我们要注入的函数写入这个空间
    3. 创建远程线程

    我们可以看下如下代码:

    1 void __stdcall addHP()
    2 {
    3 __asm
    4 {
    5 mov eax, 0x00401630
    6 call eax
    7 }
    8 }
    9  bool remoteCall(LPCWSTR windowsName)
    10 {
    11 //1. 打开进程
    12   HWND tergetHwnd = ::FindWindow(NULL,windowsName);
    13 DWORD processId;
    14 ::GetWindowThreadProcessId(tergetHwnd,&processId);
    15 HANDLE processHandle = ::OpenProcess(PROCESS_ALL_ACCESS,
    16 FALSE, processId);
    17 if (NULL == processHandle)
    18 {
    19 AfxMessageBox(_T("Create process failed"));
    20 return false;
    21 }
    22 //2. 分配空间, 把我们要注入的函数写入这个空间
    23 LPVOID remotefunc = VirtualAllocEx(processHandle, NULL,MAX_REMOTE_DATA,
    24 MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    25 if (NULL == remotefunc)
    26 {
    27 AfxMessageBox(_T("remotefunc alloc failed"));
    28 return false;
    29 }
    30 if (!WriteProcessMemory(processHandle,remotefunc,&addHP,
    31 MAX_REMOTE_DATA, 0))
    32 {
    33 AfxMessageBox(_T("write process memory failed"));
    34 return false;
    35 }
    36 //创建远程线程
    37 DWORD threadId;
    38 HANDLE remoteHandle = CreateRemoteThread(processHandle,
    39 NULL, 0, (LPTHREAD_START_ROUTINEremotefunc), NULL, 0, &threadId);
    40 if (!remoteHandle)
    41 {
    42 AfxMessageBox(_T("CreateRemoteThread failed"));
    43 return false;
    44 }
    45 VirtualFreeEx(processHandle, remotefunc, MAX_REMOTE_DATA, MEM_RELEASE);
    46 CloseHandle(remoteHandle);
    47 return true;
    48 }

    测试一下是OK 的。 但是这样执行却有一个问题, 就是我们不能给addHP()传递参数, 因为所有关于这些参数的值都是在当前进程的, 所以我们要修改为如下程序:

    1 // 这里我们做的就是用函数指针封装 add HP 函数
    2 int const MAX_REMOTE_DATA = 1024 * 4;
    3 void __stdcall addHP(int num)
    4 {
    5 __asm
    6 {
    7 push num
    8 mov eax, 0x00401630
    9 call eax
    10 }
    11 }
    12 typedef struct tagRpcData
    13 {
    14 int num;
    15 void* pfunCall;
    16 }stRpcData, *LPRPCDATA;
    17 int const MAX_REMOTE_DATA = 1024 * 4;
    18 typedef void(__stdcall* FUNCADD)(int);
    19 void __stdcall remoteFun(LPRPCDATA pData)
    20 {
    21 FUNCADD fun = (FUNCADD)pData->pfunCall;
    22 fun(pData->num);
    23 return 0;
    24 }
    25 bool remoteCall(LPCWSTR windowsName)
    26 {
    27 //1. 打开进程
    28 HWND tergetHwnd = ::FindWindow(NULL,windowsName);
    29 DWORD processId;
    30 ::GetWindowThreadProcessId(tergetHwnd,&processId);
    31 HANDLE processHandle = ::OpenProcess(PROCESS_ALL_ACCESS,
    32 FALSE, processId);
    33 if (NULL == processHandle)
    34 {
    35 AfxMessageBox(_T("Create process failed"));
    36 return false;
    37 }
    38 //2. 分配空间, 把我们要注入的函数写入这个空间
    39 LPVOID remotefunc = VirtualAllocEx(processHandle, NULL,MAX_REMOTE_DATA,
    40 MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    41 if (NULL == remotefunc)
    42 {
    43 AfxMessageBox(_T("remotefunc alloc failed"));
    44 return false;
    45 }
    46 if (!WriteProcessMemory(processHandle,remotefunc,&addHP,
    47 MAX_REMOTE_DATA, 0))
    48 {
    49 AfxMessageBox(_T("write process memory failed"));
    50 return false;
    51 }
    52 //3. 分配空间, 把我们要注入的函数写入这个空间
    53 LPVOID remoteParam = VirtualAllocEx(processHandle, NULL,MAX_REMOTE_DATA,
    54 MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    55 if (NULL == remoteParam)
    56 {
    57 AfxMessageBox(_T("remoteParam alloc failed"));
    58 return false;
    59 }
    60 if (!WriteProcessMemory(processHandle,remoteParam,&addHP,
    61 MAX_REMOTE_DATA, 0))
    62 {
    63 AfxMessageBox(_T("write process memory failed"));
    64 return false;
    65 }
    66 //创建远程线程
    67 DWORD threadId;
    68 HANDLE remoteHandle = CreateRemoteThread(processHandle,
    69 NULL, 0, (LPTHREAD_START_ROUTINE)(remotefunc), remoteParam, 0, &threadId);
    70 if (!remoteHandle)
    71 {
    72 AfxMessageBox(_T("CreateRemoteThread failed"));
    73 return false;
    74 }
    75 VirtualFreeEx(processHandle, remotefunc, MAX_REMOTE_DATA, MEM_RELEASE);
    76 VirtualFreeEx(processHandle, remoteParam, MAX_REMOTE_DATA, MEM_RELEASE);
    77 CloseHandle(remoteHandle);
    78 return true;
    79 }

    这样就OK了。

    这里再记录两个函数:

    1 //提升进程访问权限
    2 bool enableDebugPriv()
    3 {
    4 HANDLE hToken;
    5 LUID sedebugnameValue;
    6 TOKEN_PRIVILEGES tkp;
    7 if (!OpenProcessToken(GetCurrentProcess(),
    8 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
    9 return false;
    10 }
    11 if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) {
    12 CloseHandle(hToken);
    13 return false;
    14 }
    15 tkp.PrivilegeCount = 1;
    16 tkp.Privileges[0].Luid = sedebugnameValue;
    17 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    18 if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) {
    19 CloseHandle(hToken);
    20 return false;
    21 }
    22 return true;
    23 }
    24 //根据进程名称得到进程ID,如果有多个运行实例的话,返回第一个枚举到的进程的ID
    25 DWORD processNameToId(LPCTSTR lpszProcessName)
    26 {
    27 HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    28 PROCESSENTRY32 pe;
    29 pe.dwSize = sizeof(PROCESSENTRY32);
    30 if (!Process32First(hSnapshot, &pe)) {
    31 MessageBox(NULL,
    32 _T("The frist entry of the process list has not been copyied to the buffer"),
    33 _T("Notice"), MB_ICONINFORMATION | MB_OK);
    34 return 0;
    35 }
    36 while (Process32Next(hSnapshot, &pe)) {
    37 if (!strcmp(lpszProcessName, pe.szExeFile)) {
    38 return pe.th32ProcessID;
    39 }
    40 }
    41 return 0;
    42 }

  • 相关阅读:
    快速排序算法
    学习了几天的jQuery Mobile的一点感受
    jQuery Mobile 图标无法显示
    html5基础知识
    百度地图与谷歌地图 (常识、区别,更倾向于使用百度地图,纠错信息比谷歌多)
    (转)百度Map API
    历年软件设计师下午考试试题汇总统计
    HTML5的本地存储
    EnterpriseArchitectect 软件的勾选的几个选项对应的中文意思
    访问权限控制表
  • 原文地址:https://www.cnblogs.com/sld666666/p/1939660.html
Copyright © 2011-2022 走看看