1
0
mirror of https://github.com/wine-mirror/wine synced 2024-07-08 03:45:57 +00:00

ntdll: Implement NtQueryVirtualMemory(MemoryImageInformation).

This commit is contained in:
Alexandre Julliard 2023-07-03 10:58:47 +02:00
parent 884cff8214
commit a5ff427acb
9 changed files with 149 additions and 3 deletions

View File

@ -2483,7 +2483,6 @@ static void test_query_image_information(void)
&info, sizeof(info), &len );
if (status == STATUS_INVALID_INFO_CLASS)
{
todo_wine
win_skip( "MemoryImageInformation not supported\n" );
NtUnmapViewOfSection( NtCurrentProcess(), ptr );
return;
@ -2578,6 +2577,7 @@ static void test_query_image_information(void)
offset.QuadPart = 0;
status = NtMapViewOfSection( mapping, NtCurrentProcess(), &ptr, 0, 0, &offset, &size, 1, 0, PAGE_READONLY );
ok( status == STATUS_IMAGE_NOT_AT_BASE, "Unexpected status %08lx\n", status );
todo_wine
ok( size == 0x4000, "wrong size %Ix\n", size );
NtClose( mapping );
@ -2589,6 +2589,7 @@ static void test_query_image_information(void)
ok( info.ImageBase == ptr, "wrong image base %p/%p\n", info.ImageBase, ptr );
ok( info.SizeOfImage == nt->OptionalHeader.SizeOfImage, "wrong size %Ix/%x\n",
info.SizeOfImage, (UINT)nt->OptionalHeader.SizeOfImage );
todo_wine
ok( info.ImagePartialMap, "wrong partial map\n" );
ok( !info.ImageNotExecutable, "wrong not executable\n" );
ok( info.ImageSigningLevel == 0 || info.ImageSigningLevel == 12,
@ -2606,6 +2607,7 @@ static void test_query_image_information(void)
offset.QuadPart = 0;
status = NtMapViewOfSection( mapping, NtCurrentProcess(), &ptr, 0, 0, &offset, &size, 1, 0, PAGE_READONLY );
ok( status == STATUS_IMAGE_NOT_AT_BASE, "Unexpected status %08lx\n", status );
todo_wine
ok( size == 0x5000, "wrong size %Ix\n", size );
NtClose( mapping );
@ -2617,6 +2619,7 @@ static void test_query_image_information(void)
ok( info.ImageBase == ptr, "wrong image base %p/%p\n", info.ImageBase, ptr );
ok( info.SizeOfImage == nt->OptionalHeader.SizeOfImage, "wrong size %Ix/%x\n",
info.SizeOfImage, (UINT)nt->OptionalHeader.SizeOfImage );
todo_wine
ok( info.ImagePartialMap, "wrong partial map\n" );
ok( !info.ImageNotExecutable, "wrong not executable\n" );
ok( info.ImageSigningLevel == 0 || info.ImageSigningLevel == 12,

View File

@ -4967,6 +4967,40 @@ static unsigned int get_memory_section_name( HANDLE process, LPCVOID addr,
return status;
}
static unsigned int get_memory_image_info( HANDLE process, LPCVOID addr, MEMORY_IMAGE_INFORMATION *info,
SIZE_T len, SIZE_T *res_len )
{
unsigned int status;
if (len < sizeof(*info)) return STATUS_INFO_LENGTH_MISMATCH;
memset( info, 0, sizeof(*info) );
SERVER_START_REQ( get_image_view_info )
{
req->process = wine_server_obj_handle( process );
req->addr = wine_server_client_ptr( addr );
status = wine_server_call( req );
if (!status && reply->base)
{
info->ImageBase = wine_server_get_ptr( reply->base );
info->SizeOfImage = reply->size;
info->ImageSigningLevel = 12;
}
}
SERVER_END_REQ;
if (status == STATUS_NOT_MAPPED_VIEW)
{
MEMORY_BASIC_INFORMATION basic_info;
status = get_basic_memory_info( process, addr, &basic_info, sizeof(basic_info), NULL );
if (status || basic_info.State == MEM_FREE) status = STATUS_INVALID_ADDRESS;
}
if (!status && res_len) *res_len = sizeof(*info);
return status;
}
/***********************************************************************
* NtQueryVirtualMemory (NTDLL.@)
@ -4995,6 +5029,9 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
case MemoryRegionInformation:
return get_memory_region_info( process, addr, buffer, len, res_len );
case MemoryImageInformation:
return get_memory_image_info( process, addr, buffer, len, res_len );
case MemoryWineUnixFuncs:
case MemoryWineUnixWow64Funcs:
if (len != sizeof(unixlib_handle_t)) return STATUS_INFO_LENGTH_MISMATCH;

View File

@ -190,6 +190,23 @@ typedef struct
MEMORY_WORKING_SET_EX_BLOCK32 VirtualAttributes;
} MEMORY_WORKING_SET_EX_INFORMATION32;
typedef struct
{
ULONG ImageBase;
ULONG SizeOfImage;
union
{
ULONG ImageFlags;
struct
{
ULONG ImagePartialMap : 1;
ULONG ImageNotExecutable : 1;
ULONG ImageSigningLevel : 4;
ULONG Reserved : 26;
};
};
} MEMORY_IMAGE_INFORMATION32;
typedef struct
{
NTSTATUS ExitStatus;

View File

@ -493,7 +493,7 @@ NTSTATUS WINAPI wow64_NtQueryVirtualMemory( UINT *args )
{
if (len < sizeof(MEMORY_REGION_INFORMATION32))
status = STATUS_INFO_LENGTH_MISMATCH;
if ((ULONG_PTR)addr > highest_user_address)
else if ((ULONG_PTR)addr > highest_user_address)
status = STATUS_INVALID_PARAMETER;
else
{
@ -534,6 +534,27 @@ NTSTATUS WINAPI wow64_NtQueryVirtualMemory( UINT *args )
break;
}
case MemoryImageInformation: /* MEMORY_IMAEG_INFORMATION */
{
if (len < sizeof(MEMORY_IMAGE_INFORMATION32)) return STATUS_INFO_LENGTH_MISMATCH;
if ((ULONG_PTR)addr > highest_user_address) status = STATUS_INVALID_PARAMETER;
else
{
MEMORY_IMAGE_INFORMATION info;
MEMORY_IMAGE_INFORMATION32 *info32 = ptr;
if (!(status = NtQueryVirtualMemory( handle, addr, class, &info, sizeof(info), &res_len )))
{
info32->ImageBase = PtrToUlong( info.ImageBase );
info32->SizeOfImage = info.SizeOfImage;
info32->ImageFlags = info.ImageFlags;
}
}
res_len = sizeof(MEMORY_IMAGE_INFORMATION32);
break;
}
case MemoryWineUnixWow64Funcs:
return STATUS_INVALID_INFO_CLASS;

View File

@ -2027,6 +2027,21 @@ struct map_builtin_view_reply
struct get_image_view_info_request
{
struct request_header __header;
obj_handle_t process;
client_ptr_t addr;
};
struct get_image_view_info_reply
{
struct reply_header __header;
client_ptr_t base;
mem_size_t size;
};
struct unmap_view_request
{
struct request_header __header;
@ -5629,6 +5644,7 @@ enum request
REQ_map_view,
REQ_map_image_view,
REQ_map_builtin_view,
REQ_get_image_view_info,
REQ_unmap_view,
REQ_get_mapping_committed_range,
REQ_add_mapping_committed_range,
@ -5916,6 +5932,7 @@ union generic_request
struct map_view_request map_view_request;
struct map_image_view_request map_image_view_request;
struct map_builtin_view_request map_builtin_view_request;
struct get_image_view_info_request get_image_view_info_request;
struct unmap_view_request unmap_view_request;
struct get_mapping_committed_range_request get_mapping_committed_range_request;
struct add_mapping_committed_range_request add_mapping_committed_range_request;
@ -6201,6 +6218,7 @@ union generic_reply
struct map_view_reply map_view_reply;
struct map_image_view_reply map_image_view_reply;
struct map_builtin_view_reply map_builtin_view_reply;
struct get_image_view_info_reply get_image_view_info_reply;
struct unmap_view_reply unmap_view_reply;
struct get_mapping_committed_range_reply get_mapping_committed_range_reply;
struct add_mapping_committed_range_reply add_mapping_committed_range_reply;
@ -6418,7 +6436,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 778
#define SERVER_PROTOCOL_VERSION 779
/* ### protocol_version end ### */

View File

@ -1325,6 +1325,23 @@ DECL_HANDLER(unmap_view)
free_memory_view( view );
}
/* get information about a mapped image view */
DECL_HANDLER(get_image_view_info)
{
struct process *process;
struct memory_view *view;
if (!(process = get_process_from_handle( req->process, PROCESS_QUERY_INFORMATION ))) return;
if ((view = find_mapped_addr( process, req->addr )) && (view->flags & SEC_IMAGE))
{
reply->base = view->base;
reply->size = view->size;
}
release_object( process );
}
/* get a range of committed pages in a file mapping */
DECL_HANDLER(get_mapping_committed_range)
{

View File

@ -1628,6 +1628,16 @@ enum server_fd_type
@END
/* Get information about a mapped image view */
@REQ(get_image_view_info)
obj_handle_t process; /* process handle */
client_ptr_t addr; /* address inside mapped view (in process address space) */
@REPLY
client_ptr_t base; /* view base address */
mem_size_t size; /* view size */
@END
/* Unmap a memory view from the current process */
@REQ(unmap_view)
client_ptr_t base; /* view base address */

View File

@ -186,6 +186,7 @@ DECL_HANDLER(get_mapping_info);
DECL_HANDLER(map_view);
DECL_HANDLER(map_image_view);
DECL_HANDLER(map_builtin_view);
DECL_HANDLER(get_image_view_info);
DECL_HANDLER(unmap_view);
DECL_HANDLER(get_mapping_committed_range);
DECL_HANDLER(add_mapping_committed_range);
@ -472,6 +473,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_map_view,
(req_handler)req_map_image_view,
(req_handler)req_map_builtin_view,
(req_handler)req_get_image_view_info,
(req_handler)req_unmap_view,
(req_handler)req_get_mapping_committed_range,
(req_handler)req_add_mapping_committed_range,
@ -1145,6 +1147,12 @@ C_ASSERT( FIELD_OFFSET(struct map_image_view_request, entry) == 32 );
C_ASSERT( FIELD_OFFSET(struct map_image_view_request, machine) == 36 );
C_ASSERT( sizeof(struct map_image_view_request) == 40 );
C_ASSERT( sizeof(struct map_builtin_view_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_image_view_info_request, process) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_image_view_info_request, addr) == 16 );
C_ASSERT( sizeof(struct get_image_view_info_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_image_view_info_reply, base) == 8 );
C_ASSERT( FIELD_OFFSET(struct get_image_view_info_reply, size) == 16 );
C_ASSERT( sizeof(struct get_image_view_info_reply) == 24 );
C_ASSERT( FIELD_OFFSET(struct unmap_view_request, base) == 16 );
C_ASSERT( sizeof(struct unmap_view_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_mapping_committed_range_request, base) == 16 );

View File

@ -2210,6 +2210,18 @@ static void dump_map_builtin_view_request( const struct map_builtin_view_request
dump_varargs_unicode_str( ", name=", cur_size );
}
static void dump_get_image_view_info_request( const struct get_image_view_info_request *req )
{
fprintf( stderr, " process=%04x", req->process );
dump_uint64( ", addr=", &req->addr );
}
static void dump_get_image_view_info_reply( const struct get_image_view_info_reply *req )
{
dump_uint64( " base=", &req->base );
dump_uint64( ", size=", &req->size );
}
static void dump_unmap_view_request( const struct unmap_view_request *req )
{
dump_uint64( " base=", &req->base );
@ -4622,6 +4634,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_map_view_request,
(dump_func)dump_map_image_view_request,
(dump_func)dump_map_builtin_view_request,
(dump_func)dump_get_image_view_info_request,
(dump_func)dump_unmap_view_request,
(dump_func)dump_get_mapping_committed_range_request,
(dump_func)dump_add_mapping_committed_range_request,
@ -4905,6 +4918,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
NULL,
NULL,
NULL,
(dump_func)dump_get_image_view_info_reply,
NULL,
(dump_func)dump_get_mapping_committed_range_reply,
NULL,
@ -5188,6 +5202,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"map_view",
"map_image_view",
"map_builtin_view",
"get_image_view_info",
"unmap_view",
"get_mapping_committed_range",
"add_mapping_committed_range",