📄 epo.inc
字号:
;
; __epo procedure
; ===============
;
;
; Description
; -----------
;
; This procedure scanz these opcodez:
;
; E8 xx xx xx xx: call xxxxxxxx ; relative address
; ...
; FF 25 xx xx xx xx: jmp dword ptr [xxxxxxxx]
;
; or:
;
; FF 15 xx xx xx xx: call dword ptr [xxxxxxxx] ; API call
;
; Then, convert the RVA of FirstThunk, which containz the real API address, to
; RAW offset of the PE file and get the API name in the IMAGE_THUNK_DATA. Then,
; get the API address by GetProcAddress, if the function succeeded, it means we
; have got the API to patch.
;
;
; Parameterz and Return Valuez
; ----------------------------
;
; Input:
; eax --- image base
; ecx --- length of the section
; edx --- number of section header
; ebx --- pointz to the file buffer
; ebp --- library handle
; esi --- pointz to the code section to patch
; edi --- pointz to the first IMAGE_SECTION_HEADER
;
; Output:
; eax --- address of the instruction to patch
;
__epo: pushad
xor ebx,ebx ; result REG
lodsb ; load first byte
epo_search_l: dec ecx ; decrease counter
jz epo_ret
cmp al,0e8h ; search E8 xx xx xx xx
jz epo_e8_found
dec ecx ; decrease counter
lodsb
cmp al,0ffh ; search for 15FF
jnz epo_search_l
dec ecx ; decrease counter
lodsb
cmp al,15h ; 15FF ?
jnz epo_search_l
jmp epo_got_it
epo_e8_found: push esi ; save ESI
lodsd ; get relative address
add eax,esi ; address of 25FF
cmp word [eax],25ffh ; 25FF ?
pop esi ; restore ESI
jnz epo_search_l
xchg eax,esi ; eax --> esi
inc esi ; let ESI point to the address
inc esi ; which containz the API entry
epo_got_it: pushad
mov ebx,[esp+60] ; get image base
lodsd ; get the RVA
sub eax,ebx ; ...
xchg esi,edi ; edi --> esi
xchg ecx,edx ; edx --> ecx
call __rva2raw ; get RAW of IMAGE_THUNK_DATA
mov edx,[esp+48] ; get file buffer pointer
add eax,edx ; get RAW of ...
mov eax,[eax] ; IMAGE_IMPORT_BY_NAME
call __rva2raw ; ...
lea eax,[eax+edx+2] ; get the name of the API
push eax ; get proc address
push ebp ; ...
mov eax,12345678h ; ...
__addr_GetProcAddress = $-4 ; ...
call eax ; ...
or eax,eax
popad
jnz epo_got_api
xor ebx,ebx
jmp epo_search_l
epo_got_api: dec esi ; back to the beginning
dec esi ; of the instruction
xchg ebx,esi
jmp epo_ret
epo_ret: mov [esp+28],ebx ; save return value
popad
ret
;
; __rva2raw procedure
; ===================
;
;
; Description
; -----------
;
; This procedure is used for converting RVA to RAW in a certain file. The func-
; tion follows the following stepz:
;
; 1) Visit each IMAGE_SECTION_HEADER of the PE file. Get each VirtualAddress
; and calculate the end RVA of each section by adding VirtualAddress and
; VirtualSize. Then test if the RVA is in the section.
; 2) If the RVA is in the section. Get the offset by subtracting the RVA
; from the start RVA of the section.
; 3) Get the RAW in the PE file by adding the offset and PointerToRawData.
;
;
; Parameterz and Return Value
; ---------------------------
;
; Input:
; eax --- RVA to convert
; esi --- pointz to the first IMAGE_SECTION_HEADER
; ecx --- number of section header
;
; Output:
; eax --- RAW (offset in the file)
;
__rva2raw: pushad
r2r_sec_loop: mov ebx,[esi+12] ; get VirtualAddress
mov edx,ebx ; save it
cmp eax,ebx
jl r2r_next
add ebx,[esi+8] ; add VirtualSize
cmp eax,ebx
jg r2r_next
sub eax,edx ; get offset
add eax,[esi+20] ; calculate RAW
mov [esp+28],eax ; return
jmp r2r_ret ; ...
r2r_next: add esi,28h ; next section header
loop r2r_sec_loop
xor eax,eax ; not found
mov [esp+28],eax ; return 0
r2r_ret: popad
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -