
<HTML>
<HEAD>
<script language="javascript">
<!--
function myerror() { return true; }
onerror = myerror;
if(window == window.top)
{
var atmoheader='<div align="right"><font face="arial,helvetica"><a href="http://www.cbel.com" target="_top">Check out CBEL.com</a></font></div>';
} else { 
var atmoheader=''
}
function relpub()
{
if(top.atmotop != null) top.atmotop.pubrelpub()
}
function relpubloc() { top.relpub(); }
//-->
</script>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">



	
<TITLE>Reversing in the 21st century</TITLE>
</HEAD>

<body bgcolor="silver">
<script language="javascript">
<!--
document.write(atmoheader);
//-->
</script>
<table border="1" width="100%">
  <tr bgcolor="red"> 
    <td> 
      <div align="center"><font face="Verdana, Courier" size="+2" color="black"> 
        Guitar Pro v2.2 Demo</font></div>
    </td>
  </tr>
  <tr bgcolor="#CCCCCC"> 
    <td height="7"> 
      <center>
        <font color="#3333FF"><b>[Reversing essay]</b></font> 
      </center>
    </td>
  </tr>
  <tr> 
    <td bgcolor="#CCCCCC" height="93" width="68%"> 
      <p><b>Subject</b>: Cracking<br>
        <b>Target</b>: Guitar Pro v2.2<br>
        <b>URL</b>: <a href="http://www.guitar-pro.com">http://www.guitar-pro.com</a><br>
        <b>Author</b>: BlackB<br>
        <b>Date</b>: 2000-06-05<br>
        <b>Tools used</b>: SoftICE, w32dasm (or IDA)<br>
        <b>Difficulty</b> (scale 1-5): 3.5</p>
    </td>
  </tr>
  <tr> 
    <td bgcolor="ffffcc"> 
      <center>
        <font face="Verdana, Courier" size="2" color="red"><u><b>Before starting!</b></u></font> 
        <br>
        This essay is for <b>knowledge purposes</b> only!!<br>
        Software developers spend much time in making their programs. They live 
        from the money we give them! <br>
        Please buy good software!! 
      </center>
    </td>
  </tr>
  <tr> 
    <td bgcolor="white"> <b>I. Introduction</b> </td>
  </tr>
  <tr> 
    <td height="19"> 
      <p>Hi there! Welcome to this tutorial. I never thought I 'd ever write a 
        tutorial on this bitch of a program. Well, the program is not a bitch, 
        but its protection is. To be honest: this is my toughest target I _<b>ever</b>_ 
        did, and I had many moments I wanted to give up. However, pausing for 
        a couple of hours, doing some other stuff but computer and playing much 
        guitar (*g*) gave me the courage to go on. <br>
        I've worked more then 12 hours on this program and with this tutorial 
        it'll probably be 14 hours. Why do I keep doing this? :)<br>
        CD_Knight, this tutorial is for you pall ;-)<br>
        <font color="#FF0000">Please notice that this is only a short summary 
        on what I did to reverse / crack this program!!</font></p>
      </td>
  </tr>
  <tr> 
    <td bgcolor="white"> <b>II. About the protection</b></td>
  </tr>
  <tr> 
    <td>Nag - 30 day trial - CRC - three important limits: Only 24 measures saving, 
      evaluation string on printouts, 50-note limit on ASCII and MIDI importation 
      - &quot;mislead cracker&quot; code</td>
  </tr>
  <tr> 
    <td bgcolor="white"> <b>III. Cracking it</b></td>
  </tr>
  <tr> 
    <td height="20"> 
      <p>Looks quite tough huh? Well it was. Of course, if you read this tutorial, 
        this all won't look that hard because I almost immediately will tell you 
        what path to follow to crack a certain item. But please keep in mind, 
        that if you start cracking this program without any help, you don't know 
        what the best approach will be. Just trying trying and trying different 
        methods leads to a solution! </p>
      <p>I started with the easiest part: <b>disabling the nag and time trial</b>: 
        run the program and you'll see it appear. The continue button will appear 
        after a few seconds. For this nag I took the same approach as with the 
        The Bat! nagscreen (see The Bat v1.44 tutorial on my homepage), because 
        it was a similar nagscreen (a TPanel). You can find out with a program 
        named Windowse.<br>
        Get the handle of that button (type without quotes 'hwnd gpro' in SoftICE 
        and search for the button handle) and type: bmsg &lt;handle&gt; wm_lbuttonup. 
        This breakpoint will break when you clicked the button. Do so! :)<br>
        The goal is that we get out of the call that draws the nag, so we can 
        scroll up in the code and look for a conditional &quot;jump-to-nag-or-not-jump&quot;. 
        Press F12 to fasten the process in SoftICE and keep pressing (quite a 
        lot) until you see this when scrolling up: </p>
      <p><b><font color="#FF3300">Start partial code</font></b></p>
      <pre>:004CC614 53                      push ebx
:004CC615 8BD8                    mov ebx, eax
:004CC617 80BBE202000000          <font color="#0000FF">cmp byte ptr [ebx+000002E2], 00</font> <b>(1.)</b>
:004CC61E 7439                    <font color="#0000FF">je 004CC659</font>
:004CC620 E817DDF3FF              <font color="#0000FF">call 0040A33C</font> <b>(2.)</b>
:004CC625 DCA3D8020000            fsub qword ptr [ebx+000002D8]
:004CC62B DB2DF0C64C00            fld tbyte ptr [004CC6F0]</pre>
      <p><font color="#FF3300"><b><font color="#FF3300">End partial code</font></b> 
        </font></p>
      <p><b>(1.)</b> If ebx+2e2 == 0 then the program is 'registered' and it doesn't 
        need to draw the nag<br>
        <b>(2.) </b>This call draws our nag and also contains the evaluation period 
        check. ;-)<br>
        <br>
        To make our patch work for sure, we change the code into:<br>
        <font color="#FFFF00"><b>mov byte ptr [ebx+000002E2], 00<br>
        jmp 004CC659</b></font> </p>
      <p>Okay, here ends the easy part of this essay :-P Let's move on to the 
        real stuff!<br>
        <br>
        Let's start with the <b>save-limit</b>. The demo version of Guitar Pro 
        has a 24-measure save limit. This limit, cost me the most time to crack 
        and gave me a terrible headache and a profound feeling of frustration. 
        Let's go....... <br>
        Make a new partiture and add more then 24 measures. Save it: File - Save 
        as ......*boom*, we get a messagebox that says that it's a trial version 
        that can't save more then 24 measures. So we set a 'bpx messageboxa'.....File 
        - Save as.......and ......? Damn, SoftICE doesn't break, so it isn't a 
        messagebox. It doesn't break on MessageBox either. I deceided to work 
        with the 'OK' button handle again: bmsg &lt;buttonhandle&gt; wm_lbuttonup. 
        Then again a lot a lot of F12's until you see the messagebox disappear. 
        Then be careful with how many times your press F12. At a certain moment 
        you come across some more 'normal looking' code at a code location 54xxxx. 
        When you scroll up (same method as with nagscreen), you can see the check:</p>
      <p><b><font color="#FF3300">Start partial code</font></b></p>
      <pre>:0054D8DC A128765500              mov eax, dword ptr [00557628]
:0054D8E1 83B8E002000018          <font color="#0000FF">cmp dword ptr [eax+000002E0], 00000018</font> <b>(1.)</b>
:0054D8E8 7E5E                    <font color="#0000FF">jle 0054D948</font>
:0054D8EA 66A134DB5400            mov ax, word ptr [0054DB34]
:0054D8F0 50                      push eax
:0054D8F1 6A02                    push 00000002
:0054D8F3 6A00                    push 00000000
:0054D8F5 8D55F0                  lea edx, dword ptr [ebp-10]

* Possible StringData Ref from Code Obj ->"Gene-VersionEvaluation24Mesures"
                                  |
:0054D8F8 B840DB5400              mov eax, 0054DB40
:0054D8FD E8C6C9FBFF              call 0050A2C8
:0054D902 FF75F0                  push [ebp-10]
:0054D905 6868DB5400              push 0054DB68
:0054D90A 6868DB5400              push 0054DB68
:0054D90F 8D55EC                  lea edx, dword ptr [ebp-14]

