您的位置:首页 > 其它

小试X64 inline HOOK,hook explorer.exe--->CreateProcessInternalW监视进程创建

2013-11-24 14:20 519 查看
原始函数是这样的

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)测试都没问题
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: