📄 r32r0.cpp
字号:
SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
&OldDACLs,
NULL,
&SecurityDescriptor
);
if ( ret != ERROR_SUCCESS )
{
PrintWin32Error( "GetSecurityInfo() failed", ret );
boolean_ret = FALSE;
goto SetPhysicalMemoryDACLs_return;
}
/*
* DWORD SetEntriesInAcl
* (
* ULONG cCountOfExplicitEntries,
* PEXPLICIT_ACCESS pListOfExplicitEntries,
* PACL OldAcl,
* PACL *NewAcl
* );
*/
ZeroMemory( &Access, sizeof( Access ) );
Access.grfAccessPermissions = SECTION_ALL_ACCESS;
Access.grfAccessMode = GRANT_ACCESS;
Access.grfInheritance = NO_INHERITANCE;
Access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
Access.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
Access.Trustee.TrusteeType = TRUSTEE_IS_USER;
Access.Trustee.ptstrName = ptstrName;
ret = SetEntriesInAcl( 1, &Access, OldDACLs, &NewDACLs );
if ( ret != ERROR_SUCCESS )
{
PrintWin32Error( "SetEntriesInAcl() failed", ret );
boolean_ret = FALSE;
goto SetPhysicalMemoryDACLs_return;
}
/*
* DWORD SetSecurityInfo
* (
* HANDLE handle,
* SE_OBJECT_TYPE ObjectType,
* SECURITY_INFORMATION SecurityInfo,
* PSID psidOwner,
* PSID psidGroup,
* PACL pDacl,
* PACL pSacl
* );
*/
ret = SetSecurityInfo
(
handle,
SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
NewDACLs,
NULL
);
if ( ret != ERROR_SUCCESS )
{
PrintWin32Error( "SetSecurityInfo() failed", ret );
boolean_ret = FALSE;
goto SetPhysicalMemoryDACLs_return;
}
SetPhysicalMemoryDACLs_return:
if ( NewDACLs != NULL )
{
LocalFree( NewDACLs );
NewDACLs = NULL;
}
if ( SecurityDescriptor != NULL )
{
LocalFree( SecurityDescriptor );
SecurityDescriptor = NULL;
}
return( boolean_ret );
} /* end of SetPhysicalMemoryDACLs */
static VOID UnmapPhysicalMemory ( IN PVOID LinearAddress )
{
NTSTATUS status;
char error_msg[256];
/*
* NTSTATUS ZwUnmapViewOfSection
* (
* IN HANDLE ProcessHandle,
* IN PVOID BaseAddress
* );
*/
status = ZwUnmapViewOfSection( ( HANDLE )-1, LinearAddress );
if ( !NT_SUCCESS( status ) )
{
sprintf( error_msg, "Could not unmap LinearAddress from 0x%08X", ( unsigned int )LinearAddress );
PrintZwError( error_msg, status );
}
return;
} /* end of UnmapPhysicalMemory */
static void usage ( char *arg )
{
fprintf( stderr, "Usage: %s [-h] [-g Gdtrbase] [-a Address] [-l Length]\n", arg );
exit( EXIT_FAILURE );
} /* end of usage */
int main ( int argc, char * argv[] )
{
int i;
GATEDESCRIPTOR *callgate = NULL;
GATEDESCRIPTOR orig_callgate;
unsigned short int selector = RING0_CODE_SELECTOR;
ULONG Ring0CodeLength = 0;
CALL_ARG_0 call_arg_0;
CALL_ARG_1 call_arg_1;
CALL_ARG_2 call_arg_2;
PSEUDODESCRIPTOR GDTR;
WORD CURRENT_CS, CURRENT_DS, CURRENT_ES, CURRENT_SS, CURRENT_FS;
HANDLE mem = NULL;
PVOID orig_GdtMapAddress = NULL;
PVOID GdtMapAddress = NULL;
ULONG GdtMapSize = 0;
PHYSICAL_ADDRESS orig_GdtPhysicalAddress;
PHYSICAL_ADDRESS GdtPhysicalAddress;
ULONG Address = 0;
ULONG Length = 0;
unsigned char buf[8192];
ZeroMemory( &GDTR, sizeof( GDTR ) );
/*
* 从argv[1]开始循环处理命令行参数
*/
for ( i = 1; i < argc; i++ )
{
/*
* 同时支持-和/两种引入命令行参数的方式
*/
if ( ( argv[i][0] == '-' ) || ( argv[i][0] == '/' ) )
{
/*
* 在这个字节上,大小写不敏感
*/
switch ( tolower( argv[i][1] ) )
{
case 'a':
/*
* 欲访问的线性地址
*/
Address = strtoul( argv[++i], NULL, 0 );
break;
case 'g':
/*
* 有些环境中sgdt失灵,可通过-g指定GDTR的基址。但此时指定
* 的limit很冒险。
*/
GDTR.base = ( unsigned int )strtoul( argv[++i], NULL, 0 );
GDTR.limit = 0x03FF;
break;
case 'l':
Length = strtoul( argv[++i], NULL, 0 );
break;
case 'h':
case '?':
default:
usage( argv[0] );
} /* end of switch */
}
else
{
usage( argv[0] );
}
} /* end of for */
if ( GDTR.base < 0x80000000 || GDTR.base >= 0xa0000000 )
{
/*
* 获取GDTR寄存器的值。这个动作无法在VMware Workstation 3.2中完成,返
* 回的线性基址不正确,必须在真实主机上测试。
*/
__asm
{
sgdt GDTR
mov CURRENT_CS,cs
mov CURRENT_DS,ds
mov CURRENT_ES,es
mov CURRENT_SS,ss
mov CURRENT_FS,fs
}
printf( "GDTR.base = 0x%08X\n"
"GDTR.limit = 0x%04X\n"
"CURRENT_CS = 0x%04X\n"
"CURRENT_DS = 0x%04X\n"
"CURRENT_ES = 0x%04X\n"
"CURRENT_SS = 0x%04X\n"
"CURRENT_FS = 0x%04X\n",
GDTR.base, GDTR.limit, CURRENT_CS, CURRENT_DS,
CURRENT_ES, CURRENT_SS, CURRENT_FS );
if ( GDTR.base < 0x80000000 || GDTR.base >= 0xa0000000 )
{
fprintf( stderr, "Checking your GDTR.base( 0x%08X )\n", GDTR.base );
return( EXIT_FAILURE );
}
}
/*
* 如果没有指定线性地址,缺省处理GDT
*/
if ( 0 == Address )
{
Address = GDTR.base;
}
if ( FALSE == LocateNtdllEntry() )
{
fprintf( stderr, "LocateNtdllEntry() failed\n" );
return( EXIT_FAILURE );
}
if ( FALSE == LocateNtoskrnlEntry() )
{
fprintf( stderr, "LocateNtoskrnlEntry() failed\n" );
return( EXIT_FAILURE );
}
ZeroMemory( &system_info, sizeof( system_info ) );
GetSystemInfo( &system_info );
printf( "PageSize = 0x%08X\n"
"AllocationGranularity = 0x%08X\n",
system_info.dwPageSize, system_info.dwAllocationGranularity );
/*
* 如果没有指定长度,缺省按一页处理。
*/
if ( 0 == Length )
{
Length = system_info.dwPageSize;
}
if ( Length > sizeof( buf ) )
{
Length = sizeof( buf );
}
/*
* GDTR.limit对应的是最后有效偏移,不要先增一再强制类型转换,否则可能
* 发生短整型溢出,这是编译器相关的。
*/
GdtMapSize = ( ULONG )GDTR.limit + 1;
ZeroMemory( &orig_GdtPhysicalAddress, sizeof( orig_GdtPhysicalAddress ) );
ZeroMemory( &GdtPhysicalAddress, sizeof( GdtPhysicalAddress ) );
/*
* 为映射GDT作准备
*/
orig_GdtPhysicalAddress = PrivateMmGetPhysicalAddress( ( PVOID )GDTR.base );
if ( orig_GdtPhysicalAddress.LowPart == 0 )
{
fprintf( stderr, "orig_GdtPhysicalAddress.LowPart == 0\n" );
return( EXIT_FAILURE );
}
GdtPhysicalAddress = orig_GdtPhysicalAddress;
/*
* 为读写DACLs而打开句柄
*/
if ( ( mem = OpenPhysicalMemory( READ_CONTROL | WRITE_DAC ) ) == NULL )
{
return( EXIT_FAILURE );
}
else
{
SetPhysicalMemoryDACLs( mem, "CURRENT_USER" );
ZwClose( mem );
mem = NULL;
}
/*
* 试图读写打开"\Device\PhysicalMemory"
*/
if ( ( mem = OpenPhysicalMemory( SECTION_MAP_READ | SECTION_MAP_WRITE ) ) == NULL )
{
return( EXIT_FAILURE );
}
/*
* 读/写映射GDT
*/
if ( TRUE == MapPhysicalMemory( mem, &GdtMapAddress, &GdtMapSize, &GdtPhysicalAddress, PAGE_READWRITE ) )
{
orig_GdtMapAddress = ( unsigned char * )GdtMapAddress + ( orig_GdtPhysicalAddress.LowPart - GdtPhysicalAddress.LowPart );
/*
* 搜索空闲描述符并设置调用门
*/
callgate = InstallCallgate( ( ULONG )orig_GdtMapAddress,
( ULONG )GDTR.limit,
( DWORD )Ring0Code,
&orig_callgate );
if ( NULL != callgate )
{
/*
* 指向GDT中调用门的选择子,RPL等于0。
*/
selector = ( unsigned short int )( ( unsigned char * )callgate - ( unsigned char * )orig_GdtMapAddress );
printf( "idle selector = 0x%04X\n", selector );
/*
* 获取Ring 0权限,执行Ring 0代码
*/
ZeroMemory( &call_arg_0, sizeof( call_arg_0 ) );
Ring0CodeLength = ( ULONG )( ( unsigned char * )SetPhysicalMemoryDACLs - ( unsigned char * )Ring0Code );
ExecuteRing0Code( ( PVOID )Ring0Code, Ring0CodeLength, selector, 0, &call_arg_0 );
printf( "CR0 = 0x%08X\n"
"CR2 = 0x%08X\n"
"CR3 = 0x%08X\n"
"DR0 = 0x%08X\n"
"DR1 = 0x%08X\n"
"DR2 = 0x%08X\n"
"DR3 = 0x%08X\n"
"DR6 = 0x%08X\n"
"DR7 = 0x%08X\n",
call_arg_0.cr0, call_arg_0.cr2, call_arg_0.cr3,
call_arg_0.dr0, call_arg_0.dr1, call_arg_0.dr2,
call_arg_0.dr3, call_arg_0.dr6, call_arg_0.dr7 );
ZeroMemory( &call_arg_1, sizeof( call_arg_1 ) );
call_arg_1.LinearAddress = ( PVOID )( GDTR.base );
ExecuteRing0Code( ( PVOID )Ring0Code, Ring0CodeLength, selector, 1, &call_arg_1 );
printf( "GDTR.base(Physical) = 0x%08X\n", call_arg_1.PhysicalAddress.LowPart );
ZeroMemory( &call_arg_1, sizeof( call_arg_1 ) );
call_arg_1.LinearAddress = ( PVOID )0xc0300000;
ExecuteRing0Code( ( PVOID )Ring0Code, Ring0CodeLength, selector, 1, &call_arg_1 );
/*
* 注意与CR3的值作比较,如果没出错的话,CR3 == PDR
*/
printf( "PDR(Physical) = 0x%08X\n", call_arg_1.PhysicalAddress.LowPart );
ZeroMemory( &call_arg_2, sizeof( call_arg_2 ) );
/*
* 如果Address导致异常,结果未知,别问我。
*/
call_arg_2.src = ( PVOID )Address;
call_arg_2.dst = ( PVOID )buf;
call_arg_2.len = Length;
ExecuteRing0Code( ( PVOID )Ring0Code, Ring0CodeLength, selector, 2, &call_arg_2 );
outputBinary( stdout, ( const unsigned char * )call_arg_2.dst, ( const size_t )call_arg_2.len );
/*
* 恢复被征用的"空闲"描述符
*/
memcpy( callgate, &orig_callgate, sizeof( GATEDESCRIPTOR ) );
}
/*
* 解除对GDT的映射
*/
UnmapPhysicalMemory( GdtMapAddress );
}
if ( mem != NULL )
{
ZwClose( mem );
mem = NULL;
}
return( EXIT_SUCCESS );
} /* end of main */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -