News:

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

Main Menu

structures on resource file

Started by TouEnMasm, June 03, 2013, 03:11:55 PM

Previous topic - Next topic

TouEnMasm


I have read that ketil had written some structures to read resource (resdlg).
Couldn't find them,any help ?
I have the start point (pecoff and a sample) but it isn't really clear.

mov esi,presource
xor eax,eax
xor ecx,ecx
mov ax, [esi].IMAGE_RESOURCE_DIRECTORY.NumberOfNamedEntries
mov cx,[esi].IMAGE_RESOURCE_DIRECTORY.NumberOfIdEntries
add eax,ecx
mov count,eax
mov SavPos,0
;-----------------------------------
loopresource:
mov     eax, SavPos  ;pecoff say there is a "tree" here
add     eax, 10h
mov     SavPos, eax
sub     SavPos, 8
;---------- [Check for valid resource ID  1-2-3-5-etc.] ----------
.if dword ptr[esi+eax] != 0 && dword ptr[esi+eax] < 23 || ebx == 80h ;17
PuPo     SavID, dword ptr[esi+eax]             ; Save the ID
add     eax, 4
mov     ebx, dword ptr[esi+eax]               ; Offset to Resource Directory (Name ID)
and     ebx, 00ffffffh ;0000ffffh
add     ebx, 0eh                              ; Offset to Total num of ID's for group
xor     ecx, ecx
mov     cx, word ptr[esi+ebx]                 ; Total num of ID's for the group
add     cx, word ptr[esi+ebx-2]               ; Total num of named ID's for the group
mov     NumIds2, ecx                          ; Total num of items for the group
mov     Dlgs, ecx
sub     ebx, 2
and     CntID, 0
;----- cut -----
.endif ;debug
Fa is a musical note to play with CL

dedndave

you probably already have the pe/coff specification ?

TouEnMasm


I have it,but it isn't an easy task to read it.
Fa is a musical note to play with CL

dedndave

 :biggrin:
i have to agree, there - lol

attached is a little document that makes part of it easier

also - that specific structure is defined in windows.inc - you probably know that

try downloading ResEd

http://www.oby.ro/rad_asm/resed/index.html

there are a number of structures defined, there

Dubby

Quote from: dedndave on June 03, 2013, 07:33:43 PM
:biggrin:
i have to agree, there - lol
count me in...  :lol:

I plan on answering but after seeing Dave's attachment, The answer is already there.
but I'll post my own explanation anyway, so it goes like this:

there are 3 layer deep of IMAGE_RESOURCE_DIRECTORY structure followed by it's entries IMAGE_RESOURCE_DIRECTORY_ENTRY (see attachment by Dave)
1. is the root, this is where the type is declared: such as RT_DIALOG, RT_RCDATA, etc...
2. is the the ID or a name of a resource... where it's entries are :the ID is a WORD value, but if it's a string then this member XORED by IMAGE_RESOURCE_NAME_IS_STRING, and the name this member is a pointer to the IMAGE_RESOURCE_DIR_STRING_U...
3. is the language... where it's entries points to the IMAGE_RESOURCE_DATA_ENTRY....

the first 2 each IMAGE_RESOURCE_DATA_ENTRY offsetToData member is xored by IMAGE_RESOURCE_DATA_IS_DIRECTORY.
as explained before the "Name" member of the entries if they point to the string they are xored by IMAGE_RESOURCE_NAME_IS_STRING.

then the IMAGE_RESOURCE_DATA_ENTRY have the member OffsetToData which point to the resource data... if I remember correctly this member is the RVA... you have to calculate the offset to obtain the actual resource...

hope this helps..
please let me know if want further explanation...

TouEnMasm


Knowing of what the tree is made and with a source code, things seems more easy.
The first lines of code (first post) can be changes as this:

;esi point on .rsrc
mov     eax, SavPos ;offset 0
add     eax, sizeof IMAGE_RESOURCE_DIRECTORY
mov     SavPos, eax
sub     SavPos, sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY
;---------- [Check for valid resource ID  1-2-3-5-etc.] ----------
.if dword ptr[esi+eax] != 0 && dword ptr[esi+eax] < 23 || ebx == 80h ;17
PuPo     SavID, dword ptr[esi+eax]             ; Save the ID
add     eax, 4
mov     ebx, dword ptr[esi+eax]               ; Offset to Resource Directory (Name ID)
and     ebx, 00ffffffh ;0000ffffh
add     ebx, 0eh                              ; Offset to Total num of ID's for group
xor     ecx, ecx
mov     cx, word ptr[esi+ebx]                 ; Total num of ID's for the group
add     cx, word ptr[esi+ebx-2]               ; Total num of named ID's for the group
mov     NumIds2, ecx                          ; Total num of items for the group
mov     Dlgs, ecx
sub     ebx, 2
and     CntID, 0
.endif ;debug

Thanks at all.

Fa is a musical note to play with CL

Vortex

Hi ToutEnMasm,

Are you working on a resource editor?

TouEnMasm

Not on A resource editor but on a little include file who simplify the use of of th pecoff format in 32 or 64 bits.
here is the draft of code i use.
The SearchPointeurs functions can be used on external exe or dll and inside a dll or an exe.It give the value of various pointers of the PE.i have try to make it work in 64 bits,but i cannot test it.
Have a look on the APE_POINTEURS structure.


.NOLIST
include sdk32.inc
include commctrl.sdk
include richedit.sdk
include perso32.inc
includelib advapi32.lib
;includelib perso32.lib
    include  D:\asmedit\Include\DSPMACRO.ASM
include macros.inc
InitInstance PROTO :DWORD
UnMap PROTO  pFichMem:DWORD

.const
RsrcMisc        PROTO
RsrcCursorIcon  PROTO
RsrcBitmap      PROTO
RsrcGrpImages   PROTO
RsrcAnimate     PROTO
LireRessource PROTO  presource:DWORD
LireImportTable PROTO
LireExportTable PROTO
SearchPointeurs PROTO :DWORD,:DWORD
lstrcmpbchain PROTO  pchain1:DWORD,  pchain2:DWORD



MapFile PROTO  pfullpath:DWORD,pFichMem:DWORD
APE_POINTEURS STRUCT
pIMAGE_DOS_HEADER DWORD ?
pIMAGE_NT_HEADERS32 DWORD ?
pIMAGE_NT_HEADERS64 DWORD ?
pIMAGE_FILE_HEADER DWORD ?
pIMAGE_OPTIONAL_HEADER32 DWORD ?
pIMAGE_OPTIONAL_HEADER64 DWORD ?
;----------------------------------------
pIMAGE_EXPORT_DIRECTORY DWORD ?
pIMAGE_IMPORT_DESCRIPTOR      DWORD ?
;----------------------------------------
NumberOfSections DWORD ?
segdata DWORD ?
segrdata DWORD ?
segidata DWORD ?
segtext DWORD ?
segtextbss DWORD ?
segrsrc DWORD ?
segreloc DWORD ?
segdrectve DWORD ?
segedata DWORD ?
segpdata DWORD ?
segtls DWORD ?
segcormeta DWORD ?
segsxdata DWORD ?
PointerToSymbolTable DWORD ?
AddressOfEntryPoint DWORD ?
APE_POINTEURS ENDS

.data
icidata label dword
machine dd 0
map FichMem <>
aDiff dd 0
arsrcOn dd 0
Nbrelocation dd 0

pe APE_POINTEURS <>
hInstance dd 0
Hfenetre  dd 0
.code
include output.inc
start:
invoke InitInstance,1
invoke SearchPointeurs,addr pe,NULL ;map.Mpoint
mov eax,pe.segrsrc
.if eax != 0
invoke LireRessource,eax
.endif
fin:
invoke InitInstance,0
invoke ExitProcess,0
InitInstance PROC  init:DWORD
Local  retour:DWORD
mov retour,1
.if init == 1
invoke GetModuleHandle,NULL
mov hInstance,eax
;invoke MapFile,TXT("E:\concatene\strcat.exe"),addr map
;invoke MapFile,TXT("C:\WINDOWS\system32\msvcrt.dll"),addr map
;------------------------------------------------------------
;invoke LoadLibrary,TXT("msvcrt.dll")
;mov map.Hmem,eax
;mov map.Mpoint,eax
;-----------------------------------------------------------
;mov map.Mpoint,eax
.else
;invoke UnMap,addr map
;------------------------------------
;invoke FreeLibrary,map.Hmem
;---------------------------------------
;-----------------------------------------
.endif

FindeInitInstance:
mov eax,retour
ret
InitInstance endp
;code_invalid_parameter


;################################################################
LireExportTable PROC uses esi edi ebx
Local  retour:DWORD,pIMAGE_EXPORT_DIRECTORY
         mov retour,0
.if machine == IMAGE_FILE_MACHINE_I386
mov edi,pe.pIMAGE_NT_HEADERS32
mov edi, [edi].IMAGE_NT_HEADERS32.OptionalHeader.DataDirectory.VirtualAddress
.else
mov edi,pe.pIMAGE_NT_HEADERS64
mov edi, [edi].IMAGE_NT_HEADERS64.OptionalHeader.DataDirectory.VirtualAddress
.endif
;----------- controle --------------------------
mov edx,edi
.if edx != 0
add edx,map.Mpoint
mov retour,edx
mov esi,[edx].IMAGE_EXPORT_DIRECTORY.AddressOfNames  ;tableau d'adresses
add esi,map.Mpoint
mov edx,[esi]
add edx,map.Mpoint ;edx tableau de noms
.endif
FindeLireExportTable:
         mov eax,retour
         ret
LireExportTable endp

;################################################################



;################################################################
LireImportTable PROC uses esi edi ebx
Local  retour:DWORD,pIMAGE_IMPORT_DESCRIPTOR
      mov retour,0
.if machine == IMAGE_FILE_MACHINE_I386
mov edi,pe.pIMAGE_NT_HEADERS32
mov edi, [edi].IMAGE_NT_HEADERS32.OptionalHeader.DataDirectory[sizeof IMAGE_DATA_DIRECTORY].VirtualAddress
.else
mov edi,pe.pIMAGE_NT_HEADERS64
mov edi, [edi].IMAGE_NT_HEADERS64.OptionalHeader.DataDirectory[sizeof IMAGE_DATA_DIRECTORY].VirtualAddress
.endif
.if edi != 0
add edi,map.Mpoint
mov retour,edi
mov edx,[edi].IMAGE_IMPORT_DESCRIPTOR.Name1
add edx,map.Mpoint ;tableau des fonctions importées commençant par nom dll 
.endif

FindeLireImportTable:
         mov eax,retour
         ret
LireImportTable endp

;################################################################


;----------- segrsrc ---------------
;################################################################
LireRessource PROC uses esi edi ebx presource:DWORD
Local  retour:DWORD,count,SavPos,SavID,NumIds2,CntID,Dlgs
      mov retour,0
mov esi,presource
xor eax,eax
xor ecx,ecx
mov ax, [esi].IMAGE_RESOURCE_DIRECTORY.NumberOfNamedEntries
mov cx,[esi].IMAGE_RESOURCE_DIRECTORY.NumberOfIdEntries
add eax,ecx
mov count,eax
mov SavPos,0
;-----------------------------------
loopresource:
mov edx,sizeof IMAGE_RESOURCE_DIRECTORY  ;10h
mov ecx,sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY  ;8
add edx,ecx
mov     eax, SavPos ;offset 0
add     eax, sizeof IMAGE_RESOURCE_DIRECTORY
mov     SavPos, eax
sub     SavPos, sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY
;---------- [Check for valid resource ID  1-2-3-5-etc.] ----------
.if dword ptr[esi+eax] != 0 && dword ptr[esi+eax] < 23 || ebx == 80h ;17
PuPo     SavID, dword ptr[esi+eax]             ; Save the ID
add     eax, 4
mov     ebx, dword ptr[esi+eax]               ; Offset to Resource Directory (Name ID)
and     ebx, 00ffffffh ;0000ffffh
add     ebx, 0eh                              ; Offset to Total num of ID's for group
xor     ecx, ecx
mov     cx, word ptr[esi+ebx]                 ; Total num of ID's for the group
add     cx, word ptr[esi+ebx-2]               ; Total num of named ID's for the group
mov     NumIds2, ecx                          ; Total num of items for the group
mov     Dlgs, ecx
sub     ebx, 2
and     CntID, 0
.endif ;debug
;-------------------------------------

FindeLireRessource:
         mov eax,retour
         ret
LireRessource endp





;################################################################
SearchPointeurs PROC uses esi ebx pAPE_POINTEURS:DWORD,hmodule:DWORD
Local VirtualAddress:DWORD,PointerToRawData,segadr
Local module_Handle:DWORD,a32_64:DWORD,count
Local  retour:DWORD
mov retour,0
.if hmodule == 0
invoke GetModuleHandle,NULL
mov module_Handle,eax
mov map.Mpoint,eax
.else
mov eax,hmodule
mov module_Handle,eax
mov map.Mpoint,eax ;répète
.endif
;controle
mov     esi,module_Handle
.if [esi].IMAGE_DOS_HEADER.e_magic == IMAGE_DOS_SIGNATURE
add esi,[esi].IMAGE_DOS_HEADER.e_lfanew
.if [esi].IMAGE_NT_HEADERS32.Signature == IMAGE_NT_SIGNATURE
jmp OkPE
.endif
.endif
jmp FindeSearchPointeurs
OkPE:
;
;chaque donnée donne la RVA (Relative Virtual Adress) du pointeur
;relatif au point zero du chargement en mémoire
mov esi,module_Handle ;IMAGE_DOS_HEADER
mov ebx,pAPE_POINTEURS
mov [ebx].APE_POINTEURS.pIMAGE_DOS_HEADER,esi
mov eax,[esi].IMAGE_DOS_HEADER.e_lfanew ;IMAGE_NT_HEADERS32 -> IMAGE_FILE_HEADER
add esi,eax ; -> IMAGE_OPTIONAL_HEADER32
;----- wait to see if 32 64 ---------------------
;mov [ebx].APE_POINTEURS.pIMAGE_NT_HEADERS 32 64 ?,esi   
;---------------------------------------------------
;IMAGE_NT_HEADERS32 64 STRUCT DEFALIGNMASM
; Signature DWORD ?
; FileHeader IMAGE_FILE_HEADER <>
; OptionalHeader IMAGE_OPTIONAL_HEADER32 64 <>
;IMAGE_NT_HEADERS32 ENDS
;-----------------------------------------------------
lea edx,[esi].IMAGE_NT_HEADERS32.FileHeader ;même adresse 32 64
movzx eax,[edx].IMAGE_FILE_HEADER.Machine
mov machine,eax
;IMAGE_FILE_MACHINE_I386,IMAGE_FILE_MACHINE_IA64,IMAGE_FILE_MACHINE_AMD64
mov retour,eax
mov [ebx].APE_POINTEURS.pIMAGE_FILE_HEADER,edx   ;idem 32 64


.if eax == IMAGE_FILE_MACHINE_I386
mov [ebx].APE_POINTEURS.pIMAGE_NT_HEADERS32,esi
lea edx,[esi].IMAGE_NT_HEADERS32.OptionalHeader
mov [ebx].APE_POINTEURS.pIMAGE_OPTIONAL_HEADER32,edx
mov a32_64,0
;3.4.1. Optional Header Standard Fields (Image Only)
mov esi,[ebx].APE_POINTEURS.pIMAGE_OPTIONAL_HEADER32
movzx eax,[esi].IMAGE_OPTIONAL_HEADER32.Magic ;
mov eax,[esi].IMAGE_OPTIONAL_HEADER32.AddressOfEntryPoint
add eax,module_Handle
mov [ebx].APE_POINTEURS.AddressOfEntryPoint,eax

;------- sections -------------
mov esi,[ebx].APE_POINTEURS.pIMAGE_NT_HEADERS32
movzx     eax, [esi].IMAGE_NT_HEADERS32.FileHeader.NumberOfSections
mov count,eax
mov [ebx].APE_POINTEURS.NumberOfSections,eax
add  esi, sizeof IMAGE_NT_HEADERS32
.if eax == 0
jmp suite
.endif
loops32:
call IdentifieSection
dec count
.if count != 0 && ecx != 0
add esi,sizeof IMAGE_SECTION_HEADER
jmp loops32
.endif

.else
mov [ebx].APE_POINTEURS.pIMAGE_NT_HEADERS64,esi
lea edx,[esi].IMAGE_NT_HEADERS64.OptionalHeader
mov [ebx].APE_POINTEURS.pIMAGE_OPTIONAL_HEADER64,edx
mov a32_64,1
;3.4.1. Optional Header Standard Fields (Image Only)
mov esi,[ebx].APE_POINTEURS.pIMAGE_OPTIONAL_HEADER64
movzx eax,[esi].IMAGE_OPTIONAL_HEADER64.Magic ;
mov eax,[esi].IMAGE_OPTIONAL_HEADER64.AddressOfEntryPoint
add eax,module_Handle
mov [ebx].APE_POINTEURS.AddressOfEntryPoint,eax
;------- sections -------------
mov esi,[ebx].APE_POINTEURS.pIMAGE_NT_HEADERS64
movzx     eax, [esi].IMAGE_NT_HEADERS64.FileHeader.NumberOfSections
mov count,eax
.if eax == 0
jmp suite
.endif
add  esi, sizeof IMAGE_NT_HEADERS64
loops64:
call IdentifieSection
dec count
.if count != 0 && ecx != 0
add esi,sizeof IMAGE_SECTION_HEADER
jmp loops64
.endif

.endif
suite:
;3.3. COFF File Header (Object & Image)

mov esi,[ebx].APE_POINTEURS.pIMAGE_FILE_HEADER
;---------- retourne machine type -------------
movzx eax,[esi].IMAGE_FILE_HEADER.Machine
mov retour,eax
;-----------------------------------------------
mov edx,[esi].IMAGE_FILE_HEADER.PointerToSymbolTable
add edx,module_Handle
mov [ebx].APE_POINTEURS.PointerToSymbolTable,edx
movzx eax,[esi].IMAGE_FILE_HEADER.NumberOfSections

;--------------------------------------------------------
invoke LireExportTable
mov [ebx].APE_POINTEURS.pIMAGE_EXPORT_DIRECTORY,eax
invoke LireImportTable
mov [ebx].APE_POINTEURS.pIMAGE_IMPORT_DESCRIPTOR,eax
;--------------------------------------------------------
mov retour,1
FindeSearchPointeurs:
         mov eax,retour
         ret
IdentifieSection:
;------- calcul adresse segment ------------
PuPo     VirtualAddress, [esi].IMAGE_SECTION_HEADER.VirtualAddress
PuPo     PointerToRawData, [esi].IMAGE_SECTION_HEADER.PointerToRawData
;-----------------------------
mov eax,VirtualAddress
add eax,map.Mpoint
mov segadr,eax

invoke lstrcmpi,TXT(".data"),esi
.if eax == 0
PuPo [ebx].APE_POINTEURS.segdata,segadr
jmp finidentifie
.endif
invoke lstrcmpi,TXT(".rdata"),esi
.if eax == 0
PuPo [ebx].APE_POINTEURS.segrdata,segadr
jmp finidentifie
.endif
invoke lstrcmpi,TXT(".idata"),esi
.if eax == 0
PuPo [ebx].APE_POINTEURS.segidata,segadr
jmp finidentifie
.endif
invoke lstrcmpi,TXT(".text"),esi
.if eax == 0
PuPo [ebx].APE_POINTEURS.segtext,segadr
jmp finidentifie
.endif
invoke lstrcmpi,TXT(".rsrc"),esi
.if eax == 0
PuPo [ebx].APE_POINTEURS.segrsrc,segadr
jmp finidentifie
.endif
invoke lstrcmpi,TXT(".reloc"),esi
.if eax == 0
PuPo [ebx].APE_POINTEURS.segreloc,segadr
jmp finidentifie
.endif
invoke lstrcmpi,TXT(".drectve"),esi
.if eax == 0
PuPo [ebx].APE_POINTEURS.segdrectve,segadr
jmp finidentifie
.endif
invoke lstrcmpi,TXT(".edata"),esi
.if eax == 0
PuPo [ebx].APE_POINTEURS.segedata,segadr
jmp finidentifie
.endif
invoke lstrcmpi,TXT(".pdata"),esi
.if eax == 0
PuPo [ebx].APE_POINTEURS.segpdata,segadr
jmp finidentifie
.endif
invoke lstrcmpi,TXT(".tls"),esi
.if eax == 0
PuPo [ebx].APE_POINTEURS.segtls,segadr
jmp finidentifie
.endif
invoke lstrcmpi,TXT(".cormeta"),esi
.if eax == 0
PuPo [ebx].APE_POINTEURS.segcormeta,segadr
jmp finidentifie
.endif
invoke lstrcmpi,TXT(".sxdata"),esi
.if eax == 0
PuPo [ebx].APE_POINTEURS.segsxdata,segadr
jmp finidentifie
.endif
invoke lstrcmpbchain,esi,TXT(".textbss")
.if eax == 1
PuPo [ebx].APE_POINTEURS.segtextbss,segadr
jmp finidentifie
.endif
finidentifie:
retn
SearchPointeurs endp

