Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
29f265fa
Commit
29f265fa
authored
Jul 29, 2002
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Set the correct permissions on the PE image sections.
parent
786d2490
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
116 additions
and
101 deletions
+116
-101
pe_image.c
loader/pe_image.c
+2
-98
virtual.c
memory/virtual.c
+114
-3
No files found.
loader/pe_image.c
View file @
29f265fa
...
...
@@ -378,90 +378,6 @@ DWORD PE_fixup_imports( WINE_MODREF *wm )
return
0
;
}
/***********************************************************************
* do_relocations
*
* Apply the relocations to a mapped PE image
*/
static
int
do_relocations
(
char
*
base
,
const
IMAGE_NT_HEADERS
*
nt
,
const
char
*
filename
)
{
const
IMAGE_DATA_DIRECTORY
*
dir
;
const
IMAGE_BASE_RELOCATION
*
rel
;
int
delta
=
base
-
(
char
*
)
nt
->
OptionalHeader
.
ImageBase
;
dir
=
&
nt
->
OptionalHeader
.
DataDirectory
[
IMAGE_DIRECTORY_ENTRY_BASERELOC
];
rel
=
(
IMAGE_BASE_RELOCATION
*
)(
base
+
dir
->
VirtualAddress
);
WARN
(
"Info: base relocations needed for %s
\n
"
,
filename
);
if
(
!
dir
->
VirtualAddress
||
!
dir
->
Size
)
{
if
(
nt
->
OptionalHeader
.
ImageBase
==
0x400000
)
ERR
(
"Standard load address for a Win32 program (0x00400000) not available - security-patched kernel ?
\n
"
);
else
ERR
(
"FATAL: Need to relocate %s from addr %lx, but %s
\n
"
,
filename
,
nt
->
OptionalHeader
.
ImageBase
,
(
nt
->
FileHeader
.
Characteristics
&
IMAGE_FILE_RELOCS_STRIPPED
)
?
"relocation records are stripped"
:
"no relocation records present"
);
return
0
;
}
/* FIXME: If we need to relocate a system DLL (base > 2GB) we should
* really make sure that the *new* base address is also > 2GB.
* Some DLLs really check the MSB of the module handle :-/
*/
if
((
nt
->
OptionalHeader
.
ImageBase
&
0x80000000
)
&&
!
((
DWORD
)
base
&
0x80000000
))
ERR
(
"Forced to relocate system DLL (base > 2GB). This is not good.
\n
"
);
for
(
;
((
char
*
)
rel
<
base
+
dir
->
VirtualAddress
+
dir
->
Size
)
&&
rel
->
SizeOfBlock
;
rel
=
(
IMAGE_BASE_RELOCATION
*
)((
char
*
)
rel
+
rel
->
SizeOfBlock
))
{
char
*
page
=
base
+
rel
->
VirtualAddress
;
WORD
*
TypeOffset
=
(
WORD
*
)(
rel
+
1
);
int
i
,
count
=
(
rel
->
SizeOfBlock
-
sizeof
(
*
rel
))
/
sizeof
(
*
TypeOffset
);
if
(
!
count
)
continue
;
/* sanity checks */
if
((
char
*
)
rel
+
rel
->
SizeOfBlock
>
base
+
dir
->
VirtualAddress
+
dir
->
Size
||
page
>
base
+
nt
->
OptionalHeader
.
SizeOfImage
)
{
ERR_
(
module
)(
"invalid relocation %p,%lx,%ld at %p,%lx,%lx
\n
"
,
rel
,
rel
->
VirtualAddress
,
rel
->
SizeOfBlock
,
base
,
dir
->
VirtualAddress
,
dir
->
Size
);
return
0
;
}
TRACE_
(
module
)(
"%ld relocations for page %lx
\n
"
,
rel
->
SizeOfBlock
,
rel
->
VirtualAddress
);
/* patching in reverse order */
for
(
i
=
0
;
i
<
count
;
i
++
)
{
int
offset
=
TypeOffset
[
i
]
&
0xFFF
;
int
type
=
TypeOffset
[
i
]
>>
12
;
switch
(
type
)
{
case
IMAGE_REL_BASED_ABSOLUTE
:
break
;
case
IMAGE_REL_BASED_HIGH
:
*
(
short
*
)(
page
+
offset
)
+=
HIWORD
(
delta
);
break
;
case
IMAGE_REL_BASED_LOW
:
*
(
short
*
)(
page
+
offset
)
+=
LOWORD
(
delta
);
break
;
case
IMAGE_REL_BASED_HIGHLOW
:
*
(
int
*
)(
page
+
offset
)
+=
delta
;
/* FIXME: if this is an exported address, fire up enhanced logic */
break
;
default:
FIXME_
(
module
)(
"Unknown/unsupported fixup type %d.
\n
"
,
type
);
break
;
}
}
}
return
1
;
}
/**********************************************************************
* PE_LoadImage
* Load one PE format DLL/EXE into memory
...
...
@@ -487,22 +403,10 @@ HMODULE PE_LoadImage( HANDLE hFile, LPCSTR filename, DWORD flags )
CloseHandle
(
mapping
);
if
(
!
base
)
return
0
;
hModule
=
(
HMODULE
)
base
;
/* perform base relocation, if necessary */
/* virus check */
hModule
=
(
HMODULE
)
base
;
nt
=
PE_HEADER
(
hModule
);
if
(
hModule
!=
nt
->
OptionalHeader
.
ImageBase
)
{
if
(
!
do_relocations
(
base
,
nt
,
filename
))
{
UnmapViewOfFile
(
base
);
SetLastError
(
ERROR_BAD_EXE_FORMAT
);
return
0
;
}
}
/* virus check */
if
(
nt
->
OptionalHeader
.
AddressOfEntryPoint
)
{
...
...
memory/virtual.c
View file @
29f265fa
...
...
@@ -491,6 +491,67 @@ static void *anon_mmap_aligned( void *base, unsigned int size, int prot, int fla
/***********************************************************************
* do_relocations
*
* Apply the relocations to a mapped PE image
*/
static
int
do_relocations
(
char
*
base
,
const
IMAGE_DATA_DIRECTORY
*
dir
,
int
delta
,
DWORD
total_size
)
{
IMAGE_BASE_RELOCATION
*
rel
;
for
(
rel
=
(
IMAGE_BASE_RELOCATION
*
)(
base
+
dir
->
VirtualAddress
);
((
char
*
)
rel
<
base
+
dir
->
VirtualAddress
+
dir
->
Size
)
&&
rel
->
SizeOfBlock
;
rel
=
(
IMAGE_BASE_RELOCATION
*
)((
char
*
)
rel
+
rel
->
SizeOfBlock
)
)
{
char
*
page
=
base
+
rel
->
VirtualAddress
;
WORD
*
TypeOffset
=
(
WORD
*
)(
rel
+
1
);
int
i
,
count
=
(
rel
->
SizeOfBlock
-
sizeof
(
*
rel
))
/
sizeof
(
*
TypeOffset
);
if
(
!
count
)
continue
;
/* sanity checks */
if
((
char
*
)
rel
+
rel
->
SizeOfBlock
>
base
+
dir
->
VirtualAddress
+
dir
->
Size
||
page
>
base
+
total_size
)
{
ERR_
(
module
)(
"invalid relocation %p,%lx,%ld at %p,%lx,%lx
\n
"
,
rel
,
rel
->
VirtualAddress
,
rel
->
SizeOfBlock
,
base
,
dir
->
VirtualAddress
,
dir
->
Size
);
return
0
;
}
TRACE_
(
module
)(
"%ld relocations for page %lx
\n
"
,
rel
->
SizeOfBlock
,
rel
->
VirtualAddress
);
/* patching in reverse order */
for
(
i
=
0
;
i
<
count
;
i
++
)
{
int
offset
=
TypeOffset
[
i
]
&
0xFFF
;
int
type
=
TypeOffset
[
i
]
>>
12
;
switch
(
type
)
{
case
IMAGE_REL_BASED_ABSOLUTE
:
break
;
case
IMAGE_REL_BASED_HIGH
:
*
(
short
*
)(
page
+
offset
)
+=
HIWORD
(
delta
);
break
;
case
IMAGE_REL_BASED_LOW
:
*
(
short
*
)(
page
+
offset
)
+=
LOWORD
(
delta
);
break
;
case
IMAGE_REL_BASED_HIGHLOW
:
*
(
int
*
)(
page
+
offset
)
+=
delta
;
/* FIXME: if this is an exported address, fire up enhanced logic */
break
;
default:
FIXME_
(
module
)(
"Unknown/unsupported fixup type %d.
\n
"
,
type
);
break
;
}
}
}
return
1
;
}
/***********************************************************************
* map_image
*
* Map an executable (PE format) image into memory.
...
...
@@ -648,15 +709,65 @@ static LPVOID map_image( HANDLE hmapping, int fd, char *base, DWORD total_size,
}
}
/* perform base relocation, if necessary */
if
(
ptr
!=
base
)
{
const
IMAGE_DATA_DIRECTORY
*
relocs
;
relocs
=
&
nt
->
OptionalHeader
.
DataDirectory
[
IMAGE_DIRECTORY_ENTRY_BASERELOC
];
if
(
!
relocs
->
VirtualAddress
||
!
relocs
->
Size
)
{
if
(
nt
->
OptionalHeader
.
ImageBase
==
0x400000
)
ERR
(
"Standard load address for a Win32 program (0x00400000) not available - security-patched kernel ?
\n
"
);
else
ERR
(
"FATAL: Need to relocate module from addr %lx, but there are no relocation records
\n
"
,
nt
->
OptionalHeader
.
ImageBase
);
SetLastError
(
ERROR_BAD_EXE_FORMAT
);
goto
error
;
}
/* FIXME: If we need to relocate a system DLL (base > 2GB) we should
* really make sure that the *new* base address is also > 2GB.
* Some DLLs really check the MSB of the module handle :-/
*/
if
((
nt
->
OptionalHeader
.
ImageBase
&
0x80000000
)
&&
!
((
DWORD
)
base
&
0x80000000
))
ERR
(
"Forced to relocate system DLL (base > 2GB). This is not good.
\n
"
);
if
(
!
do_relocations
(
ptr
,
relocs
,
ptr
-
base
,
total_size
))
{
SetLastError
(
ERROR_BAD_EXE_FORMAT
);
goto
error
;
}
}
if
(
removable
)
hmapping
=
0
;
/* don't keep handle open on removable media */
if
(
!
(
view
=
VIRTUAL_CreateView
(
ptr
,
total_size
,
0
,
VPROT_COMMITTED
|
VPROT_READ
|
VPROT_WRITE
|
VPROT_WRITECOPY
,
hmapping
)))
if
(
!
(
view
=
VIRTUAL_CreateView
(
ptr
,
total_size
,
0
,
VPROT_COMMITTED
|
VPROT_READ
,
hmapping
)))
{
SetLastError
(
ERROR_OUTOFMEMORY
);
goto
error
;
}
/* set the image protections */
sec
=
(
IMAGE_SECTION_HEADER
*
)((
char
*
)
&
nt
->
OptionalHeader
+
nt
->
FileHeader
.
SizeOfOptionalHeader
);
for
(
i
=
0
;
i
<
nt
->
FileHeader
.
NumberOfSections
;
i
++
,
sec
++
)
{
DWORD
size
=
ROUND_SIZE
(
sec
->
VirtualAddress
,
sec
->
Misc
.
VirtualSize
);
BYTE
vprot
=
VPROT_COMMITTED
;
if
(
sec
->
Characteristics
&
IMAGE_SCN_MEM_READ
)
vprot
|=
VPROT_READ
;
if
(
sec
->
Characteristics
&
IMAGE_SCN_MEM_WRITE
)
vprot
|=
VPROT_WRITE
|
VPROT_WRITECOPY
;
if
(
sec
->
Characteristics
&
IMAGE_SCN_MEM_EXECUTE
)
vprot
|=
VPROT_EXEC
;
/* make sure the import directory is writable */
if
(
imports
&&
imports
->
VirtualAddress
>=
sec
->
VirtualAddress
&&
imports
->
VirtualAddress
<
sec
->
VirtualAddress
+
size
)
vprot
|=
VPROT_READ
|
VPROT_WRITE
|
VPROT_WRITECOPY
;
VIRTUAL_SetProt
(
view
,
ptr
+
sec
->
VirtualAddress
,
size
,
vprot
);
}
SetLastError
(
err
);
/* restore last error */
close
(
fd
);
if
(
shared_fd
!=
-
1
)
close
(
shared_fd
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment