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
代码语言:javascript复制#include "windows.h"
#include "stdio.h"
#include "tchar.h"
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 system
lpszPrivilege, // 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;
else
tp.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 privilege
SetPrivilege(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位的时代 故有此章进行一些区别的介绍
红客突击队于2019年由队长k龙牵头,联合国内多位顶尖高校研究生成立。其团队从成立至今多次参加国际网络安全竞赛并取得良好成绩,积累了丰富的竞赛经验。团队现有三十多位正式成员及若干预备人员,下属联合分队数支。红客突击队始终秉承先做人后技术的宗旨,旨在打造国际顶尖网络安全团队。