;################################################################
lstrcmpbchain PROC uses esi edi ebx  pchain1:DWORD,  pchain2:DWORD
Local  retour:DWORD
         mov retour,0
mov esi,pchain1
mov edi,pchain2
mov ebx,0
@@:
mov al,[edi+ebx]
.if al == 0
mov retour,1
.elseif al == byte ptr [esi+ebx]
inc ebx
jmp @B
.endif
Findelstrcmpbchain:
         mov eax,retour
         ret
lstrcmpbchain endp

;################################################################



;################################################################
MapFile PROC  pfullpath:DWORD,pFichMem:DWORD
Local  retour:DWORD,hFile,FileSize,hMap
         mov retour,0
INVOKE     CreateFile,pfullpath,\
GENERIC_READ ,NULL,\
0, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, 0

.if eax == INVALID_HANDLE_VALUE
jmp FindeMapFile
.endif
mov     hFile, eax
INVOKE     GetFileSize, hFile, 0
mov     FileSize, eax

INVOKE     CreateFileMapping, hFile, NULL,PAGE_READONLY, 0, 0, 0
.if eax == FALSE
jmp FindeMapFile
.endif
mov     hMap, eax
mov edx,pFichMem
mov [edx].FichMem.Hmem,eax
INVOKE     CloseHandle, hFile
INVOKE     MapViewOfFile, hMap, FILE_MAP_READ, 0, 0, 0
.if eax == FALSE
jmp FindeMapFile
.endif
mov edx,pFichMem
mov [edx].FichMem.Mpoint,eax

mov     retour, eax

FindeMapFile:
         mov eax,retour
         ret
MapFile endp

;################################################################


;################################################################
UnMap PROC  pFichMem:DWORD
Local  retour:DWORD
         mov retour,1
mov edx,pFichMem
mov edx,[edx].FichMem.Hmem
invoke CloseHandle,edx
mov edx,pFichMem
mov edx,[edx].FichMem.Mpoint
invoke UnmapViewOfFile,edx

FindeUnMap:
         mov eax,retour
         ret
UnMap endp

;################################################################
comment µ
;iczelion
;DRVAToadresse PROTO pFileMap:DWORD,RVA:DWORD

;iczelion ---------------------------------------
DRVAToadresse PROC uses edi esi edx ecx pFileMap:DWORD,RVA:DWORD
mov esi,pFileMap
add esi,[esi].IMAGE_DOS_HEADER.e_lfanew
mov edi,RVA ; edi == RVA
mov edx,esi
add edx,sizeof IMAGE_NT_HEADERS32
mov cx,[esi].IMAGE_NT_HEADERS32.FileHeader.NumberOfSections
movzx ecx,cx
.while ecx>0 ; check all sections
.if edi >= [edx].IMAGE_SECTION_HEADER.VirtualAddress
mov eax,[edx].IMAGE_SECTION_HEADER.VirtualAddress
add eax,[edx].IMAGE_SECTION_HEADER.SizeOfRawData
.if edi<eax ; The address is in this section
mov eax,[edx].IMAGE_SECTION_HEADER.VirtualAddress
sub edi,eax
mov eax,[edx].IMAGE_SECTION_HEADER.PointerToRawData
add eax,edi ; eax == file offset
add eax,map.Mpoint
ret
.endif
.endif
add edx,sizeof IMAGE_SECTION_HEADER
dec ecx
.endw
mov eax,edi
ret
DRVAToadresse endp
µ

;################################################################
end start



Quote
FichMem    struc
               Hmem     dd ?
               Mpoint   dd ?
               Taille   dd ?
        FichMem    ends
Fa is a musical note to play with CL

Dubby

just a suggestion in "DRVAToadresse" proc, I believe that you need to check whether the loaded PE is either x86/32 bit or x64/64 ones... 
make a check before this :
add edx,sizeof IMAGE_NT_HEADERS32
you can modify my modified iczelion routine here:
http://masm32.com/board/index.php?topic=1003.0
post #8

TouEnMasm

the DRVAToadresse proc is just put in comment and not use.
It's the iczelion tutorial who use it.
The pecoff say what is a relative adress,relative to the start adress of load.
If it is a loaded module,add the module handle (exe dll).
If it is a mapped file,add the pointer on the start memory buffer.
There is no need of the iczelion DRVAToadresse who is just wrong when reading the pe inside an executable or an dll.It work only in case you read the pe of another module,mapped file.
The only one proc to use is SearchPointeurs who take care of the x64 or x 32 machine.He put the result on "machine".Like that other proc can read it and made the correct action.
Fa is a musical note to play with CL

Dubby

ooh didn't notice about it...   :icon_redface:

anyway good luck with your project..  :t

TouEnMasm


Must be a genius who have done this.All must be read in order and there is a very simple way to do it.Here is what i get.
Quote
identifiant chaine adresse:40801c :BATCH,
identifiant :819,
identifiant :1033,
OffsetToData :407ac0

identifiant chaine adresse:407fa2 :WAVE,
identifiant :530,
identifiant :1033,
OffsetToData :407ad0

identifiant :2,
identifiant :800,
identifiant :1033,
OffsetToData :407ae0

identifiant :801,
identifiant :1033,
OffsetToData :407af0

identifiant :802,
passage:9
identifiant :1033,
OffsetToData :407b00
Fa is a musical note to play with CL

TouEnMasm

Here is the code to read the resource directory,with a sample who show the output on an enough big rc file.
the callback is called for each resource and receive effective adress + pimgdata.
The pimgdata is in text format,it give:
Type,ID,language,adress of IMAGE_RESOURCE_DATA_ENTRY

At start ReadRsRc32 receive the adress of the rsrc segment
invoke  ReadRsRc32,prsrc,prsrc


ReadRsRc32 PROC uses esi edi ebx prsrc:DWORD,newlevel:DWORD
Local NBentry:DWORD
Local buffer[300]:WORD
Local phrase[300]:WORD
Local chaine[300]:WORD
Local  retour:DWORD
      mov retour,0
mov esi,newlevel
;------- to interrupt the loop -------
mov loopReadRsRc32,1
;-------------------------------------------
mov ecx,0
mov cx,[esi].IMAGE_RESOURCE_DIRECTORY.NumberOfNamedEntries
add cx,[esi].IMAGE_RESOURCE_DIRECTORY.NumberOfIdEntries
mov NBentry,ecx
add esi,sizeof IMAGE_RESOURCE_DIRECTORY
loopLevel_entry:
.if loopReadRsRc32 == 0
jmp FindeReadRsRc32
.endif

.if dword ptr [esi].IMAGE_RESOURCE_DIRECTORY_ENTRY.Name1 ==0
;invoke lstrcat,addr reponse_ReadRsRc32,TXT("NULL,")
;do nothing
.else ;if dword ptr [esi].IMAGE_RESOURCE_DIRECTORY_ENTRY.Name1 < 23
;rname,Name1,Id word :UNION DWORD
; The address of a string that gives the Type, Name, or Language ID entry,
;depending on level of table. içi type
;--- VALUES FOR THE RESOURCE ,id,lang,type
mov ebx,[esi].IMAGE_RESOURCE_DIRECTORY_ENTRY.rName
test ebx,Bit31 ;Bit31 equ 1 SHL 31
.if ZERO?
;---------------- nombre -----------------
invoke wsprintf,addr buffer,TXT("%X,"),ebx
invoke lstrcat,addr reponse_ReadRsRc32,addr buffer
;invoke EcrireRapport,addr buffer
;IMAGE_RESOURCE_DIRECTORY_STRING
.else
;------------- chain --------------------------
and ebx,7FFFFFFFh
mov ecx,ebx
add ebx,prsrc
movzx ecx,word ptr [ebx]
inc ecx
add ebx,2
invoke lstrcpynW,addr chaine,ebx,ecx
invoke WideCharToMultiByte,CP_ACP,NULL,addr chaine,\
-1,addr buffer,LENGTHOF buffer,NULL,NULL
invoke wsprintf,addr phrase,TXT("%s,",),addr buffer
invoke lstrcat,addr reponse_ReadRsRc32,addr phrase

