;************************************************************************
; Take out resource imformation on third stage resource, if succeed, Return to take out resource length
;************************************************************************
SearchResourceByIDInThirdLayer proc
PEHeader:dword,ResourceAddr:dword,ChildResource:dword,pOutValue:dword
LOCAL RetValue:dword
pusha
xor eax, eax
mov RetValue, eax
mov esi, ChildResource
mov cx, [esi+0Ch];Be named after entry count
add cx, [esi+0Eh];Entry count To ID named
movzx ecx, cx
add esi, 10h ;esi point back IMAGE_RESOURCE_DIRECTORY_ENTRY
cmp ecx, 0
jbe Quit
mov ebx, [esi+4] ;offsetToData directory entry pointer
and ebx, 7FFFFFFFh
add ebx, ResourceAddr ;ebx point IMAGE_RESOURCE_DATA_ENTRY structure
mov eax, [ebx] ; Take out RVA of resource data, amount to first term of IMAGE_RESOURCE_DATA_ENTRY structure
add eax, PEHeader
mov ecx, pOutValue ;pOutValue point address of resource data
mov [ecx], eax
mov ecx, [ebx+4]
mov RetValue, ecx ;Return resource data length
Quit:
popa
mov eax, RetValue
retn
SearchResourceByIDInThirdLayer endp
;************************************************************************
; Find resource term for ID named after ChildResID on second stage resource
;************************************************************************
SearchResourceByIDInSecondLayer proc
PEHeader:dword,ResourceAddr:dword,ChildResource:dword,ChildResID:dword,pOutValue:dword
LOCAL RetValue:dword
pusha
xor eax, eax
mov RetValue, eax
mov esi, ChildResource
mov cx, [esi+0Ch] ;Be named after entry count
add cx, [esi+0Eh] ;Entry count To ID named
movzx ecx, cx
add esi, 10h ;esi point back IMAGE_RESOURCE_DIRECTORY_ENTRY
jmp StartSearchChildDirectoryEntry
ContinueSearchChildDirectoryEntry:
push ecx
mov ebx, [esi+4] ;offsetToData directory entry pointer
test ebx, 80000000h
jz JumpOver ;; If highest 31bit is zero, Skip to continue next directory entry.
and ebx, 7FFFFFFFh
add ebx, ResourceAddr ;Otherwise take out next address
mov edx, [esi] ;Take out string pointer or ID of directory entry
test edx, 80000000h
jnz JumpOver ;If highest 31bit is 1,[esi] oow order represent string pointer
cmp edx, ChildResID
jnz JumpOver
push pOutValue
push ebx
push ResourceAddr
push PEHeader
call SearchResourceByIDInThirdLayer
mov RetValue, eax
or eax, eax
jz JumpOver
pop ecx
jmp Quit
JumpOver:
add esi, 8
pop ecx
dec ecx
StartSearchChildDirectoryEntry:
cmp ecx, 0
ja ContinueSearchChildDirectoryEntry
Quit:
popa
mov eax, RetValue
retn
SearchResourceByIDInSecondLayer endp
;******************************************************************************************
; Find resource term for ID named after RESOURCEID on first stage
resource
;******************************************************************************************
SearchResourceByIDInFirstLayer proc
PEHeader:dword,ChildResID:dword,RESOURCEID:dword,pOutValue:dword
LOCAL retvalue:dword
LOCAL ResourceAddr:dword
pusha
xor eax, eax
mov retvalue, eax
mov edi, PEHeader
mov edi, [edi+3Ch]
add edi, PEHeader
mov ecx, [edi+8Ch] ;Resource table size
or ecx, ecx
jz QUIT
mov eax, [edi+88h] ;Resource table RVA
add eax, PEHeader
mov ResourceAddr, eax
push eax ; VirtualAddress
call MmIsAddressValid
or eax, eax
jnz @F
jmp QUIT
@@:
mov esi, ResourceAddr
mov cx, [esi+0Ch];Be named after entry count
add cx, [esi+0Eh];Entry count To ID named
movzx ecx, cx
add esi, 10h ;esi point back IMAGE_RESOURCE_DIRECTORY_ENTRY
jmp StartSearchDirectoryEntry
ContinueSearchDirectoryEntry:
push ecx
mov ebx, [esi+4] ;offsetToData directory entry pointer
test ebx, 80000000h
jz JumpOver ; If highest 31bit is zero, Skip to continue next directory entry.
and ebx, 7FFFFFFFh
add ebx, ResourceAddr ;Save next address
mov eax, [esi];Take directory string pointer or ID
test eax, 80000000h
jnz JumpOver ;If highest 31bit is 1,[esi] oow order represent string pointer
cmp eax, RESOURCEID
jnz JumpOver
push pOutValue ;Find matched resource ID
push ChildResID
push ebx
push ResourceAddr
push PEHeader
call SearchResourceByIDInSecondLayer
mov retvalue, eax
pop ecx
jmp QUIT
JumpOver:
add esi, 8 ;Continue read next directory entry
pop ecx
dec ecx
StartSearchDirectoryEntry:
cmp ecx, 0 ;Judge directory entry whether ergodic finish
ja ContinueSearchDirectoryEntry
QUIT:
popa
mov eax, retvalue
retn
SearchResourceByIDInFirstLayer endp
;
************************************************************************
; Get memory load place of current driver file, if can't find, Return zero
;*************************************************************************
GetPeHeader proc near
LOCAL PEStart:dword
pusha
mov PEStart, 0
CURRENT_EIP:
lea ebx, CURRENT_EIP
and ebx, 0FFFFFC00h ; Low bit zero clearing
CHECKPEHEADER: ; VirtualAddress
push ebx
call MmIsAddressValid ;Judge current address whether valid
or eax, eax
jz QUIT ;unsuccess is jumped to exit
cmp ebx, 80000000h ;If current eip less than or equal to 80000000h, exit
jbe QUIT
cmp word ptr [ebx], 5A4Dh ; 'MZ'
jnz SEARCHDOSHEADER
mov edi, ebx
add edi, [ebx+3Ch]
push edi ; VirtualAddress
call MmIsAddressValid
or eax, eax
jz SEARCHPEHEADER
cmp word ptr [edi], 4550h ;'PE'
jnz SEARCHPEHEADER
mov PEStart, ebx
jmp QUIT
SEARCHPEHEADER:
sub ebx, 400h
jmp CHECKPEHEADER
jmp QUIT
SEARCHDOSHEADER:
sub ebx, 400h
jmp CHECKPEHEADER
QUIT:
popa
mov eax, PEStart
retn
GetPeHeader endp
No comments:
Post a Comment