Flag: Tornado! Hurricane!

Blogs >> RolfRolles's Blog

Created: Tuesday, January 1 2008 13:43.13 CST Modified: Wednesday, January 2 2008 03:19.08 CST
Printer Friendly ...
Weird Code: CCs on the Stack
Author: RolfRolles # Views: 3416

A friend of a friend wanted to know whether I had a better name in mind for the following function:


Write_CCs_To_Stack_WTF proc near

var_CC  = byte ptr -0CCh
var_8   = dword ptr -8

push    ebp
mov     ebp, esp
sub     esp, 0CCh
push    ebx
push    esi
push    edi
push    ecx
lea     edi, [ebp+var_CC]
mov     ecx, 33h
mov     eax, 0CCCCCCCCh
rep stosd
pop     ecx
mov     [ebp+var_8], ecx
pop     edi
pop     esi
pop     ebx
mov     esp, ebp
pop     ebp
retn

Write_CCs_To_Stack_WTF endp


I can't argue:  this sure does look like a WTF on its face.  If you don't often debug debug-build code compiled with MSVC, and know the trick behind this, then it's bound to be a mystery.  I can imagine all sorts of strange thoughts crossing one's mind when encountering this.

What's actually happening here is this.  As an aid to debugging, MSVC has a compiler switch (/GZ) that will force it to write 0xCC bytes atop uninitialized variables of any scope.  This is documented, amongst other places, here.  Notice that var_8 is also overwritten due to the length of the memset.  So /GZ explains the CC bytes on the stack.

Of course, we can clearly see that neither stack variable is used at all after it's declared/initialized, so that adds to the puzzling effect.  An optimizing compiler would have sensed (as the result of a global reaching assignments data flow analysis) that the variables had no uses, and would have eliminated both (and the initializing/saving of ecx code) altogether in its first dead code elimination phase.  Therefore I surmise that the compiler has all optimizations disabled (which makes sense in combination with the previous paragraph -- debug builds are typically unoptimized).

Further evidence for this "no optimizations" theory comes in noticing that ebx and esi are saved in the function's prologue and restored in the epilogue, despite neither being used throughout the course of the function.  This is called "register saving", and is subject to optimization when optimizations are enabled.  In fact, none of the registers need to be saved if the two dead variables and related initialization are eliminated.

With the stack variables eliminated and no alloca() present, the compiler can (and should) decide to use an esp-based frame instead.  The result is that the function needs no prologue/epilogue, and ebp no longer needs to be saved as above.

So really, this whole function should have been optimized down into one instruction:  "retn".  If whole-program optimizations had been applied (and/or devirtualization, if this is a virtual function -- I didn't see the references) this function would be a good candidate for inlining, in which case all call-sites to this function would simply disappear, and the function itself would not be present in the final binary.


Blog Comments
shegget Posted: Saturday, January 5 2008 00:54.07 CST
awesome! good explanation and a nice reference link!



Add New Comment
Comment:









There are 31,314 total registered users.


Recently Created Topics
[help] Unpacking VMP...
Mar/12
Reverse Engineering ...
Jul/06
hi!
Jul/01
let 'IDAPython' impo...
Sep/24
set 'IDAPython' as t...
Sep/24
GuessType return une...
Sep/20
About retrieving the...
Sep/07
How to find specific...
Aug/15
How to get data depe...
Jul/07
Identify RVA data in...
May/06


Recent Forum Posts
Finding the procedur...
rolEYder
Question about debbu...
rolEYder
Identify RVA data in...
sohlow
let 'IDAPython' impo...
sohlow
How to find specific...
hackgreti
Problem with ollydbg
sh3dow
How can I write olly...
sh3dow
New LoadMAP plugin v...
mefisto...
Intel pin in loaded ...
djnemo
OOP_RE tool available?
Bl4ckm4n


Recent Blog Entries
halsten
Mar/14
Breaking IonCUBE VM

oleavr
Oct/24
Anatomy of a code tracer

hasherezade
Sep/24
IAT Patcher - new tool for ...

oleavr
Aug/27
CryptoShark: code tracer ba...

oleavr
Jun/25
Build a debugger in 5 minutes

More ...


Recent Blog Comments
nieo on:
Mar/22
IAT Patcher - new tool for ...

djnemo on:
Nov/17
Kernel debugger vs user mod...

acel on:
Nov/14
Kernel debugger vs user mod...

pedram on:
Dec/21
frida.github.io: scriptable...

capadleman on:
Jun/19
Using NtCreateThreadEx for ...

More ...


Imagery
SoySauce Blueprint
Jun 6, 2008

[+] expand

View Gallery (11) / Submit