Future Patching Made Easy

Posted: June 11, 2010 in security
Tags: , , , , , ,

Future Patching, got no clue how to call it otherwise, is in my opinion creating a crack/keygen that will patch future versions of the software without having to reverse it again. First time I saw this was on the awarenetwork website. They created a rather interesting crack for winrar. Since then I was intrigued by the concept, it’s just a lot of work imo to keep finding patterns manually and coding them, until I decided to give immunity debugger another go. For some librecognition will be nothing new and they already know the commands by heart, others will be pleased to see something being made easy.

I was pleasantly surprised, because of it not crashing/being slow anymore. It had been a while since I had played with it and for some odd reason it used to be a pain in the ass. Nowadayd I must say it’s really nice to work with. So this method still remains a pain in the ass the first time you apply it, since you have to manually reverse the application until finding the protection mechanism. After you have identified the code responsible for the protection a world of laziness opens up.

For impatient ones here is the quick-things-to-do-list:

  • Find the protection function
  • Create a signature for it and store it
  • Write a script to auto patch it/prepare it
  • Get new version and enjoy the magic

So where is the magic in all this you ask? It’s in immunity debugger librecognition library. Now that stuff is funky, here is the short command line reference when you invoke it with !recognize:

0BADF00D  ################# Immunity’s Function Recognizing ################
0BADF00D  !recognize -{a|m} -n name [ -x address ] [ -i filename ] [-v version/extra]
0BADF00D  !recognize -d [ -i filename ] -n name
0BADF00D  !recognize -l [-i filename] [-n name]
0BADF00D  !recognize -f -n name [-i filename] [-v version/extra] [-o module] [-h heuristic_threasold]
0BADF00D  !recognize -r -x address [-i filename] [-h heuristic_threasold]
0BADF00D    ex (find a pattern, accept 80% of match): !recognize -f -n iTunes.AntiDebuggers -h 80 -o iTunes.exe
0BADF00D    ex (resolv an address, accept 93% of match): !recognize -r -x 004EDE00 -h 93
0BADF00D    ex (add a pattern): !recognize -a -x 004EDE00 -n iTunes.AntiDebuggers -i itunes.dat -v 7.4.1
0BADF00D    ex (add a pattern guessing the address from labels or symbols): !recognize -a -n _SPExternalAlloc@4
0BADF00D    ex (modify a pattern): !recognize -m -x 004EDE00 -n iTunes.AntiDebug

Now that looks a lot easier then creating function patterns manually doesn’t it? The only command you initially need to create the signature is, of course replacing the values with the ones that fit your needs:

!recognize -a -x 004EDE00 -n iTunes.AntiDebuggers -i itunes.dat -v 7.4.1

The fun stuff is that applying the signature on a file afterward to find the protection function is just as easy, you only need this command:

!recognize -f -n iTunes.AntiDebuggers -h 80 -o iTunes.exe

This makes life a lot easier but we can make it even easier with some automation, using immunity debuggers’s support for python scripts. This script is just an example and it lacks the feature of actually doing the patch instead it puts a breakpoint on the opcode that needs to be patched. It will mainly show you how to use the recognize function from python and how to step through the application. Just to be sure:

THIS IS AN EXAMPLE SCRIPT FOR A SPECIFIC KEYGENME IT WILL NOT WORK ON APPLICATIONS, you’ll have to code your own script for that.

source on pastebin: http://pastebin.com/WzmUMiBm

inline:

"""
DiabloHorn https://diablohorn.wordpress.com
Educational purposes only.
- learn about immunitydebugger scripting
- learn about function recognition
"""
__VERSION__ = "0.1"

import immlib
from librecognition import *

#main called by debugger
def main():
imd = immlib.Debugger() #create debugger instance
imd.Log("%s" % "Started KeygenMe Universal Patch Prepare")
found = imd.searchFunctionByName("KeygenMe.serial_calc",75,"KeygenMe") #search for the dreaded function
lfound = len(found)
if lfound == 0:
imd.Log("No matching function found")
return
imd.Log("Amount of matching functions: %i" % lfound)

if lfound != 1:
imd.log("Too much functions found, manual assistance needed")
return

#due to previous check we are sure it's 1 match only
for off,heur in found:
keepstepping = True
imd.Log("Found Function at: %08X" % off)
#so we found the function by now, let's find the CALL references to it
srchstr = str("CALL %08X" % off)
imd.Log("Searching references using string: " + srchstr)
calls = imd.searchCommands(srchstr)
for call in calls:
result=imd.disasm(call[0])
if result.result == str("CALL KeygenMe.%08X" % off):
imd.Log("Found %s at 0x%X (%s)"% (result.result, call[0], call[2]), address=call[0],  focus=1)
#go to the call reference we found, and start running
imd.Run(call[0])
imd.deleteBreakpoint(imd.getCurrentAddress()) #disable the breakpoints set by the call to .Run()
while keepstepping:
imd.stepOver()
curaddr = imd.getCurrentAddress()
opcode = imd.Disasm(curaddr)
#here we search for the first comparison afte the call to the protection function
if opcode.isConditionalJmp():
#set a breakpoint on the opcode that needs to be patched
imd.setBreakpoint(curaddr)
break;
imd.restartProcess(-2)  #make sure it's a silent restart
imd.Log("Go ahead run the app, it will automatically break on the correct Jxx opcodes.")

if __name__ == "__main__":
print "This file is only intended to be loaded by Immunity Debugger"

so after the script is finished you can just hit alt+b(show breakpoints) and start patching, then saving the changes. You could also improve the script to actually perform the patching so that you only have to save the patched binary after it’s run.Hope you enjoyed this as much as me when I was working on it. For a very nice tutorial on immunity debugger scripting check out the following page:

http://www.corelan.be:8800/index.php/2010/01/26/starting-to-write-immunity-debugger-pycommands-my-cheatsheet/

Some like nostalgia other just look back to learn, I love them both. It’s really nice to see that techniques like function recognition to make life easier was already done in 2005. Just makes you wonder how far some people are nowadays.

Advertisements
Comments
  1. DiabloHorn says:

    This method is mainly intended as yet another way to perform future patching. You are right it can be a little bit cumbersome. The nice thing about it, is the algorithm used to generalize a function, which in theory should make it easier to patch in the future even if the function changes. Working with wildcards is a option, but imo it’s not versatile enough. Search & replace patterns can be a lot of work to compile, specially if they change with every minor/major version.

  2. locu says:

    this method seems to be very messed up. You can simply make a search & replace patcher that looks for a pattern of bytes then patch, you can use wildcard to avoid the byte that change in new version. All this stuff can be done manually or by a patcher like dup2.

  3. […] This post was mentioned on Twitter by Héctor López, trufae. trufae said: RT @daveaitel: Future Patching Made Easy « DiabloHorn http://dlvr.it/1dHJH […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s