64位 & Windows 内核6
前言
继续学习《逆向工程核心原理》,本篇笔记是第五部分:64位 & Windows 内核6
一、x64
1、x64处理器中的变化
含有VA的指令大小增加了4个字节
虚拟内存从4GB变成16GB
通用寄存器的数量变为18个,如下
函数调用统一为fastcall,可以传递4个参数,如下
栈不用PUSH/POP命令了,通过MOV操作寄存器和指定的栈
栈帧不用RBP,改用RSP
2、PE32+
PE32+是64位PE文件
(1)IMAGE_NT_HEADERS
主要是第三个成员不同——
IMAGE_OPTIONAL_HEADER64和IMAGE_OPTIONAL_HEADER32
其中IMAGE_FILE_HEADER主要是Machine值变了,如下图所示
而IMAGE_OPTIONAL_HEADER变化很大
Magic值从010B变为020B,作为识别32位还是64位的标志
BaseOfData删除了
ImageBase从DWORD变为ULONGLONG类型
与栈和堆有关的字段也变为ULONGLONG类型
(2)IMAGE_THUNK_DATA
大小从4个字节变为8个字节
(3)IMAGE_TLS_DIRECTORY
部分成员是VA值,扩展为8个字节
3、WinDbg
基本指令
二、内核6
kernel 6 是vista之后的系统
Win10 是kernel 10
1、会话
会话:登录后的用户环境,kernel 6引入
系统会话是0,与用户会话隔离(即第一个登录的用户是会话1,而之前是会话0)
但是会话1中的进程可以强行终止会话0中的进程
2、DLL注入
原先的用CreateRemoteThread()进行DLL注入的方法无法生效
原因是新增的API,如下:
对此,给出新的InjectDll.exe
BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege){TOKEN_PRIVILEGES tp;HANDLE hToken;LUID luid;if( !OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken) ){_tprintf(L"OpenProcessToken error: %un", GetLastError());return FALSE;}if( !LookupPrivilegeValue(NULL, // lookup privilege on local systemlpszPrivilege, // privilege to lookup&luid) ) // receives LUID of privilege{_tprintf(L"LookupPrivilegeValue error: %un", GetLastError() );return FALSE;}tp.PrivilegeCount = 1;tp.Privileges[0].Luid = luid;if( bEnablePrivilege )tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;elsetp.Privileges[0].Attributes = 0;// Enable the privilege or disable all privileges.if( !AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES) NULL,(PDWORD) NULL) ){_tprintf(L"AdjustTokenPrivileges error: %un", GetLastError() );return FALSE;}if( GetLastError() == ERROR_NOT_ALL_ASSIGNED ){_tprintf(L"The token does not have the specified privilege. n");return FALSE;}return TRUE;}typedef DWORD (WINAPI *PFNTCREATETHREADEX)(PHANDLE ThreadHandle,ACCESS_MASK DesiredAccess,LPVOID ObjectAttributes,HANDLE ProcessHandle,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,BOOL CreateSuspended,DWORD dwStackSize,DWORD dw1,DWORD dw2,LPVOID Unknown);BOOL IsVistaOrLater(){OSVERSIONINFO osvi;ZeroMemory(&osvi, sizeof(OSVERSIONINFO));osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);GetVersionEx(&osvi);if( osvi.dwMajorVersion >= 6 )return TRUE;return FALSE;}BOOL MyCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE pThreadProc, LPVOID pRemoteBuf){HANDLE hThread = NULL;FARPROC pFunc = NULL;if( IsVistaOrLater() ) // Vista, 7, Server2008{pFunc = GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtCreateThreadEx");if( pFunc == NULL ){printf("MyCreateRemoteThread() : GetProcAddress("NtCreateThreadEx") failed!!! [%d]n",GetLastError());return FALSE;}((PFNTCREATETHREADEX)pFunc)(&hThread,0x1FFFFF,NULL,hProcess,pThreadProc,pRemoteBuf,FALSE,NULL,NULL,NULL,NULL);if( hThread == NULL ){printf("MyCreateRemoteThread() : NtCreateThreadEx() failed!!! [%d]n", GetLastError());return FALSE;}}else // 2000, XP, Server2003{hThread = CreateRemoteThread(hProcess,NULL,0,pThreadProc,pRemoteBuf,0,NULL);if( hThread == NULL ){printf("MyCreateRemoteThread() : CreateRemoteThread() failed!!! [%d]n", GetLastError());return FALSE;}}if( WAIT_FAILED == WaitForSingleObject(hThread, INFINITE) ){printf("MyCreateRemoteThread() : WaitForSingleObject() failed!!! [%d]n", GetLastError());return FALSE;}return TRUE;}BOOL InjectDll(DWORD dwPID, char *szDllName){HANDLE hProcess = NULL;LPVOID pRemoteBuf = NULL;FARPROC pThreadProc = NULL;DWORD dwBufSize = strlen(szDllName)+1;if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) ){printf("[ERROR] OpenProcess(%d) failed!!! [%d]n",dwPID, GetLastError());return FALSE;}pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize,MEM_COMMIT, PAGE_READWRITE);WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName,dwBufSize, NULL);pThreadProc = GetProcAddress(GetModuleHandle(L"kernel32.dll"),"LoadLibraryA");if( !MyCreateRemoteThread(hProcess, (LPTHREAD_START_ROUTINE)pThreadProc, pRemoteBuf) ){printf("[ERROR] MyCreateRemoteThread() failed!!!n");return FALSE;}VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);CloseHandle(hProcess);return TRUE;}int main(int argc, char *argv[]){// adjust privilegeSetPrivilege(SE_DEBUG_NAME, TRUE);// InjectDll.exe <PID> <dll_path>if( argc != 3 ){printf("usage : %s <PID> <dll_path>n", argv[0]);return 1;}if( !InjectDll((DWORD)atoi(argv[1]), argv[2]) ){printf("InjectDll() failed!!!n");return 1;}printf("InjectDll() succeeded!!!n");return 0;}
结语
主要是本书编写的时候刚好是32位进入64位的时代
故有此章进行一些区别的介绍
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……




还没有评论,来说两句吧...