Thread: problem while reading inport table

  1. #1
    Registered User
    Join Date
    Sep 2006
    Posts
    19

    problem while reading inport table

    Code:
    #include <windows.h>
    #include <stdio.h>
    
    
    
    #include <conio.h>
    #include<winnt.h>
    
    #define BUF_SIZE 256
    TCHAR szName[]=TEXT("process.c");
    TCHAR szMsg[]=TEXT("Message from first process");
    
    LPCTSTR MapFileRead(LPCTSTR szFileName, size_t * lpcbSize)
    {
    	PCHAR       pThunk;
    PCHAR       pHintName;
    DWORD       dwAPIaddress;
    PCHAR       pDllName;
    PCHAR       pAPIName;
    	HANDLE hFile, hMapping;
    	DWORD  dwFileSize;
    	LPTSTR lpView;
    	MEMORY_BASIC_INFORMATION mbi;
    
    	HANDLE hMapFile;
       LPCTSTR pBuf;
       PIMAGE_NT_HEADERS pimage_nt_headers;
    
    	*lpcbSize = 0;
    
    	hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
    	                 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    //	hFile=OpenProcess(PROCESS_ALL_ACCESS,0,szFileName);
    	//printf("%d",GetLastError());
    	if (INVALID_HANDLE_VALUE == hFile)
    	{
    		return NULL;
    	}
    
    	dwFileSize = GetFileSize(hFile, NULL);
    	printf("%d",GetLastError());
    	if (INVALID_FILE_SIZE == dwFileSize)
    	{
    		CloseHandle(hFile);
    		return NULL;
    	}
    
    
    	hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    	if (NULL == hMapping)
    	{
    		CloseHandle(hFile);
    		return NULL;
    	}
    
    	lpView = (LPTSTR)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
    
    //printf("%d",lpView);
    
    
    	  
       PIMAGE_DOS_HEADER pimage_dos_header = PIMAGE_DOS_HEADER(lpView);
       printf("%d...",pimage_dos_header->e_lfanew+lpView);
    
       pimage_nt_headers = (PIMAGE_NT_HEADERS)
       (lpView + pimage_dos_header->e_lfanew);
       DWORD it_voffset = pimage_nt_headers->OptionalHeader.
       DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
    
    
       PIMAGE_IMPORT_DESCRIPTOR pimage_import_descriptor= (PIMAGE_IMPORT_DESCRIPTOR)
                                                       (lpView+it_voffset);
    
        printf("%d",pimage_import_descriptor->Name);
    
      while(pimage_import_descriptor->Name!=0)
    {
        pThunk= lpView+pimage_import_descriptor->FirstThunk;
        pHintName= lpView;
        if(pimage_import_descriptor->OriginalFirstThunk!=0)
        {
            pHintName+= pimage_import_descriptor->OriginalFirstThunk;
        }
        else
        {
            pHintName+=  pimage_import_descriptor->FirstThunk;
        }
        pDllName= lpView + pimage_import_descriptor->Name;
        printf(" DLL Name: %s ", pDllName           );
    }
    CloseHandle(hMapping);
    	CloseHandle(hFile);
    
    	if (NULL != lpView)
    	{
    		if (VirtualQuery(lpView, &mbi, sizeof(mbi)) >= sizeof(mbi))
    		{
    			*lpcbSize = min(dwFileSize, mbi.RegionSize);
    		}
    		else
    		{
    			*lpcbSize = dwFileSize;
    		}
    	}
    
    	return lpView;
    }
    
    
    /*
     * Close a file mapping view.
     */
    BOOL MapFileClose(LPCVOID lpView)
    {
    	return UnmapViewOfFile(lpView);
    }
    
    
    int main(void)
    {
    	size_t cbSize, i;
    	const char * file_view;
    
    	file_view = (const char *) MapFileRead(TEXT("C:\\WINNT\\system32\\calc.exe"), &cbSize);
    
    		return 0;
    }


    In this program i am trying to read the import table of an executable .
    In order to write this code i have taken help from google.
    when i run this code .. i am getting the error "MEMORY COULD NOT BE READ"

    the point where i am getting this error is highlighted with red color

    can someone help me........
    Last edited by Salem; 09-12-2006 at 11:57 PM. Reason: Learn to use code tags or learn to accept code being deleted

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Please use code tags if you want someone to read that...
    If you understand what you're doing, you're not learning anything.

  3. #3
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Code:
    PIMAGE_IMPORT_DESCRIPTOR pimage_import_descriptor= (PIMAGE_IMPORT_DESCRIPTOR)
    (lpView+it_voffset);
    I believe your problem is in the way the above is calculated. It's pointing to questionable memory NOT the correct memory. It would behoove you to research RVA's and how they are calculated. An RVA is a Relative Virtual Address of an item. The address it will have relative to the base address at which the PE file is loaded AFTER the file is loaded in memory. This is NOT the same offset within the PE file.

  4. #4
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    I think you have to get the raw data address of the section it is in and then subtract that section's RVA address from the the import table's RVA and add it to the raw data address.

    This explanation was quite messy, but I hope you understand it...

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    19
    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <conio.h>
    #include<winnt.h>
    #define BUF_SIZE 256
    
    LPCTSTR MapFileRead(LPCTSTR szFileName, size_t * lpcbSize)
    {
    
    /*   variable declare section */
    PCHAR       pThunk;
    PCHAR       pHintName;
    DWORD       dwAPIaddress;
    PCHAR       pDllName;
    PCHAR       pAPIName;
    HANDLE hFile, hMapping;
    DWORD  dwFileSize;
    LPTSTR lpView;
    MEMORY_BASIC_INFORMATION mbi;
    HANDLE hMapFile;
    LPCTSTR pBuf;
    PIMAGE_NT_HEADERS pimage_nt_headers;
    *lpcbSize = 0
    
    /*   hFile is the handle to the calc.exe returned by createfile function   */
    
    hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
    OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    
    if (INVALID_HANDLE_VALUE == hFile)
    {
    	return NULL;
    }
    
    dwFileSize = GetFileSize(hFile, NULL);
    if (INVALID_FILE_SIZE == dwFileSize)
    {
    	CloseHandle(hFile);
    	return NULL;
    }
    
    hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    if (NULL == hMapping)
    {
    	CloseHandle(hFile);
    	return NULL;
    }
    
    lpView = (LPTSTR)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
    	  
    PIMAGE_DOS_HEADER pimage_dos_header = PIMAGE_DOS_HEADER(lpView);
    
    pimage_nt_headers = (PIMAGE_NT_HEADERS)
       (pimage_dos_header + pimage_dos_header->e_lfanew);
    
     if(pimage_nt_headers->Signature != IMAGE_NT_SIGNATURE)
    	 return 0;
    
       DWORD it_voffset = pimage_nt_headers->OptionalHeader.
       DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
    
    
       PIMAGE_IMPORT_DESCRIPTOR pimage_import_descriptor= (PIMAGE_IMPORT_DESCRIPTOR)
    (pimage_dos_header+it_voffset);
    
    char *dll_name = NULL;
    for (int count = 0; pimage_import_descriptor[count].Characteristics != 0; count++)
    {
    dll_name = (char*) (pimage_import_descriptor[count].Name + (DWORD) pimage_dos_header);
    }
    CloseHandle(hMapping);
    CloseHandle(hFile);
    if (NULL != lpView)
    {
    	if (VirtualQuery(lpView, &mbi, sizeof(mbi)) >= sizeof(mbi))
    	{
    		*lpcbSize = min(dwFileSize, mbi.RegionSize);
    	}
    	else
    	{
    		*lpcbSize = dwFileSize;
    	}
    }
    
    	return lpView;
    }
    
    
    /*
     * Close a file mapping view.
     */
    BOOL MapFileClose(LPCVOID lpView)
    {
    	return UnmapViewOfFile(lpView);
    }
    
    
    int main(void)
    {
    	size_t cbSize, i;
    	const char * file_view;
    	file_view = (const char *) MapFileRead(TEXT("C:\\WINDOWS\\system32\\calc.exe"), &cbSize);
    
    	MapFileClose(file_view);
    	return 0;
    }

    error is highlighted with red color in the code itself..............
    i have 2 issues here

    1)
    instead of using return 0 in dat if statement if i use return STATUS_INVALID_IMAGE_FORMAT then i am gettign error wich says STATUS_INVALID_IMAGE_FORMAT is undifined.....

    2)
    why control is entering into if statement [dat is highlighted with red color in the code]
    Last edited by Brij; 09-16-2006 at 01:02 PM.

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    19
    To Manorator

    I think i have calculated the RVA correctly ...........
    i also refered a book on rootkit and they also have done it in the same way ..

  7. #7
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Well, I modified your code a bit as per maxorator's excellent description of the problem. It now displays the import table.
    Code:
    #include <windows.h>
    #include <stdio.h>
    
    DWORD Rva2Offset(DWORD dwRva, PIMAGE_SECTION_HEADER dwSectionRva, USHORT uNumberOfSections)
    {
        for (USHORT i=0; i<uNumberOfSections; i++)
        {
            if (dwRva >= dwSectionRva->VirtualAddress)
            {
                if (dwRva < dwSectionRva->VirtualAddress + dwSectionRva->Misc.VirtualSize)
                {
                    return (DWORD)(dwRva - dwSectionRva->VirtualAddress + dwSectionRva->PointerToRawData) ;
                }
            }
            dwSectionRva ++ ;
        }
        return (DWORD)-1 ;
    }
    
    int MapFileRead(LPCTSTR szFileName)
    {
        /*   variable declare section */
        USHORT uNumberOfSections ;
        HANDLE hFile, hMapping;
        DWORD  dwFileSize;
        DWORD  dwImportTableVirtualAddress ;
        DWORD  dwImportTableVirtualSize ;
        LPVOID lpView;
        HANDLE hMapFile;
        PIMAGE_NT_HEADERS pimage_nt_headers;
        PIMAGE_DATA_DIRECTORY pimage_data_directory ;
        PIMAGE_OPTIONAL_HEADER pimage_optional_header ;
        PIMAGE_IMPORT_DESCRIPTOR pimage_import_desciptor ;
        PIMAGE_SECTION_HEADER pimage_import_section_header ;
        PIMAGE_THUNK_DATA pimage_thunk_data ;
        PIMAGE_IMPORT_BY_NAME pimage_import_by_name ;
        PIMAGE_SECTION_HEADER pimage_section_header ;
    
        /*   hFile is the handle to the calc.exe returned by createfile function   */
    
        hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (INVALID_HANDLE_VALUE == hFile)
        {
            return -1;
        }
        dwFileSize = GetFileSize(hFile, NULL);
        if (INVALID_FILE_SIZE == dwFileSize)
        {
            CloseHandle(hFile);
            return -1;
        }
        hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
        if (NULL == hMapping)
        {
            CloseHandle(hFile);
            return -1;
        }
        lpView = (LPTSTR)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
        PIMAGE_DOS_HEADER pimage_dos_header = PIMAGE_DOS_HEADER(lpView);
        pimage_nt_headers = (PIMAGE_NT_HEADERS)
            (pimage_dos_header + pimage_dos_header->e_lfanew);
        if (pimage_dos_header->e_magic == IMAGE_DOS_SIGNATURE)
        {
            pimage_nt_headers = (PIMAGE_NT_HEADERS) ((DWORD)lpView + pimage_dos_header->e_lfanew) ;
        }
        else return NULL;
        if (pimage_nt_headers->Signature == IMAGE_NT_SIGNATURE)
        {
            uNumberOfSections  = pimage_nt_headers->FileHeader.NumberOfSections ;
        }
        else return -1;    
        pimage_optional_header = &pimage_nt_headers->OptionalHeader ;
        pimage_data_directory = pimage_optional_header->DataDirectory ;
        ++pimage_data_directory;  
        dwImportTableVirtualAddress = pimage_data_directory->VirtualAddress ;
        dwImportTableVirtualSize = pimage_data_directory->Size ;
        pimage_section_header = (PIMAGE_SECTION_HEADER) ((DWORD) lpView + pimage_dos_header->e_lfanew + sizeof(IMAGE_NT_HEADERS)) ;
        pimage_import_section_header = pimage_section_header ;
        if (dwImportTableVirtualSize != 0)
        {
            pimage_import_desciptor  = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD) lpView + Rva2Offset(dwImportTableVirtualAddress, pimage_import_section_header, uNumberOfSections)) ;
            printf("\nIMAGE_IMPORT_DESCRIPTOR\n") ;
            while (pimage_import_desciptor->Name != NULL)
            {
                printf("Name                               ") ;
                printf("%s\n", (char *)((DWORD) lpView + Rva2Offset(pimage_import_desciptor->Name, pimage_import_section_header, uNumberOfSections))) ;
                printf("OriginalFirstThunk                 %08lX\n", pimage_import_desciptor->OriginalFirstThunk) ;
                printf("TimeDateStamp                      %08lX\n", pimage_import_desciptor->TimeDateStamp) ;
                printf("ForwarderChain                     %08lX\n", pimage_import_desciptor->ForwarderChain) ;
                printf("FirstThunk                         %08lX\n", pimage_import_desciptor->FirstThunk) ;
                if (pimage_import_desciptor->OriginalFirstThunk != 0)
                {
                    pimage_thunk_data   = (PIMAGE_THUNK_DATA) ((DWORD) lpView + Rva2Offset(pimage_import_desciptor->OriginalFirstThunk, pimage_import_section_header, uNumberOfSections)) ;
                }
                else
                {
                    pimage_thunk_data   = (PIMAGE_THUNK_DATA) ((DWORD) lpView + Rva2Offset(pimage_import_desciptor->FirstThunk, pimage_import_section_header, uNumberOfSections)) ;
                }
                printf("\nHint                               Function\n") ;
                while (pimage_thunk_data->u1.Ordinal != 0)
                {
                    pimage_import_by_name  = (PIMAGE_IMPORT_BY_NAME) ((DWORD) lpView + Rva2Offset(pimage_thunk_data->u1.Function, pimage_import_section_header, uNumberOfSections)) ;
                    if (pimage_thunk_data->u1.Ordinal & IMAGE_ORDINAL_FLAG32)
                    {
                        printf("Hint                               %08lX\n", pimage_thunk_data->u1.Ordinal - IMAGE_ORDINAL_FLAG32) ;
                    }
                    else
                    {
                        printf("%08lX                           %s\n", pimage_import_by_name->Hint, pimage_import_by_name->Name) ;
                    }
                    pimage_thunk_data ++ ;
                }
                printf("\n") ;
                pimage_import_desciptor ++ ;
            }
        }
        else
        {
            printf("No Import Table!\n") ;
        }
        CloseHandle(hMapping);
        CloseHandle(hFile);
        return 0;
    }
    
    int main(void)
    {
        MapFileRead(TEXT("C:\\WINDOWS\\system32\\calc.exe"));
        return 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem reading input
    By gp364481 in forum C Programming
    Replies: 3
    Last Post: 09-24-2008, 05:10 PM
  2. Problem Reading Process Memory
    By carrotcake1029 in forum C Programming
    Replies: 12
    Last Post: 04-14-2008, 10:33 AM
  3. Problem in reading Character
    By Bargi in forum C Programming
    Replies: 5
    Last Post: 04-10-2008, 11:40 PM
  4. Problem with reading in file...
    By Bizmark in forum C Programming
    Replies: 3
    Last Post: 03-27-2008, 01:11 PM
  5. Replies: 20
    Last Post: 06-12-2005, 11:53 PM