zoukankan      html  css  js  c++  java
  • 《逆向工程核心原理》--注入学习

    Windows消息钩取

    一、钩子和消息钩子

    钩子,英文Hook,泛指偷看或截取信息时所用的手段或工具。

    Windows操作系统向用户提供GUI,它是以事件驱动(Event Driven)方式工作。事件发生后,OS将事先定义好的消息发送给相应的应用程序,应用程序分析收到的消息后执行相应动作。以敲击键盘为例,

    常规Windows消息流:

    1. 发生键盘输入事件,WM_KEYDOWN消息被添加到OS消息队列;
    2. OS判断哪个应用程序发生了事件,从OS消息队列中取出消息,添加到相应应用程序的app消息队列;
    3. 应用程序监视自身的消息队列,发现新添加的WM_KEYDOWN消息,调用相应的事件处理程序进行处理。

    附带钩子的信息流:

    1. 发生键盘输入事件,WM_KEYDOWN消息被添加到OS消息队列;
    2. OS判断哪个应用程序发生了事件,从OS消息队列中取出消息,发送给应用程序;
    3. 钩子程序截取信息,对消息采取一定的动作(因钩子目的而定);
    4. 如钩子程序不拦截消息,消息最终传输给应用程序,此时的消息可能经过了钩子程序的修改。

     

    DLL注入

    DLL注入:向运行中的其他进程强制插入特定的DLL文件,主要是命令其他进程自行调用LoadLibrary() API,加载用户指定的DLL文件。

    DLL注入与一般DLL加载的主要区别是加载的目标进程是其自身或其他进程。

    DLL

    DLL(Dynamic Linked Library,动态链接库),DLL被加载到进程后会自动运行DllMain函数,用户可以把想要执行的额代码放到DllMain函数,每当加载DLL时,添加的代码就会自动得到执行。利用该特性可以修复程序BUG,或向程序添加新功能

      1 // CodeInject.cpp : 定义控制台应用程序的入口点。
      2 //
      3  
      4 //#include "stdafx.h"
      5 #include "windows.h"
      6 #include "stdio.h"
      7 #include <iostream>
      8 #include <cstring> 
      9 #include "string.h" 
     10 using namespace std; 
     11 //该结构体用于接收API和4个字符串
     12 typedef struct _THREAD_PARAM {
     13     FARPROC pFunc[2];
     14     char szBuf[4][128];
     15 } THREAD_PARAM, *PTHREAD_PARAM;
     16  
     17 typedef HMODULE (WINAPI *PFLOADLIBRARYA)
     18 (
     19     LPCSTR lpLibFileName
     20 );
     21  
     22 typedef FARPROC (WINAPI *PFGETPROCADDRESS)
     23 (
     24     HMODULE hModule,
     25     LPCSTR lpProcName
     26 );
     27  
     28 typedef int (WINAPI *PFMESSAGEBOXA)
     29 (
     30     HWND hWnd,
     31     LPCSTR lpText,
     32     LPCSTR lpCaption,
     33     UINT uType
     34 );
     35  
     36 DWORD WINAPI ThreadProc(LPVOID lParam){
     37     PTHREAD_PARAM pParam = (PTHREAD_PARAM)lParam;
     38     HMODULE hMod = NULL;
     39     FARPROC pFunc = NULL;
     40  
     41     //未直接调用相关API和未直接定义使用字符串,而通过THREAD_PARAM结构体以线程参数的形式传递使用
     42     // LoadLibrary()
     43     hMod = ((PFLOADLIBRARYA)pParam->pFunc[0])(pParam->szBuf[0]);    // "user32.dll"
     44     if( !hMod ){
     45         return 1;
     46     }
     47         
     48  
     49     // GetProcAddress()
     50     pFunc = (FARPROC)((PFGETPROCADDRESS)pParam->pFunc[1])(hMod, pParam->szBuf[1]);  // "MessageBoxA"
     51     if( !pFunc ){
     52         return 1;
     53     }
     54  
     55     // MessageBoxA()
     56     ((PFMESSAGEBOXA)pFunc)(NULL, pParam->szBuf[2], pParam->szBuf[3], MB_OK);
     57  
     58     return 0;
     59 }
     60  
     61 BOOL InjectCode(DWORD dwPID){
     62     HMODULE hMod = NULL;
     63     THREAD_PARAM param = {0,};
     64     HANDLE hProcess = NULL;
     65     HANDLE hThread = NULL;
     66     LPVOID pRemoteBuf[2] = {0,};
     67     DWORD dwSize = 0;
     68  
     69     hMod = GetModuleHandleA("kernel32.dll");
     70  
     71     //设置THREAD_PARAM结构体
     72     //加载到所有进程的kernel32.dll的地址都相同,因此从本进程获取的API与在notepad进程中获取的API地址是一样的
     73     param.pFunc[0] = GetProcAddress(hMod, "LoadLibraryA");
     74     param.pFunc[1] = GetProcAddress(hMod, "GetProcAddress");
     75     strcpy(param.szBuf[0], "user32.dll");
     76     strcpy(param.szBuf[1], "MessageBoxA");
     77     strcpy(param.szBuf[2], "代码注入 By SKI12");
     78     strcpy(param.szBuf[3], "blog.csdn.net/ski_12");
     79  
     80     // Open Process
     81     if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS,   // dwDesiredAccess
     82                                   FALSE,                // bInheritHandle
     83                                   dwPID)) )             // dwProcessId
     84     {
     85         printf("OpenProcess() fail : err_code = %d
    ", GetLastError());
     86         return FALSE;
     87     }
     88  
     89     // Allocation for THREAD_PARAM
     90     //注入数据部分到进程
     91     dwSize = sizeof(THREAD_PARAM);
     92     if( !(pRemoteBuf[0] = VirtualAllocEx(hProcess,          // hProcess
     93                                       NULL,                 // lpAddress
     94                                       dwSize,               // dwSize
     95                                       MEM_COMMIT,           // flAllocationType
     96                                       PAGE_READWRITE)) )    // flProtect
     97     {
     98         printf("VirtualAllocEx() fail : err_code = %d
    ", GetLastError());
     99         return FALSE;
    100     }
    101     //param参数值为数据
    102     if( !WriteProcessMemory(hProcess,                       // hProcess
    103                             pRemoteBuf[0],                  // lpBaseAddress
    104                             (LPVOID)&param,                 // lpBuffer
    105                             dwSize,                         // nSize
    106                             NULL) )                         // [out] lpNumberOfBytesWritten
    107     {
    108         printf("WriteProcessMemory() fail : err_code = %d
    ", GetLastError());
    109         return FALSE;
    110     }
    111  
    112     // Allocation for ThreadProc()
    113     //注入代码部分到进程
    114     dwSize = (DWORD)InjectCode - (DWORD)ThreadProc;
    115     if( !(pRemoteBuf[1] = VirtualAllocEx(hProcess,          // hProcess
    116                                       NULL,                 // lpAddress
    117                                       dwSize,               // dwSize
    118                                       MEM_COMMIT,           // flAllocationType
    119                                       PAGE_EXECUTE_READWRITE)) )    // flProtect
    120     {
    121         printf("VirtualAllocEx() fail : err_code = %d
    ", GetLastError());
    122         return FALSE;
    123     }
    124     //ThreadProc()函数为操作代码
    125     if( !WriteProcessMemory(hProcess,                       // hProcess
    126                             pRemoteBuf[1],                  // lpBaseAddress
    127                             (LPVOID)ThreadProc,             // lpBuffer
    128                             dwSize,                         // nSize
    129                             NULL) )                         // [out] lpNumberOfBytesWritten
    130     {
    131         printf("WriteProcessMemory() fail : err_code = %d
    ", GetLastError());
    132         return FALSE;
    133     }
    134  
    135     //将数据与代码注入到进程内存后,调用CreateRemoteThread()执行远程线程
    136     if( !(hThread = CreateRemoteThread(hProcess,            // hProcess
    137                                        NULL,                // lpThreadAttributes
    138                                        0,                   // dwStackSize
    139                                        (LPTHREAD_START_ROUTINE)pRemoteBuf[1],     // dwStackSize
    140                                        pRemoteBuf[0],       // lpParameter
    141                                        0,                   // dwCreationFlags
    142                                        NULL)) )             // lpThreadId
    143     {
    144         printf("CreateRemoteThread() fail : err_code = %d
    ", GetLastError());
    145         return FALSE;
    146     }
    147  
    148     WaitForSingleObject(hThread, INFINITE);    
    149  
    150     CloseHandle(hThread);
    151     CloseHandle(hProcess);
    152  
    153     return TRUE;
    154 }
    155  
    156 BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) {
    157     TOKEN_PRIVILEGES tp;
    158     HANDLE hToken;
    159     LUID luid;
    160  
    161     if( !OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) ){
    162         printf("OpenProcessToken error: %u
    ", GetLastError());
    163         return FALSE;
    164     }
    165  
    166     if( !LookupPrivilegeValue(NULL,           // lookup privilege on local system
    167                               lpszPrivilege,  // privilege to lookup 
    168                               &luid) )        // receives LUID of privilege
    169     {
    170         printf("LookupPrivilegeValue error: %u
    ", GetLastError() ); 
    171         return FALSE; 
    172     }
    173  
    174     tp.PrivilegeCount = 1;
    175     tp.Privileges[0].Luid = luid;
    176     if( bEnablePrivilege )
    177         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    178     else
    179         tp.Privileges[0].Attributes = 0;
    180  
    181     // Enable the privilege or disable all privileges.
    182     if( !AdjustTokenPrivileges(hToken, 
    183                                FALSE, 
    184                                &tp, 
    185                                sizeof(TOKEN_PRIVILEGES), 
    186                                (PTOKEN_PRIVILEGES) NULL, 
    187                                (PDWORD) NULL) )
    188     { 
    189         printf("AdjustTokenPrivileges error: %u
    ", GetLastError() ); 
    190         return FALSE; 
    191     } 
    192  
    193     if( GetLastError() == ERROR_NOT_ALL_ASSIGNED ){
    194         printf("The token does not have the specified privilege. 
    ");
    195         return FALSE;
    196     } 
    197  
    198     return TRUE;
    199 }
    200  
    201 int main(int argc, char* argv[]){
    202     DWORD dwPID = 0;
    203     if( argc != 2 ){
    204         printf("
     USAGE  : %s <pid>
    ", argv[0]);
    205         return 1;
    206     }
    207  
    208     // change privilege
    209     if( !SetPrivilege(SE_DEBUG_NAME, TRUE) ){
    210         return 1;
    211     }
    212  
    213     // code injection
    214     //将字符串转换为长整型
    215     dwPID = (DWORD)atol(argv[1]);
    216     InjectCode(dwPID);
    217  
    218     return 0;
    219 }
    220  

    待续。。。

  • 相关阅读:
    2014 I/O归来:Google连接一切
    Android漫游记(4)---.so文件动态调试一例
    Python笔记之面向对象
    Caffe —— Deep learning in Practice
    JAVA学习笔记 -- 数据结构
    UICollectionView——整体总结
    一些优秀的学习网站(Android)
    10个很棒的学习Android 开发的网站
    Android圆形图片不求人,自定义View实现(BitmapShader使用)
    Android图像处理之冰冻效果
  • 原文地址:https://www.cnblogs.com/mysky007/p/12991819.html
Copyright © 2011-2022 走看看