As a programmer we strive to make our everyday lives easier. The very engine behind all innovation is lazyness, after all, if it weren’t for us being lazy, why would we use - and by that, have a need - for things like automobiles, computers and so forth?
I often meet people who aren’t aware of the many great tools that aid developers when debugging websites in Internet Explorer. I’ll mention a few of the most valuable ones that I use here.
If you know of any great tools that I’ve failed to mention, please let me know!
Fiddler enables you to catch incoming and outgoing HTTP requests and debug them before they’re sent or received. This enables you to follow the HTTP stream and debug possible problems. You can even set debug points and modify the requests and respones before they arrive at their destination. This is especially great if you’re developing applications that make requests behind-the-scene, like for instance, Flash applications that make HTTP requests themselves.
HttpWatch is a more user friendly version of Fiddler. HttpWatch doesn’t have nearly as many features, you can’t set debug points or modify the requests/responses. What HttpWatch does have to offer is a much more slick and fast user interface, and direct integration into IE. Unless I have to use debug points I much prefer to use HttpWatch during my daily work. HttpWatch however is not free.
Suggested by Steve McCoole. ieHttpHeaders fall into the same category as Fiddler and HttpWatch, it gives a live display of the HTTP requests/responses. ieHttpHeaders only shows the headers, although both HttpWatch and Fiddler does this too, ieHttpHeaders is free (beats HttpWatch) and it’s neatly integrated into IE itself (beats Fiddler), so it definitely has value.
Don’t worry, although it says Internet Explorer 5, it works great in both IE6 and IE7. This WebDev powertoy enables a great feature in the IE context menu, “View partial source”. How many times have you not looked through a webpages source in Notepad, searching for a specific section? With the partial source view function you can simply highlight any part of the website and select “view partial source” and a window will open up, showing only that part of the webpages source, neat!
This tools mimics Firefox’s inline search function to near perfection. I for one love Firefox’s search function as it’s very quick to use and it doesn’t use a bulky modal dialog. This tool gives the exact same functionality in IE, it simply overwrites the usual search dialog.
Suggested by Steve McCoole. FullSource enables you to view the actual current source code of the page you’re viewing. That is, not the source code that was originally served to IE, but the source code that IE is currently rendering, including any DOM manipulations caused by JavaScript, XSL transformations etc.
Non IE addons
Although the next two tools are not IE specific, I simply have to mention them as I use them to a great extent.
This is by far the best color picker tool that I’ve come across. It makes it a snap to pick colors with pixel precision, no matter if it’s from a webpage, application or windows itself.
JRuler is exactly what the name implies, an onscreen ruler that can be used anywhere. It has great support for measuring in various units. Although there is a builtin ruler in the IE developer toolbar, this one also works outside IE.
During the last couple of weeks, I have been giving lectures on the subject of .NET code protection at some of the danish universities.
Part of being a Microsoft Student Partner is exactly this, travelling the universities and spreading knowledge of the Microsoft platform. Naturally .NET is the most exciting topic to talk about as the primary audience mostly consists of computer scientists.
Due to my work as a MSP I’ve got my 2006 Tech-Ed conference entry ticket paid, so I’m taking a short trip to Barcelona on the 8th of november untill the 11th of november. Hopefully I’ll get a lot of hands-on experiences with the new technologies and platforms, I can’t wait!
When you write your code, compile it, and distribute the exe/dll’s, is your source safe? We’re not talking about protection against buffer overruns, SQL injection and various other code hacking techniques, we’re talking protection of the source code itself, protection of intellectual properties.
This article is the result of me touring the danish universities as a Microsoft Student Partner, giving lectures on the subject of securing code and intellectual properties in the realm of the .NET Framework.
Why even bother protecting our source code? There are millions of reasons for why we would want to protect our source code. Although security does not derive from obfuscation, but instead from writing secure code, there are a lot of situations where we simply cannot distribute our source code for various reasons.
You might be developing code that does not belong to you, due to you developing the code at your job. It could be that you’re developing an application that will be commercialised, it wouldn’t be appropriate to release the source code as that would most likely lower your sales and open up all sorts of risks of counterfeited copies (I won’t go into the topic of open source enterprises as they are vastly out of scope, but of course they do have their basis for existance). It could also simply be a matter of security. As mentioned before, security shouldn’t come from obfuscation, but any extra bit of unneccesary information that a potential hacker can get about your application will add up to the overall risk.
Why is this an inherent problem with .NET?
To understand why this problem is especially explicit in .NET, one must understand how the .NET framework works. Let me introduce you to a simple illustration of the .NET framework levels:
One of the coolest parts of the .NET framework is that we can write in more or less any language we want. C#, VB.NET, C++.NET, Delphi.NET, SmallTalk.NET, you name it! What enables us to do this is the Microsoft Intermediate Language (or MSIL in short). The MSIL compiler compiles your .NET language code into an intermediate language called MSIL. The MSIL language is common for all .NET languages, they all compile into this intermediate stage. Compared to native code, MSIL is a high level language. Although it is not easily read, it doesn’t take long to get a grip of what’s happening if you look at it. When an application (application being any .NET code, ASP.NET, DLL, EXE and so forth) is run, the Just-In-Time (or JIT in short) compiler takes over and compiles the MSIL code into native code that the CPU can run.
Java, C++, Pascal etc
The MSIL language can easily be compared to the Java bytecode intermediate code. All Java code is compiled into Java bytecode which is then run by the Java Virtual Machine (or JVM in short). Although Java bytecode is not nearly as highlevel as MSIL, it is still easily parsable, making it easy to reverse engineer it back into real Java code. Although the reasoning behind the JVM and the MSIL/CLR compiler are not the same, Java has the same disadvantage as .NET. Other native languages like C++ and Pascal (and a lot others) do not have this problem. Instead of compiling into an intermediate language, they simply compile directly into native code. This has the advantage that code execution is usually faster and the disk footprint is smaller. Also while it is possible, it is unfeasible to reverse engineer large amounts of native code.
So why not just dump the MSIL?
Having the MSIL/JIT combination has a lot of advantages, some of them being that the .NET framework can boast of a vast amount of supported languages and that the JIT compiler can make CPU/platform specific optimizations when it compiles from MSIL to native code. I won’t be making any in depth analysis of the advantages and disadvantages of JIT compilation versus direct native compilation in this article, I’ll leave that for a followup article later on.
Tools
Alright, before we start, let me introduce you to a couple of tools that I will be using to demonstrate the weaknesses of the .NET application protection schemes that I will be showcasing.
Reflector
You will have to learn to live with, love, hate and embrace Reflector, it’s a godsend! Click here to open Lutz Roeder’s ‘Programming .NET’ website where you can download Reflector. Reflector is used to decompile existing .NET applications, whether that be EXE’s or DLL’s or any other .NET code. I won’t be describing how to use Reflector, I will simply show the results of using Reflector.
IL DASM
If you have the .NET Framework SDK installed then you will also have installed the Microsoft ‘MSIL Disassembler’ tool, called IL DASM in short. IL DASM is used to decompile .NET code into the underlying MSIL code. Reflector does the same, though Reflector can go a step further and reverse engineer the MSIL code into more humanly readable .NET code in the most commong .NET languages.
Preemptive’s Dotfuscator is a great .NET code obfuscation tool. A lightweight community edition ships with Visual Studio .NET 2003 & 2005. The professional edition has a lot more options for code obfuscation and code compression.
I demoed the evaluation version of Dotfuscator during my MSP lectures. Just before my demo at the last university on the tour, I had an emergency. “Your evaluation copy has expired”… Not what you want to read when you are to show the demo in just under two hours. I got hold of the european office department by phone and within minutes I had a new evaluation license that I could use. Great support!
Simple password protection
In this example we will be creating a simple .NET application that includes a “secret” algorithm that we want to protect, as well as protect the actual appliction by requiring a password before it can be used.
Creating the application
Start out by creating a new Windows Application project, call it “SecureApplication”. Add a TextBox and a Button to the form, Form1.cs like so:
Now insert the following two functions into the form:
The answerToAllLife() method is the secret algorithm we want to secure. Never mind the complexity of it, is simply to make it a bit less readable when we decompile our application, to make things a bit more realistic. Now if you run the application, it will only allow you to run the algorithm if you provide the correct passowrd: ‘password’. Simple and effective eh? Oh, you don’t think that’s protection enough?
Decompiling the application
Now, let’s see what happens when we open the application using the ILDASM tool that ships with every installation of the .NET Framework:
I am by no means an MSIL expert, but we can pretty easily spot the strings “password” and “Error” and by putting two and two together, I wonder what the “password” might be? This is a crude example, but still, it shows the point, we cannot embed our password into the application.
Not only can we not include our password in our application, we also can’t exchange the password with some kind of registration key pattern matching algorithm as that one could also be reverse engineered, opening up for the possibility of key generators and the likes.
But hey, this is the least of our problems. In case you didn’t notice, the complete source code of our algorithm is also available!
Now this code isn’t especially readable when it get’s large, but what if we try using Reflector instead? This is what we get when we decompile our buttons Click event:
Looks familiar? This should make it pretty obvious that our code is NOT safe, it is simply too easy to decompile unprotected .NET code. So what can we do?
Using native code to protect vital parts
I gave a comparison between .NET and the native languages earlier on. What if we were to create our vital code parts in native code, and then keep all the non-vital code as .NET? Let’s try to protect our algorithm by coding that one in native code while presevering the user interface in .NET. Of course we ought to also code the password check in native code, but for this example I’ll stick with our algorithm.
Creating a VC++ DLL and calling it from .NET
Create a new VC++ Win32 Project to the solution, call it “SecureComponent”. When prompted, select “DLL” as application type and make sure that you check the “Export symbols” checkbox.
Now replace the whole SecureComponent.cpp file with the following code:
And replace the corresponding header file SecureComponent.h with the following code:
I am by no means a C++ expert, and you need not be either. This C++ DLL project contains a single function, AnswerToAllLife() of type char* which corresponds to a .NET string. Instead of writing the actual algorithm we’ll suffice with returning the alogrithm result, “Hello”.
Compile the SecureComponent project and locate the resulting SecureComponent.dll file in the output directory. We will be calling this DLL through platform invoke (p/invoke in short) as that is the simplest and quickest way to call our native code from .NET.
Copy the SecureComponent.dll file into the %windir%system32 directory. Now modify the SecureApplication form1.cs code so it matches the following:
Make sure that you import the correct namespace (System.Runtime.InteropServices) for the DllImport attribute to work.
Now try running the SecureApplication project and test that it works (messagebox saying “Hello” when you provide the correct password and click the button).
Now comes the interesting part. Open up Reflector and add the SecureApplication.exe file to the list of loaded assemblies (make sure you remove it if it’s already loaded as Reflector will otherwise show an old cached version). Browse to the AnswerToAllLife() function est voilá:
Now our algorithm is securely hidden from the usual means of decompilation. This however does not mean that our code is universally secure. Sure it’s somwhat more difficult to get to our algorithm than before, but it ain’t possible. Native code can be reverse engineered but it’s a very tough job, especially as the code get’s larger and more complicated.
A drawback with this method is that we’ll have to write our vital code parts in native code. Naturally we’d prefer to write in managed code, but depending on the project, native code is an opportunity. So what am I saying? No matter what you do, if your code is physically at the clients machine, it is not safe. No matter what you do. As long as the code is physically at the client, all we can do is to make it as cumbersome as possible to get to the original source as possible, hopefully evading most reverse engineering attempts.
Creating a webservice that will host our algorithm
Let’s make our code 100% secure. How? By not supplying the clients with our algorithm at all, but simply allowing them to invoke the algorithm remotely. The easiest way to do this in the .NET framework is by using web services.
Creating the web service
Add a new ASP.NET Web Service to the solution, call it “AlgorithmService”. Now open the Service.asmx codebehind file and replace the contents with this code:
Our webservice contains a single function, AnswerToAllLife that represents our algorithm, just like our C++ version. Try running the webservice (you may need to set the Service.asmx file as the start page) and check that the web service works by invoking the AnswerToAllLife function:
Now add a web reference to the SecureApplication project. Click the “Web services in this solution” link and select the AlgorithmService web service. Name it “AlgorithmService” and click the “Add reference” button.
Now modify the button1_click method as follows:
Now, when the user provides the correct password, we invoke the AlgorithmService web service and show the result. If you decompile the SecureApplication exe file using Reflector, this is the code you’ll see for our button’s click event:
And this is the code we see if we go to the “AnswerToAllLife” method in the Service class:
Neat eh? Now there is no way that our source code can be compromised. There are however some drawbacks to using web services. First of all, we’ll need to require that our clients are connected to the internet, or at least to some kind of network that’ll allow access to our web service. Also web services impose a significant overhead on each algorithm call compared to direct managed/native calls. Finally there may also be security issues, for instance, a credit card validation service might not be the best of projects to provide via a web service.
Recap
Without any protection at all, our code is very unsafe. Any person is able to decompile a .NET application using only free tools within minutes.
We may protect our code by writing it in a native language. Though it is not bulletproof, it severely complicates the process of reverse engineering our code. It is however also morecumbersome for us to write our vital code in the native language as oposed to writing it in managed code.
The only 100% secure way to protect our code is to not supply it to our clients in any way. Web services and remoting are two ideal methods of accomplishing this separation. It isn’t always possible separate parts of our code due to certain circumstances, so it’ll be a matter of judgement whether it’s possible.
Obfuscation
Ok, so we can remove our algorithm code by utilizing web services, but what about the password check? And what about our other code that we’d also prefer to keep to ourselves? Let’s look at obfuscation.
Obfuscation is a technique used to complicate code. Obfuscation makes code harder to understand when it is decompiled, but it typically has no affect on the functionality of the code.
PreEmptive Dotfuscator
I have tested several tools that boast of being able to obfuscate .NET code without providing a lot of overhead on the developers… Us. The most effective and efficient obfuscation tool that I have tested so far is PreEmptive’s Dotfuscator. You can request a free 14 day evaluation at their website. Don’t worry if you haven’t gotten it up and running while following this article, I’ll be showing screenshots of the most important aspects of using the Dotfuscator product.
Seamless Visual Studio integration
What’s cool with Dotfuscator is that it integrates directly into Visual Studio (2003 and 2005) by providing a new project type:
After creating the project, we can add any number of assemblies to obfuscate, or even project outputs - Dotfuscator will then make sure to obfuscate the resulting assemblies automatically.
We can set the individual obfuscation settings by using the six setting categories. I won’t go into major details as that is out of scope of this article.
Under the renaming category we can set the options for how our assembly members should be renamed. We can choose to rename using numeric names, lower/uppercase alpha names, or my favorite - the unprintable characters. Although we can rename our members to our liking, there are still certain restrictions. In .NET every function must have a unique signature. Normally the signature consists of the name of the function as well as the parameter types. Dotfuscator can use the “Enhanced overload induction” to also identify functions by their return type, effectively causing us to give a lot more functions the same names, confusing our potential decompilers even more.
We can also choose to alter the control flow, causing a number of lables and goto calls to be embedded in our code, I haven’t observed any noticable performance hits. Dotfuscator also supports automatic encryption of strings in our application without us having to do anything. You can choose which strings encrypt and which to keep unencrypted. The strings are decrypted on-the-fly as the application is running, so keeping unimportant strings in cleartext will be the most efficient.
The process of obfuscating
Obfuscating our SecureApplication is very easy. Simply add the SecureApplication project output to the “Input Assemblies” part of our Dotfuscator project and compile the project as we would compile any other project. After compiling, try to open the project in Reflector:
Notice how our namespace and class structure is completely unreadable, thanks to the unprintable characters. We can still find our buttons click method by looking at the method signature - as our methods still have to have a unique signature. We can identify our buttons click event by looking for a method with the same signature: void(object, EventArgs).
IL DASM can still decompile our application, this is the resulting code from out buttons click method:
Notice how our “password” string now looks like this: bytearray (14 65 16 76 18 6A 1A 68 1C 6A 1E 70 20 53 22 47 ), neat eh?
Checking our password through a web service
Although our password is encrypted, it still isn’t safe to have the password check on the client machine. Why don’t we check the password via a web service? Again, this is only possible if we can require a network connection to our web service. If that isn’t possible, we might want to code our password check in a native language.
Creating our password checking web service
Add a new ASP.NET web service project to our solution, call it “PasswordService”. Modify the Service.asmx.cs file so it contains the following code:
Our password checking web service only contains a single method, ValidPassword. ValidPassword takes a single parameter, the password to check. It returns true if the password is valid, and false otherwise. Now, this time we’ll publish our web service to an actual web server as the local hosting won’t be sufficient for the next section of this article. If you don’t have access to a web server yourself, you can use my web password checking web service running at http://service.improve.dk/Service.asmx.
Add a web reference to the SecureApplication project, remember to use the location “http://service.improve.dk/Service.asmx” this time. Call the service “PasswordService” and click “Add reference”. Now modify our buttons click event so it matches the following:
Notice how we this time use our PasswordService to check our password while still using our AlgorithmService to run the algorithm. So what’s the advantage? Both our password checking code as well as our algorithm code is 100% secured this time. Combine this with the obfuscation and you’ve got some really tough to read MSIL code.
Cracking the password check
Now that our code is totally safe, how can we get around the password check? Let’s ignore the fact that it is possible to decompile our application to MSIL code, remove the password checking parts and then reconnect the bits to create our complete application, except the password check. While this is possible, it’s more or less unfeasible for a major project, especially if you’ve obfuscated it effectively. Let’s change the scenario.
Now we’re the hacker who’s trying to beat our password check. We do not have access to the code of our SecureApplication, but we do have the distributed exe file (that utilizes our two previous web services).
Analyzing the SecureApplication
We want to know what happens under the hood of the SecureApplication that we’ve got. Fire up Wireshark and start a new capture.
Be aware that if you’re using a WIFI, you may have to turn off promiscuous mode. We’ll cheat a tiny bit, since we know the application uses webservices, let’s setup a filter so we only see TCP HTTP (port 80) traffic, this’ll reduce a lot of unwanted traffic.
Now start the capture, run the SecureApplication and type in a false password (remember, we’re the hacker, we haven’t got the correct password). Close down the SecureApplication and stop the capture, hopefully you’ll see a result like this:
Right click on one of the green lines and select “Follow TCP stream”, you should see a stream like this:
Analyzing the contained HTTP request and response gives us som valuable information. The top part is the POST request and the bottom is the response.
In the request we can gather that the host is “service.improve.dk” and that we’re requesting the file “/service.asmx”. The SOAP XML tells us that a function called ValidPassword is being called, and it expects the parameter “password”. Heck, we just found out the structure of the password checking web service. Now, what can we gather from the response?
Well, I wonder what false means… If only we somehow could switch that “false” to a true.
Faking the web service
Our goal here is to setup our own web service and somehow make the SecureApplication call our own service instead of the real one. We cannot change the code of the SecureApplication, so we’ll have to work around it somehow. Start by adding a new ASP.NET web service to our solution, call it “FakePassword”. Modify the Service.asmx.cs file so it matches the following code:
From the HTTP stream we gathered the function name, type and parameter(s). In our fake service we’ll just return “true” everytime, effectively bypassing the password check by ignoring the password parameter. Now open up your IIS and set the default website home directory to the folder where your fake password service lies.
Now if you go to http://localhost/Service.asmx, you should see our fake password service. What we need now is for our service to somehow respond to the address http://service.improve.dk/Service.asmx. Open up the file “hosts” in the following directory: %windir%system32driversetchosts, note that it does not have an extension, simply open it in notepad. Now add the following two lines:
You have to ensure that you keep the tabs just like the default line in the hosts file. Now if you go to http://service.improve.dk/Service.asmx, you’ll no longer get to the real web service as we’ve just setup our system so that 127.0.0.1 (our local machine) responds to this domain name instead. You can’t test the webservice locally through this address as it will fail if you don’t use the proper .NET classes. Now think about what happens when we run our SecureApplication again… It will connect to the address it was built to connect to, http://service.improve.dk, but it’s no longer the original web service, this is now our fake service. This should be the result:
No matter what password we supply, our algorithm will be run as our fake web service will tell the application that our password is valid.
Recap
Obfuscation vastly improves the safety of our application since strings and member names are no longer visible. Also it forces people to look at the MSIL code or break the obfuscation before they have access to our code. Obfuscation isn’t safety in itself, but combined with other methods of protection, it’s a big plus.
We really shouldn’t have any registration methods lying in the client application as they can and eventually will be cracked, resulting in either keygens or password floating around on the internet. If possible, use remote checking of registration codes.
Don’t put a lot of trust in your solution just because you use remote checking, it can be broken.
A proposed solution
My proposed solution is a mix of the earlier mentioned methods, combined together it is rather effective. It does however require a connection to our remote registration server.
For this demo I won’t be creating any code as it gets rather complex. Instead I will be describing the overall thought behind the solution. I am considering making a general purpose registration framework that will encompass my proposed solution. When I do make this framework, I will surely be releasing an article describing it in more detail.
Public key cryptography
The solution is built upon a publick key cryptosystem, in my implemented solution I’ve used the RSA cryptosystem, but which specific system is used really isn’t important.
Public key cryptosystems are built upon the idea that every person get’s a set of keys, a public key that anyone knows about as well as a secret (normally the word private is used, by to avoid confusion due to both public and private starting with a “p”, I’ll use the term secret for the private key) key. The secret key is to be kept totally secret from everybody else, only you should know the contents of that one.
The correlation between the keys is that any data encrypted with a public key can only be decrypted by using the matching secret key. Likewise, any data encrypted using the secret key can only be decrypted using the matching public key. This allows us for two very important scenarios of cryptography.
Say I want to send a secret message to Alice, I’ll use Alice’s public key to encrypt my message. The only way to decrypt the message is to use Alice’s secret key, and only Alice knows that one, so only Alice can read my message. Now, Alice can’t positively know who the message comes from, that is, unless I sign the message. Signing the message implies that I use my secret key to encrypt the already encrypted data (encrypted with Alice’s public key as before) with my secret key. Now only my public key can decrypt the data, hence the message can only come from me if it’s decryptable by using my public key.
Using these correlations it’s possible for me to send a message to Alice that only Alice is able to read. Furthermore I can sign my message so that Alice can verify it is coming from me.
Customer entity
First of all we have the Customer. The Customer consists of the customer data itself, not really important to this solution. Besides the trivial customer data, the customer has a Keyset.
Keyset
The Keyset contains three keys (keys of the RSA cryptosystem):
The customers public key.
The customers secret key.
The registration servers public key.
The reason for the customer to have to registration servers public key is so that we can verify the messages being received from the registration server.
The registration server
The registration server can be set up in any way you like. I’ve personally used an ASP.NET Webservice, but you could use remoting or any other means of communication. The registration server only has two functions, GetKeyset and GetLicense.
Step 1
When the customer starts up the application for the first time, the GetKeyset function is invoked on the registration server. The GetKeyset function takes the users registration code as a parameter and returns the proper Keyset, provided that the registration code is valid. If a registration code at some point is misused, shared or in any other way has been used in an illegal way, simply inactivate the registration code on the registration server, ensuring that no new keysets will be returned for that registration code in the future.
Step 2
After the keyset has been retrieved, we now have the means to decipher any licenses we retrieve from the registration server.
The next step is to invoke the GetLicense method, again passing in our registration code as a parameter. The license is in its most basic form simply a boolean value, true/false, telling us whether we’re allowed to run the application or not. The important part here is that we first encrypt the license result using customers public key, then we encrypt/sign that data with the registration servers secret key.
Step 3
Now that we have retrieved the license, all we need to do is to decipher the result and then verify that the result originates from the correct registration server. We do this by first deciphering the data using the customers secret key. Then we decipher that data using the registration servers public key. If the data is valid, we know it comes from the correct registration server.
The FCKGW effect
One of the most common problems with registration protection of software is that users tend to share registration keys. As mentioned before, we can mark registration keys as invalid on the registration server. Marking keys as invalid will cause any new keyset requests for that specific key to be denied. But what if a thousand people had already requested - and successfully retrieved - keysets? Of course there could be implemented an automatic check ensuring a max number of keyset requests for a single registration key, IP protection and so forth. What we really want, is to be able to invalidate a keyset/license that a user has already retrieved.
A way to do this is to impose a time restriction on the licenses that a customer retrieves from the registration server. For instance, if a license was automatically invalidated on the client machine after a week, then the customer would have to retrieve a new license from the registration server. If the registration had been invalidated on the server in the meantime, the license wouldn’t be able to update, and thus the client wouldn’t be allowed to run the application any longer.
Ending remarks
Deciding whether to protect your code, and to what degree, is not a simple task. You must carefully weigh the pros and cons of the various techniques, and to what degree you need the protection.
Always remember that there is no totally safe way to protect your code, unless you keep it away from the client computer.
Please feel free to post any comments you may have on my article, I’ll appreciate any feedback you give.
Today we wanted to try a buffet, not something I’ve done a lot of over here (except the Aladdin buffet which wasn’t really that good). Me and three others went to the Wynn, a rather new and very grand hotel to test their buffet. Compared to the Aladdin this one was far superior. Only downside is that their speciality was seafood, which isn’t exactly my kinda thing. Anyways, it was great food and a great scenery!
After eating at the Wynn we went downtown to Fremont Street to see the incredible lightshows.
Hanging above Fremont Street is a “monitor” of unimagineable size, literally covering the whole street. On this monitor area shows are being shown each our from 7 PM until midnight. Different shows are shown at different times, unfortunately we only had the time to see one of them (as we arrived near midnight). Although the picture quality isn’t really that great due to lack of light and very changing light conditions, it should be rather easy to notice that the show contained a lot of lightly clothed women - not bad!
Afterwards we went into the 4 Queens casino & hotel to play some serious -EV games! I had major SKRUB in the Texas Holdem table game, hitting several bonuses with a max bonus bet of $50 (all of downtown is low stakes unfortunately). On one hand I hit AA with $50 on the bonus field, giving 30:1 back - not bad. Afterwards I made a major hit on a “Wheel of Fortune” slot machine, netting around $500. All in all I ended up around $1500-$2000 purely by playing -EV games… -EV - I say not!
Tomorrow is my last day over here. I really could’ve used a week or two more, I am not looking forward to the prospect of going home. Sure it’s going to be nice to see folks at home, get a glass of real milk, eat real food and so forth, but I’m not looking forward to the amount of work and school stuff waiting for me to come home.
Tomorrow we’ve talked about visiting the Las Vegas Gun Shop to try some AK47’s, UZI’s and similar cool guns. Afterwards we might take a trip to the Stratosphere to finally try some of the rides. We’ll round off the night by seing Jay Leno at the Mirage at 10:30 PM that night.
My plane leaves at around 8 AM saturday. Due to the recent terrorist plots discovered in the UK, I’m not really sure how much trouble I’ll have while flying home. I’m fearing I might not have enough transit time in the airports due to the increased security checks and so forth. Worst case scenario is that I’ll be forced to get a later plane, delaying my arrival time at home.
Today there was to be no gambling… A day I never thought was possible. After I got up at around 5 PM I went with Morten to the Hooters hotel & casino to dine and look around. The Hooters girls are in a class of their own, they’re much nicer than most of the Spearmint girls, I simply have to stay at this hotel at some point!
Unfortunately when we got our pics taken we didn’t switch cameras, so I’ve got the picture of Sally (our lovely waitress) together with Morten and vice versa, but nevermind, Sally’s what’s interesting in this picture.
Afterwards we went to the Las Vegas premium outlets to do some shopping. Damn it’s cheap! I went nuts in the Tommy Hilfiger shop, expecting the bill to be around $5-600 (which I’d still perceive as cheap)… It didn’t pass $200. You can really do some scoops here when it comes to clothe shopping!
Afterwards we went to the Stratosphere to enjoy the view and look at the rides. Unfortunately due to all our shopping bags we couldn’t take the rides as we didn’t really feel like leaving our bags on the ground in the mean time. I might go to the Stratosphere one of the next days, I really wanna take the Big Shot ride.
The last $1500 NLHE event was starting at 10 AM, so I really had to get up early. Though I’d never be able to do so at home, I actually managed to get up at 8 AM and get to the Rio at 9 AM. When I registered I was told that the tournament wasn’t starting until 11 AM though - it seems I messed up in the dates, the last $1500 event was actually tomorrow, not today.
After eating breakfast I still had one and a half hours of time to kill… So I found myself a free CardPlayer magazine and sat down at a slot machine. One of the female attendants came over jokingly asking me why I’d just sit there playing the slots while reading the magazine, I didn’t really look like the typical slot player, hardly interested in the slot machine itself. I ran good, really good. When I went back to play I’d built up a surplus of $800 on the slot machine, not bad!
The tournament itself was yet another disappointment. I finally today realized how awfully bad the structure is. I ran card dead for the first hour, and at that point I only had around $800 back, 20 BBs. These tournaments start with $1500 stacks, 25/25 blinds that rise every hour (about 25 hands/hour). It is simply a disgrace to call these events for WSOP events, and even more of a disgrace that there are bracelets for the winner of these events, since there’s rarely more than 350-400 participants.
A couple of pictures showing the final four tables of the WSOP ME:
Later in the day I went to the Mirage with a couple of the others to play some $2/5 NL. Mirage had a nice room, although I don’t really like their cards (KEM) when compared to the WSOP Copag cards. Also their brush was working a manual list that wasn’t visible to players. To sum up the play, I ended down around $900, most of it due to the last pot I played. Me and Joachim had just agreed that this would be our last hand before we’d go (I was UTG, just before the BB). So I look down, and what do I see? Black kings! I raise it up to $20. I get a single caller in MP from an extremely tight player - really, really tight. The flop comes 646r. I bet out 3/4 pot, he calls. At this point I really only fear hands like 44, 66 and pairs 77-AA. 66 is unlikely though, so is QQ-AA as he’d have reraised me preflop with those holdings. Turn is another 6 which counterfeits his 44 full house in case he has that one. I bet 3/4 pot, he calls. River is a jack, a pretty blank card unless he has JJ, I’m pretty sure he’d have raised me earlier with JJ though. I bet out 1/2 pot, and he immediatly goes all in. I have to call as the pot is now very big. He turns up A6o for the turned quads, and he rakes in the almost $1k pot. I have no idea how these awfully tight players suddenly wake up, calling a $20 UTG raise with utter crap.
Later on we went to the Venetian to play some $1/2 donk NL. Venetian has a spectacular room! Great scenery, great tables (although I don’t like their felt as much as the Rios) and above average cocktail services. Also this was the juiciest $1/2 table I have ever seen, it is unbelievable, I can’t even describe it. Just imagine people calling down with ace high all the time, that about sums it up. I ended up $32 after about 5 hours play due to me donking it up with the other sjufts at the table.
Today was the second last $1500 NLHE event of this years WSOP. I went to bed at 8 PM the night before and slept all the way until 9 AM so I couldn’t blame my performance on lack of sleep today - unfortunately.
I had Bill Chen (2-time WSOP bracelet winner in the 2006 series!) and Max Pescatori (1-time WSOP bracelet winner in the 2006 series) to my left, there were definitely a couple of other pros at the table, but those were the only two I really recognized. Also Joe Hachem was sitting at the table right next to mine.
The funny thing about these $1500 events is that they’re actually a lot tougher than the main event! The pro/amateur ratio on the tables are a lot less than in the main event. Also due to the small stack structure you really can’t afford to make any mistakes. Max played a very crazy game, making some insane preflop pushes, trying to push people off hands. He’d been caught with J7o, 22, 99 and various other weird hands, and amazingly he’d won even though he went in as an underdog every time. Bill played rather ABC, but I noticed he’d made a lot of squeeze plays. In general it seemed like he had great perception of the table situation and he was able to take down a lot of pots without going to showdown.
I started out absolutely great! Though I do not remember all the hands any more, I managed to build my chipstack up to chipleader status within the first couple of hours, having nearly 18k when the average was around 3k. Unfortunately my luck ended suddenly. It started out in a pot where I had TT on the button. Blinds are 100/200. LP pushes all in for about 1500. I look down on my tens, I just smooth call, I don’t want to risk all of my stack by isolating since Max was sitting on a stack of around 10-12k himself. After my call, Bill pushes his stack in, and Max folds. I count up Bills chips, around 4000… Hmm, I’d seen him do this before and I was pretty convinced that he was trying to squueze me out with a mediocre hand since LP could’ve had any two more or less, so I called. Bill showed QQ, yuck, LP showed 97s, more or less as expected. The flop didn’t help me, and to make things worse, I’d overseen a couple of pinks in Bills stack, so he didn’t have around 4k, he had 6k, ouch.
I made a couple of great calls on the flop later on with marginal hands, nothing held up unfortunately. In a series of about four or five showdowns that I didn’t win, my stack simply dwindled away. When our table broke up I had about 3k left with blinds of 150/300 + 25 ante. I was moved to table 1 and by chance Bill sat to my direct left again. Second hand at the table it gets folded around to me, I’ve got black jacks, I push. BB thinks for a while and then calls with AT. Flop comes: AT8, Turn: T, River: no jack. I’m out. Bill gives me his hand and congratulates me on my play and gives me consolation for busting out in this way. At this time there were around 80 left in the tournamnet (420 to start), payout to top 45. Dammit.
Tomorrow is the very last WSOP event of this years world series. It’s also a $1500 NLHE event. It’s going to be tough getting up since it starts at 10 AM, but I’m destined to give this my very best try… This is my last chance at getting a bracelet and thereby setting the record for youngest bracelet winner ever.
I got back home from Spearmint at around 7:30 AM, pretty wasted to say the least. I know from experience that setting my alarm clock on my cell phone won’t help as I’ll just keep sleeping if I don’t have a life threatening reason to get out of bed, so I’d just sleep until I woke up.
I woke up just three hours later at around 11 AM… Hmm, I really did plan to get just a little bit more slep, or else I’d be completely burned out that night. I closed my eyes for a second… When I woke up again it was dark outside, it was 8:30 PM, yikes, that was a bit longer than I’d anticipated.
I had planned on playing the $1500 NLHE WSOP event on the next day, so this really fucked up my plans as my sleeping pattern was now pretty awkward. The WSOP event started at 11 AM that very next morning, and the event will run for up to 12 hours, so there would be no doubt that I’d be near death if I were to last that long.
I ended up getting a 20 minute power nap that night before I took a cab to the Rio at 9 AM to get some breakfast, register for the WSOP event and get myself prepared.
I was actually quite awake even though I’d been up for some hours by that time, so I felt prepared. The tournament was a short experience unfortunately, and I can’t blame anyone but myself. I made a terrible call in a pot that should’ve been an easy laydown.
I had around 1800, I’d just been moved to a new table, having Hassan Habib right across the table, and Vanessa Rousso (very cute) to my right. I get AhJc in MP with a single caller before me (blinds 25/25). I make it 150, I get two callers. The flop comes Js3d2d which is nearly perfect for me. Checked to me, I bet out around 350 out, both callers call again. The turn comes with a scary 6d. Now suddenly the EP caller bets out the pot, effectively putting me all in. I pondered over this bet a long time, why would he bet out this hard if he’d made his flush? Wouldn’t he either be going for the checkraise or simply betting less strongly to induce a raise? I ended up reasoning with myself that he must’ve had some kind of semi weak holding like KJ, TJ, 9J or something similar, and he wanted to take down the pot now using the scare card / bet. I pushed all in. Both callers instacalled - yuck. The LP caller showed 22 for the flopped set, and the EP caller show 7d9d. I was drawing dead. The river brought the 3s to fill up the LP caller, raking in a massive pot.
Having just 125 chips left I managed to triple up. Unfortunately I busted out with AQs against Vanessa’s AKo, fair’n’square. I didn’t last more than one and a half our. I really can’t believe I didn’t manage to fold that hand now that I’ve thought it through.
It’s now 7:30 PM and I’m going to bed. I wanna be really rested when I’m playing the next $1500 NLHE event tomorrow (there are two $1500 NLHE events left that I’m going to play).
At last I got a good nights sleep before the big day, day three of the 2006 WSOP Main Event!
I had my strategy totally planned, I knew all about the guys at my table (as written in an earlier blog entry), knew about the chip stacks, who to bully and so forth. I was prepared.
My strategy was to play pretty tight and semi passive up until the bubble (which would probably arrive after 4-5 hours). Utilizing this strategy would avoid marginal situations that could bust me before the bubble, as well as establishing a great tight passive image that I could use on the bubble to steal a lot of pots.
I started out great, folded all hands for the first 15 minutes at my table, then something unexpected occurred. I heard a couple of “Sir…” behind my back, though I didn’t relly think about it. Then someone tapped me and my shoulder and said “Excuse me sir…”, I looked around and there were a floor man. “We need to move you sir, please rack up your chips and follow me”. Shit, this was not what I needed! I had no choice though, very bad timing resulted in our table needing a man to be moved, and I was just about to receive the big blind (qualifying me to be moved), dammit!
I sit down at my new table, luckily I don’t see any immediatly recognizable faces which is good. The bad news is that the average stack on this table were vastly larger than at my old table, there were probably not more than one or two stacks smaller than mine, and there were a couple of 200k stacks, yuck!
After playing about 10 minutes on the table I realized that my tight passive strategy wouldn’t hold up on this table. Most of the players were playing a good loose aggresive strategy which resulted in me being stolen from constantly, a lot of raised pots and so forth. It was clear to me that I had to make a stand to avoid being stolen too much from, and in general to survive / build my stack before the bubble.
About half an hour in I receive a hand, 4s4c in MP. My stack is around 90k, blinds are 800/1600 + 200 ante. I raise it up to 5k, I get a single caller on the button, a big stack with around 250k. My read on this guys is that he’s playing a lot of pots (which isn’t that bad when you’re a big stack), though he seems to be playing rather bad postflop, and also he seems to be playing a bit too loose aggresive for his own good.
The flop comes something like As5h9d. I bet out around 7k, my standard bet, no matter if I hit or miss. He calls. The turn comes with the Td. I don’t want to invest too much into this pot with my weak holding so I check. He thinks for 10 seconds before he also checks. His check here reassures me he doesn’t have anything on this flop, at least nothing strong. Also there are no obvious draws, so I’m actually feeling pretty good. He might have the 5 or a smaller pair that hasn’t hit. Now the turn brings a Kc which I can’t really see improving his hand. I still don’t want to invest too much, I’d puke if I bet out here and he raised me, since I’d have to fold. I check, he thinks for about 20 seconds before he bets out 10k. 10k is a rather weak bet, and it confirms my suspicion that he’s weak, I’m pretty sure he’d bet stronger if he had a better hand. I think for 30 seconds before I say “Make it 25k” - so much for playing tight passive…
He sighs and folds his hand. Great start! I’m up to around 120k. When the bubble bursts, the average stack will be about 100k, so I’m in a great spot here.
A bit later I get into a almost identical hand with the same opponent. I get 2h2d in MP, raise it up to 5k, he calls in the blinds. The flop comes Kd3h7d. He checks, I check. Flop comes with a non diamond ace, suit doesn’t matter. It goes check check again. River brings an unimportant rag (again no diamond). He bets out about 7500 into a pot of around 20k. I’m not really sure I made the correct decision here, I feel he may have a drawing hand like TJ, JQ or some kind of diamond combination that hasn’t hit. I call and he shows A9 for the turned ace, and he takes it down. In hind sight I’m not sure I should’ve called, but following my reads had worked pretty good so far. After this hand I’m down to around 85k.
After some time I receive TsTc in the big blind, my stack’s around 80k. It’s folded around to a rather aggresive good swedish player who’d stolen a lot previously. He makes it 6k preflop. I quickly make it 14k. He thinks shortly and then calls. Flop comes Ad2c9d. The pot’s a good 30k so I bet out 20k, he quickly pushes all in, yuck. I’m pretty sure he wouldn’t do this without having hit the flop as were even stacked and loosing this hand would bust him from the tournament, pretty close to the bubble. I also can’t see him doing this with a hand having hit neither the 2 nor the 9, so I’m pretty sure he has a raggy ace or possibly a mid pair. Now, I could call and bust him if he had 33-88, though it is possible that he had JJ-AA also, either making a tricky preflop play with the AA’s or simply putting me on a resteal (which would be a reasonable assumption due to his history of steals), hence not believing I’ve hit the ace. I simply can’t see myself calling this, so I end up folding, bringing my stack down around 40k, possibly a bit less.
At this point we’re only about 30 away from the money, so suddenly my strategy changes. Now my main priority is no longer to build my stack, it’s simply to make the money and then reconsider at that point. The next hour is a boring hour, I hate shortstacked play on the bubble as I have no options, and I’m too easy to push around with a lot of big stacks on the table. I end up not playing any hands at all, even folding AJ to a LP raise (I won’t run the risk of them busting me only 5 people away from the $15k bubble).
A bit before hitting the money, Jacob Juhl joins my table, sitting right across the table from me. He’s a great guy, rooting for me to make the money, thanks!
We finally hit the money, at this point my stack’s around 26k, terrible. An Acemag reporter comes by to check on mine and Jacob’s stack and I tell him, “I’m either out in 5 minutes, or I’ve tripled”. The WSOP Main Event payout structure is absolutely terrible, it’s increidbly flat, you need to hit top 81 before the prizes start to really increase. The next 5 or 6 prize steps from top 873 increase the prize by only $1k or so, thereafter it increases by $2k for some steps. The flat structure really makes it necessary to gamble after you’ve hit the money, you have to build a stack to go deep, hence my quote to the Acemag reporter.
Just a few hands later I receive JhQh in the blinds. An EP weak player (very easy to push off hands) raises to 6k (blinds 1k/2k + 300 ante). I push my 26k in, knowing I probably have to live cards in case he calls, though I naturally run the risk of him having AA/KK/QQ, AQ, AJ or other terrible hands. He folds and I rake in the pot of a round 34k.
A couple of hands later I receive KsJs in late position. It’s folded around to me, and although I have rethought this hand a lot, I can’t see me folding this. I raise it up to 6k (which is the table standard). The bigstack loose aggro caller calls from the blinds, and a rather anonymous player calls from the button. The flop comes with a perfect Jh3d5c. Since the pot’s already about 25k due to the calls, antes and blinds, I simply push in my about 25k. The button player thinks shortly and then announces call, the laggy player folds. He tables AJ, I’m in very bad shape, I’m dominated - looking for a K to help me out. Unfortunately I don’t improve, and I’m out.
After the bubble burst people are busting like crazy. We’re probably loosing about 5 people per minute (about 90 tables left). When you bust out the procedure is to stand up and wait for you to be escorted out by an official, to make sure you get the correct bustout place recorded and so forth. This is great in theory, but when 50 people bust out within 10 minutes, they’re seriously understaffed. This resulted in me having to stand at my table for 10 minutes, just thinking about the bust, nothing else. It was terrible not being able to simply walk away. Right after a bust - especially from the greatest tournament of all times - you feel incredibly flat. Could you avoid the bust? What did I do wrong? All the prize money I could’ve won.
After the 10 minutes had passed, the floor man instructing me to wait had to excuse them being so slow to escort people out, after which he simply escorted me out himself (though it wasn’t his duty to do so). I didn’t blame him as he was in no way to be blamed for it. After busting, you get escorted to a podium in the middle where your seat / name is reported, and then you get a little yellow sticker with your bustout position (#822) as wells as your prize money. This poses a problem as your bustout position isn’t reliant on the time you actually bust, but on the order in which you receive your bustout note. I was just 2 places away from a higher payout step (+$1k), so if I hadf just stood around 30 seconds more, I would’ve received $1k more. Of course this is primarily a problem around the bubble when so many people bust, but still, it doesn’t seem reasonable.
I got the money in cash, and wow, what a feeling. Although I have a bankroll of more than $15k, never before had I held such a large bunch of benjamins ($100 bills) in my hand. I felt terribly nervous, walking around with that much cash in my pocket. Luckily I met up with Frederik and his father who were also on their way home, we took a cab together.
After arriving at home, telling everybody about how I busted and leaving the cash in my backpack, we prepared to head for town. The others were planning to go the the Aladdin and play some crazy donkfest cash games, although I’d just busted, I couldn’t resist joining. I got a quick bath, and off we went.
By coincidense we met up with Klaphat and a couple of his friends so we ended up being 10 people, just perfect for a private game! We convinced the Aladdin to open up a table for us. Due to Nevada laws they couldn’t make it private, but since we were 10 people, it wouldn’t be an issue.
The game was $1/2 NL. It was an absolutely crazy game. There were straddling everywhere, all ins in the dark, pot sweetening and delicious suckouts.
I started out by being stuck $600 within 30 minutes. Then started the most incredible run I’ve ever experienced. I flopped sets everywhere, rivered quads, flopped two pair with my 52o (which I ofcourse had to limp with in MP no matter any amount of raises) and so forth. In about an hour I built my stack up to around $1500 (and we’re still talking about a $1/2 NL, $200 max buyin game).
Without boring you, I’ll just say that in the next couple of hours I managed to dump away all of my stack (most of it to the creepy lucky luckbox Mikael) so I ended up being stuck $600 again.
After busting I went over to the bar where I found Morten and Rune totally wasted due to playing video poker and receiving free drinks.
We all decided to head out to Spearmint Rhino. And you simply can’t drive out to the Spearmint in anything but a limo, se we walked over to Caesars Palace and got a limo.
Unfortunately the rest of the night belongs under the “What happens in Vegas, stays in Vegas” category…