; 从MASM32的例子里找到的,我写了中文的注释,希望对广大菜鸟同胞理解SMC有所帮助。
;
; #########################################################################
;
; 这是一个读写PE文件代码段的例程。在这个例子里有两个过程,第一个先被调用,
; 第二个被读取并写入第一个过程里面,然后第一个过程被再次调用,前后的代码
; 已经改变了。
; 链接时应把参数设为"/section:.text,RWE",也就是说把代码段设为可读可写可执
; 行。(非常重要,不然您就等着"非法操作"吧。)
;
; #########################################################################
.386
.model flat, stdcall
option casemap :none ; case sensitive
; #########################################################################
include masm32includewindows.inc
include masm32includeuser32.inc
include masm32includekernel32.inc
includelib masm32libuser32.lib
includelib masm32libkernel32.lib
CalledProc PROTO ;过程1
ReplaceMentProc PROTO ;过程2
; #########################################################################
.data
lnth1 dd 0
szDlgTitle db "SMC example",0
Phony db "This is 1st call of proc",0
Replc db "This is 2nd call of proc",0
ttl1 db "Original Code",0
ttl2 db "Replacement Code",0
; #########################################################################
.code
start:
invoke CalledProc ; 调用第一个过程,这时的代码还是原来的,因此显示This is 1st call of proc
lea eax, rpEnd ; 找找rpEnd在哪里,原来是在第二个过程末尾
lea edx, rpStart ; 第二个过程的开始处
sub eax, edx ; 这两个LABEL的偏移量相减是什么呢
mov lnth1, eax ; 得到了第二个过程的代码长度,放在lnth1
lea esi, rpStart ; rpStart,这是第二个过程的开始处 ->ESI
lea edi, ppStart ; ppStart,这是第一个过程的开始处 ->EDI
mov ecx, lnth1 ; 把长度放在ECX
rep movsb ; 这个指令的作用是把ECX个字节从EDI处搬到ESI处(大概就是这意思),详情请查手册。
; 执行完后会怎么样呢,你一定猜到了,这时过程1实际上已经是过程2的内容了
invoke CalledProc ; 再调用第一个过程,结果呢,显示出来的是This is 2st call of proc
invoke ExitProcess,0; 退出
; #########################################################################
CalledProc proc
ppStart:: ;两个冒号表示这个LABEL是全局的,因为默认时LABEL只能在本过程内使用
invoke MessageBox,0,ADDR Phony,ADDR ttl1,MB_OK ;对话框显示This is 1st call of proc
ppEnd::
; ------------------------------------------------------
; 下面的NOP是为了给复制过来的过程2留下地方,每个NOP可以占一个字节
; ------------------------------------------------------
nop
nop
nop
nop
nop
nop
nop
nop
ret
CalledProc endp
; #########################################################################
ReplaceMentProc proc
; -----------------------------------
; 这个过程2永远不会被执行,但它的代码
; 却被复制了过去
; -----------------------------------
rpStart::
push MB_OK or MB_ICONEXCLAMATION
lea eax, ttl2
push eax
lea eax, Replc
push eax
push 0
lea eax, MessageBox
call eax ;对话框显示This is 2st call of proc
rpEnd::
ret
ReplaceMentProc endp
; #########################################################################
end start