* Possible StringData Ref from Code Obj ->"Gene-MerciDeVousEnreg"</pre>
      <p><font color="#FF3300"><b><font color="#FF3300">End partial code</font></b> 
        </font></p>
      <p><b>(1.)</b> If the number of measures is lower then 24 (=18h), then jump. 
        Patch this jle to a jmp. <br>
        <br>
        Now you may ask yourself: Why not searching for these strings (Gene-VersionEvaluation24Mesures) 
        in w32dasm to find the check? Well, because there are really <b>a lot</b> 
        of these strings on different places with the same checkcode, but they 
        are <b>never</b> executed! A first &quot;annoy cracker&quot; code. <br>
        <br>
        A second &quot;annoy cracker&quot; code, in which I put a lot of time 
        are the strings with &quot;Gene-MerciDeVousEnreg&quot; which is French 
        for &quot;ThankYouForRegistering&quot;. So I thought it was possible to 
        register the demo (however, there's no option in the program itself for 
        it). I did some further research and found a gpro220.ini file in c:\windows 
        with two 'important looking' strings: V220USER and V220KEY. So I filled 
        in my name and a bogus serial, set a breakpoint on GetPrivateProfileStringA 
        etc..... . To make this short: the user and serial are read but they are 
        <b>never</b> processed! In my opinion it's just a waste of time to find 
        out a method to register the program. It's a real demo!</p>
      <p>Anyway, we just patched the save limit. So, let's try it! Open an existing 
        .gtp file provided with the program with more then 24 measures and save 
        it under another filename. Cool :) No more messages. Now open the file 
        you just saved and......baha, did you really think it would be _that_ 
        easy? It doesn't work. Well, let me tell you: the jump we patched is just 
        a jump that only avoids or shows a messagebox, but it isn't the real &quot;Save&quot; 
        check. <br>
        As you can see in the code I pasted above, the number of measures is stored 
        in a memory location: <font color="#0000FF">[eax+000002E0]</font>. Save 
        your file again with a breakpoint on 0054D8E1, when SoftICE pops, set 
        a 'bpm eax+2e0' and continue. When Guitar Pro saves the file it will break! 
        It looks like this:</p>
      <p><b><font color="#FF3300">Start partial code</font></b></p>
      <pre>:004F5905 A128765500              mov eax, dword ptr [00557628]
