Problems iterating through AddressOfNames member of IMAGE_EXPORT_DIRECTORY structure - arrays

I'm having problems enumerating function names in kernel32.dll. I retrieved its IMAGE_EXPORT_DIRECTORY structure and stored an array of pointers to char arrays of each function name: char** name_table = (char**)(image+pExp_dir->AddressOfNames); //pExp_dir is a pointer to the IMAGE_EXPORT_DIRECTORY structure. I'm now trying to iterate through the function names and match them to a string containing the name of the function whom's RVA I need.
for(int i=0;i<pExp_dir->NumberOfNames;i++) //until i is 1 less than how many names there are to iterate through elements
{
printf("%s ", (char*)(image+(DWORD)(uintptr_t)name_table[i])); //print the name of each function iterated through, I went back and read through these names and didn't see GetProcAddress anywhere
if(proc_name == image+(DWORD)(uintptr_t)name_table[i]) //if(strcmp(proc_name, (const char*)image+(DWORD)(intptr_t)name_table[i]) == 0) //Is it the function we're looking for?
{
address = (DWORD)(uintptr_t)func_table[ord_table[i]];//If so convert the address of the function into a DWORD(hexadecimal)
system("pause");
system("CLS"); //Clear the screen
return address; //return the address of the function
}
But if it doesn't find the function then the program crashes. And after looking in the memory dump in the DBG debugger I can see that name_tables contains all of the function names including the function I'm looking for but my program seems to skip several elements even though I'm iterating through its elements one at a time. User stijn suggested that I shouldn't use intptr_t to cast char* to DWORD to use for pointer arithmetic. So my question is really about the correct way to iterate through name_table because it seems as if this is a pointer arithmetic problem. Here's the function to get the file image and the function that actually gets the RVA:
void* GetFileImage(char path[]) //Get maps the image of the file into memory and returns the beginning virtual address of the file in memory
{
HANDLE hFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);//Get a handle to the dll with read rights
if(hFile == INVALID_HANDLE_VALUE){printf("Error getting file handle: %d", (int)GetLastError());return NULL;} //Check whether or not CreateFile succeeded
HANDLE file_map = CreateFileMapping(hFile, NULL, PAGE_READONLY|SEC_IMAGE, 0, 0, "KernelMap"); //Create file map
if(file_map == INVALID_HANDLE_VALUE){printf("Error mapping file: %d", (int)GetLastError());return NULL;} //Did it succeed
LPVOID file_image = MapViewOfFile(file_map, FILE_MAP_READ, 0, 0, 0); //Map it into the virtual address space of my program
if(file_image == 0){printf("Error getting mapped view: %d", (int)GetLastError());return NULL;} //Did it succeed
return file_image; //return the base address of the image
}
DWORD RVAddress(char* image, const char* proc_name) //Gets the relative virtual address of the function and returns a DWORD to be cast to void*.
{
DWORD address = 0xFFFFFFFF;
PIMAGE_DOS_HEADER pDos_hdr = (PIMAGE_DOS_HEADER)image; //Get dos header
PIMAGE_NT_HEADERS pNt_hdr = (PIMAGE_NT_HEADERS)(image+pDos_hdr->e_lfanew); //Get PE header by using the offset in dos header + the base address of the file image
IMAGE_OPTIONAL_HEADER opt_hdr = pNt_hdr->OptionalHeader; //Get the optional header
IMAGE_DATA_DIRECTORY exp_entry = opt_hdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
PIMAGE_EXPORT_DIRECTORY pExp_dir = (PIMAGE_EXPORT_DIRECTORY)(image+exp_entry.VirtualAddress); //Get a pointer to the export directory
void** func_table = (void**)(image+pExp_dir->AddressOfFunctions); //Get an array of pointers to the functions
WORD* ord_table = (WORD*)(image+pExp_dir->AddressOfNameOrdinals); //Get an array of ordinals
char** name_table = (char**)(image+pExp_dir->AddressOfNames); //Get an array of function names
for(int i=0;i<pExp_dir->NumberOfNames;i++) //until i is 1 less than how many names there are to iterate through elements
{
printf("%s ", (char*)(image+(DWORD)(uintptr_t)name_table[i])); //print the name of each function iterated through, I went back and read through these names and didn't see GetProcAddress anywhere
if(proc_name == image+(DWORD)(uintptr_t)name_table[i]) //if(strcmp(proc_name, (const char*)image+(DWORD)(intptr_t)name_table[i]) == 0) //Is it the function we're looking for?
{
address = (DWORD)(uintptr_t)func_table[ord_table[i]];//If so convert the address of the function into a DWORD(hexadecimal)
system("pause");
system("CLS"); //Clear the screen
return address; //return the address of the function
}
}
return (DWORD)0; //Other wise return 0
}
Any help would be much appreciated!

Docs (Section 6.3) say next about AddressOfNames table
The Export Name Pointer Table is an array of addresses (RVAs) into the
Export Name Table. The pointers are 32 bits each and are relative to
the Image Base. The pointers are ordered lexically to allow binary
searches.
And about AddressOfFunctions:
Each entry in the Export Address Table is a field that uses one of two
formats, ... If the address specified is not within the export section
(as defined by the address and length indicated in the Optional
Header), the field is an Export RVA: an actual address in code or
data. Otherwise, the field is a Forwarder RVA, which names a symbol in
another DLL.
Your variables is not void** and char**, but actually all are DWORD* because these tables hold RVA. Try next code:
DWORD* func_table = (DWORD*)(image+pExp_dir->AddressOfFunctions); //Get an array of pointers to the functions
WORD* ord_table = (WORD*)(image+pExp_dir->AddressOfNameOrdinals); //Get an array of ordinals
DWORD* name_table = (DWORD*)(image+pExp_dir->AddressOfNames); //Get an array of function names
for(int i=0;i<pExp_dir->NumberOfNames;i++) //until i is 1 less than how many names there are to iterate through elements
{
printf("%s ", (char*)(image+name_table[i])); //print the name of each function iterated through, I went back and read through these names and didn't see GetProcAddress anywhere
if(strcmp(proc_name, (const char*)(image+name_table[i])) == 0) //Is it the function we're looking for?
{
// TODO should we distinguish between normal and forwarded exports?
WORD ordinal_base = 1; // TODO read it from export directory
address = func_table[ord_table[i] - ordinal_base];//If so convert the address of the function into a DWORD(hexadecimal)
system("pause");
system("CLS"); //Clear the screen
return address; //return the address of the function
}
}
So when your code runs on 32-bit machine it should work regardless of the incorrect var types, but if you are on 64-bit - pointers are twice longer than DWORD and it will skip odd entries in tables and goes out of array bound, that may cause crash.
P.S. Name table is ordered, so you can use binary search.

Related

malloc of char* also change other char* variable

I'm programming atmega8535 using C. I want to save data into flash disk using ALFAT OEM module. But, I have problem because the data that I want to save change into other variable in the middle program (Data saving is success, but the data is wrong). It occurs after malloc. I already malloc the variable data. I'm using hyperterminal to debugging my program
This is my code. I only show that related
// Declare your global variables here
char* reply = NULL;
char* directory = NULL;
char* fileName = NULL;
char* getFileName = NULL;
void writeCommand(char* command){ //to give command to ALFAT
//not related
}
void readCommand(){ //to request reply from ALFAT
//related (because contains malloc and also change my variable) but I give another example
}
void get_ErrorCode(char errorCode[4]){ //to get errorCode from ALFAT's reply
//not related
}
void get_Version(){ //to know ALFAT's version
//not related
}
void mountUSB0(){ //to mount USB port 0
//not related
}
void mountUSB1(){ //to mount USB port 1
//not related
}
void get_fileName(){ //to get fileName from ALFAT's reply after N command
//not related
}
int check_File(char port[1]){ //to check whether file already exists or not
//related (because contains malloc and also change my variable) but I give another example
}
void separate_Directory(char* fullDir, char* data){ //to separate directory and fileName from fullDirectory "fullDir"
int i,j;
int numSlash = 0; //numberOfSlash
int curNumSlash = 0; //currentNumberOfSlash
//CHECK THE DATA BEFORE MALLOC
printf("1st GUNYUH data = %s, address data = %x, directory = %s, address directory = %x\n",data,data,directory,directory);
//count backslash '\'=0x5C
for (i=0;i<strlen(fullDir);i++){
if(fullDir[i]== 0x5C ) numSlash++;
}
//count number of char for directory
i=0;
curNumSlash = 0;
while (curNumSlash != numSlash){
if(fullDir[i]== 0x5C) curNumSlash++;
i++;
}
//i = number of char for directory
//number of char for filename = strlen(fullDir)-total char directory
do{
directory = (char *) malloc (i+1);
}while(directory==NULL);
do{
fileName = (char *) malloc (strlen(fullDir)-i+1);
}while(fileName==NULL);
//CHECK THE DATA AFTER MALLOC (ALREADY CHANGED)
printf("2nd GUNYUH data = %s, address data = %x, directory = %s, address directory = %x\n",data,data,directory,directory);
//save into directory until last backslash
i=0;
curNumSlash = 0;
while (curNumSlash != numSlash){
if(fullDir[i]== 0x5C) curNumSlash++;
directory[i] = fullDir[i];
i++;
}
directory[i] = '\0';
//remaining fullDir into fileName
j=0;
while (i < strlen(fullDir)){
fileName[j] = fullDir[i];
i++;
j++;
}
fileName[j] = '\0';
//CHECK THE DATA AGAIN (CHANGED INTO directory)
printf("3rd GUNYUH data = %s, address data = %x, directory = %s, address directory = %x\n",data,data,directory,directory);
printf("separate directory = %s, fileName = %s, fullDir = %s\n",directory,fileName,fullDir);
}
void writeData (char* data, char* fullDir, char port[1], char statFileHandler[16]){
//I omit that not related
printf("1)!!!!!!!!!!!!!!!!DATA = %s, ADDRESS DATA = %x, DIRECTORY = %s, ADDRESS DIRECTORY = %x\n",data,*data,directory,*directory);
separate_Directory(fullDir,data);
printf("2)!!!!!!!!!!!!!!!!DATA = %s, ADDRESS DATA = %x, DIRECTORY = %s, ADDRESS DIRECTORY = %x\n",data,*data,directory,*directory);
//omitted
}
void main(){
char* data;
char* fullDir = NULL;
char port[1]="";
char statFileHandler[16];
//omitted
while(1){
//omitted (also omit the mounting)
do{
data = (char *) malloc (strlen("meong")+1); //+1 utk \0
}while(data==NULL);
strcpy(data,"meong");
data[strlen("meong")] = '\0';
fullDir = (char *) malloc (strlen("\\f1\\nyan.txt")+1);
strcpy(fullDir,"\\f1\\nyan.txt");
fullDir[strlen("\\f1\\nyan.txt")] = '\0';
for(i=0;i<strlen("\\f1\\nyan.txt");i++){
fullDir[i] = toupper(fullDir[i]);
}
//omit some printf for debugging
printf("fullDir di main= %s\n",fullDir);
printf("data di main = %s\n",data);
printf("address data di main = %x\n",*data);
writeData (data, fullDir, port, statFileHandler);
break;
}
while(1){}
}
}
}
Check the GUNYUH part. The output in HyperTerminal:
1st GUNYUH data = meong, address data = 196, directory = , address directory = 0
2nd GUNYUH data = , addressdata = 196, directory = , address directory = 196
3rd GUNYUH data = \F1\, address data = 196, directory = \F1\, address directory = 196
my data in main is "meong".
1st GUNYUH before malloc, the data still "meong"
2nd GUNYUH after malloc, the data already changed
3rd GUNYUH after defined the directory, the data also changed. (Well because the address also same so it point to the same address)
why it changed?
Is it because lack of memory problem? But, when there's no enough heap memory, the malloc will return NULL so it never go out from the loop. I already experienced the lack of heap memory before and it did can't go out from the loop.
I have also experience overlapping like this. But it is because I didn't use malloc. (but I didn't check the address and go for static array but not enough memory so back into dynamic and found that it need malloc)
some help please?
This is not an answer but it is too big for comments.
You have the following bugs:
In four different printf lines you cause undefined behaviour by passing null pointer for %s. (the variable directory). After undefined behaviour has begun, all bets are off.
Printing a pointer with %x causes undefined behaviour. To print a pointer use %p and cast the pointer to (void *) .
You do *THING instead of THING in 3 different places, for printf
Don't cast malloc, the cast may be hiding an error message indicating a bug
On the line for(i=0;i<strlen("\\f1\\nyan.txt");i++){ , i is undeclared.
You failed to include stdio.h, stdlib.h string.h and ctype.h .
There are two more } than { in your code.
After the line with fullDir = (char *) malloc... , you do not check to see whether malloc failed.
This code should not compile. This leads me to believe that you are not posting your real code. It is important that you post exactly the code that is failing.
You need to create a minimal program, test that that program still shows the problem, and post the code of that program unaltered.
This is because there could be problems that are in the "real code" but not in the code you posted. Since you don't know where the problem is, you can't be sure that you have included the part that causes the problem.
In fact, if I fix all the bugs listed above and remove the infinite loop at the end of main(), your code compiles and runs successfully for me. That suggests that either one of the listed points is the problem, or the problem is in code that you didn't post.

Entry Point Obscuring

I've been writing an EPO program and so far I've been able to find a call opcode and get the RVA from the following address in the binary, then parse the IAT to get names of functions that are imported and their corresponding RVA's.
I've come to a problem when trying fill arrays with the names + RVA's and going on to compare the WORD value I have from the call address against the RVA's of all the imported functions.
Here's the code I've been working with;
//Declarations.
DWORD dwImportDirectoryVA,dwSectionCount,dwSection=0,dwRawOffset;
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor;
PIMAGE_THUNK_DATA pThunkData, pFThunkData;
// Arrays to hold names + rva's
unsigned long namearray[100];
DWORD rvaArray[100];
int i = 0;
And the rest:
/* Import Code: */
dwSectionCount = pNtHeaders->FileHeader.NumberOfSections;
dwImportDirectoryVA = pNtHeaders->OptionalHeader.DataDirectory[1].VirtualAddress;
for(;dwSection < dwSectionCount && pSectionHeader->VirtualAddress <= dwImportDirectoryVA;pSectionHeader++,dwSection++);
pSectionHeader--;
dwRawOffset = (DWORD)hMap+pSectionHeader->PointerToRawData;
pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(dwRawOffset+(dwImportDirectoryVA-pSectionHeader->VirtualAddress));
for(;pImportDescriptor->Name!=0;pImportDescriptor++)
{
pThunkData = (PIMAGE_THUNK_DATA)(dwRawOffset+(pImportDescriptor->OriginalFirstThunk-pSectionHeader->VirtualAddress));
pFThunkData = (PIMAGE_THUNK_DATA)pImportDescriptor->FirstThunk;
for(;pThunkData->u1.AddressOfData != 0;pThunkData++)
{
if(!(pThunkData->u1.Ordinal & IMAGE_ORDINAL_FLAG32))
{
namearray[i] = (dwRawOffset+(pThunkData->u1.AddressOfData-pSectionHeader->VirtualAddress+2));
rvaArray[i] = pFThunkData;
i++;
//
pFThunkData++;
}
}
}
printf("\nFinished.\n");
for (i = 0 ; i <= 100 ; i++)
{
//wRva is defined and initialized earlier in code.
if (rvaArray[i] == wRva)
{
printf("Call to %s found. Address: %X\n", namearray[i], rvaArray[i]);
}
}
NOTE: A lot of this code has been stripped down ( printf statements to track progress.)
The problem is the types of arrays I've been using. I'm not sure how I can store pThunkData (Names) and pFThunkData (RVA's) correctly for usage later on.
I've tried a few things a messed around with the code but I'm admitting defeat and asking for your help.
You could create a list or array of structs, containing pThunkData and pFThunkData.
#define n 100
struct pdata
{
PIMAGE_THUNK_DATA p_thunk_data;
PIMAGE_THUNK_DATA pf_thunk_data;
}
struct pdata pdatas[n]

CvLoadImage function and lists

I am using CvLoadImage (in C programming language).
Instead of passing the path or the name of my, let's say, .jpg file as the argument of the function, can I use a list (dynamic structure) which has every path of every .jpg image I want to open?
For example, I have thought the code to be like this:
CvLoadImage(list->name)
having a list declared with all the paths of the names.
instead of being like this: CvLoadImage("name.jpg")
In every manual I read, it just specified the function receives the name or the path of one image, but I want to recursively open one image after the other with those paths coming from a list, and I don't know how to do it.
This is what I could do (some things are in spanish, because we speak spanish, and some other things are mixed with files)
struct fotos
{
char nom[30];
struct fotos *sig;
};
//....
struct fotos *lini;
//....
while(lini->sig!=0)
{
image=cvLoadImage(lini->nom,1);
cvNamedWindow("ejemplo", 0);
cvMoveWindow("ejemplo", 100, 100);
cvShowImage("ejemplo", image);
cvWaitKey(0);
lini=lini->sig;
}
image=cvLoadImage(lini->nom,1);
cvNamedWindow("ejemplo", 0);
cvMoveWindow("ejemplo", 100, 100);
cvShowImage("ejemplo", image);
cvWaitKey(0);
cvReleaseImage(&image);
But it won't work either. It creates a new window, but no image is loaded.
I've not used CvLoadImage() myself, but a quick google search shows that it has a prototype of the form:
IplImage* cvLoadImage( const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR );
The function is clearly designed to take one, and only one filename. It loads the file into memory and returns a pointer to the location into which it loaded it, or NULL for error.
If you want to load multiple files, you'll need to call the function repeatedly, one for each file. One thing you might consider is to set up an array of pointers to char:
void load_images(void)
{
int i; /* Used for looping */
/* Array of filenames */
char *filenames[4] = {
"/path/to/image0.jpg",
"/path/to/image1.jpg",
"/path/to/image2.jpg",
"/path/to/image3.jpg",
};
/* Array to store the addresses of the loaded files */
IplImage *file_addresses[4];
for (i = 0; i < 4; i++) {
file_addresses[i] = cvLoadImage(filenames[i], CV_LOAD_IMAGE_COLOR);
}
/* The address of image number N, where N starts at zero
is now in file_addresses[N]. Don't forget to check that
any given address is not NULL before you use it, in case
there was a loading error */
}
You can easily substitute the arrays for a linked list or any other data structure you like. You can also modify the function to receive a pointer to a list to populate, or return a pointer to a new list it created, etc.
What you basically have should be of the form
class list
{
element* begin;
} MyList;
class element
{
char name[200];
element* next;
};
// and you can iterate through the list like that:
for (element* it = MyList->begin; it != NULL; it = it->next)
{
IplImage* img = cvLoadImage(it->name);
doSomethingElseOn(img);
}

Value of head of linked list silently changes when list grows past 100 elements

I need to make some operations on a list of files with particular extension (*.bob), all stored in the same directory. The files are image frames, and their name format is frame_XXXX.bob. I don't know the number of frames a priori, and I need to make sure I process them in order (from frame 0 to last one). I read the content of the folder with struct dirent *readdir(DIR *dirp), but since it doesn't guarantee files will be read in alphabetical order (even though it always seems to), I want to put them into a single linked list, and then sort them before processing further.
I save the head of the list before populating it to a pointer filesListStart, then read the entire folder content, adding each entry to the list if it has ".bob" extension. This all works great when I have up to 100 frames, but for some reason breaks down above that - the value of what pointer filesListStart points at doesn't contain the filename of the first entry in the list anymore. The code doesn't use any numerals, so I don't know what would be the significance of going over 100 elements.
I wrote out memory address of filesListStart before I start populating the list, and after, and they are the same, but values they show at magically change. When I set filesListStart it points at object with field fileName equals to "frame_0000.bob" (which is as expected), but after populating the list the name it points at becomes "e_0102.bob".
The list structure is defined as
// List structure
struct FilesList {
char *fileName ;
struct FilesList *next ;
} ;
The code in question is:
DIR *moviesDir ;
moviesDir = opendir("movies") ;
if(moviesDir == NULL)
{
printf("Make Movie failed to open directory containing bob frames\n") ;
return ;
}
struct dirent *dirContent ;
// Get first .bob frame name from the directory
dirContent = readdir(moviesDir) ;
// isBobFile(dirContent) returns 1 if entry has ".bob" extension and 0 otherwise
while( !isBobFile(dirContent) )
{
dirContent = readdir(moviesDir) ;
}
struct FilesList *filesList = (struct FilesList*)
malloc( sizeof(struct FilesList) ) ;
// Initialize the list start at that first found .bob frame
filesList->fileName = dirContent->d_name;
// And save the head of the list
struct FilesList *filesListStart = filesList ;
printf("FilesListStart: %s\n", filesListStart->fileName) ;
printf("Address is: %p\n", filesListStart) ;
// For all other bob frames
while( (dirContent = readdir(moviesDir) ) != NULL )
{
if( isBobFile(dirContent) )
{
struct FilesList *temporaryNode = (struct FilesList*)
malloc( sizeof(struct FilesList) );
temporaryNode->fileName = dirContent->d_name ;
filesList->next = temporaryNode ;
filesList = temporaryNode ;
}
}
// Set the 'next' pointer of the last element in list to NULL
filesList->next = NULL ;
// close stream to directory with .bob frames
closedir(moviesDir) ;
// Check what FilesListStart points at
printf("FilesListStart: %s\n", filesListStart->fileName) ;
printf("Address is: %p\n", filesListStart) ;
// Rest of the code
You should be making a copy of dirContent->d_name rather than using the actual value.
The runtime libraries are free to change the contents of that dirent structure whenever you call readdir and, if all you've stored is it's address, the underlying memory may change. From the POSIX man-pages:
The pointer returned by readdir() points to data which may be overwritten by another call to readdir() on the same directory stream.
In other words, replace the lines:
filesList->fileName = dirContent->d_name;
temporaryNode->fileName = dirContent->d_name ;
with:
filesList->fileName = strdup (dirContent->d_name);
temporaryNode->fileName = strdup (dirContent->d_name);
assuming you have a strdup-like function and, if not, you can get one cheap here.
If it's only changing after 100 calls, it's probably the runtime trying to be a bit more intelligent but even it can't store an infinite number so it probably sets a reasonable limit.
Just remember to free all those char pointers before you free the linked list nodes (somewhere in that "rest of code" section presumably).

Pointer to Pointer

I am having a lot of trouble with this piece of code (I am not good at pointers :P). So here is the code.
printf("\n Enter the file name along with its extensions that you want to delete:-");
scanf("%s",fileName);
deletefile_1_arg=fileName;
printf("test\n");
result_5 = deletefile_1(&deletefile_1_arg, clnt);
if (result_5 == (int *) NULL) {
clnt_perror (clnt, "call failed");
}
else
{
printf("\n File is deleted sucessfully");
goto Menu2;
}
break;
Function that is getting called is as following.
int *
deletefile_1_svc(char **argp, struct svc_req *rqstp)
{
static int result;
printf("test2\n");
printf("%s",**argp);
if(remove(**argp));
{
printf("\nFile Has Been Deleted");
result=1;
}
return &result;
}
I am getting test2 on console but. It does not print value of argp / removes that perticular file. I am not sure what I am doing wrong. Please help me.
The argp is a pointer to a pointer char, and you are trying to use it as a pointer to char, try change your code to:
printf("%s", *argp);
You would also need to change your remove call to:
remove(*argp);
I always found drawing pictures helped understand pointers. Use boxes for memory addresses and a label for the box is the variable name. If the variable is a pointer, then the contents of the box is the address of another box (draw line to the other box).
You are using pointers when you don't need to. Your "deletefile1_svc" function doesn't manipulate the value of "argp" at all so it doesn't need a pointer-to-pointer. Plus your "result" doesn't need to be returned as a pointer since it is simply a numeric value. You also don't initialize result (it might be zero) or re-initialize it (it is static so it will remember the last value assigned to it).
int
deletefile_1_svc(const char *argp, struct svc_req *rqstp)
{
int result = 0; /* Initial value => failure */
if (remove (argp) == 0)
{
result = 1; /* 1 => success */
}
return result;
}
To call the function use:
result_5 = deletefile1_svc(filename, clnt);
if (result_5 == 0)
// Failed
else
// Success
That will make the code simpler and less prone to bugs.

Resources