News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

RSRC related question... :)

Started by PsYcHoCoDe, October 25, 2012, 12:29:43 AM

Previous topic - Next topic

PsYcHoCoDe

guys, does anyone know of a good example about .rsrc section parsing(Resource Directory)? i can't really grasp some of the concept quite... i.e. how should i use the IMAGE_RESOURCE_DIRECTORY_ENTRY's OffsetToData in order to get to the next "sibling" down the tree (that would be IMAGE_RESOURCE_DIRECTORY)... so really could use some good example or text on the field? :(

TouEnMasm


Best sample on pe file I know is the Objconv  ,dowload ir with is source code in C.
Search in and it seem to me that he made a search on the .rsrc
Fa is a musical note to play with CL

PsYcHoCoDe

thanks, dude, i've almost made it already... kinda almost figured it out almost completely... gonna show the proc when done, would like any advice on improvements, since i'm not going to optimize it too soon...  8)

japheth

Recently I've written a Res2Inc utility - converts .res files to assembly include files. The resulting include is virtually what you're going to see in the .rsrc section of a binary.

Source is included as a sample in the jwasm v2.09 binary package.

TouEnMasm


another source of information can be an extractor of resource in an executable.
The site of ewayne wagner had one with his source code.
http://www.massmind.org/images/www/asmedit/AsmMain.html
Fa is a musical note to play with CL

PsYcHoCoDe

#5
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!   :eusa_dance: ) and commented out structure elements aren't used in the code @all... ;)