原始函数是这样的
- kernel32!CreateProcessInternalW:
- 00000000`7738e750 4c8bdc mov r11,rsp
- 00000000`7738e753 53 push rbx
- 00000000`7738e754 56 push rsi
- 00000000`7738e755 57 push rdi
- 00000000`7738e756 4154 push r12
- 00000000`7738e758 4155 push r13
- 00000000`7738e75a 4156 push r14
- 00000000`7738e75c 4157 push r15
- 00000000`7738e75e 4881ec400b0000 sub rsp,0B40h
- 00000000`7738e765 488b0564cc0e00 mov rax,qword ptr [kernel32!local_unwind+0x606b1 (00000000`7747b3d0)]
跟32位一样,在函数入口写入跳转指令,跟32不一样的是,不能再用之前的E9 xx xx xx xx这样的指令了,E9不支持64位地址跳转,最大只能支持到32位,
直接用E9大部分情况下会出错.所以我们换一种方法.
- mov rax,0x1122334455667788
- jmp rax
机器码是48 b8 8877665544332211 ffe0总共占了12个字节,不是我们之前用E9跳转的5字节了.
最前面的48叫REX Prefix,大家可以GOOGLE下,4是固定的,8表示使用64位寄存器.
如果没有前面的48就变成了mov eax, 0x1122334455667788了,使用32位寄存器.
我们需要把函数前面12字节改成跳转指令,正好
- 00000000`7738e750 4c8bdc mov r11,rsp
- 00000000`7738e753 53 push rbx
- 00000000`7738e754 56 push rsi
- 00000000`7738e755 57 push rdi
- 00000000`7738e756 4154 push r12
- 00000000`7738e758 4155 push r13
- 00000000`7738e75a 4156 push r14
这12个字节是完整的7条指令,写入12字节指令,不会破坏后面的指令.
写入跳转指令后
- kernel32!CreateProcessInternalW:
- 00000000`7738e750 48b8001055fbfe070000 mov rax,offset x64dll!FakeCreateProcessInternal (000007fe`fb551000)
- 00000000`7738e75a ffe0 jmp rax
- 00000000`7738e75c 4157 push r15
- 00000000`7738e75e 4881ec400b0000 sub rsp,0B40h
- 00000000`7738e765 488b0564cc0e00 mov rax,qword ptr [kernel32!local_unwind+0x606b1 (00000000`7747b3d0)]
- 00000000`7738e76c 4833c4 xor rax,rsp
- 00000000`7738e76f 48898424300b0000 mov qword ptr [rsp+0B30h],rax
- 00000000`7738e777 4889a42438050000 mov qword ptr [rsp+538h],rsp
完整代码如下.
少NTDLL.h的朋友可以去搜索下载,也可以把RtlAdjustPrivilege替换成AdjustTokenPrivileges,效果样的,只是代码多几行而已.
声明:本人很菜,水平有限,汇编功底也是相当的水,如发现有误人子弟之处,敬请指正.若您有更好的方法也请多多指教.
- #include <stdio.h>
- #include <tchar.h>
- #include <windows.h>
- #include <shlwapi.h>
- #include <ntdll.h>
- #pragma comment(lib, "shlwapi.lib")
- #define CODE_LEN 12
- TCHAR ModuleFile[MAX_PATH];
- DWORD dwOldProtect;
- BYTE OldCode[CODE_LEN] = {0x90};
- 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);
- __CreateProcessInternal pfnCreateProcess = 0;
- 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)
- {
- MessageBox(NULL, lpCommandLine, lpApplicationName, MB_ICONASTERISK);
- return pfnCreateProcess(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation, hNewToken);
- }
- BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module
- DWORD fdwReason, // reason for calling function
- LPVOID lpReserved ) // reserved
- {
- switch( fdwReason )
- {
- case DLL_PROCESS_ATTACH:
- ::DisableThreadLibraryCalls(hinstDLL);
- GetModuleFileName(NULL, ModuleFile, _countof(ModuleFile));
- if (StrRStrI(ModuleFile, 0, TEXT("explorer.exe")))
- {
- pfnCreateProcess = (__CreateProcessInternal)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "CreateProcessInternalW");
- ::VirtualProtect(pfnCreateProcess, CODE_LEN, PAGE_EXECUTE_READWRITE, &dwOldProtect);
- memcpy(OldCode, pfnCreateProcess, CODE_LEN);
- memset(pfnCreateProcess, 0x90, CODE_LEN);
- /*
- mov rax, FakeCreateProcessInternal
- jmp rax
- */
- *(LPWORD)pfnCreateProcess = 0xb848;
- *(INT64*)((INT64)pfnCreateProcess+2) = (INT64)FakeCreateProcessInternal;
- *(LPWORD)((INT64)pfnCreateProcess+10) = 0xe0ff;
- ::VirtualProtect(pfnCreateProcess, CODE_LEN, dwOldProtect, NULL);
- pfnCreateProcess = (__CreateProcessInternal)VirtualAlloc(NULL, CODE_LEN+12, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
- memcpy(pfnCreateProcess, OldCode, CODE_LEN);
- /*
- mov rax, CreateProcessInternalW + CODE_LEN
- jmp rax
- */
- *(LPWORD)((INT64)pfnCreateProcess+CODE_LEN) = 0xb848;
- *(INT64*)((INT64)pfnCreateProcess+CODE_LEN+2) = (INT64)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "CreateProcessInternalW")+CODE_LEN;
- *(LPWORD)((INT64)pfnCreateProcess+CODE_LEN+10) = 0xe0ff;
- }
- else if (StrRStrI(ModuleFile, 0, TEXT("Rundll32.exe")))
- {
- DWORD dwProcessId = 0;
- HANDLE hProcess = 0;
- HWND hwndDeskTop;
- hwndDeskTop = FindWindow(TEXT("ProgMan"), NULL);
- GetModuleFileName(hinstDLL, ModuleFile, _countof(ModuleFile));
- GetWindowThreadProcessId(hwndDeskTop, &dwProcessId);
- BOOLEAN bEnable;
- ::RtlAdjustPrivilege(0x13, 1, 0, &bEnable);
- if (dwProcessId)
- {
- hProcess = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, NULL, dwProcessId);
- }
- LPVOID Param = VirtualAllocEx(hProcess, NULL, 256, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
- WriteProcessMemory(hProcess, Param, (LPVOID)ModuleFile, 256, NULL);
- HANDLE hThread = CreateRemoteThread(hProcess,
- NULL,
- NULL,
- (LPTHREAD_START_ROUTINE)LoadLibraryW,
- Param,
- NULL,
- NULL);
- if (hThread)
- {
- WaitForSingleObject(hThread, INFINITE);
- }
- VirtualFreeEx(hProcess, Param , 0, MEM_RELEASE);
- CloseHandle(hThread);
- CloseHandle(hProcess);
- }
- break;
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- case DLL_PROCESS_DETACH:
- break;
- }
- return TRUE;
- }
- int _stdcall Setup(void)
- {
- return 1;
- }
编译成DLL后,在运行里执行rundll32.exe X64Dll.dll,Setup,DLL会自动注入到explorer.exe进程.
完全工程及编译好的文件点击打开链接
顺便说下,CreateRemoteThread在WIN7下是可以用的,问题不在CreateRemoteThread,而是在OpenProcess打开进程的权限
权限设为
- 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