u're great, mates... well, here's what i came up with... it's totally messy and non-optimized, but as a first try, it does the job... any recommendations/comments on further optimizing are, of course, welcome! ;)
RES_CRYPT STRUC
ptrPEHdr DWORD ? ; pointer to the PE header...
ptrSecHdr DWORD ? ; pointer to rsrc section header
ptrRoot DWORD ? ; ptr to rsrc section...
Operation DWORD ? ; encrypt/decrypt?
;ptrOperation DWORD ? ; current data offset to process
;lenOperation DWORD ? ; size to process...
SecVirtOffset DWORD ? ; virtual offset...
CurrentLink DWORD ?
CurrentLinkCount DWORD ? ; current branch elements count!
RootTotalCount DWORD ?
;RootCharacteristics DWORD ?
RootNumberNamedEntry WORD ?
RootNumberIDEntry WORD ?
RES_CRYPT ENDS
RT_RES_ICON equ 03h
RT_RES_MANIFEST equ 018h ; 24
RT_RES_ICONGROUP equ 0Eh
RT_RES_VERSIONINFO equ 010h
resCrypt RES_CRYPT <0>
; EDI - PTR PE HEADER
; ESI - ptr IMAGE_SECTION_HEADER
; ECX - ptr MAIN IMAGE_RESOURCE_DIRECTORY
; EBX - 0 = crypt / 1 = decrypt
; EAX - PTR FILE MEMORY!
CryptRes:
;int 3
pushad
or ebx, 0
jnz @dec_res
lea eax, resCrypt
jmp @enc_res
@dec_res:
lea eax, [ebp+offset resCrypt]
@enc_res:
push eax ; ptr RES_CRYPT
ASSUME EAX:ptr RES_CRYPT
mov [eax].ptrPEHdr, edi ; ptr pe header
mov [eax].ptrSecHdr, esi ; ptr section_header
mov [eax].ptrRoot, ecx ; ptr section root directory
mov [eax].Operation, ebx ; encrypt/decrypt
ASSUME EDI:PTR IMAGE_NT_HEADERS
or ebx, 0
jnz @dont_load_from_opt
mov ecx, [edi].OptionalHeader.DataDirectory[SIZEOF IMAGE_DATA_DIRECTORY * 2].VirtualAddress ; RVA of resource dir.
@dont_load_from_opt:
mov [eax].SecVirtOffset, ecx
ASSUME ESI:ptr IMAGE_RESOURCE_DIRECTORY
movzx ecx, [esi].NumberOfNamedEntries
mov [eax].RootNumberNamedEntry, cx
movzx ecx, [esi].NumberOfIdEntries
mov [eax].RootNumberIDEntry, cx
add cx, [eax].RootNumberNamedEntry
pop esi ; ptr RES_CRYPT ( DO NOT XCHG! )
ASSUME EAX:ptr RES_CRYPT
or cx, 0
jz @exit
ASSUME ESI:PTR RES_CRYPT
mov [esi].RootTotalCount, eax
mov edi, [esi].ptrRoot
add edi, sizeof IMAGE_RESOURCE_DIRECTORY ; RESOURCE TYPE level here...
ASSUME EDI:PTR IMAGE_RESOURCE_DIRECTORY_ENTRY
@next_sec:
mov eax, [edi].Name1 ; this is the resource type...
or eax, 0
jz @exit
cmp eax, RT_RES_ICON
jz @skip_sec
cmp eax, RT_RES_MANIFEST
jz @skip_sec
cmp eax, RT_RES_ICONGROUP
jz @skip_sec
;cmp eax, RT_RES_VERSIONINFO
;jz @skip_sec
push edi ; restore before the next section
mov eax, [edi].OffsetToData
xor eax, 080000000h
add eax, [esi].ptrRoot
xchg eax, edi
ASSUME EDI:PTR IMAGE_RESOURCE_DIRECTORY ; RESOURCE ID level here...
movzx eax, [edi].NumberOfIdEntries
movzx ecx, [edi].NumberOfNamedEntries
add eax, ecx ; num of NAMED entries!
mov [esi].CurrentLinkCount, eax ; saving current branch size...
add edi, sizeof IMAGE_RESOURCE_DIRECTORY
mov [esi].CurrentLink, edi ; ...and branch location...
@next_branch:
ASSUME EDI:PTR IMAGE_RESOURCE_DIRECTORY_ENTRY
mov eax, [edi].OffsetToData
xor eax, 080000000h
add eax, [esi].ptrRoot
xchg eax, edi
ASSUME EDI:PTR IMAGE_RESOURCE_DIRECTORY ; single ID
add edi, sizeof IMAGE_RESOURCE_DIRECTORY
ASSUME EDI:PTR IMAGE_RESOURCE_DIRECTORY_ENTRY
mov eax, [edi].OffsetToData
add eax, [esi].ptrRoot
xchg eax, edi
ASSUME EDI:PTR IMAGE_RESOURCE_DATA_ENTRY ; OUR ENTRY's here! LEAF NODE!
mov ecx, [edi].Size1 ; SIZE of LEAF NODE raw data...
mov eax, [edi].OffsetToData ; RVA that is! (section VA+offset)
mov ebx, [esi].Operation ; encrypt or decrypt...
or ebx, 0
jnz @go_decrypt
sub eax, [esi].SecVirtOffset ; bla
add eax, [esi].ptrRoot
jmp @encrypt_res_now
@go_decrypt:
mov edx, [esi].ptrSecHdr
ASSUME EDX:PTR IMAGE_SECTION_HEADER
sub eax, [edx].VirtualAddress
add eax, [esi].ptrRoot
@encrypt_res_now:
push esi
push edi
xchg eax, esi
mov edi, esi ; ESI, EDI = src and target...
@encrypt_res: ; esi = crypt start, ecx = crypt size
or ebx, 0
jnz @decrypt_it
call EncryptSec
jmp @encrypted_res
@decrypt_it:
call DecryptSec
@encrypted_res:
pop edi
pop esi
mov eax, [esi].CurrentLinkCount
dec eax
or eax, 0
jz @branch_done
mov [esi].CurrentLinkCount, eax ; saving current branch size...
mov edi, [esi].CurrentLink
add edi, sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY
mov [esi].CurrentLink, edi
jmp @next_branch
@branch_done:
pop edi ; we must get back... ;)
@skip_sec:
add edi, sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY
jmp @next_sec
@exit:
popad
ret
ASSUME ESI:NOTHING
ASSUME EDI:NOTHING
ASSUME EAX:NOTHING
ASSUME EDX:NOTHING
PS: @japheth: sounds like a nice util, mate, keep it up!
PPS: that snippet does NOT currently support NAMED resources! (this means just that NAMED resources aren't CRYPTED, but are still NOT trashed!

) and commented out structure elements aren't used in the code @all... ;)