Summer at Microsoft
Tuesday, September 30, 2008
As you probably all know from my last blog post, I spent this summer interning at Microsoft in Redmond. I was hoping to keep this blog updated with all my experiences and news, but being the lazy person I am… I did not write a single line.
This is a condensed version of what happened with me during my 12 weeks in Redmond.
- Microsoft organized a lot of events for the interns – from big scale ones (21 buses, 2 concerts, lots of food and a free 8 GB Zune for everyone), through smaller ones (a few buses to Mount Rainier) to family-scale ones (some ice cream and free t-shirts for the international interns)
- I was working in the Windows Shell Test team, integrating some UI automation stuff into a bigger framework (the details are covered by the NDA I signed, sorry…)
- Mark Russinovich signed me a copy of Windows Internals book
- I saw Raymond Chen’s office. Raymond was not there when I walked by…
- I had a read only access to Windows 7 source code and daily builds. Windows 7 is awesome and MinWin rocks :)
- Mario Hewardt signed me a copy of Advanced Windows Debugging
- I had access to Office 14 builds (yes, they are skipping Office 13)
- I saw Steve Ballmer from, like, 2 meters away
- I played bowling with Jon DeVaan
- My team was working on Windows Vista SP2
- Dave Cutler, the father of Windows NT kernel, had his office in the same building and on the same floor as I had. He signed me a box of Windows NT 4
- Dev10 (the next Visual Studio) will kick your behind
- I didn’t see Bill Gates, but I saw his house (well, I biked to the gate of his house, to be more specific; no fanfares and no warm welcome from Bill’s side)
- I had access to Microsoft Company store, where you can buy Microsoft merchandise and software for funny prices
- I had time to do explorations of neighborhood (Seattle, Vancouver,…)
- Microsoft paid for me a health club. The club (Pro Sports Club) was the best I have ever seen.
All in all, it was a great summer. Microsoft gave me an offer for another internship the next summer, which I accepted. If you are still a student, give it a try and we might see each other in June 2009 :).
Topics: Personal | Comments Off on Summer at Microsoft
Interviewing with Microsoft
Wednesday, April 16, 2008
A few months ago I found an offer for a summer internship at Microsoft headquarters in Redmond. After all I have heard about working at Microsoft, it sounded like a perfect summer opportunity for me. I wasn’t very optimistic about my chances, but I would probably regret it later if I didn’t apply. So I sent them in my CV.
After a few weeks of waiting I got a call from the Czech Microsoft office saying that they like my CV and they are sending it to Redmond for further evaluation. I was happy, but still – had no reason for celebrations :). A few weeks passed until I received an e-mail from Redmond asking me several questions about my background (my motivation, programming proficiency, how much code did I write within the last year and stuff like that). I sent them all my answers and waited impatiently for a reply.
The phone interview
After a week or so, I received an e-mail with a telephone interview arrangement. Now it all started getting serious. I searched the whole internet for any hints on telephone interviews, prepared a sheet of paper with all possible questions, printed out my CV and even started brushing up my english a bit.
To my surprise, the interview went quite well. Again, there were some questions about my background and motivation and a simple problem-solving question. No “real” technical questions at all. Still, I had a pretty bad feeling about it. My answers could definitely be better and I felt that I didn’t say anything that would distinguish me from the other candidates.
In-person interview
A few weeks of radio silence followed. I started to be a bit worried that after the disastrous phone interview I am not even worth to get an e-mail telling me that I didn’t meet their expectations. Then I received an e-mail with subject “Microsoft Internship Interview Preparation – Warsaw”.
It was an invitation for an in-person interview with people from Redmond on their International Recruiting Trip in Warsaw, Poland!
The in-person interview was challenging. The interview took place in the Warsaw Microsoft office, which is a nice building about 10 kilometers from the city centre. I met 6 other internship candidates, 2 from Czech Republic, 2 from Romania and 2 from Bulgaria. I was the only one from Slovakia (the interviews were scheduled for two days and if I remember well, about 40 candidates were invited to Warsaw altogether).
I interviewed with 3 people – Holly (technical recruiter), Phil (manager from the Speech Recognition team) and Tom (developer from the “Clouds” team).
During the interview I had to write code on paper, explain my approach, design several tests and even solve puzzles (variations on the Pigeonhole principle). Even thought one interview took only 20 minutes (so 3*20 minutes together), it was exhausting.
The rest of my trip to Warsaw was fun, too. I had time for some explorations of the city and I took many pictures. The best thing about it – Microsoft paid all the hotel and travel expenses :).
Interview results
The results of my interview came in about two weeks later. I was really anxious about opening the e-mail. I really wished to get there. So I opened with jittering hands just to find out I received an offer! An offer for a SDET position at the Windows Serviceability team! Probably the best place I could get!
If everything goes well, I will start in the middle of june. So – see you in Redmond :)!
Topics: Personal | Comments Off on Interviewing with Microsoft
Singularity source code released
Wednesday, March 5, 2008
Microsoft has finally made the source code of it’s research OS called “Singularity” available to general public.
Singularity is a prototype operating system coded almost entirely in managed code. It’s written using Sing#, a language derived from Spec#, which itself has roots in C#. Spec# adds Eiffel-like contracts (loop invariants, preconditions, postconditions, etc.) to C#. Sing# extends Spec# with low-level constructs required for operating system development and channels required for communication within Singularity’s microkernel.
Okay, now what does this mean?
- Singularity’s code can be mechanically proved correct. This can easily reduce number of possible programming errors by orders of magnitude.
- Singularity’s strong typing creates impenetrable memory boundaries within operating system components and processes. This allows execution of everything, including user processes in ring 0. No more CPU cycles wasted by context switching.
- And much much more :)
Other projects attempting to create a CLI-based operating systems are SharpOS (which unfortunatelly uses the aggressive GPLv3 license) and Cosmos (released under a BSD license).
EDIT: I almost forgot the download link for Singularity; you can get it from Codeplex.
Topics: .NET | Comments Off on Singularity source code released
.NET framework libraries source code to be released
Thursday, October 4, 2007
According to Scott Guthrie’s blog, Microsoft will release the source code of .NET framework libraries together with .NET 3.5 and Visual Studio 2008 release later this year.
Nice. This means no more uncommented disassemblies of extended .NET classes from Lutz Roeder’s .NET Reflector (even though it’s a wonderful tool when you don’t have the source code, having the source code is better).
Topics: .NET | Comments Off on .NET framework libraries source code to be released
Latest development
Monday, September 17, 2007
It has been quite a long time since I have posted anything to this site. A month, to be exact. After a pretty harsh first half of my summer holidays, I have been busy catching up with some summer pleasures in it’s second half.
With my parents and my brother, I spent a week at our cottage in Low Tatras. I finally got the chance to charge my internal batteries.
After returning from the mountains a friend asked me if I would join him on his trip to Prague. He has never been there before and I just could not say no. The trip was perfect and I’ve got some nice pictures, so maybe I’ll post them somewhere.
Anyway – I promise, I will write more content for this blog now and I will also try keeping it less personal and more technical. I’ve got some fun things on the burner, so stay tuned.
Topics: Personal | Comments Off on Latest development
Don’t fool your users
Saturday, August 11, 2007
Today, I finally got into reading the series on anticracking I mentioned in my previous post. In one of the articles, I found this suggestion on what to do if you detect that your program is being cracked†:
Instead of crashing the program, you should wait several days and then change the way the program reacts. For example, in a graphical program when the user of illegal version picks green colour, the program will draw with blue colour.
The intention of this is clear: discrediting the cracker. If he doesn’t notice this additional protection layer and ships his (unfinished) crack, his credit among the cracker community will be degraded.
In reality, though, the one with degraded credit will be you. “Do not use the X program. It’s full of bugs and works in an unpredictable way.”
People do not usually associate bugs in programs with unfinished cracks. If a program works just fine after it was cracked, people tend to forget that the program was ever cracked. All errors that show up after a certain period of time will be automatically associated with you.
If you want to include delayed checks in your protection, make sure they behave in a direct way. You detected that your program is partially cracked? Show a message box‡. Display a message on the application title bar. Inform your users. Do not let them make false assumptions about your program.
†There are many ways how to detect this – a checksum doesn’t match, the registration verification procedure returned true
even though the code supplyed was intentionally not valid, etc.
‡ Of course, do not forget to hide the message in the code appropriately. You don’t want to bring the attention to this code, do you?
Topics: Security | Comments Off on Don’t fool your users
Careful with those optimisations
Sunday, August 5, 2007
I was looking over some older computer magazines today and found a promising series of articles on anticracking in a Slovak IT magazine called InfoWare. I didn’t really have much time to read the whole series, so I just peeked at the enclosed source codes.
One code snippet caught my attention in particular. The code went like this:
float sumOfNumbers = 90 - 1 + 0.03 + 50 + 300 + 0.3 - 50; if (sumOfNumbers == 389.33) { // everything's all right } else { // now confuse the cracker } |
The text around this snippet was talking something about making constants in programs more confusing.
Well – in source code, this is really terrifying and confusing. It works well, if you want to protect your source code against modifications by the mystified programmers (or by you). It will hardly confuse a cracker, who sees only the binary version. The reason? Compiler optimizations.
I made a little experiment with this code:
float f = 3.1 + 5.8 + 1.1; if (f == 10) printf("Aloha"); |
I compiled it in Visual C++ with full compiler optimizations (the “release mode”) and glanced at the produced code. The above code was compiled into this:
push Test.004020E4 ; /format = "Aloha" call dword ptr ds:[<&MSVCR80.printf>] ; \printf |
Only the printf call was left from the original code. Not very confusing anymore, is it?
Topics: Security | Comments Off on Careful with those optimisations
Advanced self-modifying code
Thursday, August 2, 2007
Self-modifying code (SMC) belongs to the strongest weapons of software protection programmers. I already presented the basic principles behind SMC in my series of cracking prevention articles. In this article we are going to dive deeper and take a closer look at some advanced techniques like polymorphism and metamorphism.
Polymorphism first appeared in a computer virus called 1260 as a method designed to hide the virus from anti-virus software. The anti-virus software at that time used patterns to identify malicious code inside of executables. Because polymorphism made the representation of the virus code different in each infected file, the anti-virus creators could not find a unique pattern identifying it.
The concept was simple: at the beginning of the virus, there was a simple decryption routine that decrypted the rest of the virus in memory. Then the actual virus code was run. When the virus found its new victim, it changed the decryption key a little, encrypted itself with this new key and placed its encrypted code together with decryption code into the executable file.
Polymorphism: the easy way
The easiest approach to polymorphism looks like this:
mov al, 12h ; set the key mov edi, codeEnd ; starting address mov ecx, codeEnd - codeStart ; length of encrypted block ; now decrypt the code, starting from the last byte decryptLoop: xor byte [edi], al ; decrypt byte dec edi ; move to the next byte loop decryptLoop codeStart: ; put encrypted code here codeEnd: |
This kind of polymorphism is easy to implement and seems as a pretty good weapon. But let’s have a look at this code from a crackers point of view: the code between codeStart and codeEnd is encrypted, so he can’t see what will happen after the loop instruction. The easiest method to go through this problem is to place a hardware or memory breakpoint after the loop instruction and wait for the code to decrypt (BPX breakpoint won’t do here because it would alter the byte after the loop instruction – this would result in garbage after the decryption).
The point of polymorphism is to force the cracker to run our program – to make static disassembly useless. The problem with this polymorphic engine is that it’s too transparent – the cracker doesn’t have to run this code. He just has to look at the decryption routine and write a macro for IDA (or similar disassembler) to decrypt the protected code for him. Then he can NOP the decryption code out of the executable.
Advanced polymorphism
More advanced polymorphic engines not only change the key protecting the sensitive code – they also change the algorithm doing the decryption. A good polymorhic engine usually has these features:
- generates different instructions which do the same thing
- swaps groups of instructions
- creates calls to dummy routines
- generates lots of conditionals jumps
- embeds anti-debugging tricks
- inserts junk instructions into real code
A combination of these techniques makes debugging of the decryption routine really hard and painful.
Generating different instruction which do the same thing
As a programmer you already know that there is always more than one way to do one thing. As an example, let’s solve this task: set the EAX register to value 100h.
; simple assignment mov eax, 100h ; using stack push 100h pop eax ; first zero register, then do a binary or sub eax, eax or eax, 100h ; this will even hide the assigned value from cracker's eyes mov eax, 12345778h ; 12345778h = 100h xor 12345678h xor eax, 12345678h |
Intermediate languages
Implementation of this is pretty straightforward. To represent the polymorphic decryptor, we create an intermediate language (a language of an abstract machine) represented by triplets. The internal representation of the decryptor will look like this:
[move, eax, 100h] [jump, label_id, null] [increment, eax, null]
Code generator will then go through the intermediate code and generate native code for each triplet. Each triplet will have one or more native code alternatives and the code generator will always pick one at random.
The representation using an intermediate language can also assist us in another tasks like swapping instructions or inserting garbage code into real code. Theory behind intermediate languages and optimizations (i.e. modifications of existing code while preserving the functionality) is explained in every book about compiler design.
Problems with classical polymorphism
The biggest problem with classical polymorphism is that after the polymorphic decryption routine finishes, the sensitive code is left naked in memory. This means that if the cracker manages to get thought all the weird and hard-to-debug computer-generated code, he will find clean and comprehensible original code. This is something we need to prevent.
To avoid this, we can divide our code into smaller modules and put each of them into its own polymorphic envelope. This will make crackers life harder, because he will never see whole code at once and he will have to trace through the polymorphic decryptors annoyingly often.
But even this approach has its downside: it is the fact that the cracker is still given the opportunity to see the comprehensible original code.
Metamorphism as an effective weapon
The solution of this problem is called metamorphism. From the outside it is similar to polymorphism – it creates different code for each application. But the key difference between polymorphism and metamorphism is that while polymorphism encrypts the sensitive code and creates a unique decryptor for it, metamorphism morphs the sensitive code to make it almost impossible to understand by a human.
With metamorphism it’s possible to create kilobytes of morphed code from several bytes of original code. Manual tracing of such code can easily take days or even weeks of hard work, with poor results (the cracker will never see the original code as with polymorphism).
Metamorphism – an example
Metamorphic engine first takes existing code, analyzes it using an internal disassembler, morphs the internal representation of code and then generates morphed native code. Let’s have an example:
mov eax, 1h mov ecx, Ah |
The resulting morphed code can look like this:
xor eax, eax inc eax sub ecx, ecx inc ecx sal ecx, 2 inc ecx sal ecx, 1 |
Implementation details
The main difference between implementation of polymorphism and metamorphism lays in the fact that polymorphism doesn’t change the original code. It only hides it.
On the other hand, metamorphism changes the original code and thus has to cope with several problems:
- Code flow: because each instruction is replaced with several new instructions, the length of code blocks changes. Engine has to detect and repair all jumping coordinates or function calls within the code to match new positions of code blocks.
- Registers used as pointers: the same problem as with code flow.
- Detecting data in code: most compilers today place some data in the text section of executable, together with code (e.g. between functions). An attempt to handle data as code (i.e. mutate it) could have fatal consequences.
This is the reason why metamorphism is never used for whole application, only for the protection itself.
Partial and full metamorphism
Because of great complexity of the task of writing a metamorphic engine, many commercially available protections resort to partial metamorphism. They decide not to write a full morpher but select only a small subset of instructions that will be morphed. The other instructions are left without change.
This approach fulfills the goal of metamorphism only partially. While it’s still harder to understand the generated code, it’s not as hard as with full metamorphism. The reason for this is that the subset of affected instructions is usually too small to generate sufficient amount of confusing code.
The complexity of writing a full metamorphic engine is also proven by the fact, that at the time of writing this article, the only commercially available protection offering full metamorphism was SVKP 2.0. You can find it at www.defendion.com.
Topics: Security | Comments Off on Advanced self-modifying code
Injecting code into executables with C
Monday, July 30, 2007
In this article, I would like to answer a commonly asked question: is it possible to use my project – PE-inject with C? The short answer: yes.
The problem with PE-inject is that it is written in Delphi. Even though a DLL version of PE-inject is available, all the samples are written in Delphi too and for a C programmer, this can be pretty confusing. So, this article will show you how easy it is to use PE-inject with C.
We will create a program which will modify an EXE file in such a way, that the user will be first prompted with a question asking her if she is really sure about running the program. If her answer is Yes, the program will run. Otherwise, it will terminate.
Creating the injection DLL
First, we need to create a DLL file containing the code to be placed in the EXE files. The PE-inject documentation says that the library must contain a function called BeforeHandlers or AfterHandlers. We will not talk about the difference between them. For us, the only important thing to know is that when the DLL is injected using PE-inject into an executable, both functions (if present) will be run before the original executable code runs.
#define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winuser.h> typedef struct _STUB_CONFIGURATION { DWORD NewEntryRVA; DWORD OrgEntryRVA; DWORD ImageBase; DWORD PrefImageBase; DWORD OrgITRVA; DWORD RelocRVA; DWORD MSLRVA; DWORD ExtraDataRVA; DWORD RedirTableRVA; DWORD Flags; } STUB_CONFIGURATION, *PSTUB_CONFIGURATION; extern "C" __declspec(dllexport) void __stdcall BeforeHandlers(PSTUB_CONFIGURATION config) { int action = MessageBox(0, TEXT("Do you really want to execute this program?"), TEXT("Confirm program execution"), MB_YESNO | MB_ICONQUESTION); if (action == IDNO) ExitProcess(0); } |
Save the above source code as injectiondll.cpp. To compile this file, you will also need to create a module definition file containing the list of functions you want to export:
LIBRARY "injectiondll" EXPORTS BeforeHandlers @1
Save it as injectiondll.def to the same directory as injectiondll.cpp. Use the following command to compile the whole code under Visual C++:
cl /MT /LD injectiondll.cpp /link /def:injectiondll.def user32.lib
Now you can use the PE-inject Frontend tool (located in the Tools directory of PE-inject) to inject this DLL into any executable file and see the result of your work.
Using PE-inject programmaticaly
The PE-inject Frontend tool is a nice thing for testing. In the real world however, it would be better to bypass PE-inject Frontend and to create something that would do it’s job in a more user-friendly way. The InjectFile function located in peinject.dll (part of PE-inject distribution) is exactly what we are looking for.
#include <stdio.h> #include <windows.h> #define INJECT_ERR_NOERROR 0 #define INJECT_ERR_FILENOTFOUND 1 #define INJECT_ERR_NOTAPEFILE 2 #define INJECT_ERR_PEHEADERFULL 3 #define INJECT_FLAG_DOIMPORTS 1 #define INJECT_FLAG_JUMPTOOEP 2 #define INJECT_FLAG_HANDLERELOC 4 #define INJECT_FLAG_STRIPRELOCS 8 #define INJECT_FLAG_COMPRESSDLL 16 #define INJECT_FLAG_BACKUPTLS 32 typedef DWORD (__stdcall *INJECTFILEPROC) (LPCSTR lpInputFile, LPCSTR lpOutputFile, LPCSTR lpDllFile, LPVOID lpExtraData, DWORD dwExtraDataSize, DWORD dwFlags); int main(int argc, char* argv[]) { HMODULE hPeinjectDll; INJECTFILEPROC InjectFile; DWORD result; if (argc != 2) { printf("Invalid arguments!\n"); return 1; } hPeinjectDll = LoadLibrary(TEXT("PEinject.dll")); if (!hPeinjectDll) { printf("Failed to load PEinject.dll!"); return 2; } InjectFile = (INJECTFILEPROC)GetProcAddress(hPeinjectDll, "InjectFile"); if (!InjectFile) { printf("InjectFile() not found!"); FreeLibrary(hPeinjectDll); return 3; } result = InjectFile(argv[1], argv[1], "injectiondll.dll", NULL, 0, INJECT_FLAG_DOIMPORTS | INJECT_FLAG_JUMPTOOEP | INJECT_FLAG_HANDLERELOC | INJECT_FLAG_COMPRESSDLL | INJECT_FLAG_BACKUPTLS); if (!result) { printf("File successfuly injected!"); } else { // one of the INJECT_ERR_ constants printf("An error occured!"); } FreeLibrary(hPeinjectDll); return 0; } |
This code will load the PEinject.dll library (must be in the same directory, or in PATH), locate the InjectFile function and use it to inject the code from injectiondll.dll into executable specified as a command line parameter.
To compile the above code with Visual C++ use this command:
cl injecttest.cpp
Topics: Programming, Projects | Comments Off on Injecting code into executables with C