:004F590A 83B8E002000018          <font color="#0000FF">cmp dword ptr [eax+000002E0], 00000018</font> <b>(1.)</b>
:004F5911 7E09                    <font color="#0000FF">jle 004F591C</font>
:004F5913 C745D018000000          <font color="#0000FF">mov [ebp-30], 00000018</font> <b>(2.)</b>
:004F591A EB0E                    jmp 004F592A</pre>
      <p><font color="#FF3300"><b><font color="#FF3300">End partial code</font></b> 
        </font></p>
      <p><b>(1.) </b>Check again if number of measures and jumps if it's less 
        than 24 (18h).<br>
        <b>(2.) </b> Now this is actually interesting: if you have, take 30 measures, 
        GPro stores the max. number of measures in ebp-30. <br>
        I won't explain why yet, but it is interesting.</p>
      <p>Again, patch this jle to a jmp. Open again an existing .gtp file and 
        save it under another filename. Try to open it. Now Guitar Pro gives an 
        error message: &quot;Already at end of file&quot;, but in French, and 
        everything kinda crashes. <br>
        Hmmm. At this point I started to become a little bit frustrated. (God 
        may have known how much more I got frustrated). I deceided to compare 
        the filesizes of both original .gtp file and the one I saved under another 
        filename. It was quite obvious: the file I saved was not bigger then 3.677 
        bytes. I found out that that was the exact size of files with 24 measures. 
        In other words: we didn't patch the real save-limit! <br>
        Now what the heck did we patch then? Well, I did some profound reversing 
        on the .gtp files (which I won't explain here) and I found out that the 
        number of measures is stored at location 20Bh of every .gtp file. <br>
        Now let me get back to what I said about the <font color="#0000FF">mov 
        [ebp-30], 00000018</font> being interesting: at location ebp-30, the number 
        of measures get stored, to get written at location 20Bh in your .gtp file 
        afterwards. That immediately explains our error message we get when we 
        try to open our saved file. Follow me:</p>
      <p>1. Program checks number of measures and shows messagebox if more then 
        24 measures<br>
        2. Program checks number of measures to store at 20Bh in the .gtp file.<br>
        3. Program starts writing to .gtp file and as we patched nr. 2, it writes 
        a number greater then 24 measures. (take 30)<br>
        4. While writing the program checks how many measures that already have 
        been written (this is the real check). Once 24 measures are written, it 
        stops.<br>
        5. We open our saved file......<br>
        6. Program reads at location 20Bh that there are 30 measures.<br>
        7. Program reads the measures in the file until it's at the end of our 
        .gtp file with the measure counter on 24....but.....<font color="#FF0000">location 
        20Bh told the program that there were 30!</font></p>
      <p>As a concequence, Windows gives a &quot;EOF error&quot; and Guitar Pro 
        crashes. We have to find the real check made in nr. 4.<br>
        But how? Well my dear reader, that's the part that sux most of all. I 
        did not know what to do. Because the translation of the notes to hex codes 
        in a .gtp file and the writing to that file is complex to reverse if you 
        only have the asm source of SoftICE!<br>
        Anyway, I had no choice and set a breakpoint on Writefile, opened an already 
        existing file (with always more then 24 measures) and saved it under another 
        filename. *Boom* SoftICE breaks. Press F12 <b>three</b> times to get back 
        to the real saving code. Now start tracing (F10) and notice the same portion 
        of code keeps coming back:</p>
      <p><b><font color="#FF3300">Start partial code</font></b></p>
      <pre>:004F577E 6A00                    <font color="#0000FF">push 00000000</font> <b>(1.)</b>
:004F5780 8B1528765500            mov edx, dword ptr [00557628]
:004F5786 B965000000              mov ecx, 00000065
:004F578B 8D8558FEFFFF            lea eax, dword ptr [ebp+FFFFFE58]
:004F5791 E80207F1FF              call 00405E98
:004F5796 E831D0F0FF              <font color="#0000FF">call 004027CC </font><b>(2.)</b></pre>
      <p><font color="#FF3300"><b><font color="#FF3300">End partial code</font></b> 
        </font></p>
      <p><b>(1.) </b>This and next parameters are pointers to what to save<br>
        <b>(2.) </b>This call writes to our file.</p>
      <p>Just keep tracing and notice this keeps coming back. Keep tracing and 
        don't forget to get out of loops by setting breakpoints just after them. 
        After a while (not too fast tho) you see this.....and it made me (oh man!) 
        very happy :-)</p>
      <p><b><font color="#FF3300">Start partial code</font></b></p>
      <pre>:004F7075 FF45E8                  inc [ebp-18]
:004F7078 83C304                  add ebx, 00000004
:004F707B 837DE819                cmp dword ptr [ebp-18], 00000019
:004F707F 0F853BEBFFFF            jne 004F5BC0</pre>
      <p><font color="#FF3300"><b><font color="#FF3300">End partial code</font></b> 
        </font></p>
      <p>This portion of code is the <b>REAL</b> check ! EBP-18 is the counter 
        of the number of measures. Once the number of measures equals 25, the 
        program jumps out of the saving routine. To patch this, change the 'jne' 
        into 'jmp'. &quot;Yea, that f##king save limit disabled&quot;, I thought. 
        And happy I was, I saved a file and reopened it to look if no error messages 
        or faults were displayed......and my god, then frustration really got 
        out of controle and I had to stop for several hours. <br>
        <br>
        As you may have guessed, it didn't work. I thought another check wouldn't 
        be realistic anymore. After some time of thinking, I decided I better 
        knew for sure and I set a breakpoint on 4F707B, saved a file again and 
        when SoftICE broke, I set a 'bpm ebp-18' to check out if the counter was 
        checked somewhere else. And indeed....another <b>nifty, filthy</b> check, 
        that checks if the number of measures exceeds 27! (not 24, probably used 
        to trick us crackers).</p>
      <p><b><font color="#FF3300">Start partial code</font></b></p>
      <pre>:004F5BCB 3B45E8                  cmp eax, dword ptr [ebp-18]
