- Код: Выделить всё
#COMPILE EXE
#INCLUDE "win32api.inc"
MACRO DumpBuffer (file, buff)
LOCAL f AS INTEGER: f = FREEFILE
OPEN file FOR BINARY AS f
PUT$ f, buff
CLOSE f
END MACRO
MACRO ShowRetVal () = MSGBOX "FUNCTION = " & STR$(retval), 0
' MODIFY ONE BYTE
MACRO Modify_One_Byte (address, value)
VirtualProtect (BYVAL code_ptr, L, _
%PAGE_EXECUTE_WRITECOPY, _
OldProtect) ' Select memory block and protect it.
POKE address, value
CALL DWORD code_ptr ' call function by address
! mov retval, eax ' obtain return value
FlushInstructionCache (GetCurrentProcess(), BYVAL code_ptr, L )
VirtualProtect (BYVAL code_ptr, L, BYVAL OldProtect, OldProtect) ' Restore status of selected memory block
END MACRO
' Modifying CODE
FUNCTION MyFunc () AS LONG
LOCAL code_len AS LONG
code_len = CODEPTR(end_lbl) - CODEPTR(begin_lbl) + 1
begin_lbl:
MSGBOX "MyFunc: Code Length is: " & STR$(code_len), 0
FUNCTION = 2004
end_lbl:
' end of code identifycator, two NOP's to be sure :-)
! nop
! nop
END FUNCTION
FUNCTION PBMAIN()
LOCAL code_ptr AS BYTE PTR, OldProtect AS DWORD, _
buffer, oldbuffer AS STRING, i, L, RetVal AS LONG
code_ptr = CODEPTR(MyFunc)
'--------------------------------------------------------
' This code calculates actual length of function in bytes
' and put byte sequences into the string buffer
'--------------------------------------------------------
i = 0
DO
IF @code_ptr[i] = &h90 AND _
@code_ptr[i+1] = &h90 THEN EXIT LOOP
buffer = buffer & CHR$( @code_ptr[i] )
INCR i
LOOP
L = LEN(buffer): oldbuffer = buffer
' Output memory dump to file
DumpBuffer ("myfunc.bin", buffer)
' Calling original function
MSGBOX "Original FUNCTION = " & STR$( MyFunc() )
'--------------------------------------------------------
' Change 'code_len' calculation code
' addr: 000022: B901000000 mov ecx, 0000001
' new code will be:
' addr: 000022: B902000000 mov ecx, 0000002
'--------------------------------------------------------
Modify_One_Byte ( code_ptr + &h23, &h2 ): ShowRetVal()
'--------------------------------------------------------
' Change returned value
' addr: 000051: mov [ebp-7C], 000007D4 ' 2004 in dec
' new code will be:
' addr: 000051: mov [ebp-7C], 000008D4 ' 2260 in decimal
'--------------------------------------------------------
Modify_One_Byte ( code_ptr + &h55, &h8 ): ShowRetVal()
'--------------------------------------------------------
' Suicide code. :)
'--------------------------------------------------------
VirtualProtect (BYVAL code_ptr, L, _
%PAGE_EXECUTE_WRITECOPY, OldProtect)
' Function has been changed totally. Now it does nothing.
' It just returns value: &h0F or 15 in decimal
POKE$ code_ptr + &h6, _
CHR$(&h31,&hC0,&HC7,&H45,&H84,&H0F,&H00,&H00,&H00)
POKE$ code_ptr + &H0F, _
STRING$(L - &H0F, &H90) ' The rest replaced with NOP's.....
CALL DWORD code_ptr
! mov retval, eax
FlushInstructionCache (GetCurrentProcess(), BYVAL code_ptr, L )
VirtualProtect (BYVAL code_ptr, L, BYVAL OldProtect, OldProtect)
MSGBOX "'MyFunc' has been killed. It did suicide :(" & $CRLF & _
"Now it returns only &h0F or 15 in decimal. " & $CRLF & _
"FUNCTION = " & STR$(retval)
' Well, it's not the end. Here goes reanimation of our code :)
VirtualProtect (BYVAL code_ptr, L, _
%PAGE_EXECUTE_WRITECOPY, OldProtect)
POKE$ code_ptr, oldbuffer
CALL DWORD code_ptr
! mov retval, eax
FlushInstructionCache (GetCurrentProcess(), BYVAL code_ptr, L )
VirtualProtect (BYVAL code_ptr, L, BYVAL OldProtect, OldProtect)
ShowRetVal()
' Program fisnished successfully.
MSGBOX "End of story."
END FUNCTION