• C++学习之DLL注入


      1 #include<stdio.h>
      2 #include<Windows.h>
      3 #include<TlHelp32.h>
      4 
      5 
      6 //typedef unsigned long       DWORD;
      7 //typedef __nullterminated CONST CHAR *LPCSTR, *PCSTR;
      8 //typedef void *HANDLE;
      9 
     10 DWORD getProcessHandle(LPCTSTR lpProcessName)//根据进程名查找进程PID
     11 {
     12     DWORD dwRet=0;
     13     HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);/*CreateToolhelp32Snapshot函数为指定的进程、
     14                                                                     进程使用的堆[HEAP]、模块[MODULE]、
     15                                                                     线程[THREAD])建立一个快照[snapshot]。*/
     16     if(hSnapShot==INVALID_HANDLE_VALUE)
     17     {
     18         //句柄无效
     19         printf("
    获得PID=%s的进程快照失败%d",lpProcessName,GetLastError());
     20         return dwRet;
     21     }
     22 
     23     //快照抓取成功  
     24     PROCESSENTRY32 pe32;//声明进程入口对象
     25     pe32.dwSize=sizeof(PROCESSENTRY32 );//填充进程入口大小
     26     Process32First(hSnapShot,&pe32);//遍历进程列表
     27     do
     28     {
     29         if(!lstrcmp(pe32.szExeFile,lpProcessName))
     30         {
     31             dwRet=pe32.th32ProcessID;
     32             break;
     33         }
     34     }
     35     while(Process32Next(hSnapShot,&pe32));
     36     CloseHandle(hSnapShot);
     37     return dwRet;
     38 
     39 }
     40 
     41 
     42 void EnableDebugPriv()  
     43 {  
     44     HANDLE hToken;          // 进程访问令牌的句柄  
     45     LUID luid;              // 用于存储调试权对应的局local unique identifier  
     46     TOKEN_PRIVILEGES tkp;   // 要设置的权限  
     47     OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);  
     48     // 获取访问令牌  
     49     LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);   // 获得调试权的luid  
     50     tkp.PrivilegeCount = 1; // 设置调试权  
     51     tkp.Privileges[0].Luid = luid;  
     52     tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  
     53     AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL); // 使进程拥有调试权  
     54     CloseHandle(hToken);  
     55 }  
     56 
     57 int main(int argc,char *argv[])
     58 {
     59     DWORD dwpid=getProcessHandle("calc.exe");
     60     LPCSTR lpDllName="D:\WorkProject\C++\20160314\DLLImport\Debug\dllDemo.dll";
     61     EnableDebugPriv();//权限提升
     62     HANDLE hProcess=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_WRITE,FALSE,dwpid);//获得要注入进程的句柄
     63     
     64     if(hProcess==NULL)
     65     {
     66         printf("
    获取进程句柄错误%d",GetLastError());
     67         return -1;
     68     }
     69 
     70     DWORD dwSize=strlen(lpDllName)+1;
     71     DWORD dwHasWrite;
     72     LPVOID lpRemoteBuf=VirtualAllocEx(hProcess,NULL,dwSize,MEM_COMMIT,PAGE_READWRITE);//在远程空间分配地址
     73     if(WriteProcessMemory(hProcess,lpRemoteBuf,lpDllName,dwSize,&dwHasWrite))//写入内存函数执行成功返回非零
     74     {
     75         if(dwHasWrite!=dwSize)
     76         {
     77             //写入内存不完整,释放内存
     78             VirtualFreeEx(hProcess,lpRemoteBuf,dwSize,MEM_COMMIT);
     79             CloseHandle(hProcess);
     80             return -1;
     81         }
     82     }
     83     else
     84     {
     85         printf("
    写入远程进程内存空间出错%d",GetLastError());
     86         CloseHandle(hProcess);
     87         return -1;
     88     }
     89     //写入成功
     90     DWORD dwNewThreadId;
     91     LPVOID lpLoadDll=LoadLibraryA;
     92     //将LoadLIbraryA作为线程函数,参数为Dll,创建新线程
     93     HANDLE hNewRemoteThread=CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)lpLoadDll,lpRemoteBuf,0,&dwNewThreadId);
     94     //HANDLE hNewRemoteThread=
     95     if(hNewRemoteThread==NULL)
     96     {
     97         printf("
    建立远程线程失败%d",GetLastError());
     98         CloseHandle(hProcess);
     99         return -1;
    100     }
    101     //等待对象句柄返回
    102     WaitForSingleObject(hNewRemoteThread,INFINITE);
    103 
    104     CloseHandle(hNewRemoteThread);
    105 
    106 
    107      //准备卸载之前注入的Dll 
    108     DWORD dwHandle,dwID; 
    109     LPVOID pFunc = GetModuleHandleA;//获得在远程线程中被注入的Dll的句柄 
    110     HANDLE hThread = CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)pFunc,lpRemoteBuf,0,&dwID); 
    111     WaitForSingleObject(hThread,INFINITE); 
    112     GetExitCodeThread(hThread,&dwHandle);//线程的结束码即为Dll模块儿的句柄 
    113     CloseHandle(hThread); 
    114     pFunc = FreeLibrary; 
    115     hThread = CreateRemoteThread(hThread,NULL,0,(LPTHREAD_START_ROUTINE)pFunc,(LPVOID)dwHandle,0,&dwID); //将FreeLibraryA注入到远程线程中去卸载Dll 
    116     WaitForSingleObject(hThread,INFINITE); 
    117     CloseHandle(hThread); 
    118     CloseHandle(hProcess); 
    119     return 0; 
    120 }
  • 相关阅读:
    .NET Core MVC 发布到IIS配置文件
    TP5导出scv格式数据,支持百万数据
    PHP导出Excel表格及设置表格样式
    如何查看Linux的内存使用状况
    tp5.1 + think-queue + supervisor
    java使用HAMC签名加密调用第三方接口
    记录:SpringBoot多个配置文件激活一个
    通过反射获取注解
    (function(){})(jQuery)与$.fn的使用
    IDEA配置203底座之lib配置
  • 原文地址:https://www.cnblogs.com/paradisekiss/p/5282158.html
Copyright © 2020-2023  润新知