PE Export Parser

03/23/2016 12:33 Cyrex'#1
May be useful for people coding their own memory mapper.

Main.cpp

credits: [Only registered and activated users can see links. Click Here To Register...]
03/23/2016 13:22 Jeoni#2
It should be said that, as LoadLibrary is used, the program should only be used on trusted modules. LoadLibrary will execute the DllMain of the module in question which may harm the system. Furthermore LoadLibrary will load all dependencies of the specified module which is not necessary.
That can be prevented by using [Only registered and activated users can see links. Click Here To Register...] and specify some flags. Note that with some flags the returned HANDLE is not equal to the image base. Or just load the module via simple file functions since it's not really more difficult.

Next; I know it won't help, but maybe one out of a million may get the point; let me quote myself (please excuse the rude phrasing):
Quote:
Originally Posted by Jeoni View Post
Why is every god damn newbie (excuse that word, but it was my experience so far) so obsessed with using DWORD as pointer type? Even the winapi does have something like UINT_PTR. In my opinion it's just bad coding style and shows that the programmer didn't make his own basic thoughts and / or has no idea what he is doing and / or is just C&Ping.
Because of that point your program is not compileable as 64 bit application (and therefor for 64 bit modules) because the module may be mapped by LoadLibrary after the lower 32 bit address space. Trying to calculate those numbers with DWORDs will then just fail. May not be critical (if 64 bit is not important), but just why?

Except from the above points, very fine.
With best regards
Jeoni
03/23/2016 13:40 Cyrex'#3
Quote:
Originally Posted by Jeoni View Post
It should be said that, as LoadLibrary is used, the program should only be used on trusted modules. LoadLibrary will execute the DllMain of the module in question which may harm the system. Furthermore LoadLibrary will load all dependencies of the specified module which is not necessary.
That can be prevented by using [Only registered and activated users can see links. Click Here To Register...] and specify some flags. Note that with some flags the returned HANDLE is not equal to the image base. Or just load the module via simple file functions since it's not really more difficult.

Next; I know it won't help, but maybe one out of a million may get the point; let me quote myself (please excuse the rude phrasing):

Because of that point your program is not compileable as 64 bit application (and therefor for 64 bit modules) because the module may be mapped by LoadLibrary after the lower 32 bit address space. Trying to calculate those numbers with DWORDs will then just fail. May not be critical (if 64 bit is not important), but just why?

Except from the above points, very fine.
With best regards
Jeoni
There's nothing wrong with using DWORD except its ptr length will not change if you compile for x64. Sure I could use DWORD_PTR or uintptr_t but the point is, I do not care.

Funny how people reduce using DWORD to people who don't know what they're doing. :)
03/23/2016 14:18 Shadow992#4
Quote:
Originally Posted by Cyrex' View Post
There's nothing wrong with using DWORD except its ptr length will not change if you compile for x64. Sure I could use DWORD_PTR or uintptr_t but the point is, I do not care.

Funny how people reduce using DWORD to people who don't know what they're doing. :)
WinDef.h defines "DWORD" as the following:
Code:
typedef unsigned long DWORD;
Datatype "unsigned long" is normally 32 Bit, when compiling as 64Bit-Application. At least for VC++ as MSDN suggests:
Quote:
Type: unsigned long
Byte: 4
Alias: unsigned long int
Range: 0 to 4.294.967.295

Source: [Only registered and activated users can see links. Click Here To Register...]
This means calculating Pointer under 64Bit may produce an integer overflow:
Code:
reinterpret_cast< DWORD* >( reinterpret_cast< DWORD >( hModule ) + pIED->AddressOfFunctions )
The innercast "reinterpret_cast< DWORD >" should be "reinterpret_cast< DWORDLONG >" or something similar.

So @[Only registered and activated users can see links. Click Here To Register...] is not aiming at some kind of "There's nothing wrong with using DWORD except its ptr length will not change if you compile for x64." but wants to state that this code will mostly give wrong results for 64Bit-Applications.
Especially as your answer is kind of wrong. The pointer size will change depending on 32Bit or 64Bit compilation. No matter which datatype you used. The compiler generates you architecture dependent code and this also means that you will get 64Bit pointers for 64Bit systems instead of 32Bit pointers.

