πŸ”’
There are new articles available, click to refresh the page.
Before yesterdaywaliedassar

Virtual PC vs. Resume Flag

27 October 2012 at 19:17
By: walied
In this post i will show you another weird behavior of Virtual PC 2007. I encountered this weird behavior while playing with Virtual PC 2007 with Windows XP SP3 installed inside. The behavior is all about how a Windows XP Virtual PC virtual machine handles the Resume Flag.

For those who don't know, the Resume Flag (Flag no. 16 in the EFLAGS register) is used to temporarily disable Hardware Breakpoints exceptions for one instruction. Without it, a Hardware-Breakpoint-On-Execution would infinitely trigger an EXCEPTION_SINGLE_STEP exception.

According to @osxreverser, Windows XP does not support the Resume Flag (RF). I was also amazed to see that also WinDbg and OllyDbg v1.10 don't use the resume flag. They use the Trap Flag (TF) instead.

Running a simple executable that on purpose makes use of the Resume Flag inside an XP Virtual PC Virtual Machine, i found out that execution flows normally as if XP supports the resume flag.

Given the finding above, i created a small executable that tries to detect if it is running inside Virtual PC 2007.
You can find it here and its source code from here.

I guess the finding above only applies if the host operating system itself supports the resume flag e.g. Windows 7 or later.

N.B. This topic is still under research.

Please don't hesitate to leave a comment.
You can also follow me on Twitter @waleedassar

Virtual PC Machine Reset

26 October 2012 at 00:58
By: walied
While playing with Virtual PC 2007, i came up with an interesting trick not only to detect Virtual PC 2007 but also to reset (restart) the Virtual Machine.

The trick is so simple that all you need to do in your code is execute "\x0F\xC7\xC8\x05\x00".Β 

Executing that x86 instruction sequence causes the following message to pop up.
A POC can be found here and its source from here.

N.B. Other x86 instruction sequences can cause the same result.

Any comments or ideas are welcome.
You can follow me on Twitter @waleedassar

PAGE_EXECUTE_WRITECOPY As Anti-Debug Trick

28 September 2012 at 14:48
By: walied
In this post, i will share with you a poorly discussed anti-debug trick that i may be the first one to discover or disclose.

Now let's start with a quick introduction. If a memory page with the "PAGE_EXECUTE_READWRITE" access protection attributes is requested from the OS, then a page with the "PAGE_EXECUTE_WRITECOPY" attributes, not the "PAGE_EXECUTE_READWRITE" attributes is given.Β Β Β 

The reason for that behavior is so simple, that is, the OS memory manager wants to physically share the page between all the process instances (since it is guaranteed to be the same in all the process instances before any write).

Once you make the first write to the new page, the OS assigns a private copy of the page to the process in which the write occurrs and the page attributes change to PAGE_EXECUTE_READWRITE.

N.B. The same applies to pages requested with the PAGE_READWRITE attributes. They are initially given the "PAGE_WRITECOPY" attributes and after the first write, they turn into PAGE_READWRITE.

N.B. PAGE_EXECUTE_WRITECOPY and PAGE_WRITECOPY are not valid parameters to the "VirtualAlloc" or "VirtualAllocEx" function.

Now if you have a section in your executable with the read, write, and execute access attributes (See section xyz in the image below), then the abovementioned applies to it.
The access protection attributes given to section xyz causes its memory page to be mapped with the "PAGE_EXECUTE_WRITECOPY" attributes. See image below.
If we design section xyz in a way that it is never written to (e.g. does not contain self-modifying code) throughout the whole lifetime of the process, then the page will always be PAGE_EXECUTE_WRITECOPY even at process exit.

If the attributes change to PAGE_EXECUTE_READWRITE, that means the page must have been written to e.g. when another process, mostly a debugger, had called the "WriteProcessMemory" function while stepping-over, tracing-over, or placing software breakpoints. That definitely means the process is being debugged. See images below.

Now our executable of question can call the "VirtualQuery" function to check the page protection attributes of section xyz. If it is something other than PAGE_EXECUTE_WRITECOPY, then a debugger is present and the process should quit.

The good thing about this trick is that, unlike the 0xCC-scanning trick, it can detect software breakpoints even if there are no longer active (removed by the debugger).

Also, most debuggers in their default settings are used to place software breakpoints on modules' entry points, which means the page protection attributes change even before the reverse engineer starts to debug the module.

