小试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

posted @ 2017-01-23 22:12  findumars  Views(1563)  Comments(0Edit  收藏  举报