|
You last visited: Today at 20:15
Advertisement
PE Export Parser
Discussion on PE Export Parser within the C/C++ forum part of the Coders Den category.
03/23/2016, 12:33
|
#1
|
elite*gold: 225
Join Date: Sep 2014
Posts: 334
Received Thanks: 460
|
PE Export Parser
May be useful for people coding their own memory mapper.
Main.cpp
Code:
#include <Windows.h>
#include <iostream>
#include <string>
DWORD GetExport( const char *dllName, const char *functionName )
{
PIMAGE_DOS_HEADER pIDH;
PIMAGE_NT_HEADERS pINH;
PIMAGE_EXPORT_DIRECTORY pIED;
HMODULE hModule;
DWORD *AddressTable, *NameTable;
WORD *NameOrdinalTable;
hModule = GetModuleHandle( dllName );
if ( !hModule )
hModule = LoadLibrary( dllName );
pIDH = reinterpret_cast< PIMAGE_DOS_HEADER >( hModule );
if ( pIDH->e_magic != IMAGE_DOS_SIGNATURE )
{
MessageBox( NULL, "Corrupted PE. [\"invalid dos header\"]", "Error", 0 );
return NULL;
}
pINH = reinterpret_cast< PIMAGE_NT_HEADERS >( reinterpret_cast< DWORD >( hModule ) + pIDH->e_lfanew );
if ( pINH->Signature != IMAGE_NT_SIGNATURE )
{
MessageBox( NULL, "Corrupted PE. [\"invalid pe header\"]", "Error", 0 );
return NULL;
}
if(!pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
{
MessageBox( NULL, "Export directory RVA is NULL", "Error", 0 );
return NULL;
}
pIED = reinterpret_cast< PIMAGE_EXPORT_DIRECTORY >( reinterpret_cast< DWORD >( hModule ) + pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress );
AddressTable = reinterpret_cast< DWORD* >( reinterpret_cast< DWORD >( hModule ) + pIED->AddressOfFunctions );
NameTable = reinterpret_cast< DWORD* >( reinterpret_cast< DWORD >( hModule ) + pIED->AddressOfNames );
NameOrdinalTable = reinterpret_cast< WORD* >( reinterpret_cast< DWORD >( hModule ) + pIED->AddressOfNameOrdinals );
for ( auto i = 0; i < pIED->NumberOfNames; ++i )
{
if ( !stricmp( functionName, reinterpret_cast< const char* >( reinterpret_cast< DWORD >( hModule ) + NameTable[i] ) ) )
return ( DWORD )( reinterpret_cast< DWORD >( hModule ) + AddressTable[NameOrdinalTable[i]] );
}
}
int main( )
{
SetConsoleTitle( "Export Parser [Cyrex']" );
std::string szExport, szDll;
DWORD dwExport = NULL;
bool bInsensitive = false;
while ( true )
{
std::cout << "Export: ";
std::cin >> szExport;
std::cout << "DLL: ";
std::cin >> szDll;
std::cout << "Function Address: " << std::hex << GetExport( szDll.c_str( ), szExport.c_str( ) ) << "\n\n";
}
std::cin.get( );
return 0;
}
credits:
|
|
|
03/23/2016, 13:22
|
#2
|
elite*gold: 966
Join Date: Apr 2010
Posts: 1,105
Received Thanks: 681
|
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  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
Why is every *** **** 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
|
#3
|
elite*gold: 225
Join Date: Sep 2014
Posts: 334
Received Thanks: 460
|
Quote:
Originally Posted by Jeoni
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  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
|
#4
|
elite*gold: 77
Join Date: May 2008
Posts: 5,430
Received Thanks: 5,878
|
Quote:
Originally Posted by Cyrex'
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:
|
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 @  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
|
#5
|
elite*gold: 225
Join Date: Sep 2014
Posts: 334
Received Thanks: 460
|
Quote:
Originally Posted by Shadow992
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 @  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
|
#6
|
elite*gold: 0
Join Date: Feb 2009
Posts: 1,137
Received Thanks: 573
|
Quote:
Originally Posted by Shadow992
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
|
#7
|
elite*gold: 77
Join Date: May 2008
Posts: 5,430
Received Thanks: 5,878
|
Quote:
Originally Posted by warfley
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).
Quote:
Originally Posted by warfley
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!"
|
|
|
 |
Similar Threads
|
Help combat parser
02/09/2014 - General Coding - 9 Replies
Hello, what i want to do is pull combat data from a game to be able to make a combat log. I have tried searching but have not found anything yet, i could be searching horribly wrong since i am not familiar with this.
This is more for self improvement so any references/tutorials for this would be a great help. The game i want to do this for is call aura kingdom. I would also like
a reference for finding where the combat data is stored as the game does not make combat log text.
I know...
|
AccountID Parser by D.E.Z.E.R.T.I.R
07/08/2012 - DarkOrbit - 20 Replies
http://i.zhyk.ru/images/ofa2S.png
in the first box insert a link to player profile. In the second field get id and in the third get GlobalID
Download
VirusTotal
|
NPC.ini Parser
03/13/2011 - CO2 Programming - 1 Replies
Ah, well I know this is REALLY simple, but as I was rummaging through my hard drive, I found something that might be useful to some people. It pretty much goes through the npc.ini and parses the data and writes it to a new text file, and writes it like this,
10-19 Storekeeper
Yeah its pretty simple, but it should help most people.
You MIGHT need to change the value of the 1122 in "for (int x = 1; x < 1122; x++)" depending on what patch the npc.ini is.
using System;
using...
|
Parser
04/08/2009 - FFXI Exploits, Hacks, Bots, Tools & Macros - 0 Replies
Hello, sorry i have been looking for a parser for some time and have tried many different ones and none seem to work in some way or another, most of the time its compatibility issues (vista x64) or some .net framework problem or something. The ones i did get working only displayed my data (which was innacurate btw) and did not display anyone elses data that was in the party. If anyone can help it would be greatly appreciated, thanks ^^
|
All times are GMT +1. The time now is 20:16.
|
|