iczelion tut29[3]

[入库:2005年8月19日] [更新:2007年3月24日]

本文简介:选择自 jimgreen 的 blog

    invoke messagebox, 0, addr searchfail, addr appname,mb_ok+mb_iconerror .endif
invoke exitprocess, 0
end start

;--------------------------------------------------------------------
; the partial source code of win.asm, our debuggee. it's actually
; the simple window example in tutorial 2 with an infinite loop inserted
; just before it enters the message loop.
;----------------------------------------------------------------------

......
mov wc.hiconsm,eax
invoke loadcursor,null,idc_arrow
mov wc.hcursor,eax
invoke registerclassex, addr wc
invoke createwindowex,null,addr classname,addr appname,\ ws_overlappedwindow,cw_usedefault,\ cw_usedefault,cw_usedefault,cw_usedefault,null,null,\ hinst,null
mov hwnd,eax
jmp $ <---- here's our infinite loop. it assembles to eb fe
invoke showwindow, hwnd,sw_shownormal
invoke updatewindow, hwnd
.while true
   invoke getmessage, addr msg,null,0,0
   .break .if (!eax)
   invoke translatemessage, addr msg
   invoke dispatchmessage, addr msg
.endw
mov eax,msg.wparam
ret
winmain endp

analysis:

invoke findwindow, addr classname, null

our program needs to attach itself to the debuggee with debugactiveprocess which requires the process id of the debuggee. we can obtain the process id by calling getwindowthreadprocessid which in turn needs the window handle as its parameter. so we need to obtain the window handle first.
with findwindow, we can specify the name of the window class we need. it returns the handle to the window created by that window class. if it returns null, no window of that class is present.

.if eax!=null
    invoke getwindowthreadprocessid, eax, addr processid
    mov threadid, eax
    invoke debugactiveprocess, processid

after we obtain the process id, we can call debugactiveprocess. then we enter the debug loop waiting for the debug events.

       .if dbevent.dwdebugeventcode==create_process_debug_event
          mov context.contextflags, context_control
          invoke getthreadcontext,dbevent.u.createprocessinfo.hthread, addr context           

when we get create_process_debug_info, it means the debuggee is suspended, ready for us to do surgery upon its process. in this example, we will overwrite the infinite loop instruction in the debuggee (0ebh 0feh) with nops ( 90h 90h).
first, we need to obtain the address of the instruction. since the debuggee is already in the loop by the time our program attached to it, eip will always point to the instruction. all we need to do is obtain the value of eip. we use getthreadcontext to achieve that goal. we set the contextflags member to context_control so as to tell getthreadcontext that we want it to fill the "control" register members of the context structure.

          invoke writeprocessmemory, dbevent.u.createprocessinfo.hprocess, context.regeip ,addr buffer, 2, null

now that we get the value of eip, we can call writeprocessmemory to overwrite the "jmp $" instruction with nops, thus effectively help the debuggee exit the infinite loop. after that we display the message to the user and then call continuedebugevent to resume the debuggee. since the "jmp $" instruction is overwritten by nops, the debuggee will be able to continue with showing its window and enter the message loop. the evidence is we will see its window on screen.

the other example uses a slightly different approach to break the debuggee out of the infinite loop.

.......
.......
.if dbevent.dwdebugeventcode==create_process_debug_event
   mov context.contextflags, context_control
   invoke getthreadcontext,dbevent.u.createprocessinfo.hthread, addr context
   add context.regeip,2
   invoke setthreadcontext,dbevent.u.createprocessinfo.hthread, addr context
   invoke messagebox, 0, addr loopskipped, addr appname, mb_ok+mb_iconinformation
.......

本文关键:iczelion asm
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top