原始函数是这样的

  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. windows - Cygwin和MinGW有什么区别?(MinGW从Cygwin 1.3.3版本中分离出来)

    windows - Cygwin和MinGW有什么区别? 我想让我的C ++项目跨平台,我正在考虑使用Cygwin / MinGW. 但是他们之间有什么区别呢? 另一个问题是,如果没有Cygwin / ...

  2. Sleep(0)的妙用

    在线程中,调用sleep(0)可以释放cpu时间,让线程马上重新回到就绪队列而非等待队列,sleep(0)释放当前线程所剩余的时间片(如果有剩余的话),这样可以让操作系统切换其他线程来执行,提升效率. ...

  3. ASP.NET中前台如何调用后台变量

    .Asp.Net中几种相似的标记符号: < %=...%>< %#... %>< % %>< %@ %>解释及用法 答: < %#... %> ...

  4. numpy 代码优化(一)—— 常见手段

    选择使用 numpy 库的应有之义就在于:应当以矢量化的方式(vectorized operations)来避免迭代操作(iterations),numpy 下的迭代操作执行起来十分耗时. impor ...

  5. PLC中ST语言的几种程序流程控制语句

    ST语言是IEC61131-3中规定的5中标准语言之一,目前常用见品牌的PLC都支持这种语言(施耐德,AB可以直接选择创建该类型的程序段或者功能块,西门子的略微麻烦一点),ST语言的一个好处是移植性好 ...

  6. url操作等

    取得url ?及以前: baseUrl = url.substr(0,url.indexOf('?')+1) searchParam = searchParam.slice(0, -1);//去掉最后 ...

  7. 利用WPF的ListView进行大数据量异步加载

    原文:利用WPF的ListView进行大数据量异步加载 由于之前利用Winform的ListView进行大数据量加载的时候,诟病良多,所以今天试着用WPF的ListView来做了一下,结果没有让我失望 ...

  8. crossplatform---Nodejs in Visual Studio Code 02.学习Nodejs

    1.开始 源码下载:https://github.com/sayar/NodeMVA 在线视频:https://mva.microsoft.com/en-US/training-courses/usi ...

  9. 如何删除您的注册js图书馆bower私人图书馆

    建立你自己bower 这样的私人图书馆参考http://blog.csdn.net/nsrainbow/article/details/35988611 本文 假设我们想注册自己的创作js私人图书馆图 ...

  10. asp .net Cookies

    Request.Cookies和Response.Cookies When validating cookies or cookie data from the browser you should ...