原始函数是这样的

  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. scala 通过apply创建类的对象

    package cn.scala_base.oop.scalaobject; class Boy(name: String) { private var age: Int = 0; println(n ...

  2. 还是Qt 通过stylesheet或者palette设置背景色的问题

    关于Qt,设置一个widget的背景色后,希望子对象不受影响. 很久以前在QtForum上问过一个问题:http://www.qtforum.org/post/94103/setting-backgr ...

  3. [Spring Boot 系列] 集成maven和Spring boot的profile 专题

    maven中配置profile节点: <project> .... <profiles> <profile> <!-- 生产环境 --> <id& ...

  4. Mybatis动态建表

    在网上查了很多,都说Mybatis不支持动态建表,心凉了一节.还好找到这么一篇,找到了希望:http://www.zzzyk.com/show/ec5660d9cf1071b3.htm 经过在mysq ...

  5. Cache memory power reduction techniques

    Methods and apparatus to provide for power consumption reduction in memories (such as cache memories ...

  6. SICP 锻炼 (1.40)解决摘要

    SICP 锻炼1.40 是一个休闲的工作非常easy,但它看起来很复杂,单的一道题. 题目原题例如以下: 请定义一个过程cubic, 它和newtons-method过程一起使用在以下形式的表达式里: ...

  7. python 教程 第二十一章、 扩展Python

    第二十一章. 扩展Python /* D:\Python27\Lib\Extest-1.0\Extest2.c */ #include <stdio.h> #include <std ...

  8. cocos2dx 2.2.3 xcode5.0,新mac项目错误

    cocos2dx 2.2.3 xcode5.0,新建mac项目报错 Undefined symbols for architecture x86_64:   "cocos2d::extens ...

  9. JS 两种数组类型

    <!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...

  10. OpenGL红宝书附带源码编译问题集锦

    以下所有源码均在win7,VS2008环境下测试.下不再赘述. 1.所有的.c扩展名请改为.cpp扩展名,以避免不可预测的错误. 想知道会出现什么不可预测的错误..请见我上一篇Blog... 2.如果 ...