Read PE and find SAFESEH status in C++ (make use of RVA) - winapi

I'm using imagehlp.h to parse my binary and get LOADED_IMAGE.
-LoadedImage.FileHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress
The above gets me the RVA for IMAGE_LOAD_CONFIG_DIRECTORY
As I unsderstand, RVA are offsets to my desired data structure.
So, (PIMAGE_LOAD_CONFIG_DIRECTORY)(RVA+LoadedImage.MappedAddress)
should return me my structure correctly (?).
Is this the right way to convert RVA to meaningful pointer.
I am not sure because the timestamp value in
PIMAGE_LOAD_CONFIG_DIRECTORY->TimeDateStamp does not show correctly.
On examination of the memory,
My LoadedImage.MappedAddress points me to "MZ" header. Which is the start of the binary file. Which means my baseaddress is correct. So I conclude that I'm not correctly using the RVA.
Anyone knows the correct way to use the RVA?
Before anyone points out, I've check that the value of virtualaddress for OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress` is not 0 before proceeding further.

Related

DW_OP_fbreg 'operand' to retrieve value of a variable is not working as expected?

Setup: I am debugging a simple C++ program compiled with option -fno-omit-frame-pointer, using libwarf for DWARF 5. Main work is to write a debugger using libdwarf.
For a particular local variable, dwarfdump shows:
DW_AT_location len 0x0002: 915c: DW_OP_fbreg -36
In the following I will refer to '-36' as 'op1', which I get from libdwarf.
Problem: Using op1 directly results in incorrect value for the variable.
(fbPointer is current value of frame base pointer).
int32_t data = (int32_t) ptrace(PTRACE_PEEKDATA, processPid, fbPointer + op1, 0);
I also tried decoding -36 as sleb128 and usleb128, and for both I got 220. Not a good value.
Trial/error shows that if I add 16 to op1, it will work for any number of int variables as parameters and local objects. However, it does not work for float/double.
Question: Is -36, as mentioned everywhere, offset of variable from frame-base pointer? If so, what am I doing wrong?
What are the preceding values in DW_AT_location: "len 0x0002: 915c:"? If they are important in evaluating op1, how do I get them via libdwart?
Thank you very much. It has been more than a week I am stuck at this point.
It seems that DW_OP_fbreg is a reference to DWARF register which in this case is 16 bytes off. That is, we need to add 16 to RBP, the real register, then add -36 to that. Finally, somehow in this case -36 is a plain number as opposed to encoded sleb128.

How is SizeOfImage in the PE optional header computed?

How is SizeOfImage in the PE optional header computed?
Trying to learn the PE format, I've come across the SizeOfImage field in the optional header.
To quote the documentation:
The size (in bytes) of the image, including all headers, as the image
is loaded in memory. It must be a multiple of SectionAlignment.
However, I've experienced that if I set this field wrongly, then the executable won't run and an error 193 (badly formatted excutable) is displayed:
How do I compute the SizeOfImage field, and why won't an executable run if its set wrong (e.g. the executable runs if it's set to 0x00003000 but not 0x00004000 or 0x00002000)?
The safest way that I know of is to loop through each section and find the section to be loaded last in memory (i.e. the highest address). You can almost always assume this is the last section and just skip directly to that section if you trust your PE file (such as if you are using a standard linker, etc). You begin with calculating the end-of-data pointer of that section as follows:
pEndOfLastSection = pLastSection->VirtualAddress + pLastSection->Misc.VirtualSize + pOptionalHeader->ImageBase
pEndOfLastSection now represents the end of the actual section's data (as it exists in the file, padded to file alignment, but not padded to memory alignment) and doesn't include any padding the loader must add to ensure the section fits exactly within the granularity of the memory section alignment.
Despite the other fields that might seem to store the end of the section rounded up to the next nearest "memory" alignment, you must you must perform this calculation yourself on the pEndOfLastSection pointer. I wrote the following function which so far has worked for my purposes:
//
// peRoundUpToAlignment() - rounds dwValue up to nearest dwAlign
//
DWORD peRoundUpToAlignment(DWORD dwAlign, DWORD dwVal)
{
if (dwAlign)
{
//do the rounding with bitwise operations...
//create bit mask of bits to keep
// e.g. if section alignment is 0x1000 1000000000000
// we want the following bitmask 11111111111111111111000000000000
DWORD dwMask = ~(dwAlign-1);
//round up by adding full alignment (dwAlign-1 since if already aligned we don't want anything to change),
// then mask off any lower bits
dwVal = (dwVal + dwAlign-1) & dwMask;
}
return(dwVal);
} //peRoundUpToAlignment()
Now take your pEndOfLastSecion and pass it to the rounding function as follows:
//NOTE: we are rounding to memory section alignment, not file
pEndOfLastSectionMem = peRoundUpToAlignment(pOptionalHeader->SectionAlignment,pEndOfLastSection)
Now you have a "simulated" pointer to the end of the PE file as it would be loaded in memory. NOTE: the end pointers calculated above actually point 1 byte past the last byte of the last section; this allows you to subtract them from their base to get the size. Once you have the end pointer of the last section as it would be loaded in memory, you can subtract this from the loader base and get the size of the PE file as it should be loaded in memory, and this size is obviously the same regardless of where the loader might relocate the PE file:
uCalcSizeOfFile = pEndOfLastSectionMem - pOptionalHeader->ImageBase
Unless the image has been tampered with, the calculation of uCalcSizeOfFile above should be equal to the pOptionalHeader->SizeOfImage field.

Calculating the file offset of a entry point in a PE file

In
http://en.redinskala.com/finding-the-ep/
there is information about how to find the file offset of the entry point in a exe-file.
Here I can read that
EP (File) = AddressOfEntryPoint – BaseOfCode + .text[PointerToRawData]
+ FileAlignment
However, when I have been calculating this myself (I used a couple of different exe files) I have came to the conclusion that
Offset of entry point in EXE file = AddressOfEntryPoint + .text[PointerToRawData] -
.text[VirtualAddress]
Where AddressOfEntryPoint is fetched from IMAGE_OPTIONAL_HEADER and the other two values from the IMAGE_SECTION_HEADER.
Is the information on that web page false? Adding FileAlignment like they do just seems wrong, it does not make sense. Or does it? A file alignment suggests that I should use modulo or something to compute a value. If BaseOfCode and FileAlignment is the same value (mostly they are), it would not disturb adding them to the calculation, but how would it make sense?
Correct, you don't need to use the FileAlignment value at all.
The algorithm should be something like as follow (very similar to yours):
Get AddressOfEntryPoint from IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint (this is a VA)
Search in which section header this VA resides (usually the 1st one, but you should really search in all section headers).
Once you have the right section header, get its VirtualAddress and PointerToRawData fields.
Subtract VirtualAddress from AddressOfEntryPoint: you now have a "delta"
As the exactly same delta applies to offsets, then: add "delta" to PointerToRawData.
You simply don't need FileAlignment because the section in which the entry point lies is already aligned on that value.

Please explain what this Syncsort code does?

The below code was in a proc which is included in my job under the DD name sort.controls.
This step was executed with the sort program, Syncsort. I can understand that the START in the below code indicates the starting position of the field used for sorting and LENGTH denotes the length of the field for sorting. But I can't understand what is ID TYPECODE=1. Can anyone please explain this?
ID TYPECODE=1,LRECL=00302,FORMAT=FB
CF1 START=00038,LENGTH=023
ID Type code 1 is system-specific. In my experience it normally means it's a disk file vs a cart or carddata or something but I'd have to know more about your environment.
LRECL is the defined length of the record for that file (302 bytes)
Format=FB means it is Fixed Block - the length is always 302 bytes and does not vary.
Hopefully that's helpful.

Cannot access animate-properties in Clutter

I am trying to animate an actor in Clutter, but when I enter a property that exists, something goes wrong.
actor.animate( AnimationMode.LINEAR, 400, scale_x:2);
gives me this error
Clutter-WARNING **: Cannot bind property '\x83\xec\u0014\x89\xc6e\xa1\u000c': objects of type 'ClutterTexture' do not have this property
Looks like Unicode-characters to me.
However, when I enter a property that does NOT exist
actor.animate( AnimationMode.LINEAR, 400, thisdoesntwork:2);
I get an error that makes much more sense
Clutter-WARNING **: Cannot bind property 'thisdoesntwork': objects of type 'ClutterTexture' do not have this property
I get the exact same problem when I try this alternative approach:
actor.animate( AnimationMode.LINEAR, 400, "scale-x", 2);
How come all properties that actually exist get converted to some mess, and what can I do to get this to work?
You should be using 2.0 for the value, not 2. 2 is an integer, 2.0 is a double. Vala can't provide type safety for variadic methods, so you have to be careful.
As for why you're seeing the behavior you are for properties which exist, my guess is it has to do with the fact that 2 is a (32-bit) integer and 2.0 is a (64-bit) double. This is simplifying things a bit, and I don't know how much experience you have with C (probably not a lot, since this is the sort of mistake someone coming from a dynamically typed language would make), however... Clutter (well, va_arg) expects a double so it parses 64 bits of data, but you only provided 32 bits, so the first 32-bits of the next argument (NULL) are included. Now, when it starts trying to parse the next argument it starts from the wrong location (32-bits into the argument), so you get the the remainder of NULL and part of whatever garbage happened to be on the stack... Unsuprisingly, that doesn't just so happen to be 32-bits of 0s so when Clutter tests to see if the value it just read == NULL it isn't and Clutter thinks it's been given a pointer to an null-terminated array of characters (which is how strings are represented in C). It reads the data at that location, which just so happens to be \x83\xec\u0014\x89\xc6e\xa1\u000c, and checks to see if there is a property with that name. There isn't, so it emits the error message you saw.
Now, if you switch to using a property which doesn't exist, Clutter will parse the argument (the name of the property), notice that it doesn't exist (just like it did with the second property above), and emit an error.

Resources