How to find exported functions' addresses in 64bit DLLs? - c++

I'm analyzing 32bit and 64bit DLLs. I would like to find out what are the exported functions' addresses. I already dealt with 32bit DLLs but the same code doesn't work with 64bit modules.
DWORD address = (*module)->getImageBaseAddress();
DWORD headerAddress = address + ((PIMAGE_DOS_HEADER)address)->e_lfanew;
PIMAGE_NT_HEADERS header = (PIMAGE_NT_HEADERS)headerAddress;
PIMAGE_EXPORT_DIRECTORY exports = (PIMAGE_EXPORT_DIRECTORY)(address + header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
PVOID names = (BYTE *)address + exports->AddressOfNames;
PVOID moduleFunctions = (BYTE *)address + exports->AddressOfFunctions;
std::cout << "Characteristics: " << exports->Characteristics << endl;
std::cout << "TimeDateStamp: " << exports->TimeDateStamp << endl;
std::cout << "Major version: " << exports->MajorVersion << endl;
std::cout << "Minor version: " << exports->MinorVersion << endl;
std::cout << "Name: " << exports->Name << endl;
std::cout << "Base: " << exports->Base << endl;
std::cout << "Number of fun: " << exports->NumberOfFunctions << endl;
std::cout << "Number of names: " << exports->NumberOfNames << endl;
for (int i = 0; i < exports->NumberOfFunctions; i++) {
std::cout << std::string((char*)((BYTE *)address + ((DWORD *)names)[i])) << " # " << ((DWORD *)moduleFunctions)[i] << endl;
}
The first output lines look fine (TimeDateStamp has proper value, function names are properly resolved etc.). Unfortunately when I compare my functions' image base offsets with those given by IDA after DLLs file analysis the results differ. E.g. for the first module I get the offset equal to 11d0b where due to IDA no valid instruction starts at this address (imageBase + 0x11d0b).
Is my method of getting the function addresses in 64bit DLLs correct? Why do I get different results? Why everything works fine with 32 bit modules?

The optional header struct is a different size if you are in a 64bit binary. Look at the PE COFF spec for the official reference.
You will need to key off of the "Magic Number" in the optional header (the first field) to identify which format of the structure to use.
Edit: Adding the code snippet which shows choosing the proper header format:
char* address = (*module)->getImageBaseAddress();
char* headerAddress = address + ((PIMAGE_DOS_HEADER)address)->e_lfanew;
PIMAGE_NT_HEADERS32 header32 = (PIMAGE_NT_HEADERS32)headerAddress;
PIMAGE_NT_HEADERS64 header64 = (PIMAGE_NT_HEADERS64)headerAddress;
PIMAGE_EXPORT_DIRECTORY exports = NULL;
if (header32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) // PE32
exports = (PIMAGE_EXPORT_DIRECTORY)(address + header32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
else if (header32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) // PE32+
exports = (PIMAGE_EXPORT_DIRECTORY)(address + header64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
else
return 0;
Also note that if you are trying to do this from an image loaded manually from a file (e.g. a raw mapping of the file), you will need to convert the RVA into a file offset by looking up the memory address in the section listing to identify the file pointer location.

Related

Named Address Spaces for MSVC

GCC and Clang support a feature called Named Address Space, that allows users to instruct the compiler to generate accesses to certain variables or members through FS or GS register.
Does MSVC support a feature like this?
(I have not been able to find anything on MSDN, but seeing how Windows has long allowed users to change the value of segment registers with FSGSBASE, the compiler must be providing some way to actually arrange the data appropriately, right?)
In MSVC most low-level things are done via intrinsics. Same to this
Read the base address: _readfsbase_u32, _readgsbase_u32, _readfsbase_u64,_readgsbase_u64
Write the base address: _writefsbase_u32, _writegsbase_u32, _writefsbase_u64, _writegsbase_u64
See x64 (amd64) intrinsics list
To operate on the pointer relative to the base address use
__addfsbyte, __addfsword, __addfsdword
__addgsbyte, __addgsword, __addgsdword, __addgsqword
__incfsbyte, __incfsword, __incfsdword
__incgsbyte, __incgsword, __incgsdword, __incgsqword
__readfsbyte, __readfsdword, __readfsqword, __readfsword
__readgsbyte, __readgsdword, __readgsqword, __readgsword
__writefsbyte, __writefsdword, __writefsqword, __writefsword
__writegsbyte, __writegsdword, __writegsqword, __writegsword
Here's an example
#include <iostream>
#include <intrin.h>
#include <immintrin.h>
#include <cstdint>
int main()
{
int data[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::cout << "&data = " << (void*)&data << '\n';
std::cout << "GS base before = " << (void*)_readgsbase_u64() << '\n';
_writegsbase_u64((uintptr_t)&data);
std::cout << "GS base after pointing to data[0] = " << (void*)_readgsbase_u64() << '\n';
std::cout << "GS:[1] = " << __readgsdword(1) << ", GS:[3] = " << __readgsdword(3) << '\n';
_writegsbase_u64((uintptr_t)&data[7]);
std::cout << "GS base after pointing to data[7] = " << (void*)_readgsbase_u64() << '\n';
std::cout << "GS:[0] = " << __readgsdword(0) << ", GS:[2] = " << __readgsdword(2) << '\n';
}
Unfortunately I don't know why in intrin.h the GS functions are only available in 64-bit mode and FS functions are only available in 32-bit mode. Since GS is used for TLS in 64-bit Windows I couldn't change it. Calling _writegsbase_u64 seems to do nothing when I step over the program, the base address is still the same before and after setting. So currently the above code doesn't work on my machine

flatbuffers::Table* to buffer_pointer

Consider this scenario.
I'm creating a struct(flatbuffers::Table) using CreateXXX generated code. This creates the struct on the FlatBuffer buffer and gives me the offset.
Then I can get the memory block with GetBufferPointer() and transfer it.
Reversely, if I get a memory block, I can use GetXXX to get my struct(flatbuffers::Table) from that.
But after I get this struct, if I need to serialize it again, how can I do it? After the serialization, I should be able to transfer that data and do GetXXX on that data like before.
flatbuffers::Parser parser;
parser.Parse(schema.c_str());
parser.SetRootType("license");
parser.Parse(j.c_str());
auto* buf = parser.builder_.GetBufferPointer();
auto li = flatbuffers::GetRoot<license>(buf);
std::cout << "ID: " << li->id()->c_str() << " Rand: " << li->rand()->c_str() << " Secret: " << li->secret()->c_str() << std::endl;
uint8_t* buf2 = ????????????
auto li2 = flatbuffers::GetRoot<license>(buf2);
std::cout << "ID: " << li2->id()->c_str() << " Rand: " << li2->rand()->c_str() << " Secret: " << li2->secret()->c_str() << std::endl;
The obvious answer is that you keep the original buffer pointer (and size) around. Then you can "re-serialize" it by just writing out the existing buffer.
There is a function GetBufferStartFromRootPointer if you really must use just the root (li in your example).

AccessViolationException when trying to call c# callback

I have this simple code:
typedef void (__stdcall * OrdersCallback)(ordersTest*);
__declspec(dllexport) void InitializeCallbacks(long ordersCallbackAddress_) {
OrdersCallback ordersCallbackFunction;
std::cout << "current ordersCallbackFunction = " << ordersCallbackFunction << " address = " << &ordersCallbackFunction << std::endl;
std::cout << "set ordersCallbackAddress_ = " << ordersCallbackAddress_ << std::endl;
ordersCallbackFunction = (OrdersCallback) ordersCallbackAddress_;
std::cout << "new ordersCallbackFunction = " << ordersCallbackFunction << " address = " << &ordersCallbackFunction << std::endl;
ordersTest test;
test.replID = 123;
std::cout << "use ordersCallbackFunction = " << ordersCallbackFunction << " address = " << &ordersCallbackFunction << std::endl;
ordersCallbackFunction(&test);
}
And when callback is calling AccessViolationException is raised:
current ordersCallbackFunction = 000007F92BC354E0 address = 0000009785D1EC68
set ordersCallbackAddress_ = -2043003524
new ordersCallbackFunction = FFFFFFFF863A3D7C address = 0000009785D1EC68
use ordersCallbackFunction = FFFFFFFF863A3D7C address = 0000009785D1EC68
Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
I can't understand what's wrong, in another project very similar code works. Thanks!
upd, more code:
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void OrdersCallback(ref OrdersTest value);
[DllImport("CGateNativeAdapter.dll"), SuppressUnmanagedCodeSecurity]
public static extern void InitializeCallbacks(
[MarshalAs(UnmanagedType.FunctionPtr)] OrdersCallback ordersSnapshotCallbackPointer);
OrdersCallback ordersCallback =
delegate(ref OrdersTest value)
{
Console.WriteLine("C# Orders call received = " +
" replID = " + value.replID);
};
InitializeCallbacks(ordersCallback);
The most obvious flaw in what you have shown is that you are attempting to pass the 64 bit pointer as 32 bit value which clearly cannot work. The ordersCallbackAddress_ parameter is declared as long, which is 32 bits wide. But you clearly have a 64 bit process. That almost certainly explains the error that your are experiencing.
Remember that in C++ on Windows, long is 32 bits wide. In C# it is 64 bits wide. In any case you should not use integral types to pass pointers. If you have a pointer, design your functions to operate on pointers.
You need to make sure that ordersCallbackAddress_ is declared to be pointer sized. I don't understand why it is not declared as OrdersCallback.
There may be other problems, but you did not show very much code. You did not show struct declarations, or anything on the managed side of the interface.

Correctly Deal With Byte Alignment Issues -- Between 16 Bit Embeded System and 32 Bit Desktop via UDP

The application I am working on receives C style structs from an embed system whose code was generated to target a 16 bit processor. The application which speaks with the embedded system is built with either a 32 bit gcc compiler, or a 32 bit MSVC c++ compiler. The communication between the application and the embedded system takes place via UDP packets over ethernet or modem.
The payload within the UDP packets consist of various different C style structs. On the application side a C++ style reinterpret_cast is capable of taking the unsigned byte array and casting it into the appropriate struct.
However, I run into problems with reinterpret_cast when the struct contains enumerated values. The 16 bit Watcom compiler will treat enumerated values as an uint8_t type. However, on the application side the enumerated values are treated as 32 bit values. When I receive a packet with enumerated values in it the data gets garbled because the size of the struct on the application side is larger the struct on the embedded side.
The solution to this problem, so far, has been to change the enumerated type within the struct on the application side to an uint8_t. However, this is not an optimal solution because we can no longer use the member as an enumerated type.
What I am looking for is a solution which will allow me to use a simple cast operation without having to tamper with the struct definition in the source on the application side. By doing so, I can use the struct as is in the upper layers of my application.
As noted, correctly deal with the issue is proper serialization and deserialization.
But it doesn't mean we can't try some hacks.
Option 1:
If you particular compiler support packing the enum (in my case gcc 4.7 in windows), this might work:
typedef enum { VALUE_1 = 1, VALUE_2, VALUE_3 }__attribute__ ((__packed__)) TheRealEnum;
Option 2:
If your particular compiler supports class sizes of < 4 bytes, you can use a HackedEnum class which uses operator overloading for the conversion (note the gcc attribute you might not want it):
class HackedEnum
{
private:
uint8_t evalue;
public:
void operator=(const TheRealEnum v) { evalue = v; };
operator TheRealEnum() { return (TheRealEnum)evalue; };
}__attribute__((packed));
You would replace TheRealEnum in your structures for HackedEnum, but you still continue using it as TheRealEnum.
A full example to see it working:
#include <iostream>
#include <stddef.h>
using namespace std;
#pragma pack(push, 1)
typedef enum { VALUE_1 = 1, VALUE_2, VALUE_3 } TheRealEnum;
typedef struct
{
uint16_t v1;
uint8_t enumValue;
uint16_t v2;
}__attribute__((packed)) ShortStruct;
typedef struct
{
uint16_t v1;
TheRealEnum enumValue;
uint16_t v2;
}__attribute__((packed)) LongStruct;
class HackedEnum
{
private:
uint8_t evalue;
public:
void operator=(const TheRealEnum v) { evalue = v; };
operator TheRealEnum() { return (TheRealEnum)evalue; };
}__attribute__((packed));
typedef struct
{
uint16_t v1;
HackedEnum enumValue;
uint16_t v2;
}__attribute__((packed)) HackedStruct;
#pragma pop()
int main(int argc, char **argv)
{
cout << "Sizes: " << endl
<< "TheRealEnum: " << sizeof(TheRealEnum) << endl
<< "ShortStruct: " << sizeof(ShortStruct) << endl
<< "LongStruct: " << sizeof(LongStruct) << endl
<< "HackedStruct: " << sizeof(HackedStruct) << endl;
ShortStruct ss;
cout << "address of ss: " << &ss << " size " << sizeof(ss) <<endl
<< "address of ss.v1: " << (void*)&ss.v1 << endl
<< "address of ss.ev: " << (void*)&ss.enumValue << endl
<< "address of ss.v2: " << (void*)&ss.v2 << endl;
LongStruct ls;
cout << "address of ls: " << &ls << " size " << sizeof(ls) <<endl
<< "address of ls.v1: " << (void*)&ls.v1 << endl
<< "address of ls.ev: " << (void*)&ls.enumValue << endl
<< "address of ls.v2: " << (void*)&ls.v2 << endl;
HackedStruct hs;
cout << "address of hs: " << &hs << " size " << sizeof(hs) <<endl
<< "address of hs.v1: " << (void*)&hs.v1 << endl
<< "address of hs.ev: " << (void*)&hs.enumValue << endl
<< "address of hs.v2: " << (void*)&hs.v2 << endl;
uint8_t buffer[512] = {0};
ShortStruct * short_ptr = (ShortStruct*)buffer;
LongStruct * long_ptr = (LongStruct*)buffer;
HackedStruct * hacked_ptr = (HackedStruct*)buffer;
short_ptr->v1 = 1;
short_ptr->enumValue = VALUE_2;
short_ptr->v2 = 3;
cout << "Values of short: " << endl
<< "v1 = " << short_ptr->v1 << endl
<< "ev = " << (int)short_ptr->enumValue << endl
<< "v2 = " << short_ptr->v2 << endl;
cout << "Values of long: " << endl
<< "v1 = " << long_ptr->v1 << endl
<< "ev = " << long_ptr->enumValue << endl
<< "v2 = " << long_ptr->v2 << endl;
cout << "Values of hacked: " << endl
<< "v1 = " << hacked_ptr->v1 << endl
<< "ev = " << hacked_ptr->enumValue << endl
<< "v2 = " << hacked_ptr->v2 << endl;
HackedStruct hs1, hs2;
// hs1.enumValue = 1; // error, the value is not the wanted enum
hs1.enumValue = VALUE_1;
int a = hs1.enumValue;
TheRealEnum b = hs1.enumValue;
hs2.enumValue = hs1.enumValue;
return 0;
}
The output on my particular system is:
Sizes:
TheRealEnum: 4
ShortStruct: 5
LongStruct: 8
HackedStruct: 5
address of ss: 0x22ff17 size 5
address of ss.v1: 0x22ff17
address of ss.ev: 0x22ff19
address of ss.v2: 0x22ff1a
address of ls: 0x22ff0f size 8
address of ls.v1: 0x22ff0f
address of ls.ev: 0x22ff11
address of ls.v2: 0x22ff15
address of hs: 0x22ff0a size 5
address of hs.v1: 0x22ff0a
address of hs.ev: 0x22ff0c
address of hs.v2: 0x22ff0d
Values of short:
v1 = 1
ev = 2
v2 = 3
Values of long:
v1 = 1
ev = 770
v2 = 0
Values of hacked:
v1 = 1
ev = 2
v2 = 3
On the application side a C++ style reinterpret_cast is capable of taking the unsigned byte array and casting it into the appropriate struct.
The layout of structs is not required to be the same between different implementations. Using reinterpret_cast in this way is not appropriate.
The 16 bit Watcom compiler will treat enumerated values as an uint8_t type. However, on the application side the enumerated values are treated as 32 bit values.
The underlying type of an enum is chosen by the implementation, and is chosen in an implementation defined manner.
This is just one of the many potential differences between implementations that can cause problems with your reinterpret_cast. There are also actual alignment issues if you're not careful, where the data in the received buffer isn't appropriately aligned for the types (e.g., an integer that requires four byte alignment ends up one byte off) which can cause crashes or poor performance. Padding might be different between platforms, fundamental types might have different sizes, endianess can differ, etc.
What I am looking for is a solution which will allow me to use a simple cast operation without having to tamper with the struct definition in the source on the application side. By doing so, I can use the struct as is in the upper layers of my application.
C++11 introduces a new enum syntax that allows you to specify the underlying type. Or you can replace your enums with integral types along with a bunch of predefined constants with manually declared values. This only fixes the problem you're asking about and not any of the other ones you have.
What you should really do is proper serialization and deserialization.
Put your enumerated type inside of a union with a 32-bit number:
union
{
Enumerated val;
uint32_t valAsUint32;
};
This would make the embedded side have it expanded to 32-bit. Should work as long as both platforms are little-endian and the structs are zero-filled initially. This would change wire format, though.
If by "simple cast operation" you mean something that's expressed in the source code, rather than something that's necessarily zero-copy, then you can write two versions of the struct -- one with enums, one with uint8_ts, and a constructor for one from the other that copies it element-by-element to repack it. Then you can use an ordinary type-cast in the rest of the code. Since the data sizes are fundamentally different (unless you use the C++11 features mentioned in another answer), you can't do this without copying things to repack them.
However, if you don't mind some small changes to the struct definition on the application side, there are a couple of options that don't involve dealing with bare uint8_t values. You could use aaronps's answer of a class that is the size of a uint8_t (assuming that's possible with your compiler) and implicitly converts to and from an enum. Alternately, you could store the values as uint8_ts and write some accessor methods for your enum values that take the uint8_t data in the struct and convert it to an enum before returning it.

How to access a field of exif data from a Photoshop filter plug-in (Photoshop SDK)

I'm looking for a very specific piece of information. I could make this a rather detailed question I guess but I'd rather try keeping it short and to the point.
I need to acces a piece of meta data (exif information) from within a Photoshop filter plug-in. I have never dealt with exif data from within a Photoshop plug-in or without and the PS SDK documentation is of a form that leaves a lot of questions. I would eventually get there but was wondering if anyone here has done this before and could help me out with an example. I'd be very grateful for that...
What we need should be documented here in the SDK:
documentation/html/group___resource_suite.html
documentation/html/imageresourcessection.html
The latter document says that the resource ID I need to retrieve the exif data is 1059 (decimal) and that accessing Exif data is supported since PS 7.0 which is good. But the SDK has no information (that I found) as to what you get, pointer? pointer to what? They just tell you to look at the exif spec. So do I get a pointer to the RAW binary exif data and if so how to I extract a field from that.
The specifications for the Exif data are here:
http://exif.org/specifications.html
As an example I'd like to get at this exif field:
Tag Name Field Name Dec Hex Type Count
Image title ImageDescription 270 10E ASCII Any
EDIT: After a deeper research I've found the following (an excerpt from the documentation):
Document: Photoshop API Guide.
Argument: Callbacks.
The callback routines are organized into “suites” collections of
related routines which implement a particular functionality.
The suites are described by a pointer to a record containing:
a 2 byte version number for the suite,
a 2 byte count of the number of routines in the suite,
a series of function pointers for the callback routines.
You are interested in the Property suite.
Current version: 1; Adobe Photoshop: 5.0; Routines: 2.
Properties are identified by a signature and key, which form a pair to
identify the property of interest.
Adobe Photoshop’s signature is always '8BIM' (0x3842494D).
The EXIF property is controlled by The Japan Electronic Industry Development Association (JEIDA) and Electronic Industries Association of Japan (EIAJ) which merged in Novemeber of 2000. The EXIF specification can be downloaded from their web site at the following location.
http://it.jeita.or.jp/jhistory/document/standard/exif_eng/jeida49eng.htm
GetPropertyProc( )
MACPASCAL OSErr (*GetPropertyProc) (OSType signature, OSType key, int32 index, int32 * simpleProperty, Handle * complexProperty);
This routine allows you to get information about the document currently being processed.
property name: propEXIFData
id:EXIF
type:complex (modifiable)
description:Camera and device data.
To recap I'll write some juicy code:
GetPropertyProc getProperty = formatParamBlock->propertyProcs->getPropertyProc;
rc = getProperty(0x3842494D, propEXIFData, 0, &simpProp, &compProp);
if ( rc )
return;
GetPIHandleSizeProc getSize = formatParamBlock->handleProcs->getSizeProc;
int32 size = getSize(compProp);
if ( !size )
return;
LockPIHandleProc lock = formatParamBlock->handleProcs->lockProc;
uint8* exif = (uint8 *)lock(compProp, false);
if ( !exif )
return;
Here's is a code sample using the Exiv2 Library: http://www.exiv2.org/doc/exifprint_8cpp-example.html
// ***************************************************************** -*- C++ -*-
// exifprint.cpp, $Rev: 2286 $
// Sample program to print the Exif metadata of an image
#include <exiv2/exiv2.hpp>
#include <iostream>
#include <iomanip>
#include <cassert>
int main(int argc, char* const argv[])
try {
if (argc != 2) {
std::cout << "Usage: " << argv[0] << " file\n";
return 1;
}
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[1]);
assert(image.get() != 0);
image->readMetadata();
Exiv2::ExifData &exifData = image->exifData();
if (exifData.empty()) {
std::string error(argv[1]);
error += ": No Exif data found in the file";
throw Exiv2::Error(1, error);
}
Exiv2::ExifData::const_iterator end = exifData.end();
for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) {
const char* tn = i->typeName();
std::cout << std::setw(44) << std::setfill(' ') << std::left
<< i->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right
<< std::hex << i->tag() << " "
<< std::setw(9) << std::setfill(' ') << std::left
<< (tn ? tn : "Unknown") << " "
<< std::dec << std::setw(3)
<< std::setfill(' ') << std::right
<< i->count() << " "
<< std::dec << i->value()
<< "\n";
}
return 0;
}
//catch (std::exception& e) {
//catch (Exiv2::AnyError& e) {
catch (Exiv2::Error& e) {
std::cout << "Caught Exiv2 exception '" << e.what() << "'\n";
return -1;
}
I combined response vulkanino and ThdK. My method uses the function PIGetEXIFData declared in file PropertyUtils.h that returns a binary exif. Next, this exif decoded Exiv2 library
#include <PropertyUtils.h>
#include <PIProperties.h>
#include <exif.hpp>
void printExif() {
Handle handle;
checkSPErr(PIGetEXIFData(handle));
std::string ss;
checkSPErr(HandleToString(handle, ss));
Exiv2::ExifData exifData;
Exiv2::ExifParser::decode(exifData, reinterpret_cast<const Exiv2::byte*>(ss.data()), ss.size());
Exiv2::ExifData::const_iterator end = exifData.end();
for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) {
const char* tn = i->typeName();
std::cout << std::setw(44) << std::setfill(' ') << std::left
<< i->key() << " "
<< "0x" << std::setw(4) << std::setfill('0') << std::right
<< std::hex << i->tag() << " "
<< std::setw(9) << std::setfill(' ') << std::left
<< (tn ? tn : "Unknown") << " "
<< std::dec << std::setw(3)
<< std::setfill(' ') << std::right
<< i->count() << " "
<< std::dec << i->value()
<< "\n";
}
}