NtCreateThreadEx+HOOK win7 x64

NtCreateThreadEx+HOOK win7 x64

本文通过NtCreateThreadEx进行线程注入(网上说这个是可以跨session的,相对来说用RtlCreateUserThread可能会更好,RtlCreateUserThread是对NtCreateThreadEx的封装。)然后接上一篇文章因为微软的detours x64的是要钱的买不起,写一个x64的hook dll,同样实现win7 x64下的进程防杀。(代码都是经过测试的,在同一个session起一个应用程序,进行taskmgr.exe代码注入即可,代码来源于互联网)


struct NtCreateThreadExBuffer;
HANDLE NtCreateThreadEx(HANDLE hProcess,LPVOID lpBaseAddress, LPVOID lpSpace);

int PIDOfProcess = 0;
std::string pathToDLL = "E:\\hjx\\workspace\\hook\\nokilltest\\Release\\Nokill64.dll\0"; ///find DLL in local directory
DWORD PID = (DWORD)PIDOfProcess; ///PID
HANDLE HProcess = NULL; ///Handle to process
LPVOID LibAddr = NULL; ///Address of procedure 'LoadLibraryA'
LPVOID DllAdr = NULL; ///Address of memory in other process
HANDLE hThread = NULL; ///Handle to remote thread
int WirteStatus = 0; ///Status of writing to memory of other process

std::cout << "Get PID of process" << std::endl;
PIDOfProcess=GetProcessIdByName("taskmgr.exe");
PID = (DWORD)PIDOfProcess;

if(EnableDebugPrivilege() == TRUE)
{
std::cout << "Debug privilege was enabled with status: "<< GetLastError() << " [OK]" << std::endl;
}else std::cout << "Debug privilege was not enabled: "<< GetLastError() << " [FAILED]" << std::endl;

/*
NtOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId );*/
/// NtOpenProcess();
HProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD, FALSE, PID);
if(HProcess == NULL)
{
std::cout << "Could not find process: "<< GetLastError() << " [FAILED]" << std::endl;
return GetLastError();
} std::cout << "Process opened: [OK]" << std::endl;

DllAdr = (LPVOID)VirtualAllocEx(HProcess, NULL, pathToDLL.size() +1, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(DllAdr == NULL)
{
std::cout << "Cannot allocate memory in remote process: "<< GetLastError() << " [FAILED]" << std::endl;
return GetLastError();
} std::cout << "Region of memory in remote process allocated: [OK]" << std::endl;

WirteStatus = WriteProcessMemory(HProcess, (LPVOID)DllAdr, pathToDLL.c_str() ,pathToDLL.size()+1, NULL);
if(WirteStatus == 0)
{
std::cout << "Could not write to process's address space: "<< GetLastError() << " [FAILED]" << std::endl;
return GetLastError();
} std::cout << "A memory has written name of DLL: [OK]" << std::endl;

LibAddr = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if(LibAddr == NULL)
{
std::cout << "Unable to locate LoadLibraryA: "<< GetLastError() << " [FAILED]" << std::endl;
return GetLastError();
} std::cout << "A address of procedure LoadLibraryA has found [OK]" << std::endl;

hThread = NtCreateThreadEx(HProcess,LibAddr,DllAdr);

if(hThread == NULL)
{
std::cout << "Could not create remote thread on process: "<< GetLastError() << " [FAILED]" << std::endl;
return GetLastError();
}
}
struct NtCreateThreadExBuffer///This information is derived based on reverse engineering work.
{
ULONG Size;
ULONG Unknown1;
ULONG Unknown2;
PULONG Unknown3;
ULONG Unknown4;
ULONG Unknown5;
ULONG Unknown6;
PULONG Unknown7;
ULONG Unknown8;
};
HANDLE NtCreateThreadEx(HANDLE hProcess,LPVOID lpBaseAddress,LPVOID lpSpace)
{
///The prototype of NtCreateThreadEx from undocumented.ntinternals.com
///typ_zwracanej_wartości (__konwencja_wywolania*nazwa_wskaźnika)(typ1 argument1, typ2 argument2);
/* 2OOO, 11 November http://undocumented.ntinternals.net/
NTSYSAPI NTSTATUS NTAPI NtCreateThread(
OUT PHANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ProcessHandle,
OUT PCLIENT_ID ClientId,
IN PCONTEXT ThreadContext,
IN PINITIAL_TEB InitialTeb,
IN BOOLEAN CreateSuspended );*/
typedef LONG64 (WINAPI * functypeNtCreateThreadEx)(
PHANDLE ThreadHandle, ///Handle to thread which will be created /// OUT
ACCESS_MASK DesiredAccess, ///possible: GENERIC_WRITE GENERIC_READ GENERIC_EXECUTE GENERIC_ALL//// IN
LPVOID ObjectAttributes, /// IN,OPTIONAL
HANDLE ProcessHandle, ///Handle to our process /// IN
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
/*DWORD*/LONG64 dwStackSize,
LONG64 SizeOfStackCommit,
LONG64 SizeOfStackReserve,
LPVOID lpBytesBuffer ///pointer to initialized object of NtCreateThreadExBuffer
);
NtCreateThreadExBuffer * ntbuffer = NULL;
HANDLE hRemoteThread = NULL;
HMODULE hNtDllModule = NULL;
functypeNtCreateThreadEx funcNtCreateThreadEx = NULL;

ntbuffer = new NtCreateThreadExBuffer;
memset (ntbuffer,0,sizeof(NtCreateThreadExBuffer));///fill buffer zeros
DWORD temp1 = 0;
DWORD temp2 = 0;

ntbuffer->Size = sizeof(NtCreateThreadExBuffer);
ntbuffer->Unknown1 = 0x10003;
ntbuffer->Unknown2 = 0x8;
ntbuffer->Unknown3 = &temp2;
ntbuffer->Unknown4 = 0;
ntbuffer->Unknown5 = 0x10004;
ntbuffer->Unknown6 = 4;
ntbuffer->Unknown7 = &temp1;
ntbuffer->Unknown8 = 0;

//Get handle for ntdll which contains NtCreateThreadEx
hNtDllModule = GetModuleHandle( "ntdll.dll" );
if ( hNtDllModule == NULL )
{
std::cout << "Cannot get module ntdll.dll error: " << GetLastError() << std::endl;
return NULL;
} std::cout << "A 'ntdll.dll' module has got: "<< GetLastError() << " [OK]" << std::endl;

funcNtCreateThreadEx = (functypeNtCreateThreadEx)GetProcAddress( hNtDllModule, "NtCreateThreadEx" );
if ( !funcNtCreateThreadEx )
{
std::cout << "Cannot get procedure address error: " << GetLastError() << std::endl;
return NULL;
} std::cout << "'NtCreateThreadEx' has executed: "<< GetLastError() << " [OK]" << std::endl;

///Here is problem - when in last argument i replace NULL
funcNtCreateThreadEx( &hRemoteThread,GENERIC_ALL /*GENERIC_ALL 0x1FFFFF/*Może tu jest błąd*/, NULL, hProcess, (LPTHREAD_START_ROUTINE)lpBaseAddress, lpSpace, FALSE, NULL, NULL, NULL, NULL );
std::cout << "_______________________________________ " << std::endl;
std::cout << "NtCreateThreadEx' has status: " << GetLastError() << std::endl;
std::cout << "hRemoteThread: " << hRemoteThread << std::endl;
std::cout << "State of handle to DLL: " << hNtDllModule << std::endl;
std::cout << "Addres of prcoedure NtCreateThreadEx: " << funcNtCreateThreadEx << std::endl;
return hRemoteThread;
}

hook dll实现:


#include <windows.h>
extern HINSTANCE hAppInstance;
DWORD dwThreadId;
typedef HANDLE (WINAPI *PFNTERMINATEPROCESS)(DWORD, BOOL,DWORD);
static PVOID hookedopenprocess;
DWORD myprocessid=0;
//x64:12 x32:5
static char OldAPI[12] = {};
static char NewAPI[12] ={0x48,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0xC3};
HANDLE WINAPI MyOpenProcess(DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwProcessId)
{
if(dwProcessId != myprocessid) //也就是说,如果不是结束本进程,那么就可以放行
{
/*letgocount++;
if(letgocount==20){
OutputDebugPrintfA("LET IT GO now processid:%d myprocessid:%d",dwProcessId,Myprocessid);
letgocount=0;
}*/
WriteProcessMemory((void*)-1,hookedopenprocess,OldAPI,12,NULL);
HANDLE handle = ((PFNTERMINATEPROCESS)hookedopenprocess)(dwDesiredAccess,bInheritHandle,dwProcessId);
WriteProcessMemory((void*)-1,hookedopenprocess,NewAPI,12,NULL);
return handle;
}
OutputDebugStringA("PERMISSION DENIED");
return NULL;
}
BOOL TryInject()
{
HWND hWnd;
hWnd = FindWindow(NULL, "nokilltest");
if(hWnd==NULL)
return FALSE;
GetWindowThreadProcessId(hWnd, &myprocessid);

HMODULE hDll = GetModuleHandleA("kernel32.dll");
if(hDll==NULL)
{
OutputDebugStringA("hDll is null");
return FALSE;
}
hookedopenprocess=GetProcAddress(hDll,"OpenProcess");

DWORD64 dwJmpAddr = 0;

dwJmpAddr = (DWORD64)MyOpenProcess;
memcpy(NewAPI +2,&dwJmpAddr,8);
//换上我们的函数地址
if(!ReadProcessMemory((void*)-1,hookedopenprocess,OldAPI,12,NULL))
{
OutputDebugStringA("read process memory error");
return FALSE;
}
if(!WriteProcessMemory((void*)-1,hookedopenprocess,NewAPI,12,NULL))
{
OutputDebugStringA("write process memory error");
return FALSE;
}
return TRUE;
}
void WINAPI Inject()
{

TryInject();

}
BOOL APIENTRY DllMain( HINSTANCE hinstDLL,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
BOOL bReturnValue = TRUE;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Inject, NULL, 0, &dwThreadId);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注