Is there any way to get my own image base without calling any WinAPI functions, such as GetModuleHandle?
Clash Royale CLAN TAG#URR8PPP
up vote
3
down vote
favorite
Is there any way to get the image base of an .exe
without calling WinAPI functions (i.e. imported functions, so that it can't be easily viewed in a diassembler/debugger)?
I've been thinking of declaring a global variable anywhere in code and reading its address in a loop backwards until e.g.MZ
is found (obviously checking for NULL
in the meantime). However, there may be a section which isn't readable, a string in .rdata which contains the MZ
characters or some value (especially a function address or generally pointers) that contains the MZ
bytes (0x4D
, 0x5A
) (and probably a few more "situations").
Have you any idea how to achieve that? Is it even possible?
windows pe executable exe
New contributor
add a comment |Â
up vote
3
down vote
favorite
Is there any way to get the image base of an .exe
without calling WinAPI functions (i.e. imported functions, so that it can't be easily viewed in a diassembler/debugger)?
I've been thinking of declaring a global variable anywhere in code and reading its address in a loop backwards until e.g.MZ
is found (obviously checking for NULL
in the meantime). However, there may be a section which isn't readable, a string in .rdata which contains the MZ
characters or some value (especially a function address or generally pointers) that contains the MZ
bytes (0x4D
, 0x5A
) (and probably a few more "situations").
Have you any idea how to achieve that? Is it even possible?
windows pe executable exe
New contributor
add a comment |Â
up vote
3
down vote
favorite
up vote
3
down vote
favorite
Is there any way to get the image base of an .exe
without calling WinAPI functions (i.e. imported functions, so that it can't be easily viewed in a diassembler/debugger)?
I've been thinking of declaring a global variable anywhere in code and reading its address in a loop backwards until e.g.MZ
is found (obviously checking for NULL
in the meantime). However, there may be a section which isn't readable, a string in .rdata which contains the MZ
characters or some value (especially a function address or generally pointers) that contains the MZ
bytes (0x4D
, 0x5A
) (and probably a few more "situations").
Have you any idea how to achieve that? Is it even possible?
windows pe executable exe
New contributor
Is there any way to get the image base of an .exe
without calling WinAPI functions (i.e. imported functions, so that it can't be easily viewed in a diassembler/debugger)?
I've been thinking of declaring a global variable anywhere in code and reading its address in a loop backwards until e.g.MZ
is found (obviously checking for NULL
in the meantime). However, there may be a section which isn't readable, a string in .rdata which contains the MZ
characters or some value (especially a function address or generally pointers) that contains the MZ
bytes (0x4D
, 0x5A
) (and probably a few more "situations").
Have you any idea how to achieve that? Is it even possible?
windows pe executable exe
windows pe executable exe
New contributor
New contributor
New contributor
asked 2 hours ago
Jason
183
183
New contributor
New contributor
add a comment |Â
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
3
down vote
accepted
I can think of a couple of ways of doing that
Scanning memory from EIP
You could easily get the EIP
of your own code without calling any APIs. There are a few ways to achieve that using inline assembly, but the most common one is to include the following two instructions:
call $+5
pop eax
This works because call
will push the next address (where pop eax
is onto the stack) and then execute the instruction right after it (again, our pop eax
). When pop eax
is executed, it'll pop the address just pushed by call $+5
into a register.
After you got your EIP
value you can easily scan backwards as you thought of doing, but this time starting at a position a lot closer to your image base.
Keeping in mind image bases are aligned to page boundaries, you can scan in PAGE_SIZE
(4096 bytes) intervals.
Reading loaded modules from PEB
The Process Environment Block structure is accessible using a designated segment register (fs
on 32bit systems and gs
on 64 bit systems) which stores the address of the Thread Information Block from which the PEB is reachable. Although most of the PEB is undocumented, in it is a lot of data relating to the operational aspects of the currently running process.
One such piece of information is the ImageBaseAddress
, an undocumented (but consistent) field that holds the process's image base. If you're interested in the .exe
's image base (opposed to a loaded DLLs image base), this will do.
If you want something more reliable you could use the Ldr
member, which points to a PEB_LDR_DATA
structure which points to a linked list of LDR_DATA_TABLE_ENTRY
s, which lists all loaded modules, their addresses and a lot of other information about each loaded module. Your executable's image base is the DllBase
field.
2
PEB.ImageBaseAddress
will be easier than walking the Ldr structures.
â josh poley
2 hours ago
@Nirlzr Thank you very much, that's a great idea! I can't however understand why I can read theeip
in0x1000
intervals. If you meant something like:while(*(WORD*)eip != 'MZ') (DWORD)eip -= PAGE_SIZE;
, then what if the image base actually was0x400000
and theeip
was, say,0x400ABC
? Am I missing something?
â Jason
1 hour ago
@joshpoley Cool. I thought there must be something like that but couldn't find it when skimming for it. I'll add that!
â NirIzr
1 hour ago
@Jason You can easily align the address to a 4k boundary by performingeip & ~(4096-1)
â NirIzr
1 hour ago
@Nirlzr Alright, I've already seen this technique with virtual addresses, just misunderstood you.
â Jason
1 hour ago
add a comment |Â
up vote
1
down vote
If you use Visual C++, you can use the special symbol __ImageBase
which points to image base of the current module. For example, here's code from VS2010 CRT source (pesect.c
):
BOOL __cdecl _IsNonwritableInCurrentImage(
PBYTE pTarget
)
PBYTE pImageBase;
DWORD_PTR rvaTarget;
PIMAGE_SECTION_HEADER pSection;
pImageBase = (PBYTE)&__ImageBase;
__try
//
// Make sure __ImageBase does address a PE image. This is likely an
// unnecessary check, since we should be running from a normal image,
// but it is fast, this routine is rarely called, and the normal call
// is for security purposes. If we don't have a PE image, return
// failure.
//
if (!_ValidateImageBase(pImageBase))
return FALSE;
//
// Convert the targetaddress to a Relative Virtual Address (RVA) within
// the image, and find the corresponding PE section. Return failure if
// the target address is not found within the current image.
//
rvaTarget = pTarget - pImageBase;
pSection = _FindPESection(pImageBase, rvaTarget);
if (pSection == NULL)
return FALSE;
//
// Check the section characteristics to see if the target address is
// located within a writable section, returning a failure if yes.
//
return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0;
__except (GetExceptionCode() == STATUS_ACCESS_VIOLATION)
//
// Just return failure if the PE image is corrupted in any way that
// triggers an AV.
//
return FALSE;
At the top of the file there is code declaring this variable as extern
:
#if defined (_WIN64) && defined (_M_IA64)
#pragma section(".base", long, read)
__declspec(allocate(".base"))
extern IMAGE_DOS_HEADER __ImageBase;
#else /* defined (_WIN64) && defined (_M_IA64) */
extern IMAGE_DOS_HEADER __ImageBase;
#endif /* defined (_WIN64) && defined (_M_IA64) */
So it may be that the key is the .base
section and not the variable name by itself.
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
I can think of a couple of ways of doing that
Scanning memory from EIP
You could easily get the EIP
of your own code without calling any APIs. There are a few ways to achieve that using inline assembly, but the most common one is to include the following two instructions:
call $+5
pop eax
This works because call
will push the next address (where pop eax
is onto the stack) and then execute the instruction right after it (again, our pop eax
). When pop eax
is executed, it'll pop the address just pushed by call $+5
into a register.
After you got your EIP
value you can easily scan backwards as you thought of doing, but this time starting at a position a lot closer to your image base.
Keeping in mind image bases are aligned to page boundaries, you can scan in PAGE_SIZE
(4096 bytes) intervals.
Reading loaded modules from PEB
The Process Environment Block structure is accessible using a designated segment register (fs
on 32bit systems and gs
on 64 bit systems) which stores the address of the Thread Information Block from which the PEB is reachable. Although most of the PEB is undocumented, in it is a lot of data relating to the operational aspects of the currently running process.
One such piece of information is the ImageBaseAddress
, an undocumented (but consistent) field that holds the process's image base. If you're interested in the .exe
's image base (opposed to a loaded DLLs image base), this will do.
If you want something more reliable you could use the Ldr
member, which points to a PEB_LDR_DATA
structure which points to a linked list of LDR_DATA_TABLE_ENTRY
s, which lists all loaded modules, their addresses and a lot of other information about each loaded module. Your executable's image base is the DllBase
field.
2
PEB.ImageBaseAddress
will be easier than walking the Ldr structures.
â josh poley
2 hours ago
@Nirlzr Thank you very much, that's a great idea! I can't however understand why I can read theeip
in0x1000
intervals. If you meant something like:while(*(WORD*)eip != 'MZ') (DWORD)eip -= PAGE_SIZE;
, then what if the image base actually was0x400000
and theeip
was, say,0x400ABC
? Am I missing something?
â Jason
1 hour ago
@joshpoley Cool. I thought there must be something like that but couldn't find it when skimming for it. I'll add that!
â NirIzr
1 hour ago
@Jason You can easily align the address to a 4k boundary by performingeip & ~(4096-1)
â NirIzr
1 hour ago
@Nirlzr Alright, I've already seen this technique with virtual addresses, just misunderstood you.
â Jason
1 hour ago
add a comment |Â
up vote
3
down vote
accepted
I can think of a couple of ways of doing that
Scanning memory from EIP
You could easily get the EIP
of your own code without calling any APIs. There are a few ways to achieve that using inline assembly, but the most common one is to include the following two instructions:
call $+5
pop eax
This works because call
will push the next address (where pop eax
is onto the stack) and then execute the instruction right after it (again, our pop eax
). When pop eax
is executed, it'll pop the address just pushed by call $+5
into a register.
After you got your EIP
value you can easily scan backwards as you thought of doing, but this time starting at a position a lot closer to your image base.
Keeping in mind image bases are aligned to page boundaries, you can scan in PAGE_SIZE
(4096 bytes) intervals.
Reading loaded modules from PEB
The Process Environment Block structure is accessible using a designated segment register (fs
on 32bit systems and gs
on 64 bit systems) which stores the address of the Thread Information Block from which the PEB is reachable. Although most of the PEB is undocumented, in it is a lot of data relating to the operational aspects of the currently running process.
One such piece of information is the ImageBaseAddress
, an undocumented (but consistent) field that holds the process's image base. If you're interested in the .exe
's image base (opposed to a loaded DLLs image base), this will do.
If you want something more reliable you could use the Ldr
member, which points to a PEB_LDR_DATA
structure which points to a linked list of LDR_DATA_TABLE_ENTRY
s, which lists all loaded modules, their addresses and a lot of other information about each loaded module. Your executable's image base is the DllBase
field.
2
PEB.ImageBaseAddress
will be easier than walking the Ldr structures.
â josh poley
2 hours ago
@Nirlzr Thank you very much, that's a great idea! I can't however understand why I can read theeip
in0x1000
intervals. If you meant something like:while(*(WORD*)eip != 'MZ') (DWORD)eip -= PAGE_SIZE;
, then what if the image base actually was0x400000
and theeip
was, say,0x400ABC
? Am I missing something?
â Jason
1 hour ago
@joshpoley Cool. I thought there must be something like that but couldn't find it when skimming for it. I'll add that!
â NirIzr
1 hour ago
@Jason You can easily align the address to a 4k boundary by performingeip & ~(4096-1)
â NirIzr
1 hour ago
@Nirlzr Alright, I've already seen this technique with virtual addresses, just misunderstood you.
â Jason
1 hour ago
add a comment |Â
up vote
3
down vote
accepted
up vote
3
down vote
accepted
I can think of a couple of ways of doing that
Scanning memory from EIP
You could easily get the EIP
of your own code without calling any APIs. There are a few ways to achieve that using inline assembly, but the most common one is to include the following two instructions:
call $+5
pop eax
This works because call
will push the next address (where pop eax
is onto the stack) and then execute the instruction right after it (again, our pop eax
). When pop eax
is executed, it'll pop the address just pushed by call $+5
into a register.
After you got your EIP
value you can easily scan backwards as you thought of doing, but this time starting at a position a lot closer to your image base.
Keeping in mind image bases are aligned to page boundaries, you can scan in PAGE_SIZE
(4096 bytes) intervals.
Reading loaded modules from PEB
The Process Environment Block structure is accessible using a designated segment register (fs
on 32bit systems and gs
on 64 bit systems) which stores the address of the Thread Information Block from which the PEB is reachable. Although most of the PEB is undocumented, in it is a lot of data relating to the operational aspects of the currently running process.
One such piece of information is the ImageBaseAddress
, an undocumented (but consistent) field that holds the process's image base. If you're interested in the .exe
's image base (opposed to a loaded DLLs image base), this will do.
If you want something more reliable you could use the Ldr
member, which points to a PEB_LDR_DATA
structure which points to a linked list of LDR_DATA_TABLE_ENTRY
s, which lists all loaded modules, their addresses and a lot of other information about each loaded module. Your executable's image base is the DllBase
field.
I can think of a couple of ways of doing that
Scanning memory from EIP
You could easily get the EIP
of your own code without calling any APIs. There are a few ways to achieve that using inline assembly, but the most common one is to include the following two instructions:
call $+5
pop eax
This works because call
will push the next address (where pop eax
is onto the stack) and then execute the instruction right after it (again, our pop eax
). When pop eax
is executed, it'll pop the address just pushed by call $+5
into a register.
After you got your EIP
value you can easily scan backwards as you thought of doing, but this time starting at a position a lot closer to your image base.
Keeping in mind image bases are aligned to page boundaries, you can scan in PAGE_SIZE
(4096 bytes) intervals.
Reading loaded modules from PEB
The Process Environment Block structure is accessible using a designated segment register (fs
on 32bit systems and gs
on 64 bit systems) which stores the address of the Thread Information Block from which the PEB is reachable. Although most of the PEB is undocumented, in it is a lot of data relating to the operational aspects of the currently running process.
One such piece of information is the ImageBaseAddress
, an undocumented (but consistent) field that holds the process's image base. If you're interested in the .exe
's image base (opposed to a loaded DLLs image base), this will do.
If you want something more reliable you could use the Ldr
member, which points to a PEB_LDR_DATA
structure which points to a linked list of LDR_DATA_TABLE_ENTRY
s, which lists all loaded modules, their addresses and a lot of other information about each loaded module. Your executable's image base is the DllBase
field.
edited 1 hour ago
answered 2 hours ago
NirIzr
8,77712268
8,77712268
2
PEB.ImageBaseAddress
will be easier than walking the Ldr structures.
â josh poley
2 hours ago
@Nirlzr Thank you very much, that's a great idea! I can't however understand why I can read theeip
in0x1000
intervals. If you meant something like:while(*(WORD*)eip != 'MZ') (DWORD)eip -= PAGE_SIZE;
, then what if the image base actually was0x400000
and theeip
was, say,0x400ABC
? Am I missing something?
â Jason
1 hour ago
@joshpoley Cool. I thought there must be something like that but couldn't find it when skimming for it. I'll add that!
â NirIzr
1 hour ago
@Jason You can easily align the address to a 4k boundary by performingeip & ~(4096-1)
â NirIzr
1 hour ago
@Nirlzr Alright, I've already seen this technique with virtual addresses, just misunderstood you.
â Jason
1 hour ago
add a comment |Â
2
PEB.ImageBaseAddress
will be easier than walking the Ldr structures.
â josh poley
2 hours ago
@Nirlzr Thank you very much, that's a great idea! I can't however understand why I can read theeip
in0x1000
intervals. If you meant something like:while(*(WORD*)eip != 'MZ') (DWORD)eip -= PAGE_SIZE;
, then what if the image base actually was0x400000
and theeip
was, say,0x400ABC
? Am I missing something?
â Jason
1 hour ago
@joshpoley Cool. I thought there must be something like that but couldn't find it when skimming for it. I'll add that!
â NirIzr
1 hour ago
@Jason You can easily align the address to a 4k boundary by performingeip & ~(4096-1)
â NirIzr
1 hour ago
@Nirlzr Alright, I've already seen this technique with virtual addresses, just misunderstood you.
â Jason
1 hour ago
2
2
PEB.ImageBaseAddress
will be easier than walking the Ldr structures.â josh poley
2 hours ago
PEB.ImageBaseAddress
will be easier than walking the Ldr structures.â josh poley
2 hours ago
@Nirlzr Thank you very much, that's a great idea! I can't however understand why I can read the
eip
in 0x1000
intervals. If you meant something like: while(*(WORD*)eip != 'MZ') (DWORD)eip -= PAGE_SIZE;
, then what if the image base actually was 0x400000
and the eip
was, say, 0x400ABC
? Am I missing something?â Jason
1 hour ago
@Nirlzr Thank you very much, that's a great idea! I can't however understand why I can read the
eip
in 0x1000
intervals. If you meant something like: while(*(WORD*)eip != 'MZ') (DWORD)eip -= PAGE_SIZE;
, then what if the image base actually was 0x400000
and the eip
was, say, 0x400ABC
? Am I missing something?â Jason
1 hour ago
@joshpoley Cool. I thought there must be something like that but couldn't find it when skimming for it. I'll add that!
â NirIzr
1 hour ago
@joshpoley Cool. I thought there must be something like that but couldn't find it when skimming for it. I'll add that!
â NirIzr
1 hour ago
@Jason You can easily align the address to a 4k boundary by performing
eip & ~(4096-1)
â NirIzr
1 hour ago
@Jason You can easily align the address to a 4k boundary by performing
eip & ~(4096-1)
â NirIzr
1 hour ago
@Nirlzr Alright, I've already seen this technique with virtual addresses, just misunderstood you.
â Jason
1 hour ago
@Nirlzr Alright, I've already seen this technique with virtual addresses, just misunderstood you.
â Jason
1 hour ago
add a comment |Â
up vote
1
down vote
If you use Visual C++, you can use the special symbol __ImageBase
which points to image base of the current module. For example, here's code from VS2010 CRT source (pesect.c
):
BOOL __cdecl _IsNonwritableInCurrentImage(
PBYTE pTarget
)
PBYTE pImageBase;
DWORD_PTR rvaTarget;
PIMAGE_SECTION_HEADER pSection;
pImageBase = (PBYTE)&__ImageBase;
__try
//
// Make sure __ImageBase does address a PE image. This is likely an
// unnecessary check, since we should be running from a normal image,
// but it is fast, this routine is rarely called, and the normal call
// is for security purposes. If we don't have a PE image, return
// failure.
//
if (!_ValidateImageBase(pImageBase))
return FALSE;
//
// Convert the targetaddress to a Relative Virtual Address (RVA) within
// the image, and find the corresponding PE section. Return failure if
// the target address is not found within the current image.
//
rvaTarget = pTarget - pImageBase;
pSection = _FindPESection(pImageBase, rvaTarget);
if (pSection == NULL)
return FALSE;
//
// Check the section characteristics to see if the target address is
// located within a writable section, returning a failure if yes.
//
return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0;
__except (GetExceptionCode() == STATUS_ACCESS_VIOLATION)
//
// Just return failure if the PE image is corrupted in any way that
// triggers an AV.
//
return FALSE;
At the top of the file there is code declaring this variable as extern
:
#if defined (_WIN64) && defined (_M_IA64)
#pragma section(".base", long, read)
__declspec(allocate(".base"))
extern IMAGE_DOS_HEADER __ImageBase;
#else /* defined (_WIN64) && defined (_M_IA64) */
extern IMAGE_DOS_HEADER __ImageBase;
#endif /* defined (_WIN64) && defined (_M_IA64) */
So it may be that the key is the .base
section and not the variable name by itself.
add a comment |Â
up vote
1
down vote
If you use Visual C++, you can use the special symbol __ImageBase
which points to image base of the current module. For example, here's code from VS2010 CRT source (pesect.c
):
BOOL __cdecl _IsNonwritableInCurrentImage(
PBYTE pTarget
)
PBYTE pImageBase;
DWORD_PTR rvaTarget;
PIMAGE_SECTION_HEADER pSection;
pImageBase = (PBYTE)&__ImageBase;
__try
//
// Make sure __ImageBase does address a PE image. This is likely an
// unnecessary check, since we should be running from a normal image,
// but it is fast, this routine is rarely called, and the normal call
// is for security purposes. If we don't have a PE image, return
// failure.
//
if (!_ValidateImageBase(pImageBase))
return FALSE;
//
// Convert the targetaddress to a Relative Virtual Address (RVA) within
// the image, and find the corresponding PE section. Return failure if
// the target address is not found within the current image.
//
rvaTarget = pTarget - pImageBase;
pSection = _FindPESection(pImageBase, rvaTarget);
if (pSection == NULL)
return FALSE;
//
// Check the section characteristics to see if the target address is
// located within a writable section, returning a failure if yes.
//
return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0;
__except (GetExceptionCode() == STATUS_ACCESS_VIOLATION)
//
// Just return failure if the PE image is corrupted in any way that
// triggers an AV.
//
return FALSE;
At the top of the file there is code declaring this variable as extern
:
#if defined (_WIN64) && defined (_M_IA64)
#pragma section(".base", long, read)
__declspec(allocate(".base"))
extern IMAGE_DOS_HEADER __ImageBase;
#else /* defined (_WIN64) && defined (_M_IA64) */
extern IMAGE_DOS_HEADER __ImageBase;
#endif /* defined (_WIN64) && defined (_M_IA64) */
So it may be that the key is the .base
section and not the variable name by itself.
add a comment |Â
up vote
1
down vote
up vote
1
down vote
If you use Visual C++, you can use the special symbol __ImageBase
which points to image base of the current module. For example, here's code from VS2010 CRT source (pesect.c
):
BOOL __cdecl _IsNonwritableInCurrentImage(
PBYTE pTarget
)
PBYTE pImageBase;
DWORD_PTR rvaTarget;
PIMAGE_SECTION_HEADER pSection;
pImageBase = (PBYTE)&__ImageBase;
__try
//
// Make sure __ImageBase does address a PE image. This is likely an
// unnecessary check, since we should be running from a normal image,
// but it is fast, this routine is rarely called, and the normal call
// is for security purposes. If we don't have a PE image, return
// failure.
//
if (!_ValidateImageBase(pImageBase))
return FALSE;
//
// Convert the targetaddress to a Relative Virtual Address (RVA) within
// the image, and find the corresponding PE section. Return failure if
// the target address is not found within the current image.
//
rvaTarget = pTarget - pImageBase;
pSection = _FindPESection(pImageBase, rvaTarget);
if (pSection == NULL)
return FALSE;
//
// Check the section characteristics to see if the target address is
// located within a writable section, returning a failure if yes.
//
return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0;
__except (GetExceptionCode() == STATUS_ACCESS_VIOLATION)
//
// Just return failure if the PE image is corrupted in any way that
// triggers an AV.
//
return FALSE;
At the top of the file there is code declaring this variable as extern
:
#if defined (_WIN64) && defined (_M_IA64)
#pragma section(".base", long, read)
__declspec(allocate(".base"))
extern IMAGE_DOS_HEADER __ImageBase;
#else /* defined (_WIN64) && defined (_M_IA64) */
extern IMAGE_DOS_HEADER __ImageBase;
#endif /* defined (_WIN64) && defined (_M_IA64) */
So it may be that the key is the .base
section and not the variable name by itself.
If you use Visual C++, you can use the special symbol __ImageBase
which points to image base of the current module. For example, here's code from VS2010 CRT source (pesect.c
):
BOOL __cdecl _IsNonwritableInCurrentImage(
PBYTE pTarget
)
PBYTE pImageBase;
DWORD_PTR rvaTarget;
PIMAGE_SECTION_HEADER pSection;
pImageBase = (PBYTE)&__ImageBase;
__try
//
// Make sure __ImageBase does address a PE image. This is likely an
// unnecessary check, since we should be running from a normal image,
// but it is fast, this routine is rarely called, and the normal call
// is for security purposes. If we don't have a PE image, return
// failure.
//
if (!_ValidateImageBase(pImageBase))
return FALSE;
//
// Convert the targetaddress to a Relative Virtual Address (RVA) within
// the image, and find the corresponding PE section. Return failure if
// the target address is not found within the current image.
//
rvaTarget = pTarget - pImageBase;
pSection = _FindPESection(pImageBase, rvaTarget);
if (pSection == NULL)
return FALSE;
//
// Check the section characteristics to see if the target address is
// located within a writable section, returning a failure if yes.
//
return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0;
__except (GetExceptionCode() == STATUS_ACCESS_VIOLATION)
//
// Just return failure if the PE image is corrupted in any way that
// triggers an AV.
//
return FALSE;
At the top of the file there is code declaring this variable as extern
:
#if defined (_WIN64) && defined (_M_IA64)
#pragma section(".base", long, read)
__declspec(allocate(".base"))
extern IMAGE_DOS_HEADER __ImageBase;
#else /* defined (_WIN64) && defined (_M_IA64) */
extern IMAGE_DOS_HEADER __ImageBase;
#endif /* defined (_WIN64) && defined (_M_IA64) */
So it may be that the key is the .base
section and not the variable name by itself.
answered 15 mins ago
Igor Skochinskyâ¦
23.2k34186
23.2k34186
add a comment |Â
add a comment |Â
Jason is a new contributor. Be nice, and check out our Code of Conduct.
Jason is a new contributor. Be nice, and check out our Code of Conduct.
Jason is a new contributor. Be nice, and check out our Code of Conduct.
Jason is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2freverseengineering.stackexchange.com%2fquestions%2f19660%2fis-there-any-way-to-get-my-own-image-base-without-calling-any-winapi-functions%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password