Hello hasherezade,
I believe there's a bug in libpeconv where a malware that doesn't have any relocation blocks returns the status: -1 in pe-sieve (with /jlvl 2) and thus is not processed.
I found that the specific malware I tested with doesn't have any relocation blocks (using your great PE-Bear tool):

It's happening in this function: peconv::process_relocation_table which I see you already addressed the issue when relocation blocks are null in this fix #22 .
A friend of mine (Ron, who found the memory leak in pe-sieve) came up with a potential fix which I tested and works. Basically the function has to return true in the case there's nothing to relocate. We added bool NoBlocks = true which is set to false if there are valid blocks and is used for the return value condition.
bool peconv::process_relocation_table(IN PVOID modulePtr, IN SIZE_T moduleSize, IN RelocBlockCallback *callback)
{
IMAGE_DATA_DIRECTORY* relocDir = peconv::get_directory_entry((const BYTE*)modulePtr, IMAGE_DIRECTORY_ENTRY_BASERELOC);
if (relocDir == NULL) {
#ifdef _DEBUG
std::cout << "[!] WARNING: no relocation table found!\n";
#endif
return false;
}
if (!validate_ptr(modulePtr, moduleSize, relocDir, sizeof(IMAGE_DATA_DIRECTORY))) {
std::cerr << "[!] Invalid relocDir pointer\n";
return false;
}
DWORD maxSize = relocDir->Size;
DWORD relocAddr = relocDir->VirtualAddress;
bool is64b = is64bit((BYTE*)modulePtr);
IMAGE_BASE_RELOCATION* reloc = NULL;
DWORD parsedSize = 0;
DWORD validBlocks = 0;
bool NoBlocks = true;
while (parsedSize < maxSize) {
reloc = (IMAGE_BASE_RELOCATION*)(relocAddr + parsedSize + (ULONG_PTR)modulePtr);
if (!validate_ptr(modulePtr, moduleSize, reloc, sizeof(IMAGE_BASE_RELOCATION))) {
#ifdef _DEBUG
std::cerr << "[-] Invalid address of relocations\n";
#endif
return false;
}
if (reloc->SizeOfBlock == 0) {
break;
}
size_t entriesNum = (reloc->SizeOfBlock - 2 * sizeof(DWORD)) / sizeof(WORD);
DWORD page = reloc->VirtualAddress;
BASE_RELOCATION_ENTRY* block = (BASE_RELOCATION_ENTRY*)((ULONG_PTR)reloc + sizeof(DWORD) + sizeof(DWORD));
if (!validate_ptr(modulePtr, moduleSize, block, sizeof(BASE_RELOCATION_ENTRY))) {
std::cerr << "[-] Invalid address of relocations block\n";
return false;
}
if (!is_empty_reloc_block(block, entriesNum, page, modulePtr, moduleSize)) {
if (process_reloc_block(block, entriesNum, page, modulePtr, moduleSize, is64b, callback)) {
validBlocks++;
NoBlocks = false;
}
else {
// the block was malformed
return false;
}
}
parsedSize += reloc->SizeOfBlock;
}
return (NoBlocks || validBlocks != 0);
Thank you, and keep up the fantastic work!
Terry
Hello hasherezade,
I believe there's a bug in libpeconv where a malware that doesn't have any relocation blocks returns the status: -1 in pe-sieve (with /jlvl 2) and thus is not processed.
I found that the specific malware I tested with doesn't have any relocation blocks (using your great PE-Bear tool):
It's happening in this function: peconv::process_relocation_table which I see you already addressed the issue when relocation blocks are null in this fix #22 .
A friend of mine (Ron, who found the memory leak in pe-sieve) came up with a potential fix which I tested and works. Basically the function has to return true in the case there's nothing to relocate. We added
bool NoBlocks = truewhich is set to false if there are valid blocks and is used for the return value condition.Thank you, and keep up the fantastic work!
Terry