原始函数是这样的

  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. CreateFileMapping和MapViewOfFile函数

    大家都是到PG是分布式网络事务处理数据库,与其他数据库优点之一就在于服务器与客户的交流是一对一的,所谓一对一是指,针对客户的每一连接服务器都会产生一个进程为其服务,那么问题就来了,这些进程间是如何交互 ...

  2. nth-child与nth-of-type

    nth-of-type这个CSS3伪类还从来没有用过,今天好好研究一番,发现还是有用的.现在下面的Demo <!DOCTYPE html> <html> <head> ...

  3. hadoop 3.x Replication与Availability不一致

    看下面的文字前先确保你的Replication值不大于你设置的虚拟机数量 如图,显示的副本数为3,但是实际可用的只有一台机器,查看了下hadoop003,hadoop004两台机器,果然没有存储数据, ...

  4. Linux常用 bash

    学会Linux常用 bash命令 目录 基本操作1.1. 文件操作1.2. 文本操作1.3. 目录操作1.4. SSH, 系统信息 & 网络操作 基本 Shell 编程2.1. 变量2.2.  ...

  5. TableLayout表格布局

    1.本节学习路线图 路线图分析: 从上面的路线图,可以看出TableLayout的用法还是很简单的,无非就是确定表格的行数,以及使用 那三个属性来设置每一行中的第某列的元素隐藏,拉伸,或者收缩即可! ...

  6. elasticsearch-jdbc

    jprante/elasticsearch-jdbc The Java Database Connection (JDBC) importer allows to fetch data from JD ...

  7. Troubleshooting routing topology based on a reference topology

    In one embodiment, a computing device (e.g., border router or network management server) transmits a ...

  8. [Linux] ssh秘钥对免密码登陆

    准备两台linux服务器 a和b , 在a上使用ssh命令登陆b服务器 , 并且不用 输入密码 1.在a服务器上,比如是root用户 ,进去/root/.ssh目录 ,没有就创建, 就是进入家目录的. ...

  9. SWIFT学习笔记02

    1.//下面的浮点文字等于十进制12.1875: let decimalDouble = 12.1875 let exponentDouble = 1.21875e1 let hexadecimalD ...

  10. Android 项目框架功能整理记录

    用来记录自己在项目用到的框架工具等,新人新记录,希望能对你搭建项目有所帮助 常用框架整理 视图绑定注解框架: butterKnife 网络请求框架: OKHttp 图片加载缓存:Gilde 数据格式解 ...