A common way to bypass this trick for stepping-over and tracing-over is to use hardware breakpoints which is an available option in OllyDbg v1.10 and OllyDbg v2.01 (alpha 4).

A simple demo can be found here and its source code from here.

Any ideas or comments are very welcome.

You can follow me on Twitter @waleedassar

Anti-Dumping - Part 3

8 September 2012 at 13:46
By: walied
In this post i will share with you a couple of small tricks that can be deployed to harden or defeat memory dumping attempts. As i have just mentioned they are small tricks, so don't flame at me.

The first trick briefly involves appending a special section header to the section table of your executable. The new section header is to be set with a huge virtual size. Don't worry, this is not going to affect the file size (on disk) since we can set the raw size of the new section to zero (completely virtual section).

This results in the the "SizeOfImage" field of the IMAGE_OPTIONAL_HEADER structure being huge as well.

Unlike old anti-dumping tricks, we don't have to forge the "SizeOfImage" field of PEB.LoaderData or that in the PE Header memory page. Here, we give the dumping tools a huge value that they are very likely to fail to allocate using e.g. the "VirtualAlloc" function or its likes. Of course, this trick does not defeat dumping tools that read the memory of processes page by page.

Since the raw size of this huge section is zero, then the new section will be zero-initialized and the OS memory manager will throw it away making the memory usage of such process as smooth as possible.

It is now obvious that the new section should be left as it is. Your code should never read, write, or execute it. As any attempt to e.g. write to it results in the OS memory manager restoring the whole section into memory.

Here you can find a demo.

The second trick was first mentioned by Kris Kaspersky. The trick is very nice and simple. If we set the memory protection of one section as PAGE_GUARD, then the "ReadProcessMemory" function will fail usually with the system error code ERROR_PARTIAL_COPY, 0x12B. To defeat this trick, dumping tools are now using the "VirtualProtectEx" function to remove the PAGE_GUARD attribute, then read the section, and finally restore the PAGE_GUARD attribute.

To enhance this trick, i have created a watching thread that infinitely calls the "VirtualQuery" function and once it detects that PAGE_GUARD is removed from the section's memory protection attributes, it just terminates the process. Here is the code and here is a demo.

N.B. For the second trick to be effective, you should place the sections you want to protect after the PAGE_GUARD section so that the process terminates before them being dumped.

N.B. The second trick theoretically has better chances to work on multi-processor systems than on single-processor ones.

Any comments or ideas are very welcome.

You can follow me on Twitter @waleedassar

Major / MinorSubsystemVersion

5 August 2012 at 21:00
By: walied
If you are still using Windows 2000, you must have noticed that certain executables refuse to run. Actually, this is due to the executables being built with Microsoft Visual Studio 2010 which sets the MajorSubSystemVersion and MinorSubsystemVersion in the PE header to 5 and 1. In other words, it creates executables to run on Windows XP (5.1) and above. This causes Windows 2000 (5.0) to refuse to load these executables.

Now, let's see where the check occurs and how to bypass it. The first place to check must be the kernel32 "CreateProcess" function.


If we start at address 0x7C4F1ECE, we can see a call to the ntdll "ZwQuerySection" function with the "InformationClass" parameter set to 1 (SectionImageInformation). After the "ZwQuerySection" function has returned successfully, the "SECTION_IMAGE_INFORMATION" structure should be filled with some useful data. Among the data returned are the executable's subsystem type and minor and major versions.

Then comes a check for the subsystem type. The subsystem type must be either GUI (IMAGE_SUBSYSTEM_WINDOWS_GUI) or console (IMAGE_SUBSYSTEM_WINDOWS_CUI). If it is not any of these two types, the "CreateProcess" function fails.


As you can see in the image above, at address 0x7C4F1F91, the major and minor subsystem versions extracted from the PE header via the "ZwQuerySection" function are passed to the "CheckSubSystem" function. If the "CheckSubSystem" function returns TRUE, the "CreateProcess" function proceeds and if it returns FALSE, the "CreateProcess" function fails as such. Now, let's check this function.


As you can see in the disassembly and C-code in the three images above, if the subsystem versions extracted from the PE header are less than 3.10, the "CheckSubsystem" function returns FALSE. Then comes the important part, if the "MajorSubsystemVersion" extracted from the PE header is greater than the value of the "NtMajorVersion" field (The field is at offset 0x26C from the _KUSER_SHARED_DATA page), the function fails. The same applies for "MinorSubSystemVersion" if "MajorSubsystemVersion" and "NtMajorVersion" are equal.