P.S.
This code may still work without any problems under GNU, as GNU (as far as I know) defines "long" as 32Bit for 32Bit compilation and 64Bit for 64Bit compilation.

But you should really avoid these limitations (like DWORD) because there is no reason to write "DWORD" instead of "int64_t" or if you prefer the Microsoft way "DWORDLONG".
03/23/2016 14:46 Cyrex'#5
Quote:
Originally Posted by Shadow992 View Post
WinDef.h defines "DWORD" as the following:
Code:
typedef unsigned long DWORD;
Datatype "unsigned long" is normally 32 Bit, when compiling as 64Bit-Application. At least for VC++ as MSDN suggests:


This means calculating Pointer under 64Bit may produce an integer overflow:
Code:
reinterpret_cast< DWORD* >( reinterpret_cast< DWORD >( hModule ) + pIED->AddressOfFunctions )
The innercast "reinterpret_cast< DWORD >" should be "reinterpret_cast< DWORDLONG >" or something similar.

So @[Only registered and activated users can see links. Click Here To Register...] is not aiming at some kind of "There's nothing wrong with using DWORD except its ptr length will not change if you compile for x64." but wants to state that this code will mostly give wrong results for 64Bit-Applications.
Especially as your answer is kind of wrong. The pointer size will change depending on 32Bit or 64Bit compilation. No matter which datatype you used. The compiler generates you architecture dependent code and this also means that you will get 64Bit pointers for 64Bit systems instead of 32Bit pointers.

P.S.
This code may still work without any problems under GNU, as GNU (as far as I know) defines "long" as 32Bit for 32Bit compilation and 64Bit for 64Bit compilation.

But you should really avoid these limitations (like DWORD) because there is no reason to write "DWORD" instead of "int64_t" or if you prefer the Microsoft way "DWORDLONG".
i will replace it, thanks.
03/23/2016 15:16 warfley#6
Quote:
Originally Posted by Shadow992 View Post
P.S.
This code may still work without any problems under GNU, as GNU (as far as I know) defines "long" as 32Bit for 32Bit compilation and 64Bit for 64Bit compilation.

But you should really avoid these limitations (like DWORD) because there is no reason to write "DWORD" instead of "int64_t" or if you prefer the Microsoft way "DWORDLONG".
I don't see the point using DWORD(LONG) for 64bit ints, because DWORD is a short name for double word which is double sized word and a word is considered a 16 bit unsigned int, and so in my opinion using a DWORD(LONG) type for 64 is just misleading, rather i would use QWORD which name implies the length.

Also i would defenetly use pointer types like uintptr_t because these have exactly the size of the Pointers on the system (8, 16, 32, or 64 bit), while are the native processing types and are faster to process by the computer, than for example a 64 bit int on a 32 bit machine (or even a 16 bit machine)
03/23/2016 16:22 Shadow992#7
Quote:
Originally Posted by warfley View Post
I don't see the point using DWORD(LONG) for 64bit ints, because DWORD is a short name for double word which is double sized word and a word is considered a 16 bit unsigned int, and so in my opinion using a DWORD(LONG) type for 64 is just misleading, rather i would use QWORD which name implies the length.
You are totaly right DWORD should be 32Bit and DWORDLONG 64Bit, even if some compilers may "save" you, you should not use it this way (by impliing that DWORD is 64Bit for GNU).
However DWORDLONG and QWORD are exactly the same (even in Code as they are both defined as "unsigned __int64").
However to be honest I would neither use DWORD(LONG) nor QWORD as this only confuses too much. This release is just another good example of how confusing these names are. If you write "int64_t" you will just see that its length is 64Bit (and if you do not see it you may think about getting some C/C++ basics).
In my opinion these Microsoft-Datatypes are real PITA (= Pain In The Ass). :D

Quote:
Originally Posted by warfley View Post
Also i would defenetly use pointer types like uintptr_t because these have exactly the size of the Pointers on the system (8, 16, 32, or 64 bit), while are the native processing types and are faster to process by the computer, than for example a 64 bit int on a 32 bit machine (or even a 16 bit machine)
Well for this small example this may be quite unimportant but I am a performance fan, too. That is why I have to say: "Pefect way to do it!"