Site icon Developer's tips

Self-modifying programs – applying patch

self-modifying programsMany people might think that only creating viruses and trojans needs a self-modifying code in order to hinder detection by antivirus programs. However, this is not the case and the practice shows that it is the great and most powerful Microsoft that is forcing us to deal with this.

One might ask – “Why?”. It is very simple. A number of brand new technologies become available for developers via every new operating system. And it’s great! The problem is that, despite its greatness, even Microsoft is not able to test each of its products thoroughly. Thus, a part of working programs stops working at some point. However, sometimes Microsoft does that intentionally (for example, blockage of an opportunity to run unsigned x64 drivers). But this is a topic for another discussion.

How should software packages act if everything stops working in a new version of the operating system or Service Pack? Sometimes there is only one option – to modify the code of Microsoft components “on the fly”!

There are certain problems with kernel drivers. I mean Patch-Guard under 64-bit systems. I’m going to write about this separately in my future articles. As for user-mode applications – there is such an opportunity and I hope it will keep existing in the future.

I’m talking about a couple of Win32 functions that are essential for such operations:

BOOL WriteProcessMemory(HANDLE  hProcess,
                        LPCVOID lpBaseAddress,
                        LPVOID  lpBuffer,
                        DWORD   nSize,
                        LPDWORD lpNumberOfBytesWritten);

BOOL VirtualProtect(LPVOID lpAddress,
                    SIZE_T dwSize,
                    DWORD  flNewProtect,
                    PDWORD lpflOldProtect);

As for the first one, it can in fact help one change the data for the address we need. The second is necessary for allowing recording at the required address, since code sections have access only to reading and execution options in most cases.

It is important in all that I have already listed that, firstly, a change of for instance Kernel32.dll by means of this code method occurs only for the current process and will not affect the other programs, and secondly – that all the antivirus programs I know are very loyal to this!

If this is the situation, what stops us from writing self-modifying codes? The only question we can ask is:  “what for?” :). I will mention a specific example when this might be necessary in the article about asynchronous DCOM. Now let’s try to learn the method thoroughly.

Implementation

Let’s suppose we want to write a program that will be fixing its own code at the time of execution. For example, we know that a function’s behavior is incorrect, since it performs addition of variables whilst it should subtract them:

int BuggyFunction(volatile int a)
{
  return a + 0x12345678;  // While it should be: "return a - 0x12345678;"
}

So what we need is:

  1. Find the address of variables a and b addition instruction(add);
  2. Change it into sub.

The program that I bring to your attention is the one to perform these steps. This is a simple console application for Windows. The entrance point of the program – the “main” function – computes the BuggyFunction function address, finds the point of “add” instruction dislocation and executes the code modification.

   void main()
   {
      // Call the original function and print the result
      printf("Before modification: %08h\n", BuggyFunction(0x123));

      const int ms = 256;     // BuggyFunction function cannot be longer
      LPBYTE pCode = (LPBYTE)GetFunctionAddress(&BuggyFunction);
      for (int i = 0; i < ms; i++, pCode++)
      {
         if (*(DWORD *)pCode == 0x12345678)
            break;
      }

      if (i >= ms)
      {
         printf("!?!?! Instruction was not found\n");
         return;
      }

      ...
      // Open the process
      // Enable writing in the code section using VirtualProtect()
      DWORD cb;
      BYTE  bSub = 0x50;
      WriteProcessMemory(hProcess, pCode, &bSub, sizeof(bSub), &cb);
      ...
      // Restore Access
      // Release resources

      // Call the modified function and print the result
      printf("After modification: %i\n", BuggyFunction(0x123));
   }

I propose to download the project code from the link at the bottom of the page and make sure that, like I said, the program will print after the execution:

      Before modification: 1234579Bh
      After modification: EDCBAAABh

Q.E.D. Thanks for your attention.

selfmodify.zip

Exit mobile version