/**************************************************
* Resource Dumper v0.1 .
* Programado por Iván Portilla.
* Actualizado 22 de junio de 2012
* http://www.h-sec.org & http://www.elhacker.net
**************************************************/
#include <stdio.h>
#include <windows.h>
#include <Strsafe.h>
#define STATIC_SIZE 0x20
void GetResources(PBYTE MappedFile, DWORD ResourceRVA, PCHAR Path, PIMAGE_SECTION_HEADER ish, DWORD NumberOfSections);
int RVA_TO_OFFSET(int RVA, PIMAGE_SECTION_HEADER ish, int NumberOfSections);
int RESOURCE_DUMP(PCHAR lFile, PCHAR MappedName, PCHAR DumpPath);
int RESOURCE_TO_FILE(PCHAR Path, PBYTE ResourceRVA, DWORD Size);
PCHAR ResourceType(DWORD ResType);
PCHAR UNICODE_TO_STRING(PIMAGE_RESOURCE_DIR_STRING_U String);
typedef BOOL (WINAPI * _PathIsDirectory)(PCHAR Directory);
typedef BOOL (WINAPI * _PathFileExists)(PCHAR Directory);
char STR_ID[STATIC_SIZE];
char STR_ID2[STATIC_SIZE];
char STR_ID3[STATIC_SIZE];
char STR_ID4[STATIC_SIZE];
char * RESOURCES[25] = {"RT_CURSOR","RT_BITMAP","RT_ICON","RT_MENU","RT_DIALOG",
"RT_STRING","RT_FONTDIR","RT_FONT","RT_ACCELERATOR","RT_RCDATA",
"RT_MESSAGETABLE","RT_GROUP_CURSOR","","GROUP_ICON","","RT_VERSION",
"RT_DLGINCLUDE","","RT_PLUGPLAY","RT_VXD","RT_ANICURSOR","RT_ANIICON",
"RT_HTML","RT_MANIFEST","UNKNOWN"};
int main(int argc, char * argv[])
{
_PathIsDirectory PathIsDirectoryA = (_PathIsDirectory)GetProcAddress(LoadLibraryA("Shlwapi.dll"), "PathIsDirectoryA");
_PathFileExists PathFileExistsA = (_PathFileExists)GetProcAddress(LoadLibraryA("Shlwapi.dll"), "PathFileExistsA");;
printf("Resource Dumper Base Model v0.1\n\n");
if ((PathFileExistsA != NULL) && (PathIsDirectoryA != NULL))
{
if (argc == 4)
{
if ((PathFileExistsA(argv[1]) == 1) && (PathIsDirectoryA(argv[3])) && (argv[2] != NULL))
{
RESOURCE_DUMP(argv[1], argv[2], argv[3]);
}
else
printf("Check your parameters [File path, File Mapped Name, Path To Save Resources] (ALL STRINGS)"); }
else
printf("This software should be execute with params [File path, File Mapped Name, Path To Save Resources] (ALL STRINGS)"); }
else
printf("Fail to load API functions of shlwapi.dll."); return 0;
}
int RESOURCE_DUMP(PCHAR iFile, PCHAR MappedName, PCHAR DumpPath)
{
HANDLE lFile, lMap;
PBYTE Mapped;
PIMAGE_DOS_HEADER IDH;
PIMAGE_NT_HEADERS INH;
DWORD Resource;
lFile = CreateFileA(iFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,0,0);
if (lFile != INVALID_HANDLE_VALUE)
{
lMap = CreateFileMappingA(lFile, NULL, PAGE_READONLY, 0, 0, MappedName);
Mapped = (PBYTE)MapViewOfFile(lMap, FILE_MAP_READ, 0, 0, 0);
IDH = (PIMAGE_DOS_HEADER)Mapped;
if (IDH->e_magic == IMAGE_DOS_SIGNATURE)
{
INH = (PIMAGE_NT_HEADERS)&Mapped[IDH->e_lfanew];
if(INH->Signature == IMAGE_NT_SIGNATURE)
{
Resource = INH->OptionalHeader.DataDirectory[2].VirtualAddress;
if (Resource > 0)
{
printf("Getting resources..\n"); GetResources(Mapped, Resource, DumpPath,(PIMAGE_SECTION_HEADER)&Mapped[IDH->e_lfanew + 24 + INH->FileHeader.SizeOfOptionalHeader], INH->FileHeader.NumberOfSections);
}
else
printf("Resource directory not present\n"); }
}
UnmapViewOfFile(Mapped);
CloseHandle(lMap);
CloseHandle(lFile);
}
else
{
return -1;
}
return 0;
}
void GetResources(PBYTE MappedFile, DWORD ResourceRVA, PCHAR Path, PIMAGE_SECTION_HEADER ish, DWORD NumberOfSections)
{
PIMAGE_RESOURCE_DIRECTORY IRD, SUBIRD, SSUBIRD;
PIMAGE_RESOURCE_DIRECTORY_ENTRY IRDRE, SUBIRDRE, SSUBIRDRE;
PIMAGE_RESOURCE_DATA_ENTRY IRDTE;
PIMAGE_RESOURCE_DIR_STRING_U IRDS;
DWORD NumberOfEntries, NumberOfSubEntries, NumberOfSSubEntries, Counter = 0, Tick = 0, lBytes = 0;
PCHAR UNICODE_STR_PARSED = NULL;
PCHAR RES_TYPE = NULL;
Tick = GetTickCount();
IRD = (PIMAGE_RESOURCE_DIRECTORY) &MappedFile[RVA_TO_OFFSET(ResourceRVA, ish, NumberOfSections)];
NumberOfEntries = (IRD->NumberOfNamedEntries + IRD->NumberOfIdEntries);
IRDRE = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((int)IRD + sizeof(IMAGE_RESOURCE_DIRECTORY));
printf("[Root resource directory entries: %X]\n\n", NumberOfEntries
); while(NumberOfEntries > 0)
{
if (IRDRE->DataIsDirectory == 1)
{
SecureZeroMemory(STR_ID3, STATIC_SIZE);
if (IRDRE->NameIsString == 0)
{
RES_TYPE = RESOURCES[(IRDRE->Id)-1];
printf(" [Resource type: %s]\n", RES_TYPE
); StringCchCopyA(STR_ID3, STATIC_SIZE, RES_TYPE);
StringCchCatA(STR_ID3, STATIC_SIZE, "_");
}
else
{
IRDS = (PIMAGE_RESOURCE_DIR_STRING_U) (IRDRE->NameOffset + (int)IRD);
UNICODE_STR_PARSED = UNICODE_TO_STRING(IRDS);
printf(" [Resource type: %s]\n", UNICODE_STR_PARSED
); StringCchCopyA(STR_ID3, STATIC_SIZE, UNICODE_TO_STRING(IRDS));
StringCchCatA(STR_ID3, STATIC_SIZE, "_");
GlobalFree(UNICODE_STR_PARSED);
}
SUBIRD = (PIMAGE_RESOURCE_DIRECTORY) ((int)IRD + IRDRE->OffsetToDirectory);
NumberOfSubEntries = SUBIRD->NumberOfNamedEntries + SUBIRD->NumberOfIdEntries;
SUBIRDRE = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((int)SUBIRD + sizeof(IMAGE_RESOURCE_DIRECTORY));
printf(" [Number of sub entries: %x]\n", NumberOfSubEntries
); while(NumberOfSubEntries > 0)
{
if(SUBIRDRE->DataIsDirectory == 1)
{
printf(" [Resource Id: %i]\n", SUBIRDRE
->Id
); SSUBIRD = (PIMAGE_RESOURCE_DIRECTORY) ((int)IRD + SUBIRDRE->OffsetToDirectory);
NumberOfSSubEntries = SSUBIRD->NumberOfNamedEntries + SSUBIRD->NumberOfIdEntries;
SSUBIRDRE = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((int)SSUBIRD + sizeof(IMAGE_RESOURCE_DIRECTORY));
printf(" [Number of re-sub entries: %x]\n", NumberOfSSubEntries
); while(NumberOfSSubEntries > 0)
{
IRDTE = (PIMAGE_RESOURCE_DATA_ENTRY) ((int)IRD +SSUBIRDRE->OffsetToData);
printf(" [RVA: 0x%X Size: 0x%X]\n", IRDTE
->OffsetToData
, IRDTE
->Size
);
SecureZeroMemory(STR_ID, STATIC_SIZE);
SecureZeroMemory(STR_ID2, STATIC_SIZE);
SecureZeroMemory(STR_ID4, STATIC_SIZE);
StringCchCatA(STR_ID4, STATIC_SIZE, STR_ID3);
_itoa(SUBIRDRE->Id, STR_ID, 10);
StringCchCatA(STR_ID, STATIC_SIZE, "_");
_itoa(SSUBIRDRE->Id, STR_ID2, 10);
StringCchCatA(STR_ID4, STATIC_SIZE, STR_ID);
StringCchCatA(STR_ID4, STATIC_SIZE, STR_ID2);
RESOURCE_TO_FILE(Path, (PBYTE)((int)MappedFile + RVA_TO_OFFSET(IRDTE->OffsetToData, ish, NumberOfSections)), IRDTE->Size);
NumberOfSSubEntries = NumberOfSSubEntries - 1;
SSUBIRDRE++;
Counter++;
lBytes += IRDTE->Size;
}
}
NumberOfSubEntries = NumberOfSubEntries - 1;
SUBIRDRE++;
}
}
NumberOfEntries = NumberOfEntries - 1;
IRDRE++;
}
printf("\nResources dumped: 0x%X.", Counter
); printf("\nTime of dumped: %i miliseconds.", (GetTickCount
()-Tick
)); printf("\nBytes dumped: 0x%X.", lBytes
); }
int RVA_TO_OFFSET(int RVA, PIMAGE_SECTION_HEADER ISH, int NumberOfSections)
{
int i, Offset = 0;
if (ISH != NULL)
{
for (i = 0; i < NumberOfSections; i++)
{
if ((RVA >= (int)ISH[i].VirtualAddress) && (RVA <= (int)(ISH[i].VirtualAddress + ISH[i].Misc.VirtualSize)))
{
Offset = (RVA - ISH[i].VirtualAddress) + ISH[i].PointerToRawData;
}
}
}
else
Offset = 0;
return Offset;
}
PCHAR UNICODE_TO_STRING(PIMAGE_RESOURCE_DIR_STRING_U String)
{
PCHAR nStr = (PCHAR) GlobalAlloc(GPTR, String->Length + 1);;
WideCharToMultiByte(CP_ACP, 0, String->NameString, String->Length * 2, nStr, String->Length, NULL, NULL);
return nStr;
}
int RESOURCE_TO_FILE(PCHAR Path, PBYTE ResourceRVA, DWORD Size)
{
PCHAR lFile = (PCHAR)GlobalAlloc(GPTR, lstrlenA(Path) + STATIC_SIZE);
PCHAR Buffer = (PCHAR)GlobalAlloc(GPTR, Size);
HANDLE sFile;
DWORD Bytes = 0, Rest;
CopyMemory(Buffer, ResourceRVA, Size);
StringCchCopyA(lFile, lstrlenA(Path) + STATIC_SIZE, Path);
if ((Path[lstrlenA(Path)-2] == 92) & (Path[lstrlenA(Path)-1] == 92))
StringCchCopyA(&lFile[lstrlenA(Path)], lstrlenA(Path) + STATIC_SIZE, STR_ID4);
else
{
lFile[lstrlenA(Path)+1] = 92;
lFile[lstrlenA(Path)] = 92;
StringCchCopyA(&lFile[lstrlenA(Path)+2], lstrlenA(Path) + STATIC_SIZE, STR_ID4);
}
sFile = CreateFileA(lFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, 0);
if (sFile != INVALID_HANDLE_VALUE)
{
WriteFile(sFile, Buffer, Size, &Bytes, NULL);
CloseHandle(sFile);
Rest = 0;
}
else
Rest = -1;
GlobalFree(Buffer);
GlobalFree(lFile);
return Rest;
}