zoukankan      html  css  js  c++  java
  • 小试X64 inline HOOK,hook explorer.exe--->CreateProcessInternalW监视进程创建

    原始函数是这样的

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. kernel32!CreateProcessInternalW:  
    2. 00000000`7738e750 4c8bdc          mov     r11,rsp  
    3. 00000000`7738e753 53              push    rbx  
    4. 00000000`7738e754 56              push    rsi  
    5. 00000000`7738e755 57              push    rdi  
    6. 00000000`7738e756 4154            push    r12  
    7. 00000000`7738e758 4155            push    r13  
    8. 00000000`7738e75a 4156            push    r14  
    9. 00000000`7738e75c 4157            push    r15  
    10. 00000000`7738e75e 4881ec400b0000  sub     rsp,0B40h  
    11. 00000000`7738e765 488b0564cc0e00  mov     rax,qword ptr [kernel32!local_unwind+0x606b1 (00000000`7747b3d0)]  


    跟32位一样,在函数入口写入跳转指令,跟32不一样的是,不能再用之前的E9 xx xx xx xx这样的指令了,E9不支持64位地址跳转,最大只能支持到32位,

    直接用E9大部分情况下会出错.所以我们换一种方法.

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. mov rax,0x1122334455667788  
    2. jmp rax  


    机器码是48 b8 8877665544332211 ffe0总共占了12个字节,不是我们之前用E9跳转的5字节了.

    最前面的48叫REX Prefix,大家可以GOOGLE下,4是固定的,8表示使用64位寄存器.

    如果没有前面的48就变成了mov eax, 0x1122334455667788了,使用32位寄存器.

    我们需要把函数前面12字节改成跳转指令,正好

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. 00000000`7738e750 4c8bdc          mov     r11,rsp  
    2. 00000000`7738e753 53              push    rbx  
    3. 00000000`7738e754 56              push    rsi  
    4. 00000000`7738e755 57              push    rdi  
    5. 00000000`7738e756 4154            push    r12  
    6. 00000000`7738e758 4155            push    r13  
    7. 00000000`7738e75a 4156            push    r14  

    这12个字节是完整的7条指令,写入12字节指令,不会破坏后面的指令.

    写入跳转指令后

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. kernel32!CreateProcessInternalW:  
    2. 00000000`7738e750 48b8001055fbfe070000 mov rax,offset x64dll!FakeCreateProcessInternal (000007fe`fb551000)  
    3. 00000000`7738e75a ffe0            jmp     rax  
    4. 00000000`7738e75c 4157            push    r15  
    5. 00000000`7738e75e 4881ec400b0000  sub     rsp,0B40h  
    6. 00000000`7738e765 488b0564cc0e00  mov     rax,qword ptr [kernel32!local_unwind+0x606b1 (00000000`7747b3d0)]  
    7. 00000000`7738e76c 4833c4          xor     rax,rsp  
    8. 00000000`7738e76f 48898424300b0000 mov     qword ptr [rsp+0B30h],rax  
    9. 00000000`7738e777 4889a42438050000 mov     qword ptr [rsp+538h],rsp  



    完整代码如下.

    少NTDLL.h的朋友可以去搜索下载,也可以把RtlAdjustPrivilege替换成AdjustTokenPrivileges,效果样的,只是代码多几行而已.

    声明:本人很菜,水平有限,汇编功底也是相当的水,如发现有误人子弟之处,敬请指正.若您有更好的方法也请多多指教.

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. #include <stdio.h>  
    2. #include <tchar.h>  
    3. #include <windows.h>  
    4. #include <shlwapi.h>  
    5. #include <ntdll.h>  
    6.   
    7. #pragma comment(lib, "shlwapi.lib")  
    8. #define CODE_LEN 12  
    9. TCHAR ModuleFile[MAX_PATH];    
    10. DWORD dwOldProtect;  
    11. BYTE OldCode[CODE_LEN] = {0x90};  
    12.   
    13. typedef HANDLE (WINAPI *__CreateProcessInternal)(HANDLE hToken,LPCTSTR lpApplicationName,LPTSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,BOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCTSTR lpCurrentDirectory,LPSTARTUPINFOA lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation,PHANDLE hNewToken);  
    14. __CreateProcessInternal pfnCreateProcess = 0;  
    15.   
    16. HANDLE WINAPI FakeCreateProcessInternal(HANDLE hToken,LPCTSTR lpApplicationName,LPTSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,BOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCTSTR lpCurrentDirectory,LPSTARTUPINFOA lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation,PHANDLE hNewToken)  
    17. {  
    18.     MessageBox(NULL, lpCommandLine, lpApplicationName, MB_ICONASTERISK);  
    19.     return pfnCreateProcess(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation, hNewToken);  
    20. }  
    21.   
    22. BOOL WINAPI DllMain(HINSTANCE hinstDLL,  // handle to DLL module  
    23.             DWORD fdwReason,     // reason for calling function  
    24.             LPVOID lpReserved )  // reserved  
    25. {  
    26.     switch( fdwReason )   
    27.     {   
    28.     case DLL_PROCESS_ATTACH:  
    29.         ::DisableThreadLibraryCalls(hinstDLL);  
    30.         GetModuleFileName(NULL, ModuleFile, _countof(ModuleFile));    
    31.   
    32.         if (StrRStrI(ModuleFile, 0, TEXT("explorer.exe")))  
    33.         {  
    34.             pfnCreateProcess = (__CreateProcessInternal)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "CreateProcessInternalW");  
    35.             ::VirtualProtect(pfnCreateProcess, CODE_LEN, PAGE_EXECUTE_READWRITE, &dwOldProtect);  
    36.             memcpy(OldCode, pfnCreateProcess, CODE_LEN);  
    37.             memset(pfnCreateProcess, 0x90, CODE_LEN);  
    38.             /* 
    39.             mov rax, FakeCreateProcessInternal 
    40.             jmp rax 
    41.             */  
    42.             *(LPWORD)pfnCreateProcess = 0xb848;  
    43.             *(INT64*)((INT64)pfnCreateProcess+2) = (INT64)FakeCreateProcessInternal;  
    44.             *(LPWORD)((INT64)pfnCreateProcess+10) = 0xe0ff;  
    45.             ::VirtualProtect(pfnCreateProcess, CODE_LEN, dwOldProtect, NULL);  
    46.   
    47.             pfnCreateProcess = (__CreateProcessInternal)VirtualAlloc(NULL, CODE_LEN+12, MEM_COMMIT, PAGE_EXECUTE_READWRITE);  
    48.             memcpy(pfnCreateProcess, OldCode, CODE_LEN);  
    49.             /* 
    50.             mov rax, CreateProcessInternalW + CODE_LEN 
    51.             jmp rax 
    52.             */  
    53.             *(LPWORD)((INT64)pfnCreateProcess+CODE_LEN) = 0xb848;  
    54.             *(INT64*)((INT64)pfnCreateProcess+CODE_LEN+2) = (INT64)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "CreateProcessInternalW")+CODE_LEN;  
    55.             *(LPWORD)((INT64)pfnCreateProcess+CODE_LEN+10) = 0xe0ff;  
    56.         }  
    57.         else if (StrRStrI(ModuleFile, 0, TEXT("Rundll32.exe")))    
    58.         {    
    59.             DWORD dwProcessId = 0;    
    60.             HANDLE hProcess = 0;     
    61.             HWND   hwndDeskTop;       
    62.   
    63.             hwndDeskTop = FindWindow(TEXT("ProgMan"), NULL);         
    64.   
    65.             GetModuleFileName(hinstDLL, ModuleFile, _countof(ModuleFile));    
    66.             GetWindowThreadProcessId(hwndDeskTop, &dwProcessId);  
    67.             BOOLEAN bEnable;  
    68.             ::RtlAdjustPrivilege(0x13, 1, 0, &bEnable);  
    69.   
    70.             if (dwProcessId)    
    71.             {    
    72.                 hProcess = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, NULL, dwProcessId);    
    73.             }    
    74.   
    75.             LPVOID Param = VirtualAllocEx(hProcess, NULL, 256, MEM_COMMIT, PAGE_EXECUTE_READWRITE);    
    76.             WriteProcessMemory(hProcess, Param, (LPVOID)ModuleFile, 256, NULL);    
    77.   
    78.             HANDLE hThread = CreateRemoteThread(hProcess,     
    79.                 NULL,     
    80.                 NULL,     
    81.                 (LPTHREAD_START_ROUTINE)LoadLibraryW,    
    82.                 Param,     
    83.                 NULL,     
    84.                 NULL);    
    85.   
    86.             if (hThread)    
    87.             {    
    88.                 WaitForSingleObject(hThread, INFINITE);    
    89.             }    
    90.   
    91.             VirtualFreeEx(hProcess, Param , 0, MEM_RELEASE);    
    92.             CloseHandle(hThread);    
    93.             CloseHandle(hProcess);    
    94.         }    
    95.   
    96.         break;  
    97.   
    98.     case DLL_THREAD_ATTACH:  
    99.     case DLL_THREAD_DETACH:  
    100.     case DLL_PROCESS_DETACH:  
    101.         break;  
    102.     }  
    103.     return TRUE;  
    104. }  
    105.   
    106. int _stdcall Setup(void)    
    107. {    
    108.     return 1;    
    109. }    


    编译成DLL后,在运行里执行rundll32.exe X64Dll.dll,Setup,DLL会自动注入到explorer.exe进程.

    完全工程及编译好的文件点击打开链接

    顺便说下,CreateRemoteThread在WIN7下是可以用的,问题不在CreateRemoteThread,而是在OpenProcess打开进程的权限

    权限设为

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION  

    就可以了,WIN7( 32/64)测试都没问题

    http://blog.csdn.net/zwfgdlc/article/details/16918565

  • 相关阅读:
    《人件》阅读笔记五
    《人件》阅读笔记四
    《人件》阅读笔记三
    《人件》阅读笔记二
    《人件》阅读笔记一
    年报系统课堂讨论记录
    系统利益相关者描述案例
    Android开发学习记录--活动生命周期
    jQuery AJAX简介
    jQuery HTML简介
  • 原文地址:https://www.cnblogs.com/findumars/p/6345061.html
Copyright © 2011-2022 走看看