.endif
;-------- HERE WHERE TO GO -------------------------------
;OffsetToData , rDirectory: DWORD
;
mov     ebx,[esi].IMAGE_RESOURCE_DIRECTORY_ENTRY.OffsetToData
test ebx,Bit31 ;Bit31 equ 1 SHL 31
.if ZERO?
;bit 31 0  Data Entry RVA
;*********** the last define value for the resource *************
add ebx,prsrc
invoke wsprintf,addr buffer,TXT("%X"),ebx
invoke lstrcat,addr reponse_ReadRsRc32,addr buffer
invoke EcrireRapport,addr reponse_ReadRsRc32
mov edi,pe.pIMAGE_NT_HEADERS32
;mov  ecx,dword ptr [edi+88h]
;DataDirectory IMAGE_DATA_DIRECTORY IMAGE_NUMBEROF_DIRECTORY_ENTRIES dup (<>)
;IMAGE_NUMBEROF_DIRECTORY_ENTRIES equ < 16> ,need an offset ? search here !
;IMAGE_DATA_DIRECTORY STRUCT DEFALIGNMASM
; VirtualAddress DWORD ?
; size1 DWORD ?
;IMAGE_DATA_DIRECTORY ENDS
;mov eax,[edi].IMAGE_NT_HEADERS32.OptionalHeader.NumberOfRvaAndSizes ;number of directories 16
mov ecx, [edi].IMAGE_NT_HEADERS32.OptionalHeader.DataDirectory[SIZEOF IMAGE_DATA_DIRECTORY * 2].VirtualAddress ; RVA of resource dir.
mov edx,[ebx].IMAGE_RESOURCE_DATA_ENTRY.OffsetToData
sub edx,ecx ;gnan gnan Need an Offset,voir au dessus,16 possibles
add edx,prsrc   ;edx effective adress of data like
;ebx effective adress of IMAGE_RESOURCE_DATA_ENTRY
invoke CallBack_ReadRsRc32,addr reponse_ReadRsRc32,ebx,edx
.if eax == 0
mov loopReadRsRc32,0 ;stop loop
.endif
;erase the values for this resource
.if dword ptr [common_res] != 0
invoke lstrcpy,addr reponse_ReadRsRc32,addr common_res
.else
mov dword ptr [reponse_ReadRsRc32],0
.if eax == 0
mov loopReadRsRc32,0
.endif
.endif

.else
;High bit 1. The lower 31 bits are the
;address of another resource directory table (the next level down).
and ebx,7FFFFFFFh ;not Bit31
add ebx,prsrc
;go to next level
;----- ecx > 1 group with common propertie
mov ecx,0
mov cx,[ebx].IMAGE_RESOURCE_DIRECTORY.NumberOfNamedEntries
add cx,[ebx].IMAGE_RESOURCE_DIRECTORY.NumberOfIdEntries
.if ecx > 1 ;groupe avec propriété commune
invoke lstrcpy,addr common_res,addr reponse_ReadRsRc32
invoke ReadRsRc32,prsrc,ebx
mov dword ptr [common_res],0
mov dword ptr [reponse_ReadRsRc32],0
mov ecx,NBentry ;debug
;on entame une série avec premier argumant commun
.else
invoke ReadRsRc32,prsrc,ebx
mov ecx,NBentry ;debug
.endif
.endif
.endif
newname:
dec NBentry
.if NBentry != 0
add esi,sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY
jmp loopLevel_entry
.endif
FindeReadRsRc32:
         mov eax,retour
         ret
ReadRsRc32 endp

;################################################################

CallBack_ReadRsRc32 PROC uses esi edi ebx preponse:DWORD,pimgdata:DWORD,effect_data:DWORD
Local  retour:DWORD
      mov retour,1    ;stop loop
;IMAGE_RESOURCE_DATA_ENTRY
;invoke lstrcmpi,preponse,TXT("IDD_INPUT_DLG1")
invoke chercherChaine,1,preponse,TXT("IDD_RECHERAPI"),1
.if eax != 0
mov retour,1 ;don't stop
.endif
mov edx,effect_data
movzx eax,[edx].DLGTEMP.long
movzx ecx,[edx].DLGTEMP.haut

FindeCallBack_ReadRsRc32:
         mov eax,retour
         ret
CallBack_ReadRsRc32 endp

;################################################################
Fa is a musical note to play with CL