原始函数是这样的

  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. idea-环境配置

    显示行号 Settings->Editor->Appearance标签项,勾选Show line numbers 关闭导航 在idea14版本中,上面有个代码导航,show breadcr ...

  2. 打造开发React Native的Sublime

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

  3. 十分钟了解 spring cloud

    1 为什么需要服务发现 简单来说,服务化的核心就是将传统的一站式应用根据业务拆分成一个一个的服务,而微服务在这个基础上要更彻底地去耦合(不再共享DB.KV,去掉重量级ESB),并且强调DevOps和快 ...

  4. linux下仅仅有rman备份集的异机不同文件夹恢复

    昨天在客户那里做了一次rman异机的恢复,把生产库弄一份给測试库用,总库大概80G,总共花费了2个小时,当时客户的环境是windows 11.2.0.3,今天早晨在linux下又一次測试了一下,记录下 ...

  5. CUDA线程协作之共享存储器“__shared__”&&“__syncthreads()”

    在GPU并行编程中,一般情况下,各个处理器都需要了解其他处理器的执行状态,在各个并行副本之间进行通信和协作,这涉及到不同线程间的通信机制和并行执行线程的同步机制. 共享内存"__share_ ...

  6. c语言学习笔记(3)——输入输出

    一.基本的输入和输出函数的用法 printf()  //屏幕输出 用法: (1)printf("字符串\n"); (2)printf("输出控制符", 输出参数 ...

  7. PowerDesigner模型分类

    原文:PowerDesigner模型分类 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/zjws23786/article/details/8005 ...

  8. Rust 2017 调查报告:学习曲线是最大痛点(最大的问题是这门语言太偏底层了,现在做底层的少了。还有C这个绕不过去的存在)

    Rust 官方在社区上做了一次调查,以了解用户如何看待 Rust 的发展.调查共收到 5368 份回复,其中有 大约 2/3 的是 Rust 用户,剩下的 1/3 是非 Rust 用户,调查结果如下. ...

  9. 圆周卷积(circular convolution)

    1. 定义与概念 圆周卷积也叫循环卷积, 2. 实现(matlab) 以圆周的形式卷积两个信号: >> z = ifft(fft(x).*fft(y));

  10. 在React开发中遇到的问题——数组引用赋值

    在React开发中遇到了一个问题: 需求是在一个选择组件中选择数据mydata数组,确定后将mydata数组返回到父组件,再次打开该选择组件时,从父组件获取之前选择的数据mydata并显示为已选择. ...