N.B. NtMajorVersion and NtMinorVersion are usually the same as the OS version info. returned by the kernel32 "GetVersion" or "GetVersionEx" functions.

As a developer, bypassing the check can easily be done by using Platform Toolset v9 in microsoft visual studio (thanks @skier_t) or by directly editing the PE header of the executable using any PE Editor.Β 

Imagine the scenario where the executable in question has CRC check upon its PE header as part of the implemented protection scheme. In this case, as a user, you won't be able to run the executable since any attempt to edit the PE header will cause the CRC check to fail. This leads us to find a system-wide solution. Yes, patching.

Speaking of patching, we have two options:

1) The first is to patch a couple of addresses inside the "CheckSubSystem" function (Actually, i don't recommend patching the return value check).

To implement the check bypass, i createdΒ  a dynamic link library, hooksubsystem.dll that once injected into a process bypasses the subsystem version check.

You can find the source code of hooksubsystem.dll here.
You can find hooksubsystem.dll here.

One drawback of this method is that it is Service pack-specific since the "CheckSubSystem" function is not exported by kernel32.dll.

2) The second is to patch the "ZwQuerySection" function such that we can manipulate the data returned in the "SECTION_IMAGE_INFORMATION" structure before being used by "CheckSubSystem" function.

To implement this method, i created another version of hooksubsystem.dll. You can find it here and its source code from here.

I also created a small application, BypassSubSystem.exe, which installs a system-wide hook of the type provided in the command line arguments. It can be used in the way you see in the image below.
BypassSubSystem.exe can be downloaded from here and its source code from here.

In a future post i will go deeper into this topic.Β 


You can follow me on Twitter @waleedassar

Native x86 User-mode System Calls Hooking

27 July 2012 at 20:41
By: walied
In this post i am going to explain how to implement system call hooking from user-mode for native x86 processes (i here refer to 32-bit processes running in 32-bit versions of Windows XP SP2 and SP3).

Let's have a look at the "ZwOpenProcess" function of Windows XP SP2 and of Windows XP SP3.

1) XP SP2


2) XP SP3

As you can see in the images above, EAX is set to 0x7A, the system call ordinal and EDX is made to point at 0x7FFE0300 in the _KUSER_SHARED_DATA page. Then comes a CALL instruction which jumps to the "KiFastSystemCall" function whose address is stored in 0x7FFE0300 (_KUSER_SHARED_DATA::SystemCall).

One difference we can see is that SYSENTER of XP SP2 is followed by 5 NOPs while in XP SP3 SYSENTER is directly followed by the RET of the "KiFastSystemCallRet" function.
Β 
The first thing one may think of to implement the user-mode system call hook in Windows XP SP3/SP2 is to overwrite the "_KUSER_SHARED_DATA::SystemCall" and "_KUSER_SHARED_DATA::SystemCallRet" fields. Unfortunately, this is not possible since the page is not writable and any attempt to change its memory protection constant always fails.

So, we should now turn to the "KiFastSystemCall" function and try to overwrite its very first instruction with a JMP instruction. Is this all? Let's see.

For XP SP2, it is okay to write a near jmp instruction (5-byte long) since we have enough space (filled with 5 NOPs) and this does not hurt the RET instruction of the "KiFastSystemCallRet" function. But for XP SP3, any attempt to write the near jmp instruction will hurt the "KiFastSystemCallRet" function. Any common method for both XP SP2 and SP3?

I thought about that and came up with something that worked for both service packs. If we allocate a memory page at an address which when converted from absolute to relative gives 0xC3 as the fifth byte of the new JMP instruction. For example, if we allocate a memory page at 0x3F910000, given that the "KiFastSystemCall" function is at 0x7C90E510, we get the new JMP instruction as a sequence of
Β "\xE9\xEB\x1A\x00\xC3". You can check the source code of InjectHookLib for more information.

N.B. We can still use a short JMP by searching for any vacant 5 bytes in the range of -128 to +127 from the address of the "KiFastSystemCall" function. LEA ESP,[ESP] seems to be okay for both service packs.

N.B. With certain processors or under certain conditions e.g. disabled VT-x/AMD-V if using VirtualBox, the "KiFastSystemCall" function is not used at all and the "KiIntSystemCall" is used instead. In these cases, you can safely overwrite the first instructions of "KiIntSystemCall" function with a near JMP instruction as long as the code you hook to takes care of that.


Any ideas or suggestions are always very welcome.

You can follow me @waleedassar
  • There are no more articles
❌