-
Notifications
You must be signed in to change notification settings - Fork 457
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
.rsrc section does not behave as expected #24
Comments
I haven't had any issues with accessing resource sections as long as BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
HRSRC rsc = FindResource(hModule, MAKEINTRESOURCE(IDI_ICON1), RT_GROUP_ICON);
...
} |
If it helps, here is some extracted code which can parse the PE resource section manually: static PIMAGE_RESOURCE_DIRECTORY_ENTRY _MemorySearchResourceEntry(void* root, PIMAGE_RESOURCE_DIRECTORY resources, LPCTSTR key)
{
PIMAGE_RESOURCE_DIRECTORY_ENTRY entries = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resources + 1);
PIMAGE_RESOURCE_DIRECTORY_ENTRY result = NULL;
DWORD start;
DWORD end;
DWORD middle;
if (IS_INTRESOURCE(key)) {
WORD check = (WORD)(uintptr_t)key;
start = resources->NumberOfNamedEntries;
end = start + resources->NumberOfIdEntries;
while (end > start) {
WORD entryName;
middle = (start + end) >> 1;
entryName = (WORD)entries[middle].Name;
if (check < entryName) {
end = (end != middle ? middle : middle - 1);
}
else if (check > entryName) {
start = (start != middle ? middle : middle + 1);
}
else {
result = &entries[middle];
break;
}
}
}
else {
LPCWSTR searchKey;
size_t searchKeyLen = wcslen(key);
searchKey = key;
start = 0;
end = resources->NumberOfNamedEntries;
while (end > start) {
int cmp;
PIMAGE_RESOURCE_DIR_STRING_U resourceString;
middle = (start + end) >> 1;
resourceString = PIMAGE_RESOURCE_DIR_STRING_U((UINT_PTR)root + (entries[middle].Name & 0x7FFFFFFF));
cmp = _wcsnicmp(searchKey, resourceString->NameString, resourceString->Length);
if (cmp == 0) {
// Handle partial match
if (searchKeyLen > resourceString->Length) {
cmp = 1;
}
else if (searchKeyLen < resourceString->Length) {
cmp = -1;
}
}
if (cmp < 0) {
end = (middle != end ? middle : middle - 1);
}
else if (cmp > 0) {
start = (middle != start ? middle : middle + 1);
}
else {
result = &entries[middle];
break;
}
}
}
return result;
}
#define RVA(type, base, rva) (type)((ULONG_PTR) base + rva)
std::string * GetResourceR(HMODULE hModule, LPCTSTR name, LPCTSTR type, WORD language)
{
PIMAGE_RESOURCE_DIRECTORY rootResources;
PIMAGE_RESOURCE_DIRECTORY nameResources;
PIMAGE_RESOURCE_DIRECTORY typeResources;
PIMAGE_RESOURCE_DIRECTORY_ENTRY foundType;
PIMAGE_RESOURCE_DIRECTORY_ENTRY foundName;
PIMAGE_RESOURCE_DIRECTORY_ENTRY foundLanguage;
if (language == 0) {
language = LANGIDFROMLCID(GetThreadLocale());
}
if (hModule == NULL)
return NULL;
PIMAGE_NT_HEADERS ntHeaders = RVA(PIMAGE_NT_HEADERS, hModule, ((PIMAGE_DOS_HEADER)hModule)->e_lfanew);
PIMAGE_DATA_DIRECTORY dataDir = &ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
if (!dataDir->Size)
return NULL;
rootResources = RVA(PIMAGE_RESOURCE_DIRECTORY, hModule, dataDir->VirtualAddress);
foundType = _MemorySearchResourceEntry(rootResources, rootResources, type);
if (foundType == NULL) {
SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND);
return NULL;
}
typeResources = RVA(PIMAGE_RESOURCE_DIRECTORY, hModule, dataDir->VirtualAddress + (foundType->OffsetToData & 0x7fffffff));
foundName = _MemorySearchResourceEntry(rootResources, typeResources, name);
if (foundName == NULL) {
SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND);
return NULL;
}
nameResources = RVA(PIMAGE_RESOURCE_DIRECTORY, hModule, dataDir->VirtualAddress + (foundName->OffsetToData & 0x7fffffff));
foundLanguage = _MemorySearchResourceEntry(rootResources, nameResources, (LPCTSTR)(uintptr_t)language);
if (foundLanguage == NULL) {
// requested language not found, use first available
if (nameResources->NumberOfIdEntries == 0) {
SetLastError(ERROR_RESOURCE_LANG_NOT_FOUND);
return NULL;
}
foundLanguage = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(nameResources + 1);
}
PIMAGE_RESOURCE_DATA_ENTRY entry = RVA(PIMAGE_RESOURCE_DATA_ENTRY, hModule, dataDir->VirtualAddress + (foundLanguage->OffsetToData & 0x7fffffff));
if (entry == NULL || !entry->OffsetToData) {
return NULL;
}
return new std::string(RVA(LPSTR, hModule, entry->OffsetToData), entry->Size);
} |
Hi Nick, I had the exact same issue. Once loaded, I couldn't use But your workaround (#24 (comment)) worked like charms :) Thanks!. |
DLLs cannot use FindResource when converted into shellcode. Same code works when not loaded using sRDI. Issue seems to be the same as TheWover/donut#70 where the PE stomping breaks the .rsrc section.
EDIT: Based on PE structure, not sure if there is a workaround other than disabling the SRDI_CLEARHEADER flag. Any ideas?
EDIT 2: Even with SRDI_CLEARHEADER it doesnt seem to work.
The text was updated successfully, but these errors were encountered: