原始函数是这样的

  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大部分情况下会出错.所以我们换一种方法.

  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字节改成跳转指令,正好

  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字节指令,不会破坏后面的指令.

写入跳转指令后

  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,效果样的,只是代码多几行而已.

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

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

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

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

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

权限设为

  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

小试X64 inline HOOK,hook explorer.exe--->CreateProcessInternalW监视进程创建的更多相关文章

  1. Hook任务栏时钟窗口(原理其实很简单,就是注入DLL到时钟窗口进程(explorer.exe))

    用过一些日历软件的小伙伴应该都知道它们都实现了在时钟窗口上的Hook,也就是屏蔽了系统原有的功能,实现自己的功能 某日历软件Hook时钟窗口后的效果 经过一番研究,发现原理其实很简单,就是注入DLL到 ...

  2. Google调用explorer.exe打开本地文件

    给IE浏览器地址栏输个本地文件路径,会自动用explorer.exe打开,这个挺好的,但是IE对jQuery稍微高点的版本不怎么待见,只好自己给Google折腾一个调用explorer的功能----- ...

  3. [转]C#中调用资源管理器(Explorer.exe)打开指定文件夹 + 并选中指定文件 + 调用(系统默认的播放类)软件(如WMP)打开(播放歌曲等)文件

    原文:http://www.crifan.com/csharp_call_explorer_to_open_destinate_folder_and_select_specific_file/ C#中 ...

  4. 怎样用delphi关闭并重新启动 explorer.exe进程

    uses Tlhelp32; function KillTask(ExeFileName:string):integer; const PROCESS_TERMINATE = $0001; var C ...

  5. 以不同用户身份运行程序,/savecred只需要输入一次密码(GetTokenByName取得EXPLORER.EXE的令牌,然后调用CreateProcessAsUser,而且使用LoadUserProfile解决另存文件的问题)good

    http://blog.sina.com.cn/s/blog_65977dde0100s7tm.html ----------------------------------------------- ...

  6. 关于电脑开机不出现桌面即不启动explorer.exe桌面程序--------正解

    针对这个问题,一开始的思路是,把自己写的界面小程序(Win.exe)放在Windows启动文件夹中, 效果到是界面程序自启动了,但是还是先出现的桌面,然后才的启动的界面程序(Win.exe),并不是我 ...

  7. explorer.exe进程简单介绍

    explorer.exe是Windows程序管理器或者Windows资源管理器,它用于管理Windows图形壳,包括开始菜单.任务栏.桌面和文件管理.不过也发现有大量的恶意病毒木马插入到explore ...

  8. win8 无法显示桌面,运行explorer.exe 提示 0xc0000018 异常 解决办法

    win8 无法显示桌面,运行explorer.exe 提示 0xc0000018 错误 解决方法改注册表.这个就是DB03.EXE引起的. cmd打开注册表:regedit找到注册表"HKE ...

  9. [转]Explorer.exe的命令行参数

    本文来自:Explorer.exe的命令行参数 摘要 本文讲述explorer.exe(资源管理器)的命令行. 语法 EXPLORER.EXE [/n][/e][,/root,<object&g ...

随机推荐

  1. jws 问题总结

    问题1.wsimport不是内部或外部命令 今天执行wsimport时报了wsimport报了不是内部或外部命令的错误,第一反应是检查环境变量,没发现什么问题,执行java  -version也正常, ...

  2. Dropout 理论基础与实战细节

    Dropout: A Simple Way to Prevent Neural Networks from Overfitting 对于 dropout 层,在训练时节点保留率(keep probab ...

  3. Java易混点记录

    1.Java 默认将所有成员变量和成员方法与 this 关联在一起,因此使用 this 在某些情况下是多余的. 2.只要类存在,程序就可以访问该类的类变量,语法如下: 类.类变量. 只要实例存在,程序 ...

  4. 打造开发React Native的Sublime

     之前一年多一直用Sublime Text做前端开发,最近做React开发,发现不太好用,就尝试其他编辑器.WebStorm和VS Code都用过,WebStorm基本不用装插件,可以直接用,但用习惯 ...

  5. Myeclipse 6.5 增加对 JavaEE 6 的支持

    网上找了一会没发现什么好的方法一想干脆自己动手丰衣足食,搜索MYECLIPSE_JAVAEE_5_CONTAINER找到了 MyEclipse6.5\myeclipse\eclipse\plugins ...

  6. Vim 写 iOS App

    Vim 写 iOS App 我们都知道 Vim 和 Emacs 都是文本编辑器中的上古神器,你也许用 ctags,cscopes 配合 Vim 完成过大型 C 或者 C++ 的开发,你也许配合过其他插 ...

  7. 解决android模拟器无法上网问题

    1.  将 android的tool增加到,windows 环境变量 path中, D:\Android\android-sdk_r3-windows\android-sdk-windows\tool ...

  8. .net程序运行流程

    程序员用.net开发的程序要在计算机上运行,首先程序经过编译后,会生成机器指令,一般以一个文件的形式保存,这个文件在外存储器上(存储器分外存与内存.外存:硬盘,U盘等:) 然后cpu会把硬盘上的文件读 ...

  9. Math对象重新整理

    注意:Math 对象是一个固有的对象,无需创建它,直接把 Math 作为对象使用就可以调用其所有属性和方法.这是它与Date,String对象的区别. Math对象的属性 --Math对象包含的属性大 ...

  10. 阐述php(五岁以下儿童) 注意事项和使用功能

    1.函数声明 <?php /** * function 函数名(參数1, 參数2.... ){ * 函数体; * 返回值; * } */ $sum = sum(3, 4); echo $sum; ...