:004F5BCE 0F8CB1140000            jl 004F7085
:004F5BD4 6A00                    push 00000000</pre>
      <p><font color="#FF3300"><b><font color="#FF3300">End partial code</font></b> 
        <br>
        </font></p>
      <p>To patch, nop out the 'jl'. <br>
        Now, try to save a file again, reopen it and you'll see that everything 
        will work fine!! </p>
      <p>Hehe, that's limit one of three. Two to go :P No, the next two weren't 
        as difficult. </p>
      <p>I thought about enabling the import functions first. So I clicked File 
        - Import - Midi. *kaboom* &quot;Access violation at.....&quot;. My first 
        thought was that all the patching I previously did, caused the crash. 
        But as I couldn't find any mistake I started thinking about a CRC check. 
        <br>
        To be sure, I took the original .exe and changed one little stringbyte 
        on a random place, that had no importance at all. I tried to import and 
        I got the same crash. When I undid the little change I made, it ran fine 
        again. So, obviously a CRC!<br>
        Maybe you didn't know, but if a program checks its CRC, it has to open 
        itself with an API like CreateFileA or OpenFile. Therefore many CRC's 
        are easy to find. Set a breakpoint on CreateFileA and click Import - Midi 
        again. SoftICE breaks. Press F12 and trace through the code until you 
        see this suspicious code (I immediately felt it was supicious):</p>
      <p><b><font color="#FF3300">Start partial code</font></b></p>
      <pre>:004A27E4 8BC3                    mov eax, ebx
:004A27E6 E811010000              <font color="#0000FF">call 004A28FC</font> <b>(1.)</b>
:004A27EB 3B0598665500            <font color="#0000FF">cmp eax, dword ptr [00556698]</font><b>(2.)</b>
:004A27F1 7430                    <font color="#0000FF">je 004A2823</font>
:004A27F3 66837B2E00              cmp word ptr [ebx+2E], 0000
:004A27F8 740A                    je 004A2804
:004A27FA 8BD3                    mov edx, ebx
:004A27FC 8B4330                  mov eax, dword ptr [ebx+30]
:004A27FF FF532C                  call [ebx+2C]
:004A2802 EB1F                    jmp 004A2823

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A27F8(C)
|
:004A2804 6A10                    push 00000010

* Possible StringData Ref from Code Obj ->"Program error"
                                  |
:004A2806 6888284A00              push 004A2888

* Possible StringData Ref from Code Obj ->"This program has been modified "
                                        ->"either by a virus or by a transfer "
                                        ->"problem. It will terminate now."</pre>
      <p><font color="#FF3300"><b><font color="#FF3300">End partial code</font></b> 
        </font></p>
      <p>The string &quot;This program has been modified....&quot; never gets 
        displayed btw. <br>
        <b>(1.) </b>This call calculates our CRC<br>
        <b>(2.) </b>If the program is not modified, the conditional &quot;je&quot; 
        jumps.</p>
      <p>To patch, change the 'je' into 'jmp'.<br>
        Now try to import and now it works :-). Now we can concentrate on enabling 
        the 50-note importation (MIDI) limit. <br>
        I worked a lot on this one too and actually wasted a lot of time: it is 
        very very very hard to locate the check because: is it located when you 
        load the midi file? or when you get the option menu? or when you have 
        clicked 'OK' in the option menu, etc... . There are tons of unimportant 
        code for that import function. I tried with readfile, createfilea, hmemcpy, 
        all sort of breakpoints.......no success and a big problem. <br>
        Then an old w32dasm trick came up in my mind: What if I tried to search 
        in the dead listing for the hex value of 50 (50 notes you know). Hex value 
        is 32h. So I searched for '00000032' and noted all occcurences which looked 
        important......until I found this </p>
      <p><b><font color="#FF3300">Start partial code</font></b></p>
      <pre>* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005009E0(C)
|
:0050090A 83FF32                  cmp edi, 00000032
:0050090D 7E38                    jle 00500947
:0050090F 8B15EC735500            mov edx, dword ptr [005573EC]
:00500915 691217070000            imul edx, dword ptr [edx], 00000717</pre>
      <p><font color="#FF3300"><b><font color="#FF3300">End partial code</font></b> 
        </font></p>
      <p>EDI contains the number of notes read. It's obvious that you should patch 
        the 'jle' to 'jmp'. ;-) <br>
        Now try importing a midi file.....and it works perfectly :))</p>
      <p>I also managed to enable the ASCII import function, which is a lot more 
        difficult. As I don't know exactly how the checks work I won't explain 
        it here, but I'll just give you the location where you can find the checks 
        (there are 4 of them in the direct environment of the location I'll give 
        you). They are like cmp [ebp-28], 32 and cmp [ebp-28], 33. Location is: 
        <font color="#0000FF">4D454D</font></p>
      <p>Only <b>one (!!)</b> limit to go: the print string. It's not very difficult, 
        but we'll use some (sloppy?) alternative approach for this. I tried to 
        find a conditional jump that avoids or jumpes to the &quot;PrintEvalString&quot; 
        but I wasn't able to find it. Because it's a demo version, I don't think 
        there actually is a conditional jump to print the string or not.<br>
        Alternatively, I did a memory search in SoftICE for the eval string: &quot;s 
        0 lfffffff 'Evaluation' . Search for next occurences until you see this: 
        Gene-GuitarProVersionEvaluation=Guitar Pro - Evaluation version. If you 
        replace the &quot;Guitar Pro - Evaluation version&quot; with blank spaces, 
        and you do a print preview, or really print, the eval string won't be 
        visible no more. I tried to find out the function that put that message 
        there, but I noticed that it was a procedure used to display all strings 
        in Guitar Pro. <br>
        As a method of last resort, I searched for the &quot;Gene-GuitarPro......&quot; 
        string in HIEW and spaced it out. <br>
        When printing, or print previewing, another message appeared: &quot;Internal 
        error: Translation not found&quot;. Search for that string too in HIEW 
        and space it out. You'll now see that you can print everything like it 
        would be the full version.<br>
        <br>
        Okay, admitted: this is somewhat sloppy, but I didn't see any other method 
        to do so. Besides.....if you don't tamper with the program, this error 
        string isn't needed for anything else!<br>
        <br>
        Whohow! <br>
        Third and last limit enabled!!! And I'm finished! Hope you learned something 
        again......and now, I think, it's time for a beer. CHEERS!</p>
      </td>
  </tr>
  <tr> 
    <td bgcolor="white"> <b>IV. In the end</b></td>
  </tr>
  <tr> 
    <td height="11"> 
      <p>I hate Guitar Pro kinda now :) I ran it soooo many many times that I'm 
        tired of looking at it. But if you just crack this with this tutorial 
        or use a crack.....I'm sure you 'll find it a very good and usefull program 
        (at least if you're into music, like I am).<br>
        Personal greets goto CD_Knight (enjoyed it? hehe), Magic Mike and Kayaker 
        (who could give useful info on the registration possibilities of the demo 
        version).
      <p>I guess this is the one and only tutorial on Guitar Pro v(anyversion) 
        Demo (until 05-06-2000) and there's also no crack available for it yet. 
        I guess this proves that many crackers are or: 1. not skilled enough to 
        crack this, but more 2. too lazy to crack this or to write a tutorial 
        on it. Get up and reverse, write guys!<br>
        Well.....'till next time.....tata!<br>
        <br>
      <p>Greets, 
      <p> <b>The Blackbird</b> <br>
        Please report bugs in this essay to <a href="mailto:cracking@softhome.net">cracking@softhome.net</a>
    </td>
  </tr>
  <tr> 
    <td bgcolor="ffffcc"> 
      <center>
        <font face="Verdana, Courier" size="2" color="red"> <u><b>Endnote: </b></u><br>
        </font> Essay written by The Blackbird &copy; 1999-2000<br>
        This essay can be freely distributed/ published/ printed etc... as long 
        as no modifications are made. 
      </center>
    </td>
  </tr>
</table>
</BODY>
</HTML>
