2008-03-26
| Table of Contents: |
| Rate This Article: | Add This Article To: |
( Page 2 of 2 )
Listing 1 describes a console-based Windows program that I created with the older Borland C++ version 4.52 compiler. Because
I tried to avoid any Borland-specific features, you should be able to compile this source code with your favorite C compiler.
Perhaps you'll need to change the #include directives, but that should be the extent of any changes you need to
make.
Although the source code probably looks intimidating, there's a logical flow to the code that should make it easier to
understand: main() invokes processPEFile(), which invokes processResRootDirectory(),
which invokes processResTypeDirectory(), which invokes processResInstDirectory(), which invokes cacheResourceInfo().
The cacheResourceInfo() function caches resource type, name, data memory address, and data memory size in a
linked list. This information is processed later by dumpResources(), which is called by processPEFile() after it successfully processes the PE file. The dumpResources() function dumps
only bitmap, cursor, and icon resources to appropriate files.
The processPEFile() function executes lpFileBase = MapViewOfFile (hFileMapping, FILE_MAP_READ, 0, 0,
0); to map the PE file into memory, which makes it easy to navigate the file's contents via pointers. The lpFileBase variable contains the address of the first byte in the memory-mapped PE file.
Working with pointers can be tricky. This is especially true when dealing with pointer arithmetic. Knowledge of what happens
when you add an offset to a pointer is helpful as you explore resdump.c. For example, consider the following
statement, which I've excerpted from the processResTypeDirectory() function:
pResInstDirEnt = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (pResTypeDir+1);
Suppose pResTypeDir contains address 80000000. Does +1 result in address 80000001 being stored in pResInstDirEnt? Because C takes into account the size of the type of the
value pointed to when performing pointer arithmetic, because pResTypeDir points to an IMAGE_RESOURCE_DIRECTORY structure, and because this structure's size is 16, the address stored in pResInstDirEnt is 80000010.
You might be wondering about my use of the goto statement in the processPEFile() function. After
all, this statement has been widely reviled because of abuse leading to spaghetti code (code whose logical flow is so
tangled that it's difficult to follow) written in languages such as the older interpreted BASIC.
I chose to use goto to eliminate duplicate cleanup code -- calls to UnmapViewOfFile() and CloseHandle() (to close the mapping and the file) in multiple places. In contrast, the dumpResourcesBMP(), dumpResourcesCUR(), and dumpResourcesICO() functions, which don't
use goto, must invoke fclose (fp); in multiple places.
My demonstration of goto reveals its usefulness in the context of exception handling for languages that don't
provide this feature (such as C). The idea is to branch forward to the latter part of a function, to execute the proper
cleanup code. Alternatively, you could use a do { break; } while (FALSE); construct to achieve the same end, but
I've found it somewhat cumbersome to use.
Test drive the resource-dumping utility
I've placed a resdump.exe file into this article's code archive to save you from having to compile the source
code. To use this program, simply specify the path and filename to an executable as the program's only command-line argument.
For example, execute the following command to dump the single icon resource stored in Windows XP's notepad.exe file (which I assume is in the c:\windows directory):
resdump c:\windows\notepad.exe
The resdump utility program creates a file named 2.ico that stores notepad's icon
resource. (If you recall our earlier tour of notepad.exe, the 2 in 2.ico is the
integer ID that's assigned to the group icon instance directory.) resdump also creates a notepad.rc file, whose textual content appears in Listing 2.
Listing 2: notepad.rc
// notepad.rc
2 ICON "2.ico"
Conclusion
Now that you know how to locate a PE file's resource section, understand this section's resource directory structure, and are familiar with the RT_BITMAP, RT_GROUP_CURSOR, RT_CURSOR, RT_GROUP_ICON, and RT_ICON resource data formats, consider expanding the resource-dumping utility to support additional formats such as RT_DIALOG and RT_MENU. To learn about these and additional formats, check out the Win32 Binary Resource Formats article.
![]() |
|


