Surprise Surprise!

Could you figure out what is the output of this snippet?


format PE console 4.0

include 'win32a.inc'

entry start

section '.data' data readable
fmt db "%d ", 0

section '.code' readable executable
start:
 mov ecx, 15
 cinvoke printf, fmt, ecx
 inc ecx
 cinvoke printf, fmt, ecx
 inc ecx
 cinvoke printf, fmt, ecx
invoke ExitProcess,

section '.idata' data import readable writeable
library kernel32, 'kernel32.dll', msvcrt, 'msvcrt.dll'
import kernel32, ExitProcess, 'ExitProcess'
import msvcrt, printf, 'printf'

At a glance, this snippet looks so simple and self-explaining.

mov ecx, 15 -> ecx = 15
cinvoke printf, fmt, ecx -> print 15
inc ecx -> ecx = 15 + 1 = 16
cinvoke printf, fmt, ecx -> print 16
inc ecx -> ecx = 16 + 1 = 17
cinvoke printf, fmt, ecx -> print 17
 invoke ExitProcess, 0 -> exit

So the result must be 15 16 17, right? That’s easy.

..

..

..

Huh??

Built and run it  yourself (use FASM). On my laptop, the result is 15 1986971169 1986971169.

Surprised?:mrgreen:

The pitfall is the ECX register is trashed, due to the invocation of printfs (hint).

So, what to do, then? Simple. Either

  1. Use EBX, ESI, or EDI because they are guaranteed to be preserved
  2. Or use a pair of push & pop to preserve the value, if you must use EAX, ECX, etc.

Example #1


format PE console 4.0

include 'win32a.inc'

entry start

section '.data' data readable
fmt db "%d ", 0

section '.code' readable executable
start:
 mov ebx, 15
 cinvoke printf, fmt, ebx
 inc ebx
 cinvoke printf, fmt, ebx
 inc ebx
 cinvoke printf, fmt, ebx
 invoke ExitProcess, 0

section '.idata' data import readable writeable
library kernel32, 'kernel32.dll', msvcrt, 'msvcrt.dll'
import kernel32, ExitProcess, 'ExitProcess'
import msvcrt, printf, 'printf'

Example #2


format PE console 4.0

include 'win32a.inc'

entry start

section '.data' data readable
fmt db "%d ", 0

section '.code' readable executable
start:
 mov ecx, 15
 push ecx
 cinvoke printf, fmt, ecx
 pop ecx
 inc ecx
 push ecx
 cinvoke printf, fmt, ecx
 pop ecx
 inc ecx
 push ecx
 cinvoke printf, fmt, ecx
 pop ecx
 invoke ExitProcess, 0

section '.idata' data import readable writeable
library kernel32, 'kernel32.dll', msvcrt, 'msvcrt.dll'
import kernel32, ExitProcess, 'ExitProcess'
import msvcrt, printf, 'printf'

Either way works:mrgreen:

BTW, the reason I write this post is sometimes I still stumble unto this error. So, yeah, let this post be the reminder.

One thought on “Surprise